From 0282345603f0649fdcb307a3ea1a7256bd5f7b88 Mon Sep 17 00:00:00 2001 From: hugh-unicenta Date: Thu, 6 Apr 2023 18:58:04 +0100 Subject: [PATCH] 5.0 Source Code Committing 5.0 Source Code --- .gitignore | 7 + pom.xml | 588 +++ .../com/unicenta/basic/BasicException.java | 58 + .../java/com/unicenta/beans/DateUtils.java | 121 + .../com/unicenta/beans/JCalendarDialog.form | 118 + .../com/unicenta/beans/JCalendarDialog.java | 274 ++ .../com/unicenta/beans/JCalendarPanel.form | 134 + .../com/unicenta/beans/JCalendarPanel.java | 376 ++ .../java/com/unicenta/beans/JClockPanel.form | 22 + .../java/com/unicenta/beans/JClockPanel.java | 252 ++ .../java/com/unicenta/beans/JFlowPanel.java | 214 + .../java/com/unicenta/beans/JGuestsPop.form | 175 + .../java/com/unicenta/beans/JGuestsPop.java | 226 ++ .../com/unicenta/beans/JNumberDialog.form | 241 ++ .../com/unicenta/beans/JNumberDialog.java | 300 ++ .../java/com/unicenta/beans/JNumberEvent.java | 51 + .../unicenta/beans/JNumberEventListener.java | 35 + .../java/com/unicenta/beans/JNumberKeys.form | 452 +++ .../java/com/unicenta/beans/JNumberKeys.java | 501 +++ .../java/com/unicenta/beans/JNumberPop.form | 175 + .../java/com/unicenta/beans/JNumberPop.java | 237 ++ .../com/unicenta/beans/JPasswordDialog.form | 204 + .../com/unicenta/beans/JPasswordDialog.java | 266 ++ .../java/com/unicenta/beans/JTimePanel.form | 92 + .../java/com/unicenta/beans/JTimePanel.java | 387 ++ .../com/unicenta/beans/LocaleResources.java | 127 + .../com/unicenta/beans/RoundedBorder.java | 268 ++ .../unicenta/data/gui/ComboBoxValModel.java | 184 + .../com/unicenta/data/gui/CompoundIcon.java | 57 + .../java/com/unicenta/data/gui/FindInfo.java | 149 + .../java/com/unicenta/data/gui/JCounter.form | 60 + .../java/com/unicenta/data/gui/JCounter.java | 104 + .../java/com/unicenta/data/gui/JFind.form | 232 ++ .../java/com/unicenta/data/gui/JFind.java | 269 ++ .../com/unicenta/data/gui/JImageEditor.form | 184 + .../com/unicenta/data/gui/JImageEditor.java | 444 +++ .../data/gui/JImageViewerCustomer.form | 131 + .../data/gui/JImageViewerCustomer.java | 395 ++ .../data/gui/JImageViewerProduct.form | 131 + .../data/gui/JImageViewerProduct.java | 395 ++ .../com/unicenta/data/gui/JLabelDirty.java | 52 + .../java/com/unicenta/data/gui/JListData.form | 117 + .../java/com/unicenta/data/gui/JListData.java | 175 + .../com/unicenta/data/gui/JListNavigator.form | 54 + .../com/unicenta/data/gui/JListNavigator.java | 150 + .../com/unicenta/data/gui/JMessageDialog.form | 180 + .../com/unicenta/data/gui/JMessageDialog.java | 249 ++ .../com/unicenta/data/gui/JNavigator.form | 22 + .../com/unicenta/data/gui/JNavigator.java | 372 ++ .../java/com/unicenta/data/gui/JSaver.form | 106 + .../java/com/unicenta/data/gui/JSaver.java | 189 + .../java/com/unicenta/data/gui/JSort.form | 221 ++ .../java/com/unicenta/data/gui/JSort.java | 270 ++ .../data/gui/ListCellRendererBasic.java | 49 + .../java/com/unicenta/data/gui/ListKeyed.java | 55 + .../unicenta/data/gui/ListQBFModelNumber.java | 141 + .../com/unicenta/data/gui/MessageInf.java | 224 ++ .../java/com/unicenta/data/gui/NullIcon.java | 55 + .../unicenta/data/gui/TableRendererBasic.java | 52 + .../unicenta/data/loader/BaseSentence.java | 275 ++ .../data/loader/BasicSentenceEnum.java | 89 + .../unicenta/data/loader/BatchSentence.java | 345 ++ .../data/loader/BatchSentenceResource.java | 63 + .../data/loader/BatchSentenceScript.java | 51 + .../unicenta/data/loader/CompanyDetails.java | 63 + .../data/loader/ComparatorCreator.java | 42 + .../data/loader/ComparatorCreatorBasic.java | 117 + .../com/unicenta/data/loader/DataField.java | 46 + .../com/unicenta/data/loader/DataParams.java | 121 + .../com/unicenta/data/loader/DataRead.java | 96 + .../unicenta/data/loader/DataResultSet.java | 56 + .../com/unicenta/data/loader/DataWrite.java | 86 + .../unicenta/data/loader/DataWriteUtils.java | 156 + .../java/com/unicenta/data/loader/Datas.java | 388 ++ .../com/unicenta/data/loader/IKeyGetter.java | 34 + .../java/com/unicenta/data/loader/IKeyed.java | 35 + .../unicenta/data/loader/IRenderString.java | 34 + .../data/loader/ISQLBuilderStatic.java | 38 + .../com/unicenta/data/loader/ImageUtils.java | 245 ++ .../unicenta/data/loader/ImportSentence.java | 62 + .../unicenta/data/loader/JDBCSentence.java | 236 ++ .../unicenta/data/loader/KeyGetterBasic.java | 54 + .../data/loader/KeyGetterBuilder.java | 51 + .../unicenta/data/loader/KeyGetterFirst.java | 50 + .../com/unicenta/data/loader/LocalRes.java | 51 + .../unicenta/data/loader/MetaSentence.java | 212 + .../unicenta/data/loader/NormalBuilder.java | 136 + .../data/loader/PreparedSentence.java | 250 ++ .../com/unicenta/data/loader/QBFBuilder.java | 201 + .../unicenta/data/loader/QBFCompareEnum.java | 140 + .../data/loader/RenderStringBasic.java | 65 + .../unicenta/data/loader/SentenceEnum.java | 56 + .../unicenta/data/loader/SentenceExec.java | 52 + .../data/loader/SentenceExecAdapter.java | 56 + .../data/loader/SentenceExecTransaction.java | 86 + .../unicenta/data/loader/SentenceFind.java | 52 + .../unicenta/data/loader/SentenceList.java | 72 + .../data/loader/SentenceUpdateResultSet.java | 154 + .../data/loader/SequenceForDerby.java | 75 + .../data/loader/SequenceForMySQL.java | 71 + .../data/loader/SequenceForSQLite.java | 48 + .../data/loader/SerializableBuilder.java | 33 + .../data/loader/SerializableRead.java | 36 + .../data/loader/SerializableWrite.java | 36 + .../unicenta/data/loader/SerializerRead.java | 37 + .../data/loader/SerializerReadBasic.java | 52 + .../data/loader/SerializerReadBuilder.java | 50 + .../data/loader/SerializerReadBytes.java | 48 + .../data/loader/SerializerReadClass.java | 55 + .../data/loader/SerializerReadDate.java | 50 + .../data/loader/SerializerReadDouble.java | 48 + .../data/loader/SerializerReadImage.java | 49 + .../data/loader/SerializerReadInteger.java | 48 + .../data/loader/SerializerReadString.java | 48 + .../data/loader/SerializerReadUTF8.java | 52 + .../unicenta/data/loader/SerializerWrite.java | 38 + .../data/loader/SerializerWriteBasic.java | 52 + .../loader/SerializerWriteBasicComposed.java | 55 + .../data/loader/SerializerWriteBasicExt.java | 55 + .../data/loader/SerializerWriteBuilder.java | 48 + .../data/loader/SerializerWriteComposed.java | 115 + .../data/loader/SerializerWriteInteger.java | 48 + .../data/loader/SerializerWriteParams.java | 47 + .../data/loader/SerializerWriteString.java | 58 + .../com/unicenta/data/loader/Session.java | 213 + .../com/unicenta/data/loader/SessionDB.java | 76 + .../unicenta/data/loader/SessionDBDerby.java | 94 + .../data/loader/SessionDBGeneric.java | 97 + .../unicenta/data/loader/SessionDBHSQLDB.java | 94 + .../data/loader/SessionDBMariaDB.java | 89 + .../unicenta/data/loader/SessionDBMySQL.java | 89 + .../unicenta/data/loader/SessionDBOracle.java | 87 + .../data/loader/SessionDBPostgreSQL.java | 94 + .../unicenta/data/loader/SessionDBSQLite.java | 70 + .../unicenta/data/loader/SimpleBuilder.java | 49 + .../unicenta/data/loader/StaticSentence.java | 224 ++ .../unicenta/data/loader/TableDefinition.java | 349 ++ .../unicenta/data/loader/TicketFooter.java | 83 + .../unicenta/data/loader/TicketHeader.java | 83 + .../com/unicenta/data/loader/Transaction.java | 74 + .../com/unicenta/data/loader/Vectorer.java | 46 + .../unicenta/data/loader/VectorerBasic.java | 77 + .../unicenta/data/loader/VectorerBuilder.java | 108 + .../java/com/unicenta/data/model/Column.java | 53 + .../java/com/unicenta/data/model/Field.java | 114 + .../com/unicenta/data/model/PrimaryKey.java | 44 + .../java/com/unicenta/data/model/Row.java | 358 ++ .../java/com/unicenta/data/model/Table.java | 159 + .../com/unicenta/data/user/BrowsableData.java | 410 ++ .../data/user/BrowsableEditableData.java | 595 +++ .../unicenta/data/user/BrowseListener.java | 34 + .../com/unicenta/data/user/DirtyListener.java | 33 + .../com/unicenta/data/user/DirtyManager.java | 123 + .../unicenta/data/user/DocumentLoader.java | 43 + .../data/user/DocumentLoaderBasic.java | 56 + .../com/unicenta/data/user/EditorCreator.java | 36 + .../data/user/EditorCreatorComposed.java | 52 + .../unicenta/data/user/EditorListener.java | 33 + .../com/unicenta/data/user/EditorRecord.java | 62 + .../data/user/FilterEditorCreator.java | 35 + .../java/com/unicenta/data/user/Finder.java | 37 + .../com/unicenta/data/user/ListProvider.java | 44 + .../data/user/ListProviderCreator.java | 82 + .../com/unicenta/data/user/SaveProvider.java | 130 + .../com/unicenta/data/user/StateListener.java | 34 + .../com/unicenta/editor/EditorComponent.java | 58 + .../java/com/unicenta/editor/EditorKeys.java | 65 + .../com/unicenta/editor/JEditorAbstract.form | 81 + .../com/unicenta/editor/JEditorAbstract.java | 245 ++ .../com/unicenta/editor/JEditorCurrency.java | 51 + .../editor/JEditorCurrencyPositive.java | 52 + .../com/unicenta/editor/JEditorDouble.java | 49 + .../editor/JEditorDoublePositive.java | 49 + .../editor/JEditorIntegerPositive.java | 49 + .../java/com/unicenta/editor/JEditorKeys.form | 279 ++ .../java/com/unicenta/editor/JEditorKeys.java | 516 +++ .../com/unicenta/editor/JEditorNumber.java | 286 ++ .../com/unicenta/editor/JEditorPassword.java | 104 + .../com/unicenta/editor/JEditorString.java | 52 + .../unicenta/editor/JEditorStringNumber.java | 48 + .../java/com/unicenta/editor/JEditorText.java | 407 ++ .../java/com/unicenta/format/DoubleUtils.java | 22 + .../java/com/unicenta/format/Formats.java | 438 ++ .../com/unicenta/format/FormatsConstrain.java | 56 + .../com/unicenta/format/FormatsException.java | 41 + .../com/unicenta/format/FormatsRESOURCE.java | 76 + .../com/unicenta/format/FormatsValidate.java | 87 + .../java/com/unicenta/orderpop/OrderPop.java | 308 ++ .../java/com/unicenta/orderpop/listStyle.css | 22 + .../unicenta/pos/admin/DataLogicAdmin.java | 131 + .../com/unicenta/pos/admin/JPeopleFinder.form | 339 ++ .../com/unicenta/pos/admin/JPeopleFinder.java | 417 ++ .../java/com/unicenta/pos/admin/OWWatch.java | 174 + .../com/unicenta/pos/admin/PeopleInfo.java | 102 + .../com/unicenta/pos/admin/PeoplePanel.java | 131 + .../unicenta/pos/admin/PeopleRenderer.java | 49 + .../com/unicenta/pos/admin/PeopleView.form | 289 ++ .../com/unicenta/pos/admin/PeopleView.java | 467 +++ .../com/unicenta/pos/admin/ResourceType.java | 39 + .../unicenta/pos/admin/ResourcesPanel.java | 130 + .../com/unicenta/pos/admin/ResourcesView.form | 164 + .../com/unicenta/pos/admin/ResourcesView.java | 377 ++ .../com/unicenta/pos/admin/RoleExtInfo.java | 80 + .../java/com/unicenta/pos/admin/RoleInfo.java | 105 + .../com/unicenta/pos/admin/RolesPanel.java | 121 + .../com/unicenta/pos/admin/RolesView.java | 192 + .../unicenta/pos/catalog/CatalogSelector.java | 67 + .../unicenta/pos/catalog/CategoryStock.java | 118 + .../com/unicenta/pos/catalog/JCatalog.form | 229 ++ .../com/unicenta/pos/catalog/JCatalog.java | 622 +++ .../com/unicenta/pos/catalog/JCatalogTab.form | 22 + .../com/unicenta/pos/catalog/JCatalogTab.java | 98 + .../pos/catalog/JProductsSelector.form | 44 + .../pos/catalog/JProductsSelector.java | 95 + .../com/unicenta/pos/comm/CommStream.java | 123 + .../com/unicenta/pos/config/JFrmConfig.form | 31 + .../com/unicenta/pos/config/JFrmConfig.java | 128 + .../pos/config/JPanelConfigCompany.form | 492 +++ .../pos/config/JPanelConfigCompany.java | 425 ++ .../pos/config/JPanelConfigDatabase.form | 1150 ++++++ .../pos/config/JPanelConfigDatabase.java | 1298 ++++++ .../unicenta/pos/config/JPanelConfigERP.form | 226 ++ .../unicenta/pos/config/JPanelConfigERP.java | 247 ++ .../pos/config/JPanelConfigGeneral.form | 655 +++ .../pos/config/JPanelConfigGeneral.java | 668 ++++ .../pos/config/JPanelConfigLocale.form | 347 ++ .../pos/config/JPanelConfigLocale.java | 425 ++ .../pos/config/JPanelConfigPayment.form | 216 + .../pos/config/JPanelConfigPayment.java | 303 ++ .../pos/config/JPanelConfigPeripheral.form | 2344 +++++++++++ .../pos/config/JPanelConfigPeripheral.java | 2549 ++++++++++++ .../pos/config/JPanelConfigSystem.form | 922 +++++ .../pos/config/JPanelConfigSystem.java | 828 ++++ .../pos/config/JPanelConfiguration.form | 312 ++ .../pos/config/JPanelConfiguration.java | 384 ++ .../pos/config/JPanelTicketSetup.form | 244 ++ .../pos/config/JPanelTicketSetup.java | 400 ++ .../unicenta/pos/config/LocaleComparator.java | 39 + .../com/unicenta/pos/config/PanelConfig.java | 54 + .../unicenta/pos/config/ParametersConfig.java | 56 + .../pos/config/ParametersPrinter.form | 70 + .../pos/config/ParametersPrinter.java | 149 + .../unicenta/pos/customers/CustomerInfo.java | 171 + .../pos/customers/CustomerInfoExt.java | 467 +++ .../pos/customers/CustomerInfoGlobal.java | 88 + .../pos/customers/CustomerRenderer.java | 53 + .../pos/customers/CustomerTransaction.java | 209 + .../pos/customers/CustomersPanel.java | 135 + .../pos/customers/CustomersPayment.form | 572 +++ .../pos/customers/CustomersPayment.java | 793 ++++ .../unicenta/pos/customers/CustomersView.form | 1373 +++++++ .../unicenta/pos/customers/CustomersView.java | 1639 ++++++++ .../pos/customers/DataLogicCustomers.java | 381 ++ .../pos/customers/JCustomerFinder.form | 551 +++ .../pos/customers/JCustomerFinder.java | 699 ++++ .../pos/customers/JDialogNewCustomer.form | 582 +++ .../pos/customers/JDialogNewCustomer.java | 520 +++ .../pos/customers/OrderCustomerList.form | 42 + .../pos/customers/OrderCustomerList.java | 360 ++ .../pos/customers/TicketSelector.java | 46 + src/main/java/com/unicenta/pos/epm/Break.java | 110 + .../java/com/unicenta/pos/epm/BreaksInfo.java | 89 + .../com/unicenta/pos/epm/BreaksPanel.java | 133 + .../java/com/unicenta/pos/epm/BreaksView.form | 127 + .../java/com/unicenta/pos/epm/BreaksView.java | 239 ++ .../pos/epm/DataLogicPresenceManagement.java | 450 +++ .../com/unicenta/pos/epm/EmployeeInfo.java | 87 + .../com/unicenta/pos/epm/EmployeeInfoExt.java | 54 + .../unicenta/pos/epm/EmployeeRenderer.java | 48 + .../com/unicenta/pos/epm/JEmployeeFinder.form | 288 ++ .../com/unicenta/pos/epm/JEmployeeFinder.java | 383 ++ .../pos/epm/JPanelEmployeePresence.form | 133 + .../pos/epm/JPanelEmployeePresence.java | 327 ++ .../java/com/unicenta/pos/epm/LeavesInfo.java | 164 + .../com/unicenta/pos/epm/LeavesPanel.java | 130 + .../java/com/unicenta/pos/epm/LeavesView.form | 237 ++ .../java/com/unicenta/pos/epm/LeavesView.java | 432 ++ .../com/unicenta/pos/forms/AppConfig.java | 400 ++ .../java/com/unicenta/pos/forms/AppLocal.java | 65 + .../com/unicenta/pos/forms/AppProperties.java | 48 + .../java/com/unicenta/pos/forms/AppUser.java | 304 ++ .../com/unicenta/pos/forms/AppUserView.java | 52 + .../java/com/unicenta/pos/forms/AppView.java | 74 + .../unicenta/pos/forms/AppViewConnection.java | 145 + .../com/unicenta/pos/forms/BeanFactory.java | 33 + .../unicenta/pos/forms/BeanFactoryApp.java | 35 + .../unicenta/pos/forms/BeanFactoryCache.java | 56 + .../unicenta/pos/forms/BeanFactoryData.java | 64 + .../pos/forms/BeanFactoryDataSingle.java | 58 + .../pos/forms/BeanFactoryException.java | 50 + .../unicenta/pos/forms/BeanFactoryObj.java | 45 + .../unicenta/pos/forms/BeanFactoryScript.java | 82 + .../unicenta/pos/forms/DataLogicOrders.java | 81 + .../unicenta/pos/forms/DataLogicSales.java | 2828 +++++++++++++ .../unicenta/pos/forms/DataLogicSystem.java | 891 +++++ .../com/unicenta/pos/forms/DriverWrapper.java | 73 + .../pos/forms/JDlgChangePassword.form | 219 + .../pos/forms/JDlgChangePassword.java | 242 ++ .../com/unicenta/pos/forms/JPanelMenu.form | 50 + .../com/unicenta/pos/forms/JPanelMenu.java | 153 + .../com/unicenta/pos/forms/JPanelNull.form | 60 + .../com/unicenta/pos/forms/JPanelNull.java | 115 + .../com/unicenta/pos/forms/JPanelView.java | 54 + .../com/unicenta/pos/forms/JPrincipalApp.form | 202 + .../com/unicenta/pos/forms/JPrincipalApp.java | 650 +++ .../java/com/unicenta/pos/forms/JRootApp.form | 443 +++ .../java/com/unicenta/pos/forms/JRootApp.java | 1217 ++++++ .../com/unicenta/pos/forms/JRootFrame.form | 28 + .../com/unicenta/pos/forms/JRootFrame.java | 161 + .../com/unicenta/pos/forms/JRootKiosk.form | 28 + .../com/unicenta/pos/forms/JRootKiosk.java | 175 + .../unicenta/pos/forms/MenuDefinition.java | 94 + .../com/unicenta/pos/forms/MenuElement.java | 33 + .../unicenta/pos/forms/MenuExecAction.java | 52 + .../pos/forms/MenuItemDefinition.java | 60 + .../unicenta/pos/forms/MenuPanelAction.java | 73 + .../pos/forms/MenuTitleDefinition.java | 51 + .../java/com/unicenta/pos/forms/Payments.java | 163 + .../com/unicenta/pos/forms/ProcessAction.java | 37 + .../java/com/unicenta/pos/forms/StartPOS.java | 138 + .../pos/imports/CustomerCSVImport.form | 1302 ++++++ .../pos/imports/CustomerCSVImport.java | 2005 ++++++++++ .../com/unicenta/pos/imports/JPanelCSV.form | 28 + .../com/unicenta/pos/imports/JPanelCSV.java | 53 + .../pos/imports/JPanelCSVCleardb.form | 133 + .../pos/imports/JPanelCSVCleardb.java | 238 ++ .../unicenta/pos/imports/JPanelCSVImport.form | 1268 ++++++ .../unicenta/pos/imports/JPanelCSVImport.java | 2076 ++++++++++ .../unicenta/pos/imports/StockQtyImport.form | 443 +++ .../unicenta/pos/imports/StockQtyImport.java | 897 +++++ .../com/unicenta/pos/instance/AppMessage.java | 36 + .../pos/instance/InstanceManager.java | 52 + .../unicenta/pos/instance/InstanceQuery.java | 51 + .../pos/inventory/AttributeFilter.form | 69 + .../pos/inventory/AttributeFilter.java | 177 + .../unicenta/pos/inventory/AttributeInfo.java | 62 + .../pos/inventory/AttributeSetFilter.form | 71 + .../pos/inventory/AttributeSetFilter.java | 170 + .../pos/inventory/AttributeSetInfo.java | 72 + .../pos/inventory/AttributeSetsEditor.form | 66 + .../pos/inventory/AttributeSetsEditor.java | 179 + .../pos/inventory/AttributeSetsPanel.java | 80 + .../pos/inventory/AttributeUseEditor.form | 108 + .../pos/inventory/AttributeUseEditor.java | 261 ++ .../pos/inventory/AttributeUsePanel.java | 134 + .../pos/inventory/AttributeValuesEditor.form | 66 + .../pos/inventory/AttributeValuesEditor.java | 196 + .../pos/inventory/AttributeValuesPanel.java | 128 + .../pos/inventory/AttributesEditor.form | 66 + .../pos/inventory/AttributesEditor.java | 179 + .../pos/inventory/AttributesPanel.java | 80 + .../pos/inventory/AuxiliarEditor.form | 206 + .../pos/inventory/AuxiliarEditor.java | 427 ++ .../unicenta/pos/inventory/AuxiliarPanel.java | 134 + .../unicenta/pos/inventory/BundleEditor.form | 207 + .../unicenta/pos/inventory/BundleEditor.java | 412 ++ .../unicenta/pos/inventory/BundlePanel.java | 118 + .../pos/inventory/CategoriesEditor.form | 383 ++ .../pos/inventory/CategoriesEditor.java | 675 ++++ .../pos/inventory/CategoriesPanel.java | 120 + .../com/unicenta/pos/inventory/CodeType.java | 75 + .../unicenta/pos/inventory/InvEditLine.form | 112 + .../unicenta/pos/inventory/InvEditLine.java | 137 + .../unicenta/pos/inventory/InventoryLine.java | 212 + .../pos/inventory/InventoryRecord.java | 204 + .../pos/inventory/JDlgUploadProducts.form | 114 + .../pos/inventory/JDlgUploadProducts.java | 212 + .../pos/inventory/JInventoryLines.form | 61 + .../pos/inventory/JInventoryLines.java | 362 ++ .../unicenta/pos/inventory/LocationInfo.java | 117 + .../pos/inventory/LocationsPanel.java | 120 + .../unicenta/pos/inventory/LocationsView.form | 105 + .../unicenta/pos/inventory/LocationsView.java | 227 ++ .../pos/inventory/MaterialFilter.form | 160 + .../pos/inventory/MaterialFilter.java | 164 + .../pos/inventory/MaterialProdInfo.java | 169 + .../pos/inventory/MovementReason.java | 85 + .../pos/inventory/PriceImportPanel.java | 148 + .../unicenta/pos/inventory/ProductStock.java | 186 + .../pos/inventory/ProductsBundleInfo.java | 92 + .../pos/inventory/ProductsEditor.form | 1823 +++++++++ .../pos/inventory/ProductsEditor.java | 2371 +++++++++++ .../unicenta/pos/inventory/ProductsPanel.java | 144 + .../inventory/ProductsWarehouseEditor.form | 157 + .../inventory/ProductsWarehouseEditor.java | 271 ++ .../pos/inventory/ProductsWarehousePanel.java | 173 + .../pos/inventory/StockDiaryEditor.form | 665 ++++ .../pos/inventory/StockDiaryEditor.java | 993 +++++ .../pos/inventory/StockDiaryPanel.java | 104 + .../pos/inventory/StockManagement.form | 828 ++++ .../pos/inventory/StockManagement.java | 1345 +++++++ .../unicenta/pos/inventory/StockModel.java | 73 + .../pos/inventory/TaxCategoriesEditor.form | 72 + .../pos/inventory/TaxCategoriesEditor.java | 197 + .../pos/inventory/TaxCategoriesPanel.java | 120 + .../pos/inventory/TaxCategoryInfo.java | 91 + .../inventory/TaxCustCategoriesEditor.form | 56 + .../inventory/TaxCustCategoriesEditor.java | 182 + .../pos/inventory/TaxCustCategoriesPanel.java | 120 + .../pos/inventory/TaxCustCategoryInfo.java | 88 + .../com/unicenta/pos/inventory/TaxEditor.form | 259 ++ .../com/unicenta/pos/inventory/TaxEditor.java | 428 ++ .../com/unicenta/pos/inventory/TaxPanel.java | 132 + .../com/unicenta/pos/inventory/UomEditor.form | 77 + .../com/unicenta/pos/inventory/UomEditor.java | 158 + .../com/unicenta/pos/inventory/UomInfo.java | 59 + .../com/unicenta/pos/inventory/UomPanel.java | 59 + .../com/unicenta/pos/mant/Applications.java | 122 + .../java/com/unicenta/pos/mant/Floors.java | 121 + .../com/unicenta/pos/mant/FloorsEditor.form | 105 + .../com/unicenta/pos/mant/FloorsEditor.java | 197 + .../com/unicenta/pos/mant/FloorsInfo.java | 101 + .../com/unicenta/pos/mant/JPanelFloors.java | 117 + .../com/unicenta/pos/mant/JPanelPlaces.java | 141 + .../java/com/unicenta/pos/mant/Places.java | 245 ++ .../com/unicenta/pos/mant/PlacesEditor.form | 349 ++ .../com/unicenta/pos/mant/PlacesEditor.java | 418 ++ .../unicenta/pos/panels/AuxiliarFilter.form | 208 + .../unicenta/pos/panels/AuxiliarFilter.java | 362 ++ .../com/unicenta/pos/panels/BundleFilter.form | 194 + .../com/unicenta/pos/panels/BundleFilter.java | 310 ++ .../unicenta/pos/panels/ComboItemLocal.java | 73 + .../unicenta/pos/panels/EnumerationIter.java | 49 + .../unicenta/pos/panels/JPanelCloseMoney.form | 613 +++ .../unicenta/pos/panels/JPanelCloseMoney.java | 797 ++++ .../pos/panels/JPanelCloseMoneyReprint.form | 597 +++ .../pos/panels/JPanelCloseMoneyReprint.java | 690 ++++ .../unicenta/pos/panels/JPanelPayments.java | 87 + .../unicenta/pos/panels/JPanelPrinter.form | 60 + .../unicenta/pos/panels/JPanelPrinter.java | 129 + .../com/unicenta/pos/panels/JPanelTable.form | 51 + .../com/unicenta/pos/panels/JPanelTable.java | 274 ++ .../com/unicenta/pos/panels/JPanelTable2.java | 94 + .../unicenta/pos/panels/JProductFinder.form | 280 ++ .../unicenta/pos/panels/JProductFinder.java | 372 ++ .../unicenta/pos/panels/JTextFieldLimit.java | 22 + .../unicenta/pos/panels/JTicketsFinder.form | 642 +++ .../unicenta/pos/panels/JTicketsFinder.java | 820 ++++ .../unicenta/pos/panels/PaymentsEditor.form | 150 + .../unicenta/pos/panels/PaymentsEditor.java | 357 ++ .../unicenta/pos/panels/PaymentsModel.java | 1106 ++++++ .../pos/panels/PaymentsReprintModel.java | 1097 +++++ .../pos/panels/Printer.PartialCash.xml | 186 + .../com/unicenta/pos/panels/SQLColumn.java | 75 + .../com/unicenta/pos/panels/SQLDatabase.java | 97 + .../com/unicenta/pos/panels/SQLTable.java | 111 + .../unicenta/pos/panels/SQLTableModel.java | 153 + .../pos/payment/ConfigPaymentPanelEmpty.form | 39 + .../pos/payment/ConfigPaymentPanelEmpty.java | 92 + .../payment/ConfigPaymentPanelGeneric.form | 108 + .../payment/ConfigPaymentPanelGeneric.java | 143 + .../unicenta/pos/payment/JPaymentBank.form | 140 + .../unicenta/pos/payment/JPaymentBank.java | 185 + .../unicenta/pos/payment/JPaymentCashPos.form | 230 ++ .../unicenta/pos/payment/JPaymentCashPos.java | 336 ++ .../unicenta/pos/payment/JPaymentCheque.form | 138 + .../unicenta/pos/payment/JPaymentCheque.java | 198 + .../unicenta/pos/payment/JPaymentDebt.form | 412 ++ .../unicenta/pos/payment/JPaymentDebt.java | 400 ++ .../unicenta/pos/payment/JPaymentFree.form | 50 + .../unicenta/pos/payment/JPaymentFree.java | 113 + .../pos/payment/JPaymentInterface.java | 34 + .../unicenta/pos/payment/JPaymentMagcard.form | 70 + .../unicenta/pos/payment/JPaymentMagcard.java | 162 + .../pos/payment/JPaymentNotifier.java | 38 + .../unicenta/pos/payment/JPaymentPaper.form | 254 ++ .../unicenta/pos/payment/JPaymentPaper.java | 348 ++ .../unicenta/pos/payment/JPaymentRefund.form | 48 + .../unicenta/pos/payment/JPaymentRefund.java | 115 + .../unicenta/pos/payment/JPaymentSelect.form | 379 ++ .../unicenta/pos/payment/JPaymentSelect.java | 787 ++++ .../pos/payment/JPaymentSelectCustomer.java | 97 + .../pos/payment/JPaymentSelectReceipt.java | 100 + .../pos/payment/JPaymentSelectRefund.java | 95 + .../unicenta/pos/payment/JPaymentSlip.form | 140 + .../unicenta/pos/payment/JPaymentSlip.java | 180 + .../unicenta/pos/payment/JPaymentVoucher.form | 292 ++ .../unicenta/pos/payment/JPaymentVoucher.java | 391 ++ .../unicenta/pos/payment/MagCardReader.java | 40 + .../pos/payment/MagCardReaderFac.java | 43 + .../pos/payment/MagCardReaderGeneric.java | 242 ++ .../pos/payment/MagCardReaderIntelligent.java | 137 + .../pos/payment/PaymentConfiguration.java | 49 + .../pos/payment/PaymentException.java | 42 + .../unicenta/pos/payment/PaymentGateway.java | 33 + .../pos/payment/PaymentGatewayExt.java | 40 + .../pos/payment/PaymentGatewayFac.java | 46 + .../payment/PaymentGatewayPaymentSense.java | 86 + .../com/unicenta/pos/payment/PaymentInfo.java | 39 + .../unicenta/pos/payment/PaymentInfoCash.java | 133 + .../pos/payment/PaymentInfoCash_original.java | 98 + .../unicenta/pos/payment/PaymentInfoFree.java | 86 + .../unicenta/pos/payment/PaymentInfoList.java | 62 + .../pos/payment/PaymentInfoMagcard.java | 310 ++ .../pos/payment/PaymentInfoMagcardRefund.java | 53 + .../pos/payment/PaymentInfoTicket.java | 154 + .../unicenta/pos/payment/PaymentPanel.java | 29 + .../pos/payment/PaymentPanelBasic.form | 21 + .../pos/payment/PaymentPanelBasic.java | 102 + .../unicenta/pos/payment/PaymentPanelEMV.java | 108 + .../unicenta/pos/payment/PaymentPanelFac.java | 47 + .../pos/payment/PaymentPanelMagCard.form | 267 ++ .../pos/payment/PaymentPanelMagCard.java | 518 +++ .../pos/payment/PaymentPanelType.form | 232 ++ .../pos/payment/PaymentPanelType.java | 273 ++ .../pos/payment/VoucherPaymentInfo.java | 112 + .../unicenta/pos/printer/BaseAnimator.java | 83 + .../unicenta/pos/printer/BlinkAnimator.java | 54 + .../unicenta/pos/printer/CurtainAnimator.java | 56 + .../unicenta/pos/printer/DeviceDisplay.java | 71 + .../pos/printer/DeviceDisplayBase.java | 146 + .../pos/printer/DeviceDisplayImpl.java | 32 + .../pos/printer/DeviceDisplayNull.java | 97 + .../pos/printer/DeviceFiscalPrinter.java | 83 + .../pos/printer/DeviceFiscalPrinterNull.java | 114 + .../unicenta/pos/printer/DevicePrinter.java | 82 + .../pos/printer/DevicePrinterNull.java | 149 + .../unicenta/pos/printer/DeviceTicket.java | 432 ++ .../unicenta/pos/printer/DisplayAnimator.java | 45 + .../unicenta/pos/printer/FlyerAnimator.java | 54 + .../unicenta/pos/printer/NullAnimator.java | 73 + .../unicenta/pos/printer/ScrollAnimator.java | 56 + .../unicenta/pos/printer/TicketParser.java | 506 +++ .../pos/printer/TicketPrinterException.java | 52 + .../unicenta/pos/printer/escpos/Codes.java | 258 ++ .../pos/printer/escpos/CodesEpson.java | 155 + .../pos/printer/escpos/CodesIthaca.java | 154 + .../pos/printer/escpos/CodesStar.java | 258 ++ .../pos/printer/escpos/CodesSurePOS.java | 169 + .../pos/printer/escpos/CodesTMU220.java | 197 + .../printer/escpos/DeviceDisplayESCPOS.java | 76 + .../printer/escpos/DeviceDisplaySerial.java | 121 + .../printer/escpos/DeviceDisplaySurePOS.java | 66 + .../printer/escpos/DevicePrinterESCPOS.java | 227 ++ .../printer/escpos/DevicePrinterPlain.java | 168 + .../unicenta/pos/printer/escpos/ESCPOS.java | 55 + .../pos/printer/escpos/PrinterWritter.java | 114 + .../printer/escpos/PrinterWritterFile.java | 91 + .../printer/escpos/PrinterWritterRXTX.java | 111 + .../pos/printer/escpos/PrinterWritterRaw.java | 167 + .../pos/printer/escpos/UnicodeTranslator.java | 188 + .../printer/escpos/UnicodeTranslatorEur.java | 76 + .../printer/escpos/UnicodeTranslatorInt.java | 214 + .../printer/escpos/UnicodeTranslatorStar.java | 192 + .../escpos/UnicodeTranslatorSurePOS.java | 214 + .../printer/javapos/DeviceDisplayJavaPOS.java | 136 + .../javapos/DeviceFiscalPrinterJavaPOS.form | 246 ++ .../javapos/DeviceFiscalPrinterJavaPOS.java | 323 ++ .../printer/javapos/DevicePrinterJavaPOS.java | 280 ++ .../printer/printer/DevicePrinterPrinter.java | 362 ++ .../printer/printer/PrintableBasicTicket.java | 100 + .../printer/screen/DeviceDisplayPanel.form | 77 + .../printer/screen/DeviceDisplayPanel.java | 200 + .../printer/screen/DeviceDisplayWindow.form | 49 + .../printer/screen/DeviceDisplayWindow.java | 134 + .../printer/screen/DevicePrinterPanel.form | 33 + .../printer/screen/DevicePrinterPanel.java | 188 + .../unicenta/pos/printer/screen/JTicket.form | 30 + .../unicenta/pos/printer/screen/JTicket.java | 107 + .../pos/printer/screen/JTicketContainer.form | 25 + .../pos/printer/screen/JTicketContainer.java | 133 + .../java/com/unicenta/pos/printer/ticket.dtd | 48 + .../pos/printer/ticket/BasicTicket.java | 169 + .../printer/ticket/BasicTicketForPrinter.java | 73 + .../printer/ticket/BasicTicketForScreen.java | 68 + .../pos/printer/ticket/MyPrinterState.java | 103 + .../pos/printer/ticket/PrintItem.java | 44 + .../pos/printer/ticket/PrintItemBarcode.java | 118 + .../pos/printer/ticket/PrintItemImage.java | 73 + .../pos/printer/ticket/PrintItemLine.java | 129 + .../unicenta/pos/reports/JPanelReport.form | 100 + .../unicenta/pos/reports/JPanelReport.java | 330 ++ .../unicenta/pos/reports/JParamsComposed.form | 24 + .../unicenta/pos/reports/JParamsComposed.java | 142 + .../unicenta/pos/reports/JParamsCustomer.form | 98 + .../unicenta/pos/reports/JParamsCustomer.java | 204 + .../pos/reports/JParamsDatesInterval.form | 156 + .../pos/reports/JParamsDatesInterval.java | 242 ++ .../unicenta/pos/reports/JParamsLocation.form | 74 + .../unicenta/pos/reports/JParamsLocation.java | 179 + .../pos/reports/JParamsLocationWithFirst.java | 43 + .../unicenta/pos/reports/JParamsReason.form | 75 + .../unicenta/pos/reports/JParamsReason.java | 161 + .../pos/reports/JParamsSuppliers.form | 103 + .../pos/reports/JParamsSuppliers.java | 207 + .../com/unicenta/pos/reports/JParamsText.form | 58 + .../com/unicenta/pos/reports/JParamsText.java | 234 ++ .../com/unicenta/pos/reports/JParamsUser.form | 93 + .../com/unicenta/pos/reports/JParamsUser.java | 201 + .../pos/reports/JRDataSourceBasic.java | 97 + .../unicenta/pos/reports/PanelReportBean.java | 201 + .../pos/reports/ReportEditorCreator.java | 50 + .../unicenta/pos/reports/ReportException.java | 49 + .../unicenta/pos/reports/ReportFields.java | 36 + .../pos/reports/ReportFieldsArray.java | 68 + .../com/unicenta/pos/resets/JPanelResets.form | 28 + .../com/unicenta/pos/resets/JPanelResets.java | 53 + .../unicenta/pos/resets/JResetPickupID.java | 134 + .../unicenta/pos/sales/DataLogicReceipts.java | 384 ++ .../unicenta/pos/sales/JMooringDetails.form | 159 + .../unicenta/pos/sales/JMooringDetails.java | 307 ++ .../com/unicenta/pos/sales/JPanelButtons.form | 22 + .../com/unicenta/pos/sales/JPanelButtons.java | 221 ++ .../pos/sales/JPanelResetPickupId.form | 114 + .../pos/sales/JPanelResetPickupId.java | 275 ++ .../com/unicenta/pos/sales/JPanelTicket.form | 1072 +++++ .../com/unicenta/pos/sales/JPanelTicket.java | 3515 +++++++++++++++++ .../unicenta/pos/sales/JPanelTicketEdits.java | 126 + .../unicenta/pos/sales/JPanelTicketSales.java | 150 + .../unicenta/pos/sales/JProductAttEdit.form | 149 + .../unicenta/pos/sales/JProductAttEdit.java | 426 ++ .../unicenta/pos/sales/JProductAttEdit1.form | 149 + .../unicenta/pos/sales/JProductAttEdit1.java | 427 ++ .../unicenta/pos/sales/JProductAttEdit2.form | 152 + .../unicenta/pos/sales/JProductAttEdit2.java | 426 ++ .../unicenta/pos/sales/JProductAttEditI.java | 52 + .../pos/sales/JProductAttEditItem.form | 63 + .../pos/sales/JProductAttEditItem.java | 129 + .../pos/sales/JProductAttListItem.form | 67 + .../pos/sales/JProductAttListItem.java | 151 + .../unicenta/pos/sales/JProductLineEdit.form | 492 +++ .../unicenta/pos/sales/JProductLineEdit.java | 566 +++ .../pos/sales/JProductLineEditTax.form | 525 +++ .../pos/sales/JProductLineEditTax.java | 584 +++ .../com/unicenta/pos/sales/JRefundLines.form | 177 + .../com/unicenta/pos/sales/JRefundLines.java | 216 + .../pos/sales/JSalesLayoutManager.java | 10 + .../pos/sales/JTicketCatalogLines.form | 22 + .../pos/sales/JTicketCatalogLines.java | 129 + .../com/unicenta/pos/sales/JTicketLines.form | 50 + .../com/unicenta/pos/sales/JTicketLines.java | 482 +++ .../com/unicenta/pos/sales/JTicketsBag.java | 86 + .../unicenta/pos/sales/JTicketsBagTicket.form | 397 ++ .../unicenta/pos/sales/JTicketsBagTicket.java | 613 +++ .../pos/sales/JTicketsBagTicketBag.form | 128 + .../pos/sales/JTicketsBagTicketBag.java | 170 + .../unicenta/pos/sales/KitchenDisplay.java | 86 + .../pos/sales/MenuActionListener.java | 14 + .../com/unicenta/pos/sales/ReceiptSplit.form | 235 ++ .../com/unicenta/pos/sales/ReceiptSplit.java | 339 ++ .../unicenta/pos/sales/ReprintTicketInfo.java | 93 + .../unicenta/pos/sales/SharedTicketInfo.java | 113 + .../com/unicenta/pos/sales/SimpleReceipt.form | 296 ++ .../com/unicenta/pos/sales/SimpleReceipt.java | 450 +++ .../unicenta/pos/sales/TaxesException.java | 51 + .../com/unicenta/pos/sales/TaxesLogic.java | 314 ++ .../unicenta/pos/sales/TaxesLogicElement.java | 61 + .../pos/sales/TicketsBagRestaurantMap.java | 13 + .../com/unicenta/pos/sales/TicketsEditor.java | 42 + .../java/com/unicenta/pos/sales/dlSales.java | 13 + .../unicenta/pos/sales/restaurant/Floor.java | 138 + .../restaurant/JCalendarItemRenderer.form | 96 + .../restaurant/JCalendarItemRenderer.java | 186 + .../restaurant/JTicketsBagRestaurant.form | 174 + .../restaurant/JTicketsBagRestaurant.java | 440 +++ .../restaurant/JTicketsBagRestaurantMap.form | 225 ++ .../restaurant/JTicketsBagRestaurantMap.java | 1085 +++++ .../restaurant/JTicketsBagRestaurantRes.form | 480 +++ .../restaurant/JTicketsBagRestaurantRes.java | 710 ++++ .../unicenta/pos/sales/restaurant/Place.java | 233 ++ .../sales/restaurant/RestaurantDBUtils.java | 624 +++ .../pos/sales/shared/JTicketsBagShared.form | 202 + .../pos/sales/shared/JTicketsBagShared.java | 504 +++ .../sales/shared/JTicketsBagSharedList.form | 133 + .../sales/shared/JTicketsBagSharedList.java | 236 ++ .../pos/sales/shared/JTicketsReprintList.form | 134 + .../pos/sales/shared/JTicketsReprintList.java | 415 ++ .../pos/sales/simple/JTicketsBagSimple.form | 54 + .../pos/sales/simple/JTicketsBagSimple.java | 142 + .../com/unicenta/pos/scale/DeviceScale.java | 106 + .../java/com/unicenta/pos/scale/Scale.java | 34 + .../unicenta/pos/scale/ScaleAcomPC100.java | 181 + .../com/unicenta/pos/scale/ScaleAvery.java | 195 + .../com/unicenta/pos/scale/ScaleCASPDII.java | 178 + .../com/unicenta/pos/scale/ScaleCasioPD1.java | 202 + .../com/unicenta/pos/scale/ScaleComm.java | 178 + .../com/unicenta/pos/scale/ScaleDialog.java | 57 + .../unicenta/pos/scale/ScaleException.java | 41 + .../com/unicenta/pos/scale/ScaleFake.java | 38 + .../com/unicenta/pos/scale/ScaleMTIND221.java | 198 + .../unicenta/pos/scale/ScaleSamsungEsp.java | 193 + .../unicenta/pos/scanpal2/DeviceScanner.java | 72 + .../pos/scanpal2/DeviceScannerComm.java | 368 ++ .../pos/scanpal2/DeviceScannerException.java | 60 + .../pos/scanpal2/DeviceScannerFactory.java | 53 + .../pos/scanpal2/ProductDownloaded.java | 68 + .../unicenta/pos/scripting/ScriptEngine.java | 52 + .../pos/scripting/ScriptEngineBeanshell.java | 68 + .../pos/scripting/ScriptEngineVelocity.java | 107 + .../pos/scripting/ScriptException.java | 52 + .../unicenta/pos/scripting/ScriptFactory.java | 70 + .../pos/suppliers/DataLogicSuppliers.java | 242 ++ .../pos/suppliers/JDialogNewSupplier.form | 424 ++ .../pos/suppliers/JDialogNewSupplier.java | 399 ++ .../pos/suppliers/JSupplierFinder.form | 545 +++ .../pos/suppliers/JSupplierFinder.java | 692 ++++ .../pos/suppliers/OrderSupplierList.form | 42 + .../pos/suppliers/OrderSupplierList.java | 334 ++ .../unicenta/pos/suppliers/SupplierInfo.java | 178 + .../pos/suppliers/SupplierInfoExt.java | 272 ++ .../pos/suppliers/SupplierInfoGlobal.java | 83 + .../pos/suppliers/SupplierRenderer.java | 49 + .../pos/suppliers/SupplierTicketSelector.java | 46 + .../pos/suppliers/SupplierTransaction.java | 171 + .../pos/suppliers/SuppliersPanel.java | 134 + .../unicenta/pos/suppliers/SuppliersView.form | 1050 +++++ .../unicenta/pos/suppliers/SuppliersView.java | 1336 +++++++ .../com/unicenta/pos/ticket/CardInfo.java | 72 + .../unicenta/pos/ticket/CategoryFilter.form | 71 + .../unicenta/pos/ticket/CategoryFilter.java | 167 + .../unicenta/pos/ticket/CategoryFilter_1.form | 71 + .../unicenta/pos/ticket/CategoryFilter_1.java | 167 + .../com/unicenta/pos/ticket/CategoryInfo.java | 172 + .../unicenta/pos/ticket/FindTicketsInfo.java | 97 + .../pos/ticket/FindTicketsRenderer.java | 69 + .../com/unicenta/pos/ticket/HostInfo.java | 76 + .../pos/ticket/LocationFilterSales.form | 242 ++ .../pos/ticket/LocationFilterSales.java | 288 ++ .../unicenta/pos/ticket/ProductFilter.form | 265 ++ .../unicenta/pos/ticket/ProductFilter.java | 318 ++ .../unicenta/pos/ticket/ProductFilter1.form | 204 + .../unicenta/pos/ticket/ProductFilter1.java | 269 ++ .../unicenta/pos/ticket/ProductFilter2.form | 278 ++ .../unicenta/pos/ticket/ProductFilter2.java | 321 ++ .../unicenta/pos/ticket/ProductFilter3.form | 291 ++ .../unicenta/pos/ticket/ProductFilter3.java | 344 ++ .../unicenta/pos/ticket/ProductFilter4.form | 160 + .../unicenta/pos/ticket/ProductFilter4.java | 236 ++ .../pos/ticket/ProductFilterSales.form | 276 ++ .../pos/ticket/ProductFilterSales.java | 322 ++ .../com/unicenta/pos/ticket/ProductInfo.java | 124 + .../unicenta/pos/ticket/ProductInfoEdit.java | 207 + .../unicenta/pos/ticket/ProductInfoExt.java | 384 ++ .../unicenta/pos/ticket/ProductRenderer.java | 64 + .../unicenta/pos/ticket/ProductVectorer.java | 69 + .../com/unicenta/pos/ticket/ProviderInfo.java | 72 + .../unicenta/pos/ticket/SalesDetailInfo.java | 130 + .../pos/ticket/SalesDetailInfo_1.java | 129 + .../unicenta/pos/ticket/Signumprovider.java | 68 + .../java/com/unicenta/pos/ticket/TaxInfo.java | 213 + .../com/unicenta/pos/ticket/TicketInfo.java | 773 ++++ .../unicenta/pos/ticket/TicketLineInfo.java | 484 +++ .../unicenta/pos/ticket/TicketLineInfo1.java | 637 +++ .../unicenta/pos/ticket/TicketTaxInfo.java | 108 + .../com/unicenta/pos/ticket/UserInfo.java | 56 + .../com/unicenta/pos/transfer/Transfer.form | 1109 ++++++ .../com/unicenta/pos/transfer/Transfer.java | 3018 ++++++++++++++ .../unicenta/pos/transfer/TransferPanel.form | 28 + .../unicenta/pos/transfer/TransferPanel.java | 115 + .../com/unicenta/pos/util/AltEncrypter.java | 83 + .../com/unicenta/pos/util/BarcodeImage.java | 164 + .../com/unicenta/pos/util/Base64Encoder.java | 70 + .../com/unicenta/pos/util/DirectoryEvent.java | 75 + .../pos/util/ElapsedTimeBetweenDates.java | 47 + .../java/com/unicenta/pos/util/FXWeb.java | 124 + .../unicenta/pos/util/FileChooserEvent.java | 75 + .../unicenta/pos/util/FlatLookAndFeel.java | 45 + .../java/com/unicenta/pos/util/FtpUpload.java | 69 + .../com/unicenta/pos/util/Hashcypher.java | 133 + .../com/unicenta/pos/util/HtmlTester.java | 67 + .../com/unicenta/pos/util/HtmlTester2.java | 33 + .../com/unicenta/pos/util/HtmlTester3.form | 64 + .../com/unicenta/pos/util/HtmlTester3.java | 114 + .../unicenta/pos/util/InactivityListener.java | 96 + .../unicenta/pos/util/JRPrinterAWT300.java | 308 ++ .../com/unicenta/pos/util/JRViewer400.form | 567 +++ .../com/unicenta/pos/util/JRViewer400.java | 2410 +++++++++++ .../java/com/unicenta/pos/util/LabelIcon.java | 82 + .../com/unicenta/pos/util/LuhnAlgorithm.java | 62 + .../java/com/unicenta/pos/util/NewFXMain.java | 51 + .../com/unicenta/pos/util/NewFXSwingMain.java | 98 + .../com/unicenta/pos/util/OSValidator.java | 76 + .../com/unicenta/pos/util/PropertyUtils.java | 98 + .../com/unicenta/pos/util/ReportUtils.java | 82 + .../com/unicenta/pos/util/ReturnInfo.java | 87 + .../com/unicenta/pos/util/RoundUtils.java | 63 + .../com/unicenta/pos/util/SelectPrinter.form | 163 + .../com/unicenta/pos/util/SelectPrinter.java | 228 ++ .../unicenta/pos/util/SessionKeepAlive.java | 32 + .../com/unicenta/pos/util/StringParser.java | 63 + .../com/unicenta/pos/util/StringUtils.java | 170 + .../com/unicenta/pos/util/SwingUtils.java | 152 + .../unicenta/pos/util/SwingWorkerExample.java | 191 + .../unicenta/pos/util/ThumbNailBuilder.java | 203 + .../com/unicenta/pos/util/UniBrowser.java | 173 + .../unicenta/pos/util/ValidateBuilder.java | 130 + .../com/unicenta/pos/util/VideoPlayer.java | 56 + .../java/com/unicenta/pos/util/uOWWatch.java | 151 + .../pos/voucher/JDialogReportPanel.form | 132 + .../pos/voucher/JDialogReportPanel.java | 293 ++ .../unicenta/pos/voucher/VoucherEditor.form | 251 ++ .../unicenta/pos/voucher/VoucherEditor.java | 439 ++ .../com/unicenta/pos/voucher/VoucherInfo.java | 147 + .../unicenta/pos/voucher/VoucherPanel.java | 49 + src/main/java/net/proteanit/sql/DbUtils.java | 55 + .../org/usb4java/examples/ListDevices.java | 93 + src/main/resources/beans_messages.properties | 7 + .../resources/beans_messages_al_SQ.properties | 19 + .../resources/beans_messages_ar.properties | 19 + .../resources/beans_messages_da.properties | 23 + .../resources/beans_messages_de.properties | 27 + .../resources/beans_messages_el.properties | 19 + .../resources/beans_messages_en_US.properties | 20 + .../resources/beans_messages_es.properties | 20 + .../resources/beans_messages_es_AR.properties | 27 + .../resources/beans_messages_es_MX.properties | 28 + .../resources/beans_messages_et.properties | 20 + .../resources/beans_messages_fr.properties | 28 + .../resources/beans_messages_hr.properties | 29 + .../resources/beans_messages_it.properties | 19 + .../resources/beans_messages_nl.properties | 6 + .../resources/beans_messages_pt.properties | 20 + .../resources/beans_messages_pt_BR.properties | 20 + .../resources/com/unicenta/images/.01.png | Bin 0 -> 776 bytes .../resources/com/unicenta/images/.02.png | Bin 0 -> 1015 bytes .../resources/com/unicenta/images/.05.png | Bin 0 -> 1036 bytes .../resources/com/unicenta/images/.10.png | Bin 0 -> 842 bytes .../resources/com/unicenta/images/.20.png | Bin 0 -> 1002 bytes .../resources/com/unicenta/images/.25.png | Bin 0 -> 945 bytes .../resources/com/unicenta/images/.50.png | Bin 0 -> 1023 bytes .../resources/com/unicenta/images/1.00.png | Bin 0 -> 587 bytes .../resources/com/unicenta/images/10.00.png | Bin 0 -> 835 bytes .../resources/com/unicenta/images/100.00.png | Bin 0 -> 1217 bytes .../resources/com/unicenta/images/1000.00.png | Bin 0 -> 1523 bytes .../com/unicenta/images/1downarrow.png | Bin 0 -> 567 bytes .../com/unicenta/images/1leftarrow.png | Bin 0 -> 603 bytes .../com/unicenta/images/1rightarrow.png | Bin 0 -> 582 bytes .../com/unicenta/images/1uparrow.png | Bin 0 -> 564 bytes .../resources/com/unicenta/images/2.00.png | Bin 0 -> 866 bytes .../resources/com/unicenta/images/20.00.png | Bin 0 -> 1038 bytes .../resources/com/unicenta/images/200.00.png | Bin 0 -> 1400 bytes .../com/unicenta/images/2downarrow.png | Bin 0 -> 595 bytes .../com/unicenta/images/2leftarrow.png | Bin 0 -> 588 bytes .../com/unicenta/images/2rightarrow.png | Bin 0 -> 600 bytes .../com/unicenta/images/2uparrow.png | Bin 0 -> 606 bytes .../resources/com/unicenta/images/5.00.png | Bin 0 -> 873 bytes .../resources/com/unicenta/images/50.00.png | Bin 0 -> 1076 bytes .../resources/com/unicenta/images/500.00.png | Bin 0 -> 1433 bytes .../resources/com/unicenta/images/ark2.png | Bin 0 -> 595 bytes .../com/unicenta/images/attributes.png | Bin 0 -> 669 bytes .../com/unicenta/images/auxiliary.png | Bin 0 -> 748 bytes .../resources/com/unicenta/images/bank.png | Bin 0 -> 959 bytes .../resources/com/unicenta/images/barcode.png | Bin 0 -> 236 bytes .../com/unicenta/images/bookmark.png | Bin 0 -> 652 bytes .../resources/com/unicenta/images/btn0.png | Bin 0 -> 523 bytes .../resources/com/unicenta/images/btn00.png | Bin 0 -> 568 bytes .../resources/com/unicenta/images/btn1.png | Bin 0 -> 235 bytes .../resources/com/unicenta/images/btn2.png | Bin 0 -> 509 bytes .../resources/com/unicenta/images/btn2a.png | Bin 0 -> 804 bytes .../resources/com/unicenta/images/btn3.png | Bin 0 -> 582 bytes .../resources/com/unicenta/images/btn3a.png | Bin 0 -> 804 bytes .../resources/com/unicenta/images/btn4.png | Bin 0 -> 393 bytes .../resources/com/unicenta/images/btn4a.png | Bin 0 -> 595 bytes .../resources/com/unicenta/images/btn5.png | Bin 0 -> 518 bytes .../resources/com/unicenta/images/btn5a.png | Bin 0 -> 675 bytes .../resources/com/unicenta/images/btn6.png | Bin 0 -> 542 bytes .../resources/com/unicenta/images/btn6a.png | Bin 0 -> 893 bytes .../resources/com/unicenta/images/btn7.png | Bin 0 -> 424 bytes .../resources/com/unicenta/images/btn7a.png | Bin 0 -> 790 bytes .../resources/com/unicenta/images/btn8.png | Bin 0 -> 633 bytes .../resources/com/unicenta/images/btn8a.png | Bin 0 -> 858 bytes .../resources/com/unicenta/images/btn9.png | Bin 0 -> 580 bytes .../resources/com/unicenta/images/btn9a.png | Bin 0 -> 913 bytes .../resources/com/unicenta/images/btnback.png | Bin 0 -> 371 bytes .../resources/com/unicenta/images/btnce.png | Bin 0 -> 514 bytes .../resources/com/unicenta/images/btndiv.png | Bin 0 -> 474 bytes .../resources/com/unicenta/images/btndot.png | Bin 0 -> 318 bytes .../com/unicenta/images/btnequals.png | Bin 0 -> 285 bytes .../com/unicenta/images/btnminus.png | Bin 0 -> 321 bytes .../resources/com/unicenta/images/btnmult.png | Bin 0 -> 469 bytes .../resources/com/unicenta/images/btnplus.png | Bin 0 -> 526 bytes .../resources/com/unicenta/images/bundle.png | Bin 0 -> 703 bytes .../com/unicenta/images/calculator.png | Bin 0 -> 705 bytes .../resources/com/unicenta/images/camera.png | Bin 0 -> 609 bytes .../resources/com/unicenta/images/cancel.png | Bin 0 -> 837 bytes .../resources/com/unicenta/images/cash.png | Bin 0 -> 536 bytes .../com/unicenta/images/cashdrawer.png | Bin 0 -> 716 bytes .../com/unicenta/images/category.png | Bin 0 -> 557 bytes .../resources/com/unicenta/images/ccard.png | Bin 0 -> 867 bytes .../resources/com/unicenta/images/chart.png | Bin 0 -> 950 bytes .../resources/com/unicenta/images/cheque.png | Bin 0 -> 715 bytes .../resources/com/unicenta/images/coffee.png | Bin 0 -> 659 bytes .../com/unicenta/images/configuration.png | Bin 0 -> 1031 bytes .../com/unicenta/images/customer.png | Bin 0 -> 666 bytes .../com/unicenta/images/customer_add_sml.png | Bin 0 -> 557 bytes .../com/unicenta/images/customer_sml.png | Bin 0 -> 582 bytes .../com/unicenta/images/customerpay.png | Bin 0 -> 975 bytes .../com/unicenta/images/database.png | Bin 0 -> 1042 bytes .../resources/com/unicenta/images/date.png | Bin 0 -> 718 bytes .../com/unicenta/images/discount.png | Bin 0 -> 1079 bytes .../com/unicenta/images/discount_b.png | Bin 0 -> 1543 bytes .../resources/com/unicenta/images/display.png | Bin 0 -> 539 bytes .../resources/com/unicenta/images/edit.png | Bin 0 -> 644 bytes .../com/unicenta/images/edit_group.png | Bin 0 -> 647 bytes .../com/unicenta/images/edit_group_sm.png | Bin 0 -> 774 bytes .../com/unicenta/images/editdelete.png | Bin 0 -> 587 bytes .../resources/com/unicenta/images/editnew.png | Bin 0 -> 649 bytes .../resources/com/unicenta/images/empty.png | Bin 0 -> 1229 bytes .../com/unicenta/images/encrypted.png | Bin 0 -> 577 bytes .../resources/com/unicenta/images/exit.png | Bin 0 -> 2360 bytes .../resources/com/unicenta/images/favicon.png | Bin 0 -> 1742 bytes .../com/unicenta/images/fileclose.png | Bin 0 -> 716 bytes .../com/unicenta/images/fileopen.png | Bin 0 -> 570 bytes .../com/unicenta/images/filesave.png | Bin 0 -> 546 bytes .../resources/com/unicenta/images/floors.png | Bin 0 -> 554 bytes .../resources/com/unicenta/images/gohome.png | Bin 0 -> 642 bytes .../resources/com/unicenta/images/heart.png | Bin 0 -> 1165 bytes .../com/unicenta/images/img.discount.png | Bin 0 -> 1079 bytes .../com/unicenta/images/img.discount_b.png | Bin 0 -> 1543 bytes .../com/unicenta/images/img.keyboard_32.png | Bin 0 -> 1354 bytes .../com/unicenta/images/img.ticket_print.png | Bin 0 -> 639 bytes .../resources/com/unicenta/images/import.png | Bin 0 -> 791 bytes .../resources/com/unicenta/images/inbox.png | Bin 0 -> 722 bytes .../resources/com/unicenta/images/info.png | Bin 0 -> 679 bytes .../com/unicenta/images/keyboard_32.png | Bin 0 -> 1354 bytes .../com/unicenta/images/keyboard_48.png | Bin 0 -> 771 bytes .../com/unicenta/images/kit_print.png | Bin 0 -> 896 bytes .../resources/com/unicenta/images/leaves.png | Bin 0 -> 643 bytes .../com/unicenta/images/location.png | Bin 0 -> 1182 bytes .../resources/com/unicenta/images/logo.png | Bin 0 -> 8592 bytes .../resources/com/unicenta/images/logout.png | Bin 0 -> 580 bytes .../resources/com/unicenta/images/mail24.png | Bin 0 -> 1393 bytes .../com/unicenta/images/maintain.png | Bin 0 -> 946 bytes .../com/unicenta/images/menu-left.png | Bin 0 -> 824 bytes .../com/unicenta/images/menu-right.png | Bin 0 -> 795 bytes .../resources/com/unicenta/images/mime.png | Bin 0 -> 1016 bytes .../resources/com/unicenta/images/mime2.png | Bin 0 -> 1164 bytes .../resources/com/unicenta/images/mime3.png | Bin 0 -> 1215 bytes .../com/unicenta/images/movetable.png | Bin 0 -> 662 bytes .../com/unicenta/images/no_photo.png | Bin 0 -> 1358 bytes .../resources/com/unicenta/images/notes.png | Bin 0 -> 780 bytes .../resources/com/unicenta/images/null.png | Bin 0 -> 1284 bytes src/main/resources/com/unicenta/images/ok.png | Bin 0 -> 624 bytes .../resources/com/unicenta/images/package.png | Bin 0 -> 1040 bytes .../com/unicenta/images/package_big.png | Bin 0 -> 1099 bytes .../unicenta/images/padlock_open_icon&24.pdn | Bin 0 -> 5384 bytes .../com/unicenta/images/paperboard960_600.png | Bin 0 -> 198168 bytes .../com/unicenta/images/password.png | Bin 0 -> 873 bytes .../resources/com/unicenta/images/pay.png | Bin 0 -> 679 bytes .../com/unicenta/images/payments.png | Bin 0 -> 574 bytes .../resources/com/unicenta/images/plugin.png | Bin 0 -> 841 bytes .../com/unicenta/images/poweredby_uni.png | Bin 0 -> 2048 bytes .../resources/com/unicenta/images/printer.png | Bin 0 -> 639 bytes .../unicenta/images/printer.ticket.logo.jpg | Bin 0 -> 4157 bytes .../com/unicenta/images/printer24.png | Bin 0 -> 634 bytes .../com/unicenta/images/printer24_off.png | Bin 0 -> 680 bytes .../com/unicenta/images/printer24_on.png | Bin 0 -> 692 bytes .../com/unicenta/images/products.png | Bin 0 -> 838 bytes .../com/unicenta/images/products24.png | Bin 0 -> 718 bytes .../resources/com/unicenta/images/receive.png | Bin 0 -> 873 bytes .../com/unicenta/images/refundit.png | Bin 0 -> 603 bytes .../resources/com/unicenta/images/reload.png | Bin 0 -> 763 bytes .../com/unicenta/images/remote_print.png | Bin 0 -> 835 bytes .../resources/com/unicenta/images/reports.png | Bin 0 -> 971 bytes .../com/unicenta/images/reprint24.png | Bin 0 -> 813 bytes .../com/unicenta/images/resources.png | Bin 0 -> 439 bytes .../com/unicenta/images/restaurant_floor.png | Bin 0 -> 231460 bytes .../unicenta/images/restaurant_floor_sml.png | Bin 0 -> 29443 bytes .../resources/com/unicenta/images/roles.png | Bin 0 -> 742 bytes .../com/unicenta/images/run_script.png | Bin 0 -> 3283 bytes .../resources/com/unicenta/images/sale.png | Bin 0 -> 753 bytes .../com/unicenta/images/sale_delete.png | Bin 0 -> 585 bytes .../com/unicenta/images/sale_editline.png | Bin 0 -> 665 bytes .../com/unicenta/images/sale_new.png | Bin 0 -> 647 bytes .../com/unicenta/images/sale_pending.png | Bin 0 -> 595 bytes .../com/unicenta/images/sale_split_sml.png | Bin 0 -> 814 bytes .../com/unicenta/images/saleedit.png | Bin 0 -> 1068 bytes .../resources/com/unicenta/images/sales.png | Bin 0 -> 656 bytes .../resources/com/unicenta/images/scale.png | Bin 0 -> 714 bytes .../com/unicenta/images/search24.png | Bin 0 -> 712 bytes .../com/unicenta/images/search32.png | Bin 0 -> 866 bytes .../resources/com/unicenta/images/slip.png | Bin 0 -> 777 bytes .../com/unicenta/images/sort_incr.png | Bin 0 -> 431 bytes .../com/unicenta/images/stockdiary.png | Bin 0 -> 506 bytes .../com/unicenta/images/stockmaint.png | Bin 0 -> 592 bytes .../com/unicenta/images/subcategory.png | Bin 0 -> 443 bytes .../com/unicenta/images/supplier_sml.png | Bin 0 -> 582 bytes .../resources/com/unicenta/images/tables.png | Bin 0 -> 568 bytes .../com/unicenta/images/ticket_print.png | Bin 0 -> 639 bytes .../resources/com/unicenta/images/timer.png | Bin 0 -> 894 bytes .../images/uniCenta_logo_vert_100.png | Bin 0 -> 4175 bytes .../unicenta/images/uniCenta_splash_dark.png | Bin 0 -> 29374 bytes .../com/unicenta/images/unicenta.png | Bin 0 -> 8592 bytes .../com/unicenta/images/unicentaopos.ico | Bin 0 -> 21656 bytes .../com/unicenta/images/unicentaopos.png | Bin 0 -> 27680 bytes .../resources/com/unicenta/images/user.png | Bin 0 -> 675 bytes .../com/unicenta/images/user_sml.png | Bin 0 -> 582 bytes .../resources/com/unicenta/images/users.png | Bin 0 -> 742 bytes .../com/unicenta/images/utilities.png | Bin 0 -> 1054 bytes .../com/unicenta/images/viewmag+.png | Bin 0 -> 649 bytes .../com/unicenta/images/viewmag-.png | Bin 0 -> 587 bytes .../resources/com/unicenta/images/voucher.png | Bin 0 -> 777 bytes .../resources/com/unicenta/images/wallet.png | Bin 0 -> 695 bytes .../com/unicenta/images/window.logo.png | Bin 0 -> 1067 bytes .../com/unicenta/images/yast_printer.png | Bin 0 -> 634 bytes .../com/unicenta/pos/config/Bundle.properties | 25 + .../unicenta/pos/customers/Bundle.properties | 4 + .../com/unicenta/pos/scripts/Derby-create.sql | 699 ++++ .../unicenta/pos/scripts/MariaDB-create.sql | 1003 +++++ .../pos/scripts/MariaDB-upgrade_master.sql | 61 + .../com/unicenta/pos/scripts/MySQL-FKeys.sql | 191 + .../pos/scripts/MySQL-check-tables.sql | 818 ++++ .../unicenta/pos/scripts/MySQL-clearData.sql | 57 + .../unicenta/pos/scripts/MySQL-create-sp.sql | 45 + .../pos/scripts/MySQL-create-transfer.sql | 666 ++++ .../com/unicenta/pos/scripts/MySQL-create.sql | 978 +++++ .../pos/scripts/MySQL-create_original.sql | 721 ++++ .../unicenta/pos/scripts/MySQL-dropFKeys.sql | 93 + .../pos/scripts/MySQL-normalise-tables.sql | 434 ++ .../pos/scripts/MySQL-orders-table.sql | 35 + .../pos/scripts/MySQL-upgrade-4.5.1.sql | 45 + .../pos/scripts/MySQL-upgrade-4.5.2.sql | 38 + .../pos/scripts/MySQL-upgrade-4.5.3.sql | 38 + .../pos/scripts/MySQL-upgrade-4.5.4.sql | 54 + .../pos/scripts/MySQL-upgrade-4.5.sql | 48 + .../pos/scripts/MySQL-upgrade_master.sql | 62 + .../pos/scripts/PostgreSQL-create.sql | 746 ++++ .../unicenta/pos/scripts/SQLite-create.sql | 699 ++++ .../pos/templates/APrinter.FiscalTicket.xml | 68 + .../com/unicenta/pos/templates/Cash.Close.xml | 25 + .../com/unicenta/pos/templates/Menu.Root.txt | 151 + .../templates/Printer.CloseCash.Preview.xml | 126 + .../pos/templates/Printer.CloseCash.xml | 127 + .../pos/templates/Printer.CustomerPaid.xml | 160 + .../pos/templates/Printer.CustomerPaid2.xml | 32 + .../pos/templates/Printer.FiscalTicket.xml | 67 + .../pos/templates/Printer.Inventory.xml | 83 + .../pos/templates/Printer.OpenDrawer.xml | 29 + .../pos/templates/Printer.PartialCash.xml | 201 + .../pos/templates/Printer.PrintLastTicket.xml | 405 ++ .../pos/templates/Printer.Product.xml | 42 + .../pos/templates/Printer.ReprintTicket.xml | 303 ++ .../unicenta/pos/templates/Printer.Start.xml | 34 + .../pos/templates/Printer.Ticket.P1.xml | 86 + .../pos/templates/Printer.Ticket.P2.xml | 86 + .../pos/templates/Printer.Ticket.P3.xml | 86 + .../pos/templates/Printer.Ticket.P4.xml | 86 + .../pos/templates/Printer.Ticket.P5.xml | 86 + .../pos/templates/Printer.Ticket.P6.xml | 86 + .../unicenta/pos/templates/Printer.Ticket.xml | 270 ++ .../pos/templates/Printer.Ticket2.xml | 40 + .../pos/templates/Printer.TicketClose.xml | 38 + .../pos/templates/Printer.TicketLine.xml | 43 + .../pos/templates/Printer.TicketNew.xml | 319 ++ .../pos/templates/Printer.TicketPreview.xml | 245 ++ .../templates/Printer.TicketPreview_A4.xml | 243 ++ .../pos/templates/Printer.TicketRemote.xml | 116 + .../pos/templates/Printer.TicketTotal.xml | 32 + .../pos/templates/Printer.Ticket_A4.xml | 259 ++ .../pos/templates/Role.Administrator.xml | 198 + .../unicenta/pos/templates/Role.Employee.xml | 82 + .../com/unicenta/pos/templates/Role.Guest.xml | 25 + .../unicenta/pos/templates/Role.Manager.xml | 198 + .../unicenta/pos/templates/Ticket.Buttons.xml | 121 + .../unicenta/pos/templates/Ticket.Close.xml | 59 + .../unicenta/pos/templates/Ticket.Line.xml | 56 + .../Ticket.TicketLineTaxesIncluded.xml | 34 + .../unicenta/pos/templates/Window.Title.txt | 1 + .../pos/templates/customer.created.xml | 27 + .../pos/templates/customer.deleted.xml | 27 + .../pos/templates/customer.updated.xml | 27 + .../unicenta/pos/templates/payment.cash.txt | 41 + .../pos/templates/script.Keyboard.txt | 29 + .../pos/templates/script.Linediscount.txt | 51 + .../pos/templates/script.SendOrder.txt | 76 + .../pos/templates/script.Totaldiscount.txt | 54 + .../pos/templates/script.multibuy.txt | 82 + .../pos/templates/template.Ticket.A4_Beta.vm | 208 + .../pos/templates/template.Ticket.A4_Beta.zip | Bin 0 -> 2404 bytes .../com/unicenta/reports/customers.bs | 52 + .../com/unicenta/reports/customers.jrxml | 358 ++ .../com/unicenta/reports/customers_b.bs | 45 + .../com/unicenta/reports/customers_cards.bs | 49 + .../unicenta/reports/customers_cards.jrxml | 181 + .../com/unicenta/reports/customers_debtors.bs | 51 + .../unicenta/reports/customers_debtors.jrxml | 294 ++ .../com/unicenta/reports/customers_diary.bs | 61 + .../unicenta/reports/customers_diary.jrxml | 360 ++ .../com/unicenta/reports/customers_export.bs | 47 + .../unicenta/reports/customers_export.jrxml | 270 ++ .../com/unicenta/reports/customers_list.bs | 46 + .../com/unicenta/reports/customers_list.jrxml | 315 ++ .../reports/customers_messages.properties | 44 + .../customers_messages_al_SQ.properties | 9 + .../reports/customers_messages_ar.properties | 7 + .../reports/customers_messages_de.properties | 18 + .../reports/customers_messages_el.properties | 7 + .../customers_messages_en_US.properties | 37 + .../reports/customers_messages_es.properties | 40 + .../customers_messages_es_AR.properties | 6 + .../customers_messages_es_MX.properties | 6 + .../reports/customers_messages_et.properties | 7 + .../reports/customers_messages_fr.properties | 40 + .../reports/customers_messages_hr.properties | 7 + .../reports/customers_messages_it.properties | 18 + .../reports/customers_messages_nl.properties | 8 + .../com/unicenta/reports/customers_sales.bs | 61 + .../unicenta/reports/customers_sales.jrxml | 471 +++ .../unicenta/reports/customers_vouchers.bs | 58 + .../unicenta/reports/customers_vouchers.jrxml | 282 ++ .../com/unicenta/reports/epm_dailypresence.bs | 53 + .../unicenta/reports/epm_dailypresence.jrxml | 325 ++ .../com/unicenta/reports/epm_dailyschedule.bs | 53 + .../unicenta/reports/epm_dailyschedule.jrxml | 325 ++ .../unicenta/reports/epm_messages.properties | 17 + .../reports/epm_messages_al_SQ.properties | 46 + .../reports/epm_messages_de.properties | 46 + .../reports/epm_messages_en_US.properties | 46 + .../reports/epm_messages_es.properties | 46 + .../reports/epm_messages_fr.properties | 46 + .../reports/epm_messages_it.properties | 46 + .../reports/epm_messages_nl.properties | 30 + .../com/unicenta/reports/epm_performance.bs | 44 + .../unicenta/reports/epm_performance.jrxml | 361 ++ .../com/unicenta/reports/inventory.bs | 77 + .../com/unicenta/reports/inventory.jrxml | 789 ++++ .../com/unicenta/reports/inventory_b.bs | 82 + .../com/unicenta/reports/inventory_b.jrxml | 477 +++ .../com/unicenta/reports/inventory_broken.bs | 83 + .../com/unicenta/reports/inventory_diary.bs | 69 + .../unicenta/reports/inventory_diary.jrxml | 438 ++ .../com/unicenta/reports/inventory_diff.bs | 74 + .../com/unicenta/reports/inventory_diff.jrxml | 607 +++ .../unicenta/reports/inventory_diffdetail.bs | 76 + .../reports/inventory_diffdetail.jrxml | 637 +++ .../unicenta/reports/inventory_listdetail.bs | 78 + .../reports/inventory_listdetail.jrxml | 452 +++ .../reports/inventory_messages.properties | 61 + .../inventory_messages_al_SQ.properties | 11 + .../reports/inventory_messages_ar.properties | 12 + .../reports/inventory_messages_de.properties | 15 + .../reports/inventory_messages_el.properties | 12 + .../inventory_messages_en_US.properties | 61 + .../reports/inventory_messages_es.properties | 62 + .../inventory_messages_es_AR.properties | 11 + .../inventory_messages_es_MX.properties | 10 + .../reports/inventory_messages_et.properties | 11 + .../reports/inventory_messages_fr.properties | 61 + .../reports/inventory_messages_hr.properties | 11 + .../reports/inventory_messages_it.properties | 12 + .../reports/inventory_messages_nl.properties | 62 + .../unicenta/reports/labels_barcode_sheet.bs | 26 + .../reports/labels_barcode_sheet.jrxml | 63 + .../reports/labels_barcode_shelfedge.bs | 57 + .../reports/labels_barcode_shelfedge.jrxml | 59 + .../reports/labels_messages.properties | 4 + .../reports/labels_messages_al_SQ.properties | 3 + .../reports/labels_messages_ar.properties | 3 + .../reports/labels_messages_de.properties | 3 + .../reports/labels_messages_el.properties | 3 + .../reports/labels_messages_en_US.properties | 4 + .../reports/labels_messages_es.properties | 2 + .../reports/labels_messages_es_AR.properties | 3 + .../reports/labels_messages_es_MX.properties | 3 + .../reports/labels_messages_et.properties | 4 + .../reports/labels_messages_fr.properties | 3 + .../reports/labels_messages_hr.properties | 3 + .../reports/labels_messages_it.properties | 4 + .../reports/labels_messages_nl.properties | 3 + .../com/unicenta/reports/labels_product.bs | 61 + .../com/unicenta/reports/labels_product.jrxml | 262 ++ .../resources/com/unicenta/reports/logo.png | Bin 0 -> 3124 bytes .../com/unicenta/reports/products.bs | 69 + .../com/unicenta/reports/products.jrxml | 374 ++ .../com/unicenta/reports/products_catalog.bs | 51 + .../reports/products_messages.properties | 40 + .../products_messages_al_SQ.properties | 38 + .../reports/products_messages_ar.properties | 39 + .../reports/products_messages_de.properties | 49 + .../reports/products_messages_el.properties | 38 + .../products_messages_en_US.properties | 39 + .../reports/products_messages_es.properties | 38 + .../products_messages_es_AR.properties | 52 + .../products_messages_es_MX.properties | 31 + .../reports/products_messages_et.properties | 38 + .../reports/products_messages_fr.properties | 43 + .../reports/products_messages_hr.properties | 53 + .../reports/products_messages_it.properties | 39 + .../reports/products_messages_nl.properties | 23 + .../com/unicenta/reports/salecatalog.bs | 70 + .../com/unicenta/reports/salecatalog.jrxml | 260 ++ .../com/unicenta/reports/sales_cashflow.bs | 49 + .../com/unicenta/reports/sales_cashflow.jrxml | 282 ++ .../unicenta/reports/sales_cashregisterlog.bs | 54 + .../reports/sales_cashregisterlog.jrxml | 349 ++ .../unicenta/reports/sales_categorysales.bs | 64 + .../reports/sales_categorysales.jrxml | 414 ++ .../unicenta/reports/sales_categorysales_1.bs | 69 + .../reports/sales_categorysales_1.jrxml | 541 +++ .../reports/sales_categorysalesmysql.bs | 58 + .../reports/sales_chart_piesalescat.bs | 54 + .../reports/sales_chart_piesalescat.jrxml | 292 ++ .../unicenta/reports/sales_chart_pro_test.bs | 60 + .../reports/sales_chart_pro_test.jrxml | 259 ++ .../reports/sales_chart_productsales.bs | 60 + .../reports/sales_chart_productsales.jrxml | 225 ++ .../com/unicenta/reports/sales_chart_sales.bs | 52 + .../unicenta/reports/sales_chart_sales.jrxml | 221 ++ .../reports/sales_chart_timeseriesproduct.bs | 73 + .../sales_chart_timeseriesproduct.jrxml | 292 ++ .../com/unicenta/reports/sales_chart_top10.bs | 65 + .../unicenta/reports/sales_chart_top10.jrxml | 307 ++ .../com/unicenta/reports/sales_closedpos.bs | 57 + .../unicenta/reports/sales_closedpos.jrxml | 484 +++ .../com/unicenta/reports/sales_closedpos_1.bs | 56 + .../unicenta/reports/sales_closedpos_1.jrxml | 155 + .../unicenta/reports/sales_closedproducts.bs | 73 + .../reports/sales_closedproducts.jrxml | 679 ++++ .../reports/sales_closedproducts_1.bs | 72 + .../reports/sales_closedproducts_1.jrxml | 595 +++ .../reports/sales_extendedcashregisterlog.bs | 61 + .../sales_extendedcashregisterlog.jrxml | 392 ++ .../com/unicenta/reports/sales_extproducts.bs | 76 + .../unicenta/reports/sales_extproducts.jrxml | 524 +++ .../unicenta/reports/sales_extproducts_1.bs | 70 + .../reports/sales_messages.properties | 154 + .../reports/sales_messages_al_SQ.properties | 102 + .../reports/sales_messages_ar.properties | 92 + .../reports/sales_messages_de.properties | 120 + .../reports/sales_messages_el.properties | 94 + .../reports/sales_messages_en_US.properties | 154 + .../reports/sales_messages_es.properties | 153 + .../reports/sales_messages_es_AR.properties | 38 + .../reports/sales_messages_es_MX.properties | 39 + .../reports/sales_messages_et.properties | 163 + .../reports/sales_messages_fr.properties | 166 + .../reports/sales_messages_hr.properties | 105 + .../reports/sales_messages_it.properties | 118 + .../reports/sales_messages_nl.properties | 107 + .../com/unicenta/reports/sales_payments.bs | 54 + .../com/unicenta/reports/sales_payments.jrxml | 359 ++ .../reports/sales_productsalesprofit.bs | 81 + .../reports/sales_productsalesprofit.jrxml | 414 ++ .../reports/sales_productsalesprofit_1.bs | 77 + .../reports/sales_productsalesprofit_1.jrxml | 516 +++ .../com/unicenta/reports/sales_saletaxes.bs | 58 + .../unicenta/reports/sales_saletaxes.jrxml | 379 ++ .../com/unicenta/reports/sales_taxcatsales.bs | 62 + .../unicenta/reports/sales_taxcatsales.jrxml | 514 +++ .../unicenta/reports/sales_taxcatsales_2.bs | 72 + .../reports/sales_taxcatsales_2.jrxml | 498 +++ .../com/unicenta/reports/sales_taxes.bs | 52 + .../com/unicenta/reports/sales_taxes.jrxml | 297 ++ .../com/unicenta/reports/suppliers.bs | 47 + .../com/unicenta/reports/suppliers.jrxml | 316 ++ .../unicenta/reports/suppliers_creditors.bs | 50 + .../reports/suppliers_creditors.jrxml | 294 ++ .../com/unicenta/reports/suppliers_diary.bs | 74 + .../unicenta/reports/suppliers_diary.jrxml | 451 +++ .../com/unicenta/reports/suppliers_export.bs | 47 + .../unicenta/reports/suppliers_export.jrxml | 270 ++ .../com/unicenta/reports/suppliers_list.bs | 46 + .../com/unicenta/reports/suppliers_list.jrxml | 315 ++ .../reports/suppliers_messages.properties | 86 + .../suppliers_messages_en_US.properties | 86 + .../reports/suppliers_messages_es.properties | 86 + .../reports/suppliers_messages_fr.properties | 87 + .../unicenta/reports/suppliers_products.bs | 51 + .../unicenta/reports/suppliers_products.jrxml | 271 ++ .../com/unicenta/reports/suppliers_sales.bs | 63 + .../unicenta/reports/suppliers_sales.jrxml | 460 +++ .../com/unicenta/reports/ticketsample.jrxml | 166 + .../unicenta/reports/ticketsample_lines.jrxml | 183 + .../com/unicenta/reports/tools_badprice.bs | 40 + .../com/unicenta/reports/tools_badprice.jrxml | 203 + .../unicenta/reports/tools_invalidcategory.bs | 40 + .../reports/tools_invalidcategory.jrxml | 204 + .../com/unicenta/reports/tools_invaliddata.bs | 39 + .../unicenta/reports/tools_invaliddata.jrxml | 203 + .../reports/tools_inventoryqtyupdate.bs | 37 + .../reports/tools_inventoryqtyupdate.jrxml | 203 + .../reports/tools_messages.properties | 66 + .../reports/tools_messages_al_SQ.properties | 50 + .../reports/tools_messages_de.properties | 61 + .../reports/tools_messages_en_US.properties | 65 + .../reports/tools_messages_es.properties | 66 + .../reports/tools_messages_fr.properties | 65 + .../reports/tools_messages_it.properties | 63 + .../reports/tools_messages_nl.properties | 38 + .../com/unicenta/reports/tools_missingdata.bs | 30 + .../unicenta/reports/tools_missingdata.jrxml | 218 + .../com/unicenta/reports/tools_newproducts.bs | 29 + .../unicenta/reports/tools_newproducts.jrxml | 218 + .../unicenta/reports/tools_updatedprices.bs | 39 + .../reports/tools_updatedprices.jrxml | 230 ++ .../resources/com/unicenta/reports/users.bs | 35 + .../com/unicenta/reports/users.jrxml | 201 + .../reports/users_messages.properties | 36 + .../reports/users_messages_ar.properties | 30 + .../reports/users_messages_de.properties | 35 + .../reports/users_messages_el.properties | 30 + .../reports/users_messages_en_US.properties | 56 + .../reports/users_messages_es.properties | 55 + .../reports/users_messages_es_AR.properties | 33 + .../reports/users_messages_es_MX.properties | 26 + .../reports/users_messages_et.properties | 30 + .../reports/users_messages_fr.properties | 55 + .../reports/users_messages_hr.properties | 37 + .../reports/users_messages_it.properties | 30 + .../reports/users_messages_nl.properties | 15 + .../com/unicenta/reports/users_nosales.bs | 51 + .../com/unicenta/reports/users_nosales.jrxml | 263 ++ .../com/unicenta/reports/users_sales.bs | 55 + .../com/unicenta/reports/users_sales.jrxml | 385 ++ .../com/unicenta/reports/users_tips.bs | 43 + .../com/unicenta/reports/users_tips.jrxml | 366 ++ .../com/unicenta/reports/users_voids.bs | 50 + .../com/unicenta/reports/users_voids.jrxml | 363 ++ .../com/unicenta/reports/vouchers.bs | 51 + .../com/unicenta/reports/vouchers.jrxml | 385 ++ .../reports/vouchers_messages.properties | 2 + .../reports/vouchers_messages_de.properties | 2 + .../vouchers_messages_en_US.properties | 2 + .../reports/vouchers_messages_es.properties | 2 + .../reports/vouchers_messages_fr.properties | 2 + .../reports/vouchers_messages_nl.properties | 2 + src/main/resources/data_messages.properties | 85 + .../resources/data_messages_al_SQ.properties | 88 + .../resources/data_messages_ar.properties | 85 + .../resources/data_messages_da.properties | 86 + .../resources/data_messages_de.properties | 138 + .../resources/data_messages_el.properties | 85 + .../resources/data_messages_en_US.properties | 85 + .../resources/data_messages_es.properties | 88 + .../resources/data_messages_es_AR.properties | 138 + .../resources/data_messages_es_MX.properties | 84 + .../resources/data_messages_et.properties | 85 + .../resources/data_messages_fr.properties | 130 + .../resources/data_messages_hr.properties | 132 + .../resources/data_messages_it.properties | 88 + .../resources/data_messages_nl.properties | 86 + .../resources/data_messages_pt.properties | 77 + .../resources/data_messages_pt_BR.properties | 77 + src/main/resources/erp_messages.properties | 43 + .../resources/erp_messages_al_SQ.properties | 43 + src/main/resources/erp_messages_ar.properties | 43 + src/main/resources/erp_messages_da.properties | 36 + src/main/resources/erp_messages_de.properties | 62 + src/main/resources/erp_messages_el.properties | 43 + .../resources/erp_messages_en_US.properties | 43 + src/main/resources/erp_messages_es.properties | 43 + .../resources/erp_messages_es_AR.properties | 61 + .../resources/erp_messages_es_MX.properties | 57 + src/main/resources/erp_messages_fr.properties | 56 + src/main/resources/erp_messages_hr.properties | 64 + src/main/resources/erp_messages_it.properties | 43 + src/main/resources/erp_messages_nl.properties | 24 + src/main/resources/erp_messages_pt.properties | 43 + .../resources/erp_messages_pt_BR.properties | 43 + src/main/resources/fxml/OrderPop.fxml | 14 + src/main/resources/logback.groovy | 33 + src/main/resources/pos_messages.properties | 1209 ++++++ .../resources/pos_messages_al_SQ.properties | 664 ++++ src/main/resources/pos_messages_ar.properties | 544 +++ src/main/resources/pos_messages_da.properties | 1010 +++++ src/main/resources/pos_messages_de.properties | 904 +++++ src/main/resources/pos_messages_el.properties | 550 +++ .../resources/pos_messages_en_US.properties | 1118 ++++++ src/main/resources/pos_messages_es.properties | 1193 ++++++ .../resources/pos_messages_es_AR.properties | 486 +++ .../resources/pos_messages_es_MX.properties | 471 +++ src/main/resources/pos_messages_et.properties | 504 +++ src/main/resources/pos_messages_fr.properties | 1085 +++++ src/main/resources/pos_messages_hr.properties | 484 +++ src/main/resources/pos_messages_it.properties | 755 ++++ src/main/resources/pos_messages_nl.properties | 1177 ++++++ src/main/resources/pos_messages_pt.properties | 464 +++ .../resources/pos_messages_pt_BR.properties | 406 ++ src/main/resources/styles/orderpop.css | 7 + src/other/Bonus/Barcode_3of9.zip | Bin 0 -> 4991 bytes src/other/Bonus/FRE3OF9X.TTF | Bin 0 -> 7220 bytes src/other/Bonus/Images/Clothing/bbcap.png | Bin 0 -> 12274 bytes src/other/Bonus/Images/Clothing/clothing.png | Bin 0 -> 11129 bytes src/other/Bonus/Images/Clothing/tshirt.jpg | Bin 0 -> 3310 bytes src/other/Bonus/Images/Clothing/tshirt.png | Bin 0 -> 6752 bytes .../Images/Currency/AU_Dollar/coin.10cent.jpg | Bin 0 -> 4136 bytes .../Images/Currency/AU_Dollar/coin.10cent.png | Bin 0 -> 25830 bytes .../Images/Currency/AU_Dollar/coin.1aud.jpg | Bin 0 -> 5297 bytes .../Images/Currency/AU_Dollar/coin.1aud.png | Bin 0 -> 34607 bytes .../Images/Currency/AU_Dollar/coin.20cent.jpg | Bin 0 -> 3451 bytes .../Images/Currency/AU_Dollar/coin.20cent.png | Bin 0 -> 27722 bytes .../Images/Currency/AU_Dollar/coin.2aud.jpg | Bin 0 -> 3224 bytes .../Images/Currency/AU_Dollar/coin.2aud.png | Bin 0 -> 19682 bytes .../Images/Currency/AU_Dollar/coin.50cent.jpg | Bin 0 -> 5088 bytes .../Images/Currency/AU_Dollar/coin.50cent.png | Bin 0 -> 37217 bytes .../Images/Currency/AU_Dollar/coin.5cent.jpg | Bin 0 -> 2145 bytes .../Images/Currency/AU_Dollar/coin.5cent.png | Bin 0 -> 12467 bytes .../Images/Currency/AU_Dollar/note.100aud.jpg | Bin 0 -> 26181 bytes .../Images/Currency/AU_Dollar/note.10aud.jpg | Bin 0 -> 30262 bytes .../Images/Currency/AU_Dollar/note.20aud.jpg | Bin 0 -> 27110 bytes .../Images/Currency/AU_Dollar/note.50aud.jpg | Bin 0 -> 25714 bytes .../Images/Currency/AU_Dollar/note.5aud.jpg | Bin 0 -> 27027 bytes .../Images/Currency/GB_Sterling/coin.01.png | Bin 0 -> 8593 bytes .../Images/Currency/GB_Sterling/coin.02.png | Bin 0 -> 3121 bytes .../Images/Currency/GB_Sterling/coin.05.png | Bin 0 -> 3247 bytes .../Images/Currency/GB_Sterling/coin.1.png | Bin 0 -> 3713 bytes .../Images/Currency/GB_Sterling/coin.10.png | Bin 0 -> 3008 bytes .../Images/Currency/GB_Sterling/coin.2.png | Bin 0 -> 10468 bytes .../Images/Currency/GB_Sterling/coin.20.png | Bin 0 -> 8941 bytes .../Images/Currency/GB_Sterling/coin.50.png | Bin 0 -> 5193 bytes .../Images/Currency/GB_Sterling/note.10.png | Bin 0 -> 23928 bytes .../Images/Currency/GB_Sterling/note.20.png | Bin 0 -> 23961 bytes .../Images/Currency/GB_Sterling/note.5.png | Bin 0 -> 23926 bytes .../Images/Currency/GB_Sterling/note.50.png | Bin 0 -> 25541 bytes .../Bonus/Images/Currency/Generic/.01.png | Bin 0 -> 776 bytes .../Bonus/Images/Currency/Generic/.02.png | Bin 0 -> 1015 bytes .../Bonus/Images/Currency/Generic/.05.png | Bin 0 -> 1036 bytes .../Bonus/Images/Currency/Generic/.10.png | Bin 0 -> 842 bytes .../Bonus/Images/Currency/Generic/.20.png | Bin 0 -> 1002 bytes .../Bonus/Images/Currency/Generic/.25.png | Bin 0 -> 945 bytes .../Bonus/Images/Currency/Generic/.50.png | Bin 0 -> 1023 bytes .../Bonus/Images/Currency/Generic/1.00.png | Bin 0 -> 587 bytes .../Bonus/Images/Currency/Generic/10.00.png | Bin 0 -> 835 bytes .../Bonus/Images/Currency/Generic/100.00.png | Bin 0 -> 1217 bytes .../Bonus/Images/Currency/Generic/1000.00.png | Bin 0 -> 1523 bytes .../Bonus/Images/Currency/Generic/2.00.png | Bin 0 -> 866 bytes .../Bonus/Images/Currency/Generic/20.00.png | Bin 0 -> 1038 bytes .../Bonus/Images/Currency/Generic/200.00.png | Bin 0 -> 1400 bytes .../Bonus/Images/Currency/Generic/5.00.png | Bin 0 -> 873 bytes .../Bonus/Images/Currency/Generic/50.00.png | Bin 0 -> 1076 bytes .../Bonus/Images/Currency/Generic/500.00.png | Bin 0 -> 1433 bytes .../Currency/Generic/Numbers/coin.01.png | Bin 0 -> 1172 bytes .../Currency/Generic/Numbers/coin.05.png | Bin 0 -> 1197 bytes .../Currency/Generic/Numbers/coin.1.png | Bin 0 -> 1110 bytes .../Currency/Generic/Numbers/coin.10.png | Bin 0 -> 1253 bytes .../Currency/Generic/Numbers/coin.2.png | Bin 0 -> 1140 bytes .../Currency/Generic/Numbers/coin.20.png | Bin 0 -> 1269 bytes .../Currency/Generic/Numbers/coin.25.png | Bin 0 -> 1261 bytes .../Currency/Generic/Numbers/coin.50.png | Bin 0 -> 1269 bytes .../Currency/Generic/Numbers/coin02.png | Bin 0 -> 1196 bytes .../Currency/Generic/Numbers/note.1.png | Bin 0 -> 1608 bytes .../Currency/Generic/Numbers/note.10.png | Bin 0 -> 1721 bytes .../Currency/Generic/Numbers/note.100.png | Bin 0 -> 1737 bytes .../Currency/Generic/Numbers/note.2.png | Bin 0 -> 1680 bytes .../Currency/Generic/Numbers/note.20.png | Bin 0 -> 1788 bytes .../Currency/Generic/Numbers/note.5.png | Bin 0 -> 1655 bytes .../Currency/Generic/Numbers/note.50.png | Bin 0 -> 1773 bytes .../Bonus/Images/Currency/Generic/bill1.png | Bin 0 -> 1366 bytes .../Bonus/Images/Currency/Generic/bill10.png | Bin 0 -> 2121 bytes .../Bonus/Images/Currency/Generic/bill100.png | Bin 0 -> 1897 bytes .../Images/Currency/Generic/bill1000.png | Bin 0 -> 1724 bytes .../Bonus/Images/Currency/Generic/bill2.png | Bin 0 -> 2129 bytes .../Bonus/Images/Currency/Generic/bill20.png | Bin 0 -> 2589 bytes .../Bonus/Images/Currency/Generic/bill200.png | Bin 0 -> 2173 bytes .../Images/Currency/Generic/bill2000.png | Bin 0 -> 1952 bytes .../Bonus/Images/Currency/Generic/bill5.png | Bin 0 -> 1999 bytes .../Bonus/Images/Currency/Generic/bill50.png | Bin 0 -> 2519 bytes .../Bonus/Images/Currency/Generic/bill500.png | Bin 0 -> 2153 bytes .../Images/Currency/Generic/bill5000.png | Bin 0 -> 1942 bytes .../Bonus/Images/Currency/Generic/coin.01.png | Bin 0 -> 5054 bytes .../Bonus/Images/Currency/Generic/coin.02.png | Bin 0 -> 5180 bytes .../Bonus/Images/Currency/Generic/coin.05.png | Bin 0 -> 5156 bytes .../Bonus/Images/Currency/Generic/coin.10.png | Bin 0 -> 5054 bytes .../Bonus/Images/Currency/Generic/coin.20.png | Bin 0 -> 5145 bytes .../Bonus/Images/Currency/Generic/coin.25.png | Bin 0 -> 5118 bytes .../Bonus/Images/Currency/Generic/coin.50.png | Bin 0 -> 5158 bytes .../Bonus/Images/Currency/Generic/coin1.png | Bin 0 -> 6681 bytes .../Bonus/Images/Currency/Generic/coin10.png | Bin 0 -> 6957 bytes .../Bonus/Images/Currency/Generic/coin100.png | Bin 0 -> 7073 bytes .../Bonus/Images/Currency/Generic/coin2.png | Bin 0 -> 6823 bytes .../Bonus/Images/Currency/Generic/coin20.png | Bin 0 -> 7050 bytes .../Bonus/Images/Currency/Generic/coin5.png | Bin 0 -> 6826 bytes .../Bonus/Images/Currency/Generic/coin50.png | Bin 0 -> 7050 bytes .../Bonus/Images/Currency/HR_Kune/1000kn.jpg | Bin 0 -> 6654 bytes .../Bonus/Images/Currency/HR_Kune/100kn.jpg | Bin 0 -> 10285 bytes .../Bonus/Images/Currency/HR_Kune/10kn.jpg | Bin 0 -> 9680 bytes .../Images/Currency/HR_Kune/10lipacoin.jpg | Bin 0 -> 1324 bytes .../Images/Currency/HR_Kune/10lipacoin.png | Bin 0 -> 4879 bytes .../Images/Currency/HR_Kune/1kunacoin.jpg | Bin 0 -> 1403 bytes .../Images/Currency/HR_Kune/1kunacoin.png | Bin 0 -> 4655 bytes .../Images/Currency/HR_Kune/1lipacoin.jpg | Bin 0 -> 877 bytes .../Images/Currency/HR_Kune/1lipacoin.png | Bin 0 -> 2912 bytes .../Bonus/Images/Currency/HR_Kune/200kn.jpg | Bin 0 -> 9353 bytes .../Bonus/Images/Currency/HR_Kune/20kn.jpg | Bin 0 -> 6242 bytes .../Images/Currency/HR_Kune/20lipacoin.jpg | Bin 0 -> 1058 bytes .../Images/Currency/HR_Kune/20lipacoin.png | Bin 0 -> 3084 bytes .../Images/Currency/HR_Kune/25kunacoin.jpg | Bin 0 -> 2226 bytes .../Images/Currency/HR_Kune/25kunacoin.png | Bin 0 -> 9529 bytes .../Images/Currency/HR_Kune/2kunacoin.jpg | Bin 0 -> 1423 bytes .../Images/Currency/HR_Kune/2kunacoin.png | Bin 0 -> 6230 bytes .../Images/Currency/HR_Kune/2lipacoin.jpg | Bin 0 -> 1156 bytes .../Images/Currency/HR_Kune/2lipacoin.png | Bin 0 -> 4169 bytes .../Bonus/Images/Currency/HR_Kune/500kn.jpg | Bin 0 -> 5636 bytes .../Bonus/Images/Currency/HR_Kune/50kn.jpg | Bin 0 -> 6109 bytes .../Images/Currency/HR_Kune/50lipacoin.jpg | Bin 0 -> 1174 bytes .../Images/Currency/HR_Kune/50lipacoin.png | Bin 0 -> 3956 bytes .../Images/Currency/HR_Kune/5kunacoin.jpg | Bin 0 -> 1618 bytes .../Images/Currency/HR_Kune/5kunacoin.png | Bin 0 -> 6276 bytes .../Images/Currency/HR_Kune/5lipacoin.jpg | Bin 0 -> 1177 bytes .../Images/Currency/HR_Kune/5lipacoin.png | Bin 0 -> 4240 bytes .../Images/Currency/US_Dollar/coin.01.png | Bin 0 -> 7165 bytes .../Images/Currency/US_Dollar/coin.05.png | Bin 0 -> 6938 bytes .../Bonus/Images/Currency/US_Dollar/coin.1 | Bin 0 -> 13594 bytes .../Images/Currency/US_Dollar/coin.1.png | Bin 0 -> 13439 bytes .../Images/Currency/US_Dollar/coin.10.png | Bin 0 -> 5905 bytes .../Images/Currency/US_Dollar/coin.25.png | Bin 0 -> 8747 bytes .../Images/Currency/US_Dollar/coin.50.png | Bin 0 -> 12236 bytes .../Images/Currency/US_Dollar/note.1.png | Bin 0 -> 21086 bytes .../Images/Currency/US_Dollar/note.10.png | Bin 0 -> 21489 bytes .../Images/Currency/US_Dollar/note.100.png | Bin 0 -> 21826 bytes .../Images/Currency/US_Dollar/note.2.png | Bin 0 -> 21032 bytes .../Images/Currency/US_Dollar/note.20.png | Bin 0 -> 22448 bytes .../Images/Currency/US_Dollar/note.5.png | Bin 0 -> 21087 bytes .../Images/Currency/US_Dollar/note.50.png | Bin 0 -> 22258 bytes .../Bonus/Images/Currency/euro/coin.01.png | Bin 0 -> 6965 bytes .../Bonus/Images/Currency/euro/coin.02.png | Bin 0 -> 7104 bytes .../Bonus/Images/Currency/euro/coin.05.png | Bin 0 -> 7218 bytes .../Bonus/Images/Currency/euro/coin.1.png | Bin 0 -> 6985 bytes .../Bonus/Images/Currency/euro/coin.10.png | Bin 0 -> 7054 bytes .../Bonus/Images/Currency/euro/coin.2.png | Bin 0 -> 6855 bytes .../Bonus/Images/Currency/euro/coin.20.png | Bin 0 -> 7327 bytes .../Bonus/Images/Currency/euro/coin.50.png | Bin 0 -> 6894 bytes .../Bonus/Images/Currency/euro/note.10.png | Bin 0 -> 7793 bytes .../Bonus/Images/Currency/euro/note.20.png | Bin 0 -> 8060 bytes .../Bonus/Images/Currency/euro/note.5.png | Bin 0 -> 7499 bytes .../Bonus/Images/Currency/euro/note.50.png | Bin 0 -> 7934 bytes src/other/Bonus/Images/Drink/Cocktails.jpg | Bin 0 -> 17130 bytes src/other/Bonus/Images/Drink/americano.jpg | Bin 0 -> 11339 bytes src/other/Bonus/Images/Drink/beer_bottle.jpg | Bin 0 -> 13057 bytes src/other/Bonus/Images/Drink/cappuccino.jpg | Bin 0 -> 8909 bytes src/other/Bonus/Images/Drink/cocktail.jpg | Bin 0 -> 22793 bytes src/other/Bonus/Images/Drink/coke.jpg | Bin 0 -> 2342 bytes src/other/Bonus/Images/Drink/fanta.jpg | Bin 0 -> 4086 bytes .../Images/Drink/minerals_applejuice.jpg | Bin 0 -> 17368 bytes .../Bonus/Images/Drink/minerals_water.jpg | Bin 0 -> 12328 bytes src/other/Bonus/Images/Drink/soft_coca.jpg | Bin 0 -> 23802 bytes src/other/Bonus/Images/Drink/spirit.jpg | Bin 0 -> 6584 bytes .../Bonus/Images/Drink/spirits_Whisky.jpg | Bin 0 -> 12404 bytes src/other/Bonus/Images/Drink/sprite.jpg | Bin 0 -> 36959 bytes src/other/Bonus/Images/Drink/wine_labels.jpg | Bin 0 -> 13963 bytes src/other/Bonus/Images/Drink/wine_rose.jpg | Bin 0 -> 15702 bytes src/other/Bonus/Images/Food/AlmondSlice.jpg | Bin 0 -> 2562 bytes .../Bonus/Images/Food/americancheese.png | Bin 0 -> 17033 bytes src/other/Bonus/Images/Food/apple.jpg | Bin 0 -> 3451 bytes src/other/Bonus/Images/Food/bananas.jpg | Bin 0 -> 4231 bytes src/other/Bonus/Images/Food/caesarsalad.jpg | Bin 0 -> 3244 bytes src/other/Bonus/Images/Food/carbonara.jpg | Bin 0 -> 4061 bytes src/other/Bonus/Images/Food/chickenstrips.jpg | Bin 0 -> 5407 bytes src/other/Bonus/Images/Food/chickwings.jpg | Bin 0 -> 2974 bytes src/other/Bonus/Images/Food/coffeebeans.jpg | Bin 0 -> 4245 bytes src/other/Bonus/Images/Food/cookies.jpg | Bin 0 -> 2095 bytes src/other/Bonus/Images/Food/dips.jpg | Bin 0 -> 3322 bytes .../Bonus/Images/Food/food_asparagus.png | Bin 0 -> 20159 bytes src/other/Bonus/Images/Food/food_burger.png | Bin 0 -> 23151 bytes src/other/Bonus/Images/Food/food_burgers.jpg | Bin 0 -> 10632 bytes src/other/Bonus/Images/Food/fries.png | Bin 0 -> 14920 bytes src/other/Bonus/Images/Food/fusilli.jpg | Bin 0 -> 4547 bytes src/other/Bonus/Images/Food/gardensalad.jpg | Bin 0 -> 2455 bytes .../Bonus/Images/Food/garlicpizzabread.jpg | Bin 0 -> 3185 bytes src/other/Bonus/Images/Food/girasoli.jpg | Bin 0 -> 3405 bytes src/other/Bonus/Images/Food/haagen.gif | Bin 0 -> 7811 bytes src/other/Bonus/Images/Food/hawaiian.jpg | Bin 0 -> 3130 bytes src/other/Bonus/Images/Food/italiansalad.jpg | Bin 0 -> 3521 bytes src/other/Bonus/Images/Food/lasagna.jpg | Bin 0 -> 3299 bytes src/other/Bonus/Images/Food/margherita.jpg | Bin 0 -> 2758 bytes src/other/Bonus/Images/Food/pasta.jpg | Bin 0 -> 2789 bytes src/other/Bonus/Images/Food/pepperoni.jpg | Bin 0 -> 3111 bytes src/other/Bonus/Images/Food/pizza1.jpg | Bin 0 -> 15742 bytes src/other/Bonus/Images/Food/potatoskins.jpg | Bin 0 -> 3218 bytes src/other/Bonus/Images/Food/potatowedges.jpg | Bin 0 -> 2859 bytes src/other/Bonus/Images/Food/ravioli.jpg | Bin 0 -> 3103 bytes src/other/Bonus/Images/Food/salad-01.png | Bin 0 -> 24333 bytes src/other/Bonus/Images/Food/sauce.jpg | Bin 0 -> 2956 bytes src/other/Bonus/Images/Food/spaghetti.jpg | Bin 0 -> 3769 bytes src/other/Bonus/Images/Food/sponge.jpg | Bin 0 -> 2954 bytes src/other/Bonus/Images/Food/strawberries.jpg | Bin 0 -> 10852 bytes src/other/Bonus/Images/Food/subs.jpg | Bin 0 -> 3748 bytes src/other/Bonus/Images/Food/subs_1.jpg | Bin 0 -> 10776 bytes src/other/Bonus/Images/Food/tealeaves.jpg | Bin 0 -> 7224 bytes src/other/Bonus/Images/Food/vegpizza.jpg | Bin 0 -> 2358 bytes .../Bonus/Images/System/301-keyboard.png | Bin 0 -> 3249 bytes src/other/Bonus/Images/System/cash.png | Bin 0 -> 536 bytes src/other/Bonus/Images/System/cashdrawer.png | Bin 0 -> 716 bytes src/other/Bonus/Images/System/empty.png | Bin 0 -> 1229 bytes .../Bonus/Images/System/gplv3-127x51.png | Bin 0 -> 3471 bytes .../Images/System/grey_wash_wall_@940_580.png | Bin 0 -> 191368 bytes .../Images/System/grey_wash_wall_@940_588.png | Bin 0 -> 194083 bytes .../Images/System/grey_wash_wall_@950_594.png | Bin 0 -> 202016 bytes .../Images/System/grey_wash_wall_@960_600.png | Bin 0 -> 210089 bytes src/other/Bonus/Images/System/heart.png | Bin 0 -> 1165 bytes .../Bonus/Images/System/img.cashdrawer.png | Bin 0 -> 716 bytes .../Bonus/Images/System/img.discount.png | Bin 0 -> 1079 bytes .../Bonus/Images/System/img.discount_b.png | Bin 0 -> 1543 bytes .../Bonus/Images/System/img.keyboard_32.png | Bin 0 -> 1354 bytes .../Bonus/Images/System/img.ticket_print.png | Bin 0 -> 639 bytes src/other/Bonus/Images/System/img.user.png | Bin 0 -> 1434 bytes src/other/Bonus/Images/System/keyboard_48.png | Bin 0 -> 771 bytes src/other/Bonus/Images/System/kit_print.png | Bin 0 -> 896 bytes .../Bonus/Images/System/meetingrooms.jpg | Bin 0 -> 34192 bytes src/other/Bonus/Images/System/no_photo.png | Bin 0 -> 1358 bytes .../osi_reversing_logotype_color_to_white.png | Bin 0 -> 58340 bytes .../Bonus/Images/System/osi_standard_logo.png | Bin 0 -> 61727 bytes src/other/Bonus/Images/System/refundit.png | Bin 0 -> 603 bytes .../Bonus/Images/System/remote_print.png | Bin 0 -> 835 bytes .../Bonus/Images/System/restaurant_floor.png | Bin 0 -> 231460 bytes .../Images/System/restaurant_floor_sml.png | Bin 0 -> 29443 bytes src/other/Bonus/Images/System/run_script.png | Bin 0 -> 650 bytes .../Bonus/Images/System/ticket_print.png | Bin 0 -> 1135 bytes src/other/Bonus/Images/Tile/col_0.png | Bin 0 -> 1146 bytes src/other/Bonus/Images/Tile/col_0_wide.png | Bin 0 -> 467 bytes src/other/Bonus/Images/Tile/col_1.png | Bin 0 -> 1167 bytes src/other/Bonus/Images/Tile/col_10.png | Bin 0 -> 1146 bytes src/other/Bonus/Images/Tile/col_10_wide.png | Bin 0 -> 451 bytes src/other/Bonus/Images/Tile/col_11.png | Bin 0 -> 1146 bytes src/other/Bonus/Images/Tile/col_11_wide.png | Bin 0 -> 450 bytes src/other/Bonus/Images/Tile/col_12.png | Bin 0 -> 1146 bytes src/other/Bonus/Images/Tile/col_12_wide.png | Bin 0 -> 450 bytes src/other/Bonus/Images/Tile/col_13.png | Bin 0 -> 1146 bytes src/other/Bonus/Images/Tile/col_13_wide.png | Bin 0 -> 450 bytes src/other/Bonus/Images/Tile/col_14.png | Bin 0 -> 1146 bytes src/other/Bonus/Images/Tile/col_14_wide.png | Bin 0 -> 451 bytes src/other/Bonus/Images/Tile/col_15.png | Bin 0 -> 1146 bytes src/other/Bonus/Images/Tile/col_15_wide.png | Bin 0 -> 451 bytes src/other/Bonus/Images/Tile/col_16.png | Bin 0 -> 1146 bytes src/other/Bonus/Images/Tile/col_16_wide.png | Bin 0 -> 521 bytes src/other/Bonus/Images/Tile/col_17.png | Bin 0 -> 1146 bytes src/other/Bonus/Images/Tile/col_17_wide.png | Bin 0 -> 451 bytes src/other/Bonus/Images/Tile/col_18.png | Bin 0 -> 1146 bytes src/other/Bonus/Images/Tile/col_18_wide.png | Bin 0 -> 451 bytes src/other/Bonus/Images/Tile/col_19.png | Bin 0 -> 1146 bytes src/other/Bonus/Images/Tile/col_19_wide.png | Bin 0 -> 451 bytes src/other/Bonus/Images/Tile/col_1_wide.png | Bin 0 -> 452 bytes src/other/Bonus/Images/Tile/col_2.png | Bin 0 -> 1146 bytes src/other/Bonus/Images/Tile/col_20.png | Bin 0 -> 1146 bytes src/other/Bonus/Images/Tile/col_20_wide.png | Bin 0 -> 451 bytes src/other/Bonus/Images/Tile/col_2_wide.png | Bin 0 -> 451 bytes src/other/Bonus/Images/Tile/col_3.png | Bin 0 -> 1146 bytes src/other/Bonus/Images/Tile/col_3_wide.png | Bin 0 -> 450 bytes src/other/Bonus/Images/Tile/col_4.png | Bin 0 -> 1146 bytes src/other/Bonus/Images/Tile/col_4_wide.png | Bin 0 -> 451 bytes src/other/Bonus/Images/Tile/col_5.png | Bin 0 -> 1146 bytes src/other/Bonus/Images/Tile/col_5_wide.png | Bin 0 -> 451 bytes src/other/Bonus/Images/Tile/col_6.png | Bin 0 -> 1146 bytes src/other/Bonus/Images/Tile/col_6_wide.png | Bin 0 -> 451 bytes src/other/Bonus/Images/Tile/col_7.png | Bin 0 -> 1146 bytes src/other/Bonus/Images/Tile/col_7_wide.png | Bin 0 -> 521 bytes src/other/Bonus/Images/Tile/col_8.png | Bin 0 -> 1146 bytes src/other/Bonus/Images/Tile/col_8_wide.png | Bin 0 -> 521 bytes src/other/Bonus/Images/Tile/col_9.png | Bin 0 -> 1146 bytes src/other/Bonus/Images/Tile/col_9_wide.png | Bin 0 -> 451 bytes src/other/Configs/payments_euro.txt | 44 + src/other/Configs/payments_full.txt | 46 + src/other/Configs/payments_uk.txt | 41 + src/other/Configs/payments_us.txt | 41 + .../i686-unknown-linux-gnu/librxtxParallel.so | Bin 0 -> 48472 bytes .../i686-unknown-linux-gnu/librxtxSerial.so | Bin 0 -> 159763 bytes .../ia64-unkown-linux-gnu/librxtxParallel.so | Bin 0 -> 48472 bytes .../librxtxParallel64.so | Bin 0 -> 53636 bytes .../ia64-unkown-linux-gnu/librxtxSerial.so | Bin 0 -> 159763 bytes .../ia64-unkown-linux-gnu/librxtxSerial64.so | Bin 0 -> 181757 bytes .../librxtxParallel64.so | Bin 0 -> 53636 bytes .../librxtxSerial64.so | Bin 0 -> 181757 bytes src/other/Mac_OS_X/README | 4 + src/other/Mac_OS_X/librxtxSerial.jnilib | Bin 0 -> 173624 bytes src/other/Mac_OS_X/librxtxSerial64.jnilib | Bin 0 -> 186064 bytes .../librxtxSerial-2.1-7.so | Bin 0 -> 136880 bytes .../sparc32-sun-solaris2.8/librxtxSerial.so | Bin 0 -> 136880 bytes .../librxtxSerial-2.1-7.so | Bin 0 -> 162720 bytes .../sparc64-sun-solaris2.8/librxtxSerial.so | Bin 0 -> 162720 bytes .../Templates/US_Printer.PrintLastTicket.txt | 406 ++ .../Templates/US_Printer.ReprintTicket.txt | 303 ++ src/other/Templates/US_Printer.Ticket.txt | 275 ++ src/other/Templates/US_Printer.TicketLine.txt | 46 + .../Templates/US_Printer.TicketPreview.txt | 268 ++ src/other/Windows/i368-mingw32/README | 3 + .../Windows/i368-mingw32/rxtxParallel.dll | Bin 0 -> 80527 bytes .../Windows/i368-mingw32/rxtxParallel64.dll | Bin 0 -> 138556 bytes src/other/Windows/i368-mingw32/rxtxSerial.dll | Bin 0 -> 101746 bytes .../Windows/i368-mingw32/rxtxSerial64.dll | Bin 0 -> 160194 bytes src/other/images/uniCenta_splash_dark.png | Bin 0 -> 29374 bytes src/other/images/unicentaopos.ico | Bin 0 -> 21656 bytes src/other/images/unicentaopos.png | Bin 0 -> 27680 bytes src/other/license/license.txt | 10 + src/scripts/configure.bat | 25 + src/scripts/configure.sh | 25 + src/scripts/start.bat | 59 + src/scripts/start.sh | 45 + .../java/com/unicenta/PackageScanTest.java | 13 + .../data/loader/StaticSentenceTest.java | 39 + .../unicenta/pos/ticket/TicketInfoTest.java | 122 + 1680 files changed, 241310 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/com/unicenta/basic/BasicException.java create mode 100644 src/main/java/com/unicenta/beans/DateUtils.java create mode 100644 src/main/java/com/unicenta/beans/JCalendarDialog.form create mode 100644 src/main/java/com/unicenta/beans/JCalendarDialog.java create mode 100644 src/main/java/com/unicenta/beans/JCalendarPanel.form create mode 100644 src/main/java/com/unicenta/beans/JCalendarPanel.java create mode 100644 src/main/java/com/unicenta/beans/JClockPanel.form create mode 100644 src/main/java/com/unicenta/beans/JClockPanel.java create mode 100644 src/main/java/com/unicenta/beans/JFlowPanel.java create mode 100644 src/main/java/com/unicenta/beans/JGuestsPop.form create mode 100644 src/main/java/com/unicenta/beans/JGuestsPop.java create mode 100644 src/main/java/com/unicenta/beans/JNumberDialog.form create mode 100644 src/main/java/com/unicenta/beans/JNumberDialog.java create mode 100644 src/main/java/com/unicenta/beans/JNumberEvent.java create mode 100644 src/main/java/com/unicenta/beans/JNumberEventListener.java create mode 100644 src/main/java/com/unicenta/beans/JNumberKeys.form create mode 100644 src/main/java/com/unicenta/beans/JNumberKeys.java create mode 100644 src/main/java/com/unicenta/beans/JNumberPop.form create mode 100644 src/main/java/com/unicenta/beans/JNumberPop.java create mode 100644 src/main/java/com/unicenta/beans/JPasswordDialog.form create mode 100644 src/main/java/com/unicenta/beans/JPasswordDialog.java create mode 100644 src/main/java/com/unicenta/beans/JTimePanel.form create mode 100644 src/main/java/com/unicenta/beans/JTimePanel.java create mode 100644 src/main/java/com/unicenta/beans/LocaleResources.java create mode 100644 src/main/java/com/unicenta/beans/RoundedBorder.java create mode 100644 src/main/java/com/unicenta/data/gui/ComboBoxValModel.java create mode 100644 src/main/java/com/unicenta/data/gui/CompoundIcon.java create mode 100644 src/main/java/com/unicenta/data/gui/FindInfo.java create mode 100644 src/main/java/com/unicenta/data/gui/JCounter.form create mode 100644 src/main/java/com/unicenta/data/gui/JCounter.java create mode 100644 src/main/java/com/unicenta/data/gui/JFind.form create mode 100644 src/main/java/com/unicenta/data/gui/JFind.java create mode 100644 src/main/java/com/unicenta/data/gui/JImageEditor.form create mode 100644 src/main/java/com/unicenta/data/gui/JImageEditor.java create mode 100644 src/main/java/com/unicenta/data/gui/JImageViewerCustomer.form create mode 100644 src/main/java/com/unicenta/data/gui/JImageViewerCustomer.java create mode 100644 src/main/java/com/unicenta/data/gui/JImageViewerProduct.form create mode 100644 src/main/java/com/unicenta/data/gui/JImageViewerProduct.java create mode 100644 src/main/java/com/unicenta/data/gui/JLabelDirty.java create mode 100644 src/main/java/com/unicenta/data/gui/JListData.form create mode 100644 src/main/java/com/unicenta/data/gui/JListData.java create mode 100644 src/main/java/com/unicenta/data/gui/JListNavigator.form create mode 100644 src/main/java/com/unicenta/data/gui/JListNavigator.java create mode 100644 src/main/java/com/unicenta/data/gui/JMessageDialog.form create mode 100644 src/main/java/com/unicenta/data/gui/JMessageDialog.java create mode 100644 src/main/java/com/unicenta/data/gui/JNavigator.form create mode 100644 src/main/java/com/unicenta/data/gui/JNavigator.java create mode 100644 src/main/java/com/unicenta/data/gui/JSaver.form create mode 100644 src/main/java/com/unicenta/data/gui/JSaver.java create mode 100644 src/main/java/com/unicenta/data/gui/JSort.form create mode 100644 src/main/java/com/unicenta/data/gui/JSort.java create mode 100644 src/main/java/com/unicenta/data/gui/ListCellRendererBasic.java create mode 100644 src/main/java/com/unicenta/data/gui/ListKeyed.java create mode 100644 src/main/java/com/unicenta/data/gui/ListQBFModelNumber.java create mode 100644 src/main/java/com/unicenta/data/gui/MessageInf.java create mode 100644 src/main/java/com/unicenta/data/gui/NullIcon.java create mode 100644 src/main/java/com/unicenta/data/gui/TableRendererBasic.java create mode 100644 src/main/java/com/unicenta/data/loader/BaseSentence.java create mode 100644 src/main/java/com/unicenta/data/loader/BasicSentenceEnum.java create mode 100644 src/main/java/com/unicenta/data/loader/BatchSentence.java create mode 100644 src/main/java/com/unicenta/data/loader/BatchSentenceResource.java create mode 100644 src/main/java/com/unicenta/data/loader/BatchSentenceScript.java create mode 100644 src/main/java/com/unicenta/data/loader/CompanyDetails.java create mode 100644 src/main/java/com/unicenta/data/loader/ComparatorCreator.java create mode 100644 src/main/java/com/unicenta/data/loader/ComparatorCreatorBasic.java create mode 100644 src/main/java/com/unicenta/data/loader/DataField.java create mode 100644 src/main/java/com/unicenta/data/loader/DataParams.java create mode 100644 src/main/java/com/unicenta/data/loader/DataRead.java create mode 100644 src/main/java/com/unicenta/data/loader/DataResultSet.java create mode 100644 src/main/java/com/unicenta/data/loader/DataWrite.java create mode 100644 src/main/java/com/unicenta/data/loader/DataWriteUtils.java create mode 100644 src/main/java/com/unicenta/data/loader/Datas.java create mode 100644 src/main/java/com/unicenta/data/loader/IKeyGetter.java create mode 100644 src/main/java/com/unicenta/data/loader/IKeyed.java create mode 100644 src/main/java/com/unicenta/data/loader/IRenderString.java create mode 100644 src/main/java/com/unicenta/data/loader/ISQLBuilderStatic.java create mode 100644 src/main/java/com/unicenta/data/loader/ImageUtils.java create mode 100644 src/main/java/com/unicenta/data/loader/ImportSentence.java create mode 100644 src/main/java/com/unicenta/data/loader/JDBCSentence.java create mode 100644 src/main/java/com/unicenta/data/loader/KeyGetterBasic.java create mode 100644 src/main/java/com/unicenta/data/loader/KeyGetterBuilder.java create mode 100644 src/main/java/com/unicenta/data/loader/KeyGetterFirst.java create mode 100644 src/main/java/com/unicenta/data/loader/LocalRes.java create mode 100644 src/main/java/com/unicenta/data/loader/MetaSentence.java create mode 100644 src/main/java/com/unicenta/data/loader/NormalBuilder.java create mode 100644 src/main/java/com/unicenta/data/loader/PreparedSentence.java create mode 100644 src/main/java/com/unicenta/data/loader/QBFBuilder.java create mode 100644 src/main/java/com/unicenta/data/loader/QBFCompareEnum.java create mode 100644 src/main/java/com/unicenta/data/loader/RenderStringBasic.java create mode 100644 src/main/java/com/unicenta/data/loader/SentenceEnum.java create mode 100644 src/main/java/com/unicenta/data/loader/SentenceExec.java create mode 100644 src/main/java/com/unicenta/data/loader/SentenceExecAdapter.java create mode 100644 src/main/java/com/unicenta/data/loader/SentenceExecTransaction.java create mode 100644 src/main/java/com/unicenta/data/loader/SentenceFind.java create mode 100644 src/main/java/com/unicenta/data/loader/SentenceList.java create mode 100644 src/main/java/com/unicenta/data/loader/SentenceUpdateResultSet.java create mode 100644 src/main/java/com/unicenta/data/loader/SequenceForDerby.java create mode 100644 src/main/java/com/unicenta/data/loader/SequenceForMySQL.java create mode 100644 src/main/java/com/unicenta/data/loader/SequenceForSQLite.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializableBuilder.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializableRead.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializableWrite.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializerRead.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializerReadBasic.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializerReadBuilder.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializerReadBytes.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializerReadClass.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializerReadDate.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializerReadDouble.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializerReadImage.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializerReadInteger.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializerReadString.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializerReadUTF8.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializerWrite.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializerWriteBasic.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializerWriteBasicComposed.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializerWriteBasicExt.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializerWriteBuilder.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializerWriteComposed.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializerWriteInteger.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializerWriteParams.java create mode 100644 src/main/java/com/unicenta/data/loader/SerializerWriteString.java create mode 100644 src/main/java/com/unicenta/data/loader/Session.java create mode 100644 src/main/java/com/unicenta/data/loader/SessionDB.java create mode 100644 src/main/java/com/unicenta/data/loader/SessionDBDerby.java create mode 100644 src/main/java/com/unicenta/data/loader/SessionDBGeneric.java create mode 100644 src/main/java/com/unicenta/data/loader/SessionDBHSQLDB.java create mode 100644 src/main/java/com/unicenta/data/loader/SessionDBMariaDB.java create mode 100644 src/main/java/com/unicenta/data/loader/SessionDBMySQL.java create mode 100644 src/main/java/com/unicenta/data/loader/SessionDBOracle.java create mode 100644 src/main/java/com/unicenta/data/loader/SessionDBPostgreSQL.java create mode 100644 src/main/java/com/unicenta/data/loader/SessionDBSQLite.java create mode 100644 src/main/java/com/unicenta/data/loader/SimpleBuilder.java create mode 100644 src/main/java/com/unicenta/data/loader/StaticSentence.java create mode 100644 src/main/java/com/unicenta/data/loader/TableDefinition.java create mode 100644 src/main/java/com/unicenta/data/loader/TicketFooter.java create mode 100644 src/main/java/com/unicenta/data/loader/TicketHeader.java create mode 100644 src/main/java/com/unicenta/data/loader/Transaction.java create mode 100644 src/main/java/com/unicenta/data/loader/Vectorer.java create mode 100644 src/main/java/com/unicenta/data/loader/VectorerBasic.java create mode 100644 src/main/java/com/unicenta/data/loader/VectorerBuilder.java create mode 100644 src/main/java/com/unicenta/data/model/Column.java create mode 100644 src/main/java/com/unicenta/data/model/Field.java create mode 100644 src/main/java/com/unicenta/data/model/PrimaryKey.java create mode 100644 src/main/java/com/unicenta/data/model/Row.java create mode 100644 src/main/java/com/unicenta/data/model/Table.java create mode 100644 src/main/java/com/unicenta/data/user/BrowsableData.java create mode 100644 src/main/java/com/unicenta/data/user/BrowsableEditableData.java create mode 100644 src/main/java/com/unicenta/data/user/BrowseListener.java create mode 100644 src/main/java/com/unicenta/data/user/DirtyListener.java create mode 100644 src/main/java/com/unicenta/data/user/DirtyManager.java create mode 100644 src/main/java/com/unicenta/data/user/DocumentLoader.java create mode 100644 src/main/java/com/unicenta/data/user/DocumentLoaderBasic.java create mode 100644 src/main/java/com/unicenta/data/user/EditorCreator.java create mode 100644 src/main/java/com/unicenta/data/user/EditorCreatorComposed.java create mode 100644 src/main/java/com/unicenta/data/user/EditorListener.java create mode 100644 src/main/java/com/unicenta/data/user/EditorRecord.java create mode 100644 src/main/java/com/unicenta/data/user/FilterEditorCreator.java create mode 100644 src/main/java/com/unicenta/data/user/Finder.java create mode 100644 src/main/java/com/unicenta/data/user/ListProvider.java create mode 100644 src/main/java/com/unicenta/data/user/ListProviderCreator.java create mode 100644 src/main/java/com/unicenta/data/user/SaveProvider.java create mode 100644 src/main/java/com/unicenta/data/user/StateListener.java create mode 100644 src/main/java/com/unicenta/editor/EditorComponent.java create mode 100644 src/main/java/com/unicenta/editor/EditorKeys.java create mode 100644 src/main/java/com/unicenta/editor/JEditorAbstract.form create mode 100644 src/main/java/com/unicenta/editor/JEditorAbstract.java create mode 100644 src/main/java/com/unicenta/editor/JEditorCurrency.java create mode 100644 src/main/java/com/unicenta/editor/JEditorCurrencyPositive.java create mode 100644 src/main/java/com/unicenta/editor/JEditorDouble.java create mode 100644 src/main/java/com/unicenta/editor/JEditorDoublePositive.java create mode 100644 src/main/java/com/unicenta/editor/JEditorIntegerPositive.java create mode 100644 src/main/java/com/unicenta/editor/JEditorKeys.form create mode 100644 src/main/java/com/unicenta/editor/JEditorKeys.java create mode 100644 src/main/java/com/unicenta/editor/JEditorNumber.java create mode 100644 src/main/java/com/unicenta/editor/JEditorPassword.java create mode 100644 src/main/java/com/unicenta/editor/JEditorString.java create mode 100644 src/main/java/com/unicenta/editor/JEditorStringNumber.java create mode 100644 src/main/java/com/unicenta/editor/JEditorText.java create mode 100644 src/main/java/com/unicenta/format/DoubleUtils.java create mode 100644 src/main/java/com/unicenta/format/Formats.java create mode 100644 src/main/java/com/unicenta/format/FormatsConstrain.java create mode 100644 src/main/java/com/unicenta/format/FormatsException.java create mode 100644 src/main/java/com/unicenta/format/FormatsRESOURCE.java create mode 100644 src/main/java/com/unicenta/format/FormatsValidate.java create mode 100644 src/main/java/com/unicenta/orderpop/OrderPop.java create mode 100644 src/main/java/com/unicenta/orderpop/listStyle.css create mode 100644 src/main/java/com/unicenta/pos/admin/DataLogicAdmin.java create mode 100644 src/main/java/com/unicenta/pos/admin/JPeopleFinder.form create mode 100644 src/main/java/com/unicenta/pos/admin/JPeopleFinder.java create mode 100644 src/main/java/com/unicenta/pos/admin/OWWatch.java create mode 100644 src/main/java/com/unicenta/pos/admin/PeopleInfo.java create mode 100644 src/main/java/com/unicenta/pos/admin/PeoplePanel.java create mode 100644 src/main/java/com/unicenta/pos/admin/PeopleRenderer.java create mode 100644 src/main/java/com/unicenta/pos/admin/PeopleView.form create mode 100644 src/main/java/com/unicenta/pos/admin/PeopleView.java create mode 100644 src/main/java/com/unicenta/pos/admin/ResourceType.java create mode 100644 src/main/java/com/unicenta/pos/admin/ResourcesPanel.java create mode 100644 src/main/java/com/unicenta/pos/admin/ResourcesView.form create mode 100644 src/main/java/com/unicenta/pos/admin/ResourcesView.java create mode 100644 src/main/java/com/unicenta/pos/admin/RoleExtInfo.java create mode 100644 src/main/java/com/unicenta/pos/admin/RoleInfo.java create mode 100644 src/main/java/com/unicenta/pos/admin/RolesPanel.java create mode 100644 src/main/java/com/unicenta/pos/admin/RolesView.java create mode 100644 src/main/java/com/unicenta/pos/catalog/CatalogSelector.java create mode 100644 src/main/java/com/unicenta/pos/catalog/CategoryStock.java create mode 100644 src/main/java/com/unicenta/pos/catalog/JCatalog.form create mode 100644 src/main/java/com/unicenta/pos/catalog/JCatalog.java create mode 100644 src/main/java/com/unicenta/pos/catalog/JCatalogTab.form create mode 100644 src/main/java/com/unicenta/pos/catalog/JCatalogTab.java create mode 100644 src/main/java/com/unicenta/pos/catalog/JProductsSelector.form create mode 100644 src/main/java/com/unicenta/pos/catalog/JProductsSelector.java create mode 100644 src/main/java/com/unicenta/pos/comm/CommStream.java create mode 100644 src/main/java/com/unicenta/pos/config/JFrmConfig.form create mode 100644 src/main/java/com/unicenta/pos/config/JFrmConfig.java create mode 100644 src/main/java/com/unicenta/pos/config/JPanelConfigCompany.form create mode 100644 src/main/java/com/unicenta/pos/config/JPanelConfigCompany.java create mode 100644 src/main/java/com/unicenta/pos/config/JPanelConfigDatabase.form create mode 100644 src/main/java/com/unicenta/pos/config/JPanelConfigDatabase.java create mode 100644 src/main/java/com/unicenta/pos/config/JPanelConfigERP.form create mode 100644 src/main/java/com/unicenta/pos/config/JPanelConfigERP.java create mode 100644 src/main/java/com/unicenta/pos/config/JPanelConfigGeneral.form create mode 100644 src/main/java/com/unicenta/pos/config/JPanelConfigGeneral.java create mode 100644 src/main/java/com/unicenta/pos/config/JPanelConfigLocale.form create mode 100644 src/main/java/com/unicenta/pos/config/JPanelConfigLocale.java create mode 100644 src/main/java/com/unicenta/pos/config/JPanelConfigPayment.form create mode 100644 src/main/java/com/unicenta/pos/config/JPanelConfigPayment.java create mode 100644 src/main/java/com/unicenta/pos/config/JPanelConfigPeripheral.form create mode 100644 src/main/java/com/unicenta/pos/config/JPanelConfigPeripheral.java create mode 100644 src/main/java/com/unicenta/pos/config/JPanelConfigSystem.form create mode 100644 src/main/java/com/unicenta/pos/config/JPanelConfigSystem.java create mode 100644 src/main/java/com/unicenta/pos/config/JPanelConfiguration.form create mode 100644 src/main/java/com/unicenta/pos/config/JPanelConfiguration.java create mode 100644 src/main/java/com/unicenta/pos/config/JPanelTicketSetup.form create mode 100644 src/main/java/com/unicenta/pos/config/JPanelTicketSetup.java create mode 100644 src/main/java/com/unicenta/pos/config/LocaleComparator.java create mode 100644 src/main/java/com/unicenta/pos/config/PanelConfig.java create mode 100644 src/main/java/com/unicenta/pos/config/ParametersConfig.java create mode 100644 src/main/java/com/unicenta/pos/config/ParametersPrinter.form create mode 100644 src/main/java/com/unicenta/pos/config/ParametersPrinter.java create mode 100644 src/main/java/com/unicenta/pos/customers/CustomerInfo.java create mode 100644 src/main/java/com/unicenta/pos/customers/CustomerInfoExt.java create mode 100644 src/main/java/com/unicenta/pos/customers/CustomerInfoGlobal.java create mode 100644 src/main/java/com/unicenta/pos/customers/CustomerRenderer.java create mode 100644 src/main/java/com/unicenta/pos/customers/CustomerTransaction.java create mode 100644 src/main/java/com/unicenta/pos/customers/CustomersPanel.java create mode 100644 src/main/java/com/unicenta/pos/customers/CustomersPayment.form create mode 100644 src/main/java/com/unicenta/pos/customers/CustomersPayment.java create mode 100644 src/main/java/com/unicenta/pos/customers/CustomersView.form create mode 100644 src/main/java/com/unicenta/pos/customers/CustomersView.java create mode 100644 src/main/java/com/unicenta/pos/customers/DataLogicCustomers.java create mode 100644 src/main/java/com/unicenta/pos/customers/JCustomerFinder.form create mode 100644 src/main/java/com/unicenta/pos/customers/JCustomerFinder.java create mode 100644 src/main/java/com/unicenta/pos/customers/JDialogNewCustomer.form create mode 100644 src/main/java/com/unicenta/pos/customers/JDialogNewCustomer.java create mode 100644 src/main/java/com/unicenta/pos/customers/OrderCustomerList.form create mode 100644 src/main/java/com/unicenta/pos/customers/OrderCustomerList.java create mode 100644 src/main/java/com/unicenta/pos/customers/TicketSelector.java create mode 100644 src/main/java/com/unicenta/pos/epm/Break.java create mode 100644 src/main/java/com/unicenta/pos/epm/BreaksInfo.java create mode 100644 src/main/java/com/unicenta/pos/epm/BreaksPanel.java create mode 100644 src/main/java/com/unicenta/pos/epm/BreaksView.form create mode 100644 src/main/java/com/unicenta/pos/epm/BreaksView.java create mode 100644 src/main/java/com/unicenta/pos/epm/DataLogicPresenceManagement.java create mode 100644 src/main/java/com/unicenta/pos/epm/EmployeeInfo.java create mode 100644 src/main/java/com/unicenta/pos/epm/EmployeeInfoExt.java create mode 100644 src/main/java/com/unicenta/pos/epm/EmployeeRenderer.java create mode 100644 src/main/java/com/unicenta/pos/epm/JEmployeeFinder.form create mode 100644 src/main/java/com/unicenta/pos/epm/JEmployeeFinder.java create mode 100644 src/main/java/com/unicenta/pos/epm/JPanelEmployeePresence.form create mode 100644 src/main/java/com/unicenta/pos/epm/JPanelEmployeePresence.java create mode 100644 src/main/java/com/unicenta/pos/epm/LeavesInfo.java create mode 100644 src/main/java/com/unicenta/pos/epm/LeavesPanel.java create mode 100644 src/main/java/com/unicenta/pos/epm/LeavesView.form create mode 100644 src/main/java/com/unicenta/pos/epm/LeavesView.java create mode 100644 src/main/java/com/unicenta/pos/forms/AppConfig.java create mode 100644 src/main/java/com/unicenta/pos/forms/AppLocal.java create mode 100644 src/main/java/com/unicenta/pos/forms/AppProperties.java create mode 100644 src/main/java/com/unicenta/pos/forms/AppUser.java create mode 100644 src/main/java/com/unicenta/pos/forms/AppUserView.java create mode 100644 src/main/java/com/unicenta/pos/forms/AppView.java create mode 100644 src/main/java/com/unicenta/pos/forms/AppViewConnection.java create mode 100644 src/main/java/com/unicenta/pos/forms/BeanFactory.java create mode 100644 src/main/java/com/unicenta/pos/forms/BeanFactoryApp.java create mode 100644 src/main/java/com/unicenta/pos/forms/BeanFactoryCache.java create mode 100644 src/main/java/com/unicenta/pos/forms/BeanFactoryData.java create mode 100644 src/main/java/com/unicenta/pos/forms/BeanFactoryDataSingle.java create mode 100644 src/main/java/com/unicenta/pos/forms/BeanFactoryException.java create mode 100644 src/main/java/com/unicenta/pos/forms/BeanFactoryObj.java create mode 100644 src/main/java/com/unicenta/pos/forms/BeanFactoryScript.java create mode 100644 src/main/java/com/unicenta/pos/forms/DataLogicOrders.java create mode 100644 src/main/java/com/unicenta/pos/forms/DataLogicSales.java create mode 100644 src/main/java/com/unicenta/pos/forms/DataLogicSystem.java create mode 100644 src/main/java/com/unicenta/pos/forms/DriverWrapper.java create mode 100644 src/main/java/com/unicenta/pos/forms/JDlgChangePassword.form create mode 100644 src/main/java/com/unicenta/pos/forms/JDlgChangePassword.java create mode 100644 src/main/java/com/unicenta/pos/forms/JPanelMenu.form create mode 100644 src/main/java/com/unicenta/pos/forms/JPanelMenu.java create mode 100644 src/main/java/com/unicenta/pos/forms/JPanelNull.form create mode 100644 src/main/java/com/unicenta/pos/forms/JPanelNull.java create mode 100644 src/main/java/com/unicenta/pos/forms/JPanelView.java create mode 100644 src/main/java/com/unicenta/pos/forms/JPrincipalApp.form create mode 100644 src/main/java/com/unicenta/pos/forms/JPrincipalApp.java create mode 100644 src/main/java/com/unicenta/pos/forms/JRootApp.form create mode 100644 src/main/java/com/unicenta/pos/forms/JRootApp.java create mode 100644 src/main/java/com/unicenta/pos/forms/JRootFrame.form create mode 100644 src/main/java/com/unicenta/pos/forms/JRootFrame.java create mode 100644 src/main/java/com/unicenta/pos/forms/JRootKiosk.form create mode 100644 src/main/java/com/unicenta/pos/forms/JRootKiosk.java create mode 100644 src/main/java/com/unicenta/pos/forms/MenuDefinition.java create mode 100644 src/main/java/com/unicenta/pos/forms/MenuElement.java create mode 100644 src/main/java/com/unicenta/pos/forms/MenuExecAction.java create mode 100644 src/main/java/com/unicenta/pos/forms/MenuItemDefinition.java create mode 100644 src/main/java/com/unicenta/pos/forms/MenuPanelAction.java create mode 100644 src/main/java/com/unicenta/pos/forms/MenuTitleDefinition.java create mode 100644 src/main/java/com/unicenta/pos/forms/Payments.java create mode 100644 src/main/java/com/unicenta/pos/forms/ProcessAction.java create mode 100644 src/main/java/com/unicenta/pos/forms/StartPOS.java create mode 100644 src/main/java/com/unicenta/pos/imports/CustomerCSVImport.form create mode 100644 src/main/java/com/unicenta/pos/imports/CustomerCSVImport.java create mode 100644 src/main/java/com/unicenta/pos/imports/JPanelCSV.form create mode 100644 src/main/java/com/unicenta/pos/imports/JPanelCSV.java create mode 100644 src/main/java/com/unicenta/pos/imports/JPanelCSVCleardb.form create mode 100644 src/main/java/com/unicenta/pos/imports/JPanelCSVCleardb.java create mode 100644 src/main/java/com/unicenta/pos/imports/JPanelCSVImport.form create mode 100644 src/main/java/com/unicenta/pos/imports/JPanelCSVImport.java create mode 100644 src/main/java/com/unicenta/pos/imports/StockQtyImport.form create mode 100644 src/main/java/com/unicenta/pos/imports/StockQtyImport.java create mode 100644 src/main/java/com/unicenta/pos/instance/AppMessage.java create mode 100644 src/main/java/com/unicenta/pos/instance/InstanceManager.java create mode 100644 src/main/java/com/unicenta/pos/instance/InstanceQuery.java create mode 100644 src/main/java/com/unicenta/pos/inventory/AttributeFilter.form create mode 100644 src/main/java/com/unicenta/pos/inventory/AttributeFilter.java create mode 100644 src/main/java/com/unicenta/pos/inventory/AttributeInfo.java create mode 100644 src/main/java/com/unicenta/pos/inventory/AttributeSetFilter.form create mode 100644 src/main/java/com/unicenta/pos/inventory/AttributeSetFilter.java create mode 100644 src/main/java/com/unicenta/pos/inventory/AttributeSetInfo.java create mode 100644 src/main/java/com/unicenta/pos/inventory/AttributeSetsEditor.form create mode 100644 src/main/java/com/unicenta/pos/inventory/AttributeSetsEditor.java create mode 100644 src/main/java/com/unicenta/pos/inventory/AttributeSetsPanel.java create mode 100644 src/main/java/com/unicenta/pos/inventory/AttributeUseEditor.form create mode 100644 src/main/java/com/unicenta/pos/inventory/AttributeUseEditor.java create mode 100644 src/main/java/com/unicenta/pos/inventory/AttributeUsePanel.java create mode 100644 src/main/java/com/unicenta/pos/inventory/AttributeValuesEditor.form create mode 100644 src/main/java/com/unicenta/pos/inventory/AttributeValuesEditor.java create mode 100644 src/main/java/com/unicenta/pos/inventory/AttributeValuesPanel.java create mode 100644 src/main/java/com/unicenta/pos/inventory/AttributesEditor.form create mode 100644 src/main/java/com/unicenta/pos/inventory/AttributesEditor.java create mode 100644 src/main/java/com/unicenta/pos/inventory/AttributesPanel.java create mode 100644 src/main/java/com/unicenta/pos/inventory/AuxiliarEditor.form create mode 100644 src/main/java/com/unicenta/pos/inventory/AuxiliarEditor.java create mode 100644 src/main/java/com/unicenta/pos/inventory/AuxiliarPanel.java create mode 100644 src/main/java/com/unicenta/pos/inventory/BundleEditor.form create mode 100644 src/main/java/com/unicenta/pos/inventory/BundleEditor.java create mode 100644 src/main/java/com/unicenta/pos/inventory/BundlePanel.java create mode 100644 src/main/java/com/unicenta/pos/inventory/CategoriesEditor.form create mode 100644 src/main/java/com/unicenta/pos/inventory/CategoriesEditor.java create mode 100644 src/main/java/com/unicenta/pos/inventory/CategoriesPanel.java create mode 100644 src/main/java/com/unicenta/pos/inventory/CodeType.java create mode 100644 src/main/java/com/unicenta/pos/inventory/InvEditLine.form create mode 100644 src/main/java/com/unicenta/pos/inventory/InvEditLine.java create mode 100644 src/main/java/com/unicenta/pos/inventory/InventoryLine.java create mode 100644 src/main/java/com/unicenta/pos/inventory/InventoryRecord.java create mode 100644 src/main/java/com/unicenta/pos/inventory/JDlgUploadProducts.form create mode 100644 src/main/java/com/unicenta/pos/inventory/JDlgUploadProducts.java create mode 100644 src/main/java/com/unicenta/pos/inventory/JInventoryLines.form create mode 100644 src/main/java/com/unicenta/pos/inventory/JInventoryLines.java create mode 100644 src/main/java/com/unicenta/pos/inventory/LocationInfo.java create mode 100644 src/main/java/com/unicenta/pos/inventory/LocationsPanel.java create mode 100644 src/main/java/com/unicenta/pos/inventory/LocationsView.form create mode 100644 src/main/java/com/unicenta/pos/inventory/LocationsView.java create mode 100644 src/main/java/com/unicenta/pos/inventory/MaterialFilter.form create mode 100644 src/main/java/com/unicenta/pos/inventory/MaterialFilter.java create mode 100644 src/main/java/com/unicenta/pos/inventory/MaterialProdInfo.java create mode 100644 src/main/java/com/unicenta/pos/inventory/MovementReason.java create mode 100644 src/main/java/com/unicenta/pos/inventory/PriceImportPanel.java create mode 100644 src/main/java/com/unicenta/pos/inventory/ProductStock.java create mode 100644 src/main/java/com/unicenta/pos/inventory/ProductsBundleInfo.java create mode 100644 src/main/java/com/unicenta/pos/inventory/ProductsEditor.form create mode 100644 src/main/java/com/unicenta/pos/inventory/ProductsEditor.java create mode 100644 src/main/java/com/unicenta/pos/inventory/ProductsPanel.java create mode 100644 src/main/java/com/unicenta/pos/inventory/ProductsWarehouseEditor.form create mode 100644 src/main/java/com/unicenta/pos/inventory/ProductsWarehouseEditor.java create mode 100644 src/main/java/com/unicenta/pos/inventory/ProductsWarehousePanel.java create mode 100644 src/main/java/com/unicenta/pos/inventory/StockDiaryEditor.form create mode 100644 src/main/java/com/unicenta/pos/inventory/StockDiaryEditor.java create mode 100644 src/main/java/com/unicenta/pos/inventory/StockDiaryPanel.java create mode 100644 src/main/java/com/unicenta/pos/inventory/StockManagement.form create mode 100644 src/main/java/com/unicenta/pos/inventory/StockManagement.java create mode 100644 src/main/java/com/unicenta/pos/inventory/StockModel.java create mode 100644 src/main/java/com/unicenta/pos/inventory/TaxCategoriesEditor.form create mode 100644 src/main/java/com/unicenta/pos/inventory/TaxCategoriesEditor.java create mode 100644 src/main/java/com/unicenta/pos/inventory/TaxCategoriesPanel.java create mode 100644 src/main/java/com/unicenta/pos/inventory/TaxCategoryInfo.java create mode 100644 src/main/java/com/unicenta/pos/inventory/TaxCustCategoriesEditor.form create mode 100644 src/main/java/com/unicenta/pos/inventory/TaxCustCategoriesEditor.java create mode 100644 src/main/java/com/unicenta/pos/inventory/TaxCustCategoriesPanel.java create mode 100644 src/main/java/com/unicenta/pos/inventory/TaxCustCategoryInfo.java create mode 100644 src/main/java/com/unicenta/pos/inventory/TaxEditor.form create mode 100644 src/main/java/com/unicenta/pos/inventory/TaxEditor.java create mode 100644 src/main/java/com/unicenta/pos/inventory/TaxPanel.java create mode 100644 src/main/java/com/unicenta/pos/inventory/UomEditor.form create mode 100644 src/main/java/com/unicenta/pos/inventory/UomEditor.java create mode 100644 src/main/java/com/unicenta/pos/inventory/UomInfo.java create mode 100644 src/main/java/com/unicenta/pos/inventory/UomPanel.java create mode 100644 src/main/java/com/unicenta/pos/mant/Applications.java create mode 100644 src/main/java/com/unicenta/pos/mant/Floors.java create mode 100644 src/main/java/com/unicenta/pos/mant/FloorsEditor.form create mode 100644 src/main/java/com/unicenta/pos/mant/FloorsEditor.java create mode 100644 src/main/java/com/unicenta/pos/mant/FloorsInfo.java create mode 100644 src/main/java/com/unicenta/pos/mant/JPanelFloors.java create mode 100644 src/main/java/com/unicenta/pos/mant/JPanelPlaces.java create mode 100644 src/main/java/com/unicenta/pos/mant/Places.java create mode 100644 src/main/java/com/unicenta/pos/mant/PlacesEditor.form create mode 100644 src/main/java/com/unicenta/pos/mant/PlacesEditor.java create mode 100644 src/main/java/com/unicenta/pos/panels/AuxiliarFilter.form create mode 100644 src/main/java/com/unicenta/pos/panels/AuxiliarFilter.java create mode 100644 src/main/java/com/unicenta/pos/panels/BundleFilter.form create mode 100644 src/main/java/com/unicenta/pos/panels/BundleFilter.java create mode 100644 src/main/java/com/unicenta/pos/panels/ComboItemLocal.java create mode 100644 src/main/java/com/unicenta/pos/panels/EnumerationIter.java create mode 100644 src/main/java/com/unicenta/pos/panels/JPanelCloseMoney.form create mode 100644 src/main/java/com/unicenta/pos/panels/JPanelCloseMoney.java create mode 100644 src/main/java/com/unicenta/pos/panels/JPanelCloseMoneyReprint.form create mode 100644 src/main/java/com/unicenta/pos/panels/JPanelCloseMoneyReprint.java create mode 100644 src/main/java/com/unicenta/pos/panels/JPanelPayments.java create mode 100644 src/main/java/com/unicenta/pos/panels/JPanelPrinter.form create mode 100644 src/main/java/com/unicenta/pos/panels/JPanelPrinter.java create mode 100644 src/main/java/com/unicenta/pos/panels/JPanelTable.form create mode 100644 src/main/java/com/unicenta/pos/panels/JPanelTable.java create mode 100644 src/main/java/com/unicenta/pos/panels/JPanelTable2.java create mode 100644 src/main/java/com/unicenta/pos/panels/JProductFinder.form create mode 100644 src/main/java/com/unicenta/pos/panels/JProductFinder.java create mode 100644 src/main/java/com/unicenta/pos/panels/JTextFieldLimit.java create mode 100644 src/main/java/com/unicenta/pos/panels/JTicketsFinder.form create mode 100644 src/main/java/com/unicenta/pos/panels/JTicketsFinder.java create mode 100644 src/main/java/com/unicenta/pos/panels/PaymentsEditor.form create mode 100644 src/main/java/com/unicenta/pos/panels/PaymentsEditor.java create mode 100644 src/main/java/com/unicenta/pos/panels/PaymentsModel.java create mode 100644 src/main/java/com/unicenta/pos/panels/PaymentsReprintModel.java create mode 100644 src/main/java/com/unicenta/pos/panels/Printer.PartialCash.xml create mode 100644 src/main/java/com/unicenta/pos/panels/SQLColumn.java create mode 100644 src/main/java/com/unicenta/pos/panels/SQLDatabase.java create mode 100644 src/main/java/com/unicenta/pos/panels/SQLTable.java create mode 100644 src/main/java/com/unicenta/pos/panels/SQLTableModel.java create mode 100644 src/main/java/com/unicenta/pos/payment/ConfigPaymentPanelEmpty.form create mode 100644 src/main/java/com/unicenta/pos/payment/ConfigPaymentPanelEmpty.java create mode 100644 src/main/java/com/unicenta/pos/payment/ConfigPaymentPanelGeneric.form create mode 100644 src/main/java/com/unicenta/pos/payment/ConfigPaymentPanelGeneric.java create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentBank.form create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentBank.java create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentCashPos.form create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentCashPos.java create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentCheque.form create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentCheque.java create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentDebt.form create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentDebt.java create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentFree.form create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentFree.java create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentInterface.java create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentMagcard.form create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentMagcard.java create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentNotifier.java create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentPaper.form create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentPaper.java create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentRefund.form create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentRefund.java create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentSelect.form create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentSelect.java create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentSelectCustomer.java create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentSelectReceipt.java create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentSelectRefund.java create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentSlip.form create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentSlip.java create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentVoucher.form create mode 100644 src/main/java/com/unicenta/pos/payment/JPaymentVoucher.java create mode 100644 src/main/java/com/unicenta/pos/payment/MagCardReader.java create mode 100644 src/main/java/com/unicenta/pos/payment/MagCardReaderFac.java create mode 100644 src/main/java/com/unicenta/pos/payment/MagCardReaderGeneric.java create mode 100644 src/main/java/com/unicenta/pos/payment/MagCardReaderIntelligent.java create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentConfiguration.java create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentException.java create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentGateway.java create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentGatewayExt.java create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentGatewayFac.java create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentGatewayPaymentSense.java create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentInfo.java create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentInfoCash.java create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentInfoCash_original.java create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentInfoFree.java create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentInfoList.java create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentInfoMagcard.java create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentInfoMagcardRefund.java create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentInfoTicket.java create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentPanel.java create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentPanelBasic.form create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentPanelBasic.java create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentPanelEMV.java create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentPanelFac.java create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentPanelMagCard.form create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentPanelMagCard.java create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentPanelType.form create mode 100644 src/main/java/com/unicenta/pos/payment/PaymentPanelType.java create mode 100644 src/main/java/com/unicenta/pos/payment/VoucherPaymentInfo.java create mode 100644 src/main/java/com/unicenta/pos/printer/BaseAnimator.java create mode 100644 src/main/java/com/unicenta/pos/printer/BlinkAnimator.java create mode 100644 src/main/java/com/unicenta/pos/printer/CurtainAnimator.java create mode 100644 src/main/java/com/unicenta/pos/printer/DeviceDisplay.java create mode 100644 src/main/java/com/unicenta/pos/printer/DeviceDisplayBase.java create mode 100644 src/main/java/com/unicenta/pos/printer/DeviceDisplayImpl.java create mode 100644 src/main/java/com/unicenta/pos/printer/DeviceDisplayNull.java create mode 100644 src/main/java/com/unicenta/pos/printer/DeviceFiscalPrinter.java create mode 100644 src/main/java/com/unicenta/pos/printer/DeviceFiscalPrinterNull.java create mode 100644 src/main/java/com/unicenta/pos/printer/DevicePrinter.java create mode 100644 src/main/java/com/unicenta/pos/printer/DevicePrinterNull.java create mode 100644 src/main/java/com/unicenta/pos/printer/DeviceTicket.java create mode 100644 src/main/java/com/unicenta/pos/printer/DisplayAnimator.java create mode 100644 src/main/java/com/unicenta/pos/printer/FlyerAnimator.java create mode 100644 src/main/java/com/unicenta/pos/printer/NullAnimator.java create mode 100644 src/main/java/com/unicenta/pos/printer/ScrollAnimator.java create mode 100644 src/main/java/com/unicenta/pos/printer/TicketParser.java create mode 100644 src/main/java/com/unicenta/pos/printer/TicketPrinterException.java create mode 100644 src/main/java/com/unicenta/pos/printer/escpos/Codes.java create mode 100644 src/main/java/com/unicenta/pos/printer/escpos/CodesEpson.java create mode 100644 src/main/java/com/unicenta/pos/printer/escpos/CodesIthaca.java create mode 100644 src/main/java/com/unicenta/pos/printer/escpos/CodesStar.java create mode 100644 src/main/java/com/unicenta/pos/printer/escpos/CodesSurePOS.java create mode 100644 src/main/java/com/unicenta/pos/printer/escpos/CodesTMU220.java create mode 100644 src/main/java/com/unicenta/pos/printer/escpos/DeviceDisplayESCPOS.java create mode 100644 src/main/java/com/unicenta/pos/printer/escpos/DeviceDisplaySerial.java create mode 100644 src/main/java/com/unicenta/pos/printer/escpos/DeviceDisplaySurePOS.java create mode 100644 src/main/java/com/unicenta/pos/printer/escpos/DevicePrinterESCPOS.java create mode 100644 src/main/java/com/unicenta/pos/printer/escpos/DevicePrinterPlain.java create mode 100644 src/main/java/com/unicenta/pos/printer/escpos/ESCPOS.java create mode 100644 src/main/java/com/unicenta/pos/printer/escpos/PrinterWritter.java create mode 100644 src/main/java/com/unicenta/pos/printer/escpos/PrinterWritterFile.java create mode 100644 src/main/java/com/unicenta/pos/printer/escpos/PrinterWritterRXTX.java create mode 100644 src/main/java/com/unicenta/pos/printer/escpos/PrinterWritterRaw.java create mode 100644 src/main/java/com/unicenta/pos/printer/escpos/UnicodeTranslator.java create mode 100644 src/main/java/com/unicenta/pos/printer/escpos/UnicodeTranslatorEur.java create mode 100644 src/main/java/com/unicenta/pos/printer/escpos/UnicodeTranslatorInt.java create mode 100644 src/main/java/com/unicenta/pos/printer/escpos/UnicodeTranslatorStar.java create mode 100644 src/main/java/com/unicenta/pos/printer/escpos/UnicodeTranslatorSurePOS.java create mode 100644 src/main/java/com/unicenta/pos/printer/javapos/DeviceDisplayJavaPOS.java create mode 100644 src/main/java/com/unicenta/pos/printer/javapos/DeviceFiscalPrinterJavaPOS.form create mode 100644 src/main/java/com/unicenta/pos/printer/javapos/DeviceFiscalPrinterJavaPOS.java create mode 100644 src/main/java/com/unicenta/pos/printer/javapos/DevicePrinterJavaPOS.java create mode 100644 src/main/java/com/unicenta/pos/printer/printer/DevicePrinterPrinter.java create mode 100644 src/main/java/com/unicenta/pos/printer/printer/PrintableBasicTicket.java create mode 100644 src/main/java/com/unicenta/pos/printer/screen/DeviceDisplayPanel.form create mode 100644 src/main/java/com/unicenta/pos/printer/screen/DeviceDisplayPanel.java create mode 100644 src/main/java/com/unicenta/pos/printer/screen/DeviceDisplayWindow.form create mode 100644 src/main/java/com/unicenta/pos/printer/screen/DeviceDisplayWindow.java create mode 100644 src/main/java/com/unicenta/pos/printer/screen/DevicePrinterPanel.form create mode 100644 src/main/java/com/unicenta/pos/printer/screen/DevicePrinterPanel.java create mode 100644 src/main/java/com/unicenta/pos/printer/screen/JTicket.form create mode 100644 src/main/java/com/unicenta/pos/printer/screen/JTicket.java create mode 100644 src/main/java/com/unicenta/pos/printer/screen/JTicketContainer.form create mode 100644 src/main/java/com/unicenta/pos/printer/screen/JTicketContainer.java create mode 100644 src/main/java/com/unicenta/pos/printer/ticket.dtd create mode 100644 src/main/java/com/unicenta/pos/printer/ticket/BasicTicket.java create mode 100644 src/main/java/com/unicenta/pos/printer/ticket/BasicTicketForPrinter.java create mode 100644 src/main/java/com/unicenta/pos/printer/ticket/BasicTicketForScreen.java create mode 100644 src/main/java/com/unicenta/pos/printer/ticket/MyPrinterState.java create mode 100644 src/main/java/com/unicenta/pos/printer/ticket/PrintItem.java create mode 100644 src/main/java/com/unicenta/pos/printer/ticket/PrintItemBarcode.java create mode 100644 src/main/java/com/unicenta/pos/printer/ticket/PrintItemImage.java create mode 100644 src/main/java/com/unicenta/pos/printer/ticket/PrintItemLine.java create mode 100644 src/main/java/com/unicenta/pos/reports/JPanelReport.form create mode 100644 src/main/java/com/unicenta/pos/reports/JPanelReport.java create mode 100644 src/main/java/com/unicenta/pos/reports/JParamsComposed.form create mode 100644 src/main/java/com/unicenta/pos/reports/JParamsComposed.java create mode 100644 src/main/java/com/unicenta/pos/reports/JParamsCustomer.form create mode 100644 src/main/java/com/unicenta/pos/reports/JParamsCustomer.java create mode 100644 src/main/java/com/unicenta/pos/reports/JParamsDatesInterval.form create mode 100644 src/main/java/com/unicenta/pos/reports/JParamsDatesInterval.java create mode 100644 src/main/java/com/unicenta/pos/reports/JParamsLocation.form create mode 100644 src/main/java/com/unicenta/pos/reports/JParamsLocation.java create mode 100644 src/main/java/com/unicenta/pos/reports/JParamsLocationWithFirst.java create mode 100644 src/main/java/com/unicenta/pos/reports/JParamsReason.form create mode 100644 src/main/java/com/unicenta/pos/reports/JParamsReason.java create mode 100644 src/main/java/com/unicenta/pos/reports/JParamsSuppliers.form create mode 100644 src/main/java/com/unicenta/pos/reports/JParamsSuppliers.java create mode 100644 src/main/java/com/unicenta/pos/reports/JParamsText.form create mode 100644 src/main/java/com/unicenta/pos/reports/JParamsText.java create mode 100644 src/main/java/com/unicenta/pos/reports/JParamsUser.form create mode 100644 src/main/java/com/unicenta/pos/reports/JParamsUser.java create mode 100644 src/main/java/com/unicenta/pos/reports/JRDataSourceBasic.java create mode 100644 src/main/java/com/unicenta/pos/reports/PanelReportBean.java create mode 100644 src/main/java/com/unicenta/pos/reports/ReportEditorCreator.java create mode 100644 src/main/java/com/unicenta/pos/reports/ReportException.java create mode 100644 src/main/java/com/unicenta/pos/reports/ReportFields.java create mode 100644 src/main/java/com/unicenta/pos/reports/ReportFieldsArray.java create mode 100644 src/main/java/com/unicenta/pos/resets/JPanelResets.form create mode 100644 src/main/java/com/unicenta/pos/resets/JPanelResets.java create mode 100644 src/main/java/com/unicenta/pos/resets/JResetPickupID.java create mode 100644 src/main/java/com/unicenta/pos/sales/DataLogicReceipts.java create mode 100644 src/main/java/com/unicenta/pos/sales/JMooringDetails.form create mode 100644 src/main/java/com/unicenta/pos/sales/JMooringDetails.java create mode 100644 src/main/java/com/unicenta/pos/sales/JPanelButtons.form create mode 100644 src/main/java/com/unicenta/pos/sales/JPanelButtons.java create mode 100644 src/main/java/com/unicenta/pos/sales/JPanelResetPickupId.form create mode 100644 src/main/java/com/unicenta/pos/sales/JPanelResetPickupId.java create mode 100644 src/main/java/com/unicenta/pos/sales/JPanelTicket.form create mode 100644 src/main/java/com/unicenta/pos/sales/JPanelTicket.java create mode 100644 src/main/java/com/unicenta/pos/sales/JPanelTicketEdits.java create mode 100644 src/main/java/com/unicenta/pos/sales/JPanelTicketSales.java create mode 100644 src/main/java/com/unicenta/pos/sales/JProductAttEdit.form create mode 100644 src/main/java/com/unicenta/pos/sales/JProductAttEdit.java create mode 100644 src/main/java/com/unicenta/pos/sales/JProductAttEdit1.form create mode 100644 src/main/java/com/unicenta/pos/sales/JProductAttEdit1.java create mode 100644 src/main/java/com/unicenta/pos/sales/JProductAttEdit2.form create mode 100644 src/main/java/com/unicenta/pos/sales/JProductAttEdit2.java create mode 100644 src/main/java/com/unicenta/pos/sales/JProductAttEditI.java create mode 100644 src/main/java/com/unicenta/pos/sales/JProductAttEditItem.form create mode 100644 src/main/java/com/unicenta/pos/sales/JProductAttEditItem.java create mode 100644 src/main/java/com/unicenta/pos/sales/JProductAttListItem.form create mode 100644 src/main/java/com/unicenta/pos/sales/JProductAttListItem.java create mode 100644 src/main/java/com/unicenta/pos/sales/JProductLineEdit.form create mode 100644 src/main/java/com/unicenta/pos/sales/JProductLineEdit.java create mode 100644 src/main/java/com/unicenta/pos/sales/JProductLineEditTax.form create mode 100644 src/main/java/com/unicenta/pos/sales/JProductLineEditTax.java create mode 100644 src/main/java/com/unicenta/pos/sales/JRefundLines.form create mode 100644 src/main/java/com/unicenta/pos/sales/JRefundLines.java create mode 100644 src/main/java/com/unicenta/pos/sales/JSalesLayoutManager.java create mode 100644 src/main/java/com/unicenta/pos/sales/JTicketCatalogLines.form create mode 100644 src/main/java/com/unicenta/pos/sales/JTicketCatalogLines.java create mode 100644 src/main/java/com/unicenta/pos/sales/JTicketLines.form create mode 100644 src/main/java/com/unicenta/pos/sales/JTicketLines.java create mode 100644 src/main/java/com/unicenta/pos/sales/JTicketsBag.java create mode 100644 src/main/java/com/unicenta/pos/sales/JTicketsBagTicket.form create mode 100644 src/main/java/com/unicenta/pos/sales/JTicketsBagTicket.java create mode 100644 src/main/java/com/unicenta/pos/sales/JTicketsBagTicketBag.form create mode 100644 src/main/java/com/unicenta/pos/sales/JTicketsBagTicketBag.java create mode 100644 src/main/java/com/unicenta/pos/sales/KitchenDisplay.java create mode 100644 src/main/java/com/unicenta/pos/sales/MenuActionListener.java create mode 100644 src/main/java/com/unicenta/pos/sales/ReceiptSplit.form create mode 100644 src/main/java/com/unicenta/pos/sales/ReceiptSplit.java create mode 100644 src/main/java/com/unicenta/pos/sales/ReprintTicketInfo.java create mode 100644 src/main/java/com/unicenta/pos/sales/SharedTicketInfo.java create mode 100644 src/main/java/com/unicenta/pos/sales/SimpleReceipt.form create mode 100644 src/main/java/com/unicenta/pos/sales/SimpleReceipt.java create mode 100644 src/main/java/com/unicenta/pos/sales/TaxesException.java create mode 100644 src/main/java/com/unicenta/pos/sales/TaxesLogic.java create mode 100644 src/main/java/com/unicenta/pos/sales/TaxesLogicElement.java create mode 100644 src/main/java/com/unicenta/pos/sales/TicketsBagRestaurantMap.java create mode 100644 src/main/java/com/unicenta/pos/sales/TicketsEditor.java create mode 100644 src/main/java/com/unicenta/pos/sales/dlSales.java create mode 100644 src/main/java/com/unicenta/pos/sales/restaurant/Floor.java create mode 100644 src/main/java/com/unicenta/pos/sales/restaurant/JCalendarItemRenderer.form create mode 100644 src/main/java/com/unicenta/pos/sales/restaurant/JCalendarItemRenderer.java create mode 100644 src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurant.form create mode 100644 src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurant.java create mode 100644 src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurantMap.form create mode 100644 src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurantMap.java create mode 100644 src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurantRes.form create mode 100644 src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurantRes.java create mode 100644 src/main/java/com/unicenta/pos/sales/restaurant/Place.java create mode 100644 src/main/java/com/unicenta/pos/sales/restaurant/RestaurantDBUtils.java create mode 100644 src/main/java/com/unicenta/pos/sales/shared/JTicketsBagShared.form create mode 100644 src/main/java/com/unicenta/pos/sales/shared/JTicketsBagShared.java create mode 100644 src/main/java/com/unicenta/pos/sales/shared/JTicketsBagSharedList.form create mode 100644 src/main/java/com/unicenta/pos/sales/shared/JTicketsBagSharedList.java create mode 100644 src/main/java/com/unicenta/pos/sales/shared/JTicketsReprintList.form create mode 100644 src/main/java/com/unicenta/pos/sales/shared/JTicketsReprintList.java create mode 100644 src/main/java/com/unicenta/pos/sales/simple/JTicketsBagSimple.form create mode 100644 src/main/java/com/unicenta/pos/sales/simple/JTicketsBagSimple.java create mode 100644 src/main/java/com/unicenta/pos/scale/DeviceScale.java create mode 100644 src/main/java/com/unicenta/pos/scale/Scale.java create mode 100644 src/main/java/com/unicenta/pos/scale/ScaleAcomPC100.java create mode 100644 src/main/java/com/unicenta/pos/scale/ScaleAvery.java create mode 100644 src/main/java/com/unicenta/pos/scale/ScaleCASPDII.java create mode 100644 src/main/java/com/unicenta/pos/scale/ScaleCasioPD1.java create mode 100644 src/main/java/com/unicenta/pos/scale/ScaleComm.java create mode 100644 src/main/java/com/unicenta/pos/scale/ScaleDialog.java create mode 100644 src/main/java/com/unicenta/pos/scale/ScaleException.java create mode 100644 src/main/java/com/unicenta/pos/scale/ScaleFake.java create mode 100644 src/main/java/com/unicenta/pos/scale/ScaleMTIND221.java create mode 100644 src/main/java/com/unicenta/pos/scale/ScaleSamsungEsp.java create mode 100644 src/main/java/com/unicenta/pos/scanpal2/DeviceScanner.java create mode 100644 src/main/java/com/unicenta/pos/scanpal2/DeviceScannerComm.java create mode 100644 src/main/java/com/unicenta/pos/scanpal2/DeviceScannerException.java create mode 100644 src/main/java/com/unicenta/pos/scanpal2/DeviceScannerFactory.java create mode 100644 src/main/java/com/unicenta/pos/scanpal2/ProductDownloaded.java create mode 100644 src/main/java/com/unicenta/pos/scripting/ScriptEngine.java create mode 100644 src/main/java/com/unicenta/pos/scripting/ScriptEngineBeanshell.java create mode 100644 src/main/java/com/unicenta/pos/scripting/ScriptEngineVelocity.java create mode 100644 src/main/java/com/unicenta/pos/scripting/ScriptException.java create mode 100644 src/main/java/com/unicenta/pos/scripting/ScriptFactory.java create mode 100644 src/main/java/com/unicenta/pos/suppliers/DataLogicSuppliers.java create mode 100644 src/main/java/com/unicenta/pos/suppliers/JDialogNewSupplier.form create mode 100644 src/main/java/com/unicenta/pos/suppliers/JDialogNewSupplier.java create mode 100644 src/main/java/com/unicenta/pos/suppliers/JSupplierFinder.form create mode 100644 src/main/java/com/unicenta/pos/suppliers/JSupplierFinder.java create mode 100644 src/main/java/com/unicenta/pos/suppliers/OrderSupplierList.form create mode 100644 src/main/java/com/unicenta/pos/suppliers/OrderSupplierList.java create mode 100644 src/main/java/com/unicenta/pos/suppliers/SupplierInfo.java create mode 100644 src/main/java/com/unicenta/pos/suppliers/SupplierInfoExt.java create mode 100644 src/main/java/com/unicenta/pos/suppliers/SupplierInfoGlobal.java create mode 100644 src/main/java/com/unicenta/pos/suppliers/SupplierRenderer.java create mode 100644 src/main/java/com/unicenta/pos/suppliers/SupplierTicketSelector.java create mode 100644 src/main/java/com/unicenta/pos/suppliers/SupplierTransaction.java create mode 100644 src/main/java/com/unicenta/pos/suppliers/SuppliersPanel.java create mode 100644 src/main/java/com/unicenta/pos/suppliers/SuppliersView.form create mode 100644 src/main/java/com/unicenta/pos/suppliers/SuppliersView.java create mode 100644 src/main/java/com/unicenta/pos/ticket/CardInfo.java create mode 100644 src/main/java/com/unicenta/pos/ticket/CategoryFilter.form create mode 100644 src/main/java/com/unicenta/pos/ticket/CategoryFilter.java create mode 100644 src/main/java/com/unicenta/pos/ticket/CategoryFilter_1.form create mode 100644 src/main/java/com/unicenta/pos/ticket/CategoryFilter_1.java create mode 100644 src/main/java/com/unicenta/pos/ticket/CategoryInfo.java create mode 100644 src/main/java/com/unicenta/pos/ticket/FindTicketsInfo.java create mode 100644 src/main/java/com/unicenta/pos/ticket/FindTicketsRenderer.java create mode 100644 src/main/java/com/unicenta/pos/ticket/HostInfo.java create mode 100644 src/main/java/com/unicenta/pos/ticket/LocationFilterSales.form create mode 100644 src/main/java/com/unicenta/pos/ticket/LocationFilterSales.java create mode 100644 src/main/java/com/unicenta/pos/ticket/ProductFilter.form create mode 100644 src/main/java/com/unicenta/pos/ticket/ProductFilter.java create mode 100644 src/main/java/com/unicenta/pos/ticket/ProductFilter1.form create mode 100644 src/main/java/com/unicenta/pos/ticket/ProductFilter1.java create mode 100644 src/main/java/com/unicenta/pos/ticket/ProductFilter2.form create mode 100644 src/main/java/com/unicenta/pos/ticket/ProductFilter2.java create mode 100644 src/main/java/com/unicenta/pos/ticket/ProductFilter3.form create mode 100644 src/main/java/com/unicenta/pos/ticket/ProductFilter3.java create mode 100644 src/main/java/com/unicenta/pos/ticket/ProductFilter4.form create mode 100644 src/main/java/com/unicenta/pos/ticket/ProductFilter4.java create mode 100644 src/main/java/com/unicenta/pos/ticket/ProductFilterSales.form create mode 100644 src/main/java/com/unicenta/pos/ticket/ProductFilterSales.java create mode 100644 src/main/java/com/unicenta/pos/ticket/ProductInfo.java create mode 100644 src/main/java/com/unicenta/pos/ticket/ProductInfoEdit.java create mode 100644 src/main/java/com/unicenta/pos/ticket/ProductInfoExt.java create mode 100644 src/main/java/com/unicenta/pos/ticket/ProductRenderer.java create mode 100644 src/main/java/com/unicenta/pos/ticket/ProductVectorer.java create mode 100644 src/main/java/com/unicenta/pos/ticket/ProviderInfo.java create mode 100644 src/main/java/com/unicenta/pos/ticket/SalesDetailInfo.java create mode 100644 src/main/java/com/unicenta/pos/ticket/SalesDetailInfo_1.java create mode 100644 src/main/java/com/unicenta/pos/ticket/Signumprovider.java create mode 100644 src/main/java/com/unicenta/pos/ticket/TaxInfo.java create mode 100644 src/main/java/com/unicenta/pos/ticket/TicketInfo.java create mode 100644 src/main/java/com/unicenta/pos/ticket/TicketLineInfo.java create mode 100644 src/main/java/com/unicenta/pos/ticket/TicketLineInfo1.java create mode 100644 src/main/java/com/unicenta/pos/ticket/TicketTaxInfo.java create mode 100644 src/main/java/com/unicenta/pos/ticket/UserInfo.java create mode 100644 src/main/java/com/unicenta/pos/transfer/Transfer.form create mode 100644 src/main/java/com/unicenta/pos/transfer/Transfer.java create mode 100644 src/main/java/com/unicenta/pos/transfer/TransferPanel.form create mode 100644 src/main/java/com/unicenta/pos/transfer/TransferPanel.java create mode 100644 src/main/java/com/unicenta/pos/util/AltEncrypter.java create mode 100644 src/main/java/com/unicenta/pos/util/BarcodeImage.java create mode 100644 src/main/java/com/unicenta/pos/util/Base64Encoder.java create mode 100644 src/main/java/com/unicenta/pos/util/DirectoryEvent.java create mode 100644 src/main/java/com/unicenta/pos/util/ElapsedTimeBetweenDates.java create mode 100644 src/main/java/com/unicenta/pos/util/FXWeb.java create mode 100644 src/main/java/com/unicenta/pos/util/FileChooserEvent.java create mode 100644 src/main/java/com/unicenta/pos/util/FlatLookAndFeel.java create mode 100644 src/main/java/com/unicenta/pos/util/FtpUpload.java create mode 100644 src/main/java/com/unicenta/pos/util/Hashcypher.java create mode 100644 src/main/java/com/unicenta/pos/util/HtmlTester.java create mode 100644 src/main/java/com/unicenta/pos/util/HtmlTester2.java create mode 100644 src/main/java/com/unicenta/pos/util/HtmlTester3.form create mode 100644 src/main/java/com/unicenta/pos/util/HtmlTester3.java create mode 100644 src/main/java/com/unicenta/pos/util/InactivityListener.java create mode 100644 src/main/java/com/unicenta/pos/util/JRPrinterAWT300.java create mode 100644 src/main/java/com/unicenta/pos/util/JRViewer400.form create mode 100644 src/main/java/com/unicenta/pos/util/JRViewer400.java create mode 100644 src/main/java/com/unicenta/pos/util/LabelIcon.java create mode 100644 src/main/java/com/unicenta/pos/util/LuhnAlgorithm.java create mode 100644 src/main/java/com/unicenta/pos/util/NewFXMain.java create mode 100644 src/main/java/com/unicenta/pos/util/NewFXSwingMain.java create mode 100644 src/main/java/com/unicenta/pos/util/OSValidator.java create mode 100644 src/main/java/com/unicenta/pos/util/PropertyUtils.java create mode 100644 src/main/java/com/unicenta/pos/util/ReportUtils.java create mode 100644 src/main/java/com/unicenta/pos/util/ReturnInfo.java create mode 100644 src/main/java/com/unicenta/pos/util/RoundUtils.java create mode 100644 src/main/java/com/unicenta/pos/util/SelectPrinter.form create mode 100644 src/main/java/com/unicenta/pos/util/SelectPrinter.java create mode 100644 src/main/java/com/unicenta/pos/util/SessionKeepAlive.java create mode 100644 src/main/java/com/unicenta/pos/util/StringParser.java create mode 100644 src/main/java/com/unicenta/pos/util/StringUtils.java create mode 100644 src/main/java/com/unicenta/pos/util/SwingUtils.java create mode 100644 src/main/java/com/unicenta/pos/util/SwingWorkerExample.java create mode 100644 src/main/java/com/unicenta/pos/util/ThumbNailBuilder.java create mode 100644 src/main/java/com/unicenta/pos/util/UniBrowser.java create mode 100644 src/main/java/com/unicenta/pos/util/ValidateBuilder.java create mode 100644 src/main/java/com/unicenta/pos/util/VideoPlayer.java create mode 100644 src/main/java/com/unicenta/pos/util/uOWWatch.java create mode 100644 src/main/java/com/unicenta/pos/voucher/JDialogReportPanel.form create mode 100644 src/main/java/com/unicenta/pos/voucher/JDialogReportPanel.java create mode 100644 src/main/java/com/unicenta/pos/voucher/VoucherEditor.form create mode 100644 src/main/java/com/unicenta/pos/voucher/VoucherEditor.java create mode 100644 src/main/java/com/unicenta/pos/voucher/VoucherInfo.java create mode 100644 src/main/java/com/unicenta/pos/voucher/VoucherPanel.java create mode 100644 src/main/java/net/proteanit/sql/DbUtils.java create mode 100644 src/main/java/org/usb4java/examples/ListDevices.java create mode 100644 src/main/resources/beans_messages.properties create mode 100644 src/main/resources/beans_messages_al_SQ.properties create mode 100644 src/main/resources/beans_messages_ar.properties create mode 100644 src/main/resources/beans_messages_da.properties create mode 100644 src/main/resources/beans_messages_de.properties create mode 100644 src/main/resources/beans_messages_el.properties create mode 100644 src/main/resources/beans_messages_en_US.properties create mode 100644 src/main/resources/beans_messages_es.properties create mode 100644 src/main/resources/beans_messages_es_AR.properties create mode 100644 src/main/resources/beans_messages_es_MX.properties create mode 100644 src/main/resources/beans_messages_et.properties create mode 100644 src/main/resources/beans_messages_fr.properties create mode 100644 src/main/resources/beans_messages_hr.properties create mode 100644 src/main/resources/beans_messages_it.properties create mode 100644 src/main/resources/beans_messages_nl.properties create mode 100644 src/main/resources/beans_messages_pt.properties create mode 100644 src/main/resources/beans_messages_pt_BR.properties create mode 100644 src/main/resources/com/unicenta/images/.01.png create mode 100644 src/main/resources/com/unicenta/images/.02.png create mode 100644 src/main/resources/com/unicenta/images/.05.png create mode 100644 src/main/resources/com/unicenta/images/.10.png create mode 100644 src/main/resources/com/unicenta/images/.20.png create mode 100644 src/main/resources/com/unicenta/images/.25.png create mode 100644 src/main/resources/com/unicenta/images/.50.png create mode 100644 src/main/resources/com/unicenta/images/1.00.png create mode 100644 src/main/resources/com/unicenta/images/10.00.png create mode 100644 src/main/resources/com/unicenta/images/100.00.png create mode 100644 src/main/resources/com/unicenta/images/1000.00.png create mode 100644 src/main/resources/com/unicenta/images/1downarrow.png create mode 100644 src/main/resources/com/unicenta/images/1leftarrow.png create mode 100644 src/main/resources/com/unicenta/images/1rightarrow.png create mode 100644 src/main/resources/com/unicenta/images/1uparrow.png create mode 100644 src/main/resources/com/unicenta/images/2.00.png create mode 100644 src/main/resources/com/unicenta/images/20.00.png create mode 100644 src/main/resources/com/unicenta/images/200.00.png create mode 100644 src/main/resources/com/unicenta/images/2downarrow.png create mode 100644 src/main/resources/com/unicenta/images/2leftarrow.png create mode 100644 src/main/resources/com/unicenta/images/2rightarrow.png create mode 100644 src/main/resources/com/unicenta/images/2uparrow.png create mode 100644 src/main/resources/com/unicenta/images/5.00.png create mode 100644 src/main/resources/com/unicenta/images/50.00.png create mode 100644 src/main/resources/com/unicenta/images/500.00.png create mode 100644 src/main/resources/com/unicenta/images/ark2.png create mode 100644 src/main/resources/com/unicenta/images/attributes.png create mode 100644 src/main/resources/com/unicenta/images/auxiliary.png create mode 100644 src/main/resources/com/unicenta/images/bank.png create mode 100644 src/main/resources/com/unicenta/images/barcode.png create mode 100644 src/main/resources/com/unicenta/images/bookmark.png create mode 100644 src/main/resources/com/unicenta/images/btn0.png create mode 100644 src/main/resources/com/unicenta/images/btn00.png create mode 100644 src/main/resources/com/unicenta/images/btn1.png create mode 100644 src/main/resources/com/unicenta/images/btn2.png create mode 100644 src/main/resources/com/unicenta/images/btn2a.png create mode 100644 src/main/resources/com/unicenta/images/btn3.png create mode 100644 src/main/resources/com/unicenta/images/btn3a.png create mode 100644 src/main/resources/com/unicenta/images/btn4.png create mode 100644 src/main/resources/com/unicenta/images/btn4a.png create mode 100644 src/main/resources/com/unicenta/images/btn5.png create mode 100644 src/main/resources/com/unicenta/images/btn5a.png create mode 100644 src/main/resources/com/unicenta/images/btn6.png create mode 100644 src/main/resources/com/unicenta/images/btn6a.png create mode 100644 src/main/resources/com/unicenta/images/btn7.png create mode 100644 src/main/resources/com/unicenta/images/btn7a.png create mode 100644 src/main/resources/com/unicenta/images/btn8.png create mode 100644 src/main/resources/com/unicenta/images/btn8a.png create mode 100644 src/main/resources/com/unicenta/images/btn9.png create mode 100644 src/main/resources/com/unicenta/images/btn9a.png create mode 100644 src/main/resources/com/unicenta/images/btnback.png create mode 100644 src/main/resources/com/unicenta/images/btnce.png create mode 100644 src/main/resources/com/unicenta/images/btndiv.png create mode 100644 src/main/resources/com/unicenta/images/btndot.png create mode 100644 src/main/resources/com/unicenta/images/btnequals.png create mode 100644 src/main/resources/com/unicenta/images/btnminus.png create mode 100644 src/main/resources/com/unicenta/images/btnmult.png create mode 100644 src/main/resources/com/unicenta/images/btnplus.png create mode 100644 src/main/resources/com/unicenta/images/bundle.png create mode 100644 src/main/resources/com/unicenta/images/calculator.png create mode 100644 src/main/resources/com/unicenta/images/camera.png create mode 100644 src/main/resources/com/unicenta/images/cancel.png create mode 100644 src/main/resources/com/unicenta/images/cash.png create mode 100644 src/main/resources/com/unicenta/images/cashdrawer.png create mode 100644 src/main/resources/com/unicenta/images/category.png create mode 100644 src/main/resources/com/unicenta/images/ccard.png create mode 100644 src/main/resources/com/unicenta/images/chart.png create mode 100644 src/main/resources/com/unicenta/images/cheque.png create mode 100644 src/main/resources/com/unicenta/images/coffee.png create mode 100644 src/main/resources/com/unicenta/images/configuration.png create mode 100644 src/main/resources/com/unicenta/images/customer.png create mode 100644 src/main/resources/com/unicenta/images/customer_add_sml.png create mode 100644 src/main/resources/com/unicenta/images/customer_sml.png create mode 100644 src/main/resources/com/unicenta/images/customerpay.png create mode 100644 src/main/resources/com/unicenta/images/database.png create mode 100644 src/main/resources/com/unicenta/images/date.png create mode 100644 src/main/resources/com/unicenta/images/discount.png create mode 100644 src/main/resources/com/unicenta/images/discount_b.png create mode 100644 src/main/resources/com/unicenta/images/display.png create mode 100644 src/main/resources/com/unicenta/images/edit.png create mode 100644 src/main/resources/com/unicenta/images/edit_group.png create mode 100644 src/main/resources/com/unicenta/images/edit_group_sm.png create mode 100644 src/main/resources/com/unicenta/images/editdelete.png create mode 100644 src/main/resources/com/unicenta/images/editnew.png create mode 100644 src/main/resources/com/unicenta/images/empty.png create mode 100644 src/main/resources/com/unicenta/images/encrypted.png create mode 100644 src/main/resources/com/unicenta/images/exit.png create mode 100644 src/main/resources/com/unicenta/images/favicon.png create mode 100644 src/main/resources/com/unicenta/images/fileclose.png create mode 100644 src/main/resources/com/unicenta/images/fileopen.png create mode 100644 src/main/resources/com/unicenta/images/filesave.png create mode 100644 src/main/resources/com/unicenta/images/floors.png create mode 100644 src/main/resources/com/unicenta/images/gohome.png create mode 100644 src/main/resources/com/unicenta/images/heart.png create mode 100644 src/main/resources/com/unicenta/images/img.discount.png create mode 100644 src/main/resources/com/unicenta/images/img.discount_b.png create mode 100644 src/main/resources/com/unicenta/images/img.keyboard_32.png create mode 100644 src/main/resources/com/unicenta/images/img.ticket_print.png create mode 100644 src/main/resources/com/unicenta/images/import.png create mode 100644 src/main/resources/com/unicenta/images/inbox.png create mode 100644 src/main/resources/com/unicenta/images/info.png create mode 100644 src/main/resources/com/unicenta/images/keyboard_32.png create mode 100644 src/main/resources/com/unicenta/images/keyboard_48.png create mode 100644 src/main/resources/com/unicenta/images/kit_print.png create mode 100644 src/main/resources/com/unicenta/images/leaves.png create mode 100644 src/main/resources/com/unicenta/images/location.png create mode 100644 src/main/resources/com/unicenta/images/logo.png create mode 100644 src/main/resources/com/unicenta/images/logout.png create mode 100644 src/main/resources/com/unicenta/images/mail24.png create mode 100644 src/main/resources/com/unicenta/images/maintain.png create mode 100644 src/main/resources/com/unicenta/images/menu-left.png create mode 100644 src/main/resources/com/unicenta/images/menu-right.png create mode 100644 src/main/resources/com/unicenta/images/mime.png create mode 100644 src/main/resources/com/unicenta/images/mime2.png create mode 100644 src/main/resources/com/unicenta/images/mime3.png create mode 100644 src/main/resources/com/unicenta/images/movetable.png create mode 100644 src/main/resources/com/unicenta/images/no_photo.png create mode 100644 src/main/resources/com/unicenta/images/notes.png create mode 100644 src/main/resources/com/unicenta/images/null.png create mode 100644 src/main/resources/com/unicenta/images/ok.png create mode 100644 src/main/resources/com/unicenta/images/package.png create mode 100644 src/main/resources/com/unicenta/images/package_big.png create mode 100644 src/main/resources/com/unicenta/images/padlock_open_icon&24.pdn create mode 100644 src/main/resources/com/unicenta/images/paperboard960_600.png create mode 100644 src/main/resources/com/unicenta/images/password.png create mode 100644 src/main/resources/com/unicenta/images/pay.png create mode 100644 src/main/resources/com/unicenta/images/payments.png create mode 100644 src/main/resources/com/unicenta/images/plugin.png create mode 100644 src/main/resources/com/unicenta/images/poweredby_uni.png create mode 100644 src/main/resources/com/unicenta/images/printer.png create mode 100644 src/main/resources/com/unicenta/images/printer.ticket.logo.jpg create mode 100644 src/main/resources/com/unicenta/images/printer24.png create mode 100644 src/main/resources/com/unicenta/images/printer24_off.png create mode 100644 src/main/resources/com/unicenta/images/printer24_on.png create mode 100644 src/main/resources/com/unicenta/images/products.png create mode 100644 src/main/resources/com/unicenta/images/products24.png create mode 100644 src/main/resources/com/unicenta/images/receive.png create mode 100644 src/main/resources/com/unicenta/images/refundit.png create mode 100644 src/main/resources/com/unicenta/images/reload.png create mode 100644 src/main/resources/com/unicenta/images/remote_print.png create mode 100644 src/main/resources/com/unicenta/images/reports.png create mode 100644 src/main/resources/com/unicenta/images/reprint24.png create mode 100644 src/main/resources/com/unicenta/images/resources.png create mode 100644 src/main/resources/com/unicenta/images/restaurant_floor.png create mode 100644 src/main/resources/com/unicenta/images/restaurant_floor_sml.png create mode 100644 src/main/resources/com/unicenta/images/roles.png create mode 100644 src/main/resources/com/unicenta/images/run_script.png create mode 100644 src/main/resources/com/unicenta/images/sale.png create mode 100644 src/main/resources/com/unicenta/images/sale_delete.png create mode 100644 src/main/resources/com/unicenta/images/sale_editline.png create mode 100644 src/main/resources/com/unicenta/images/sale_new.png create mode 100644 src/main/resources/com/unicenta/images/sale_pending.png create mode 100644 src/main/resources/com/unicenta/images/sale_split_sml.png create mode 100644 src/main/resources/com/unicenta/images/saleedit.png create mode 100644 src/main/resources/com/unicenta/images/sales.png create mode 100644 src/main/resources/com/unicenta/images/scale.png create mode 100644 src/main/resources/com/unicenta/images/search24.png create mode 100644 src/main/resources/com/unicenta/images/search32.png create mode 100644 src/main/resources/com/unicenta/images/slip.png create mode 100644 src/main/resources/com/unicenta/images/sort_incr.png create mode 100644 src/main/resources/com/unicenta/images/stockdiary.png create mode 100644 src/main/resources/com/unicenta/images/stockmaint.png create mode 100644 src/main/resources/com/unicenta/images/subcategory.png create mode 100644 src/main/resources/com/unicenta/images/supplier_sml.png create mode 100644 src/main/resources/com/unicenta/images/tables.png create mode 100644 src/main/resources/com/unicenta/images/ticket_print.png create mode 100644 src/main/resources/com/unicenta/images/timer.png create mode 100644 src/main/resources/com/unicenta/images/uniCenta_logo_vert_100.png create mode 100644 src/main/resources/com/unicenta/images/uniCenta_splash_dark.png create mode 100644 src/main/resources/com/unicenta/images/unicenta.png create mode 100644 src/main/resources/com/unicenta/images/unicentaopos.ico create mode 100644 src/main/resources/com/unicenta/images/unicentaopos.png create mode 100644 src/main/resources/com/unicenta/images/user.png create mode 100644 src/main/resources/com/unicenta/images/user_sml.png create mode 100644 src/main/resources/com/unicenta/images/users.png create mode 100644 src/main/resources/com/unicenta/images/utilities.png create mode 100644 src/main/resources/com/unicenta/images/viewmag+.png create mode 100644 src/main/resources/com/unicenta/images/viewmag-.png create mode 100644 src/main/resources/com/unicenta/images/voucher.png create mode 100644 src/main/resources/com/unicenta/images/wallet.png create mode 100644 src/main/resources/com/unicenta/images/window.logo.png create mode 100644 src/main/resources/com/unicenta/images/yast_printer.png create mode 100644 src/main/resources/com/unicenta/pos/config/Bundle.properties create mode 100644 src/main/resources/com/unicenta/pos/customers/Bundle.properties create mode 100644 src/main/resources/com/unicenta/pos/scripts/Derby-create.sql create mode 100644 src/main/resources/com/unicenta/pos/scripts/MariaDB-create.sql create mode 100644 src/main/resources/com/unicenta/pos/scripts/MariaDB-upgrade_master.sql create mode 100644 src/main/resources/com/unicenta/pos/scripts/MySQL-FKeys.sql create mode 100644 src/main/resources/com/unicenta/pos/scripts/MySQL-check-tables.sql create mode 100644 src/main/resources/com/unicenta/pos/scripts/MySQL-clearData.sql create mode 100644 src/main/resources/com/unicenta/pos/scripts/MySQL-create-sp.sql create mode 100644 src/main/resources/com/unicenta/pos/scripts/MySQL-create-transfer.sql create mode 100644 src/main/resources/com/unicenta/pos/scripts/MySQL-create.sql create mode 100644 src/main/resources/com/unicenta/pos/scripts/MySQL-create_original.sql create mode 100644 src/main/resources/com/unicenta/pos/scripts/MySQL-dropFKeys.sql create mode 100644 src/main/resources/com/unicenta/pos/scripts/MySQL-normalise-tables.sql create mode 100644 src/main/resources/com/unicenta/pos/scripts/MySQL-orders-table.sql create mode 100644 src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade-4.5.1.sql create mode 100644 src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade-4.5.2.sql create mode 100644 src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade-4.5.3.sql create mode 100644 src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade-4.5.4.sql create mode 100644 src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade-4.5.sql create mode 100644 src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade_master.sql create mode 100644 src/main/resources/com/unicenta/pos/scripts/PostgreSQL-create.sql create mode 100644 src/main/resources/com/unicenta/pos/scripts/SQLite-create.sql create mode 100644 src/main/resources/com/unicenta/pos/templates/APrinter.FiscalTicket.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Cash.Close.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Menu.Root.txt create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.CloseCash.Preview.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.CloseCash.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.CustomerPaid.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.CustomerPaid2.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.FiscalTicket.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.Inventory.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.OpenDrawer.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.PartialCash.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.PrintLastTicket.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.Product.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.ReprintTicket.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.Start.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P1.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P2.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P3.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P4.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P5.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P6.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.Ticket.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.Ticket2.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.TicketClose.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.TicketLine.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.TicketNew.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.TicketPreview.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.TicketPreview_A4.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.TicketRemote.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.TicketTotal.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Printer.Ticket_A4.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Role.Administrator.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Role.Employee.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Role.Guest.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Role.Manager.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Ticket.Buttons.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Ticket.Close.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Ticket.Line.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Ticket.TicketLineTaxesIncluded.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/Window.Title.txt create mode 100644 src/main/resources/com/unicenta/pos/templates/customer.created.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/customer.deleted.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/customer.updated.xml create mode 100644 src/main/resources/com/unicenta/pos/templates/payment.cash.txt create mode 100644 src/main/resources/com/unicenta/pos/templates/script.Keyboard.txt create mode 100644 src/main/resources/com/unicenta/pos/templates/script.Linediscount.txt create mode 100644 src/main/resources/com/unicenta/pos/templates/script.SendOrder.txt create mode 100644 src/main/resources/com/unicenta/pos/templates/script.Totaldiscount.txt create mode 100644 src/main/resources/com/unicenta/pos/templates/script.multibuy.txt create mode 100644 src/main/resources/com/unicenta/pos/templates/template.Ticket.A4_Beta.vm create mode 100644 src/main/resources/com/unicenta/pos/templates/template.Ticket.A4_Beta.zip create mode 100644 src/main/resources/com/unicenta/reports/customers.bs create mode 100644 src/main/resources/com/unicenta/reports/customers.jrxml create mode 100644 src/main/resources/com/unicenta/reports/customers_b.bs create mode 100644 src/main/resources/com/unicenta/reports/customers_cards.bs create mode 100644 src/main/resources/com/unicenta/reports/customers_cards.jrxml create mode 100644 src/main/resources/com/unicenta/reports/customers_debtors.bs create mode 100644 src/main/resources/com/unicenta/reports/customers_debtors.jrxml create mode 100644 src/main/resources/com/unicenta/reports/customers_diary.bs create mode 100644 src/main/resources/com/unicenta/reports/customers_diary.jrxml create mode 100644 src/main/resources/com/unicenta/reports/customers_export.bs create mode 100644 src/main/resources/com/unicenta/reports/customers_export.jrxml create mode 100644 src/main/resources/com/unicenta/reports/customers_list.bs create mode 100644 src/main/resources/com/unicenta/reports/customers_list.jrxml create mode 100644 src/main/resources/com/unicenta/reports/customers_messages.properties create mode 100644 src/main/resources/com/unicenta/reports/customers_messages_al_SQ.properties create mode 100644 src/main/resources/com/unicenta/reports/customers_messages_ar.properties create mode 100644 src/main/resources/com/unicenta/reports/customers_messages_de.properties create mode 100644 src/main/resources/com/unicenta/reports/customers_messages_el.properties create mode 100644 src/main/resources/com/unicenta/reports/customers_messages_en_US.properties create mode 100644 src/main/resources/com/unicenta/reports/customers_messages_es.properties create mode 100644 src/main/resources/com/unicenta/reports/customers_messages_es_AR.properties create mode 100644 src/main/resources/com/unicenta/reports/customers_messages_es_MX.properties create mode 100644 src/main/resources/com/unicenta/reports/customers_messages_et.properties create mode 100644 src/main/resources/com/unicenta/reports/customers_messages_fr.properties create mode 100644 src/main/resources/com/unicenta/reports/customers_messages_hr.properties create mode 100644 src/main/resources/com/unicenta/reports/customers_messages_it.properties create mode 100644 src/main/resources/com/unicenta/reports/customers_messages_nl.properties create mode 100644 src/main/resources/com/unicenta/reports/customers_sales.bs create mode 100644 src/main/resources/com/unicenta/reports/customers_sales.jrxml create mode 100644 src/main/resources/com/unicenta/reports/customers_vouchers.bs create mode 100644 src/main/resources/com/unicenta/reports/customers_vouchers.jrxml create mode 100644 src/main/resources/com/unicenta/reports/epm_dailypresence.bs create mode 100644 src/main/resources/com/unicenta/reports/epm_dailypresence.jrxml create mode 100644 src/main/resources/com/unicenta/reports/epm_dailyschedule.bs create mode 100644 src/main/resources/com/unicenta/reports/epm_dailyschedule.jrxml create mode 100644 src/main/resources/com/unicenta/reports/epm_messages.properties create mode 100644 src/main/resources/com/unicenta/reports/epm_messages_al_SQ.properties create mode 100644 src/main/resources/com/unicenta/reports/epm_messages_de.properties create mode 100644 src/main/resources/com/unicenta/reports/epm_messages_en_US.properties create mode 100644 src/main/resources/com/unicenta/reports/epm_messages_es.properties create mode 100644 src/main/resources/com/unicenta/reports/epm_messages_fr.properties create mode 100644 src/main/resources/com/unicenta/reports/epm_messages_it.properties create mode 100644 src/main/resources/com/unicenta/reports/epm_messages_nl.properties create mode 100644 src/main/resources/com/unicenta/reports/epm_performance.bs create mode 100644 src/main/resources/com/unicenta/reports/epm_performance.jrxml create mode 100644 src/main/resources/com/unicenta/reports/inventory.bs create mode 100644 src/main/resources/com/unicenta/reports/inventory.jrxml create mode 100644 src/main/resources/com/unicenta/reports/inventory_b.bs create mode 100644 src/main/resources/com/unicenta/reports/inventory_b.jrxml create mode 100644 src/main/resources/com/unicenta/reports/inventory_broken.bs create mode 100644 src/main/resources/com/unicenta/reports/inventory_diary.bs create mode 100644 src/main/resources/com/unicenta/reports/inventory_diary.jrxml create mode 100644 src/main/resources/com/unicenta/reports/inventory_diff.bs create mode 100644 src/main/resources/com/unicenta/reports/inventory_diff.jrxml create mode 100644 src/main/resources/com/unicenta/reports/inventory_diffdetail.bs create mode 100644 src/main/resources/com/unicenta/reports/inventory_diffdetail.jrxml create mode 100644 src/main/resources/com/unicenta/reports/inventory_listdetail.bs create mode 100644 src/main/resources/com/unicenta/reports/inventory_listdetail.jrxml create mode 100644 src/main/resources/com/unicenta/reports/inventory_messages.properties create mode 100644 src/main/resources/com/unicenta/reports/inventory_messages_al_SQ.properties create mode 100644 src/main/resources/com/unicenta/reports/inventory_messages_ar.properties create mode 100644 src/main/resources/com/unicenta/reports/inventory_messages_de.properties create mode 100644 src/main/resources/com/unicenta/reports/inventory_messages_el.properties create mode 100644 src/main/resources/com/unicenta/reports/inventory_messages_en_US.properties create mode 100644 src/main/resources/com/unicenta/reports/inventory_messages_es.properties create mode 100644 src/main/resources/com/unicenta/reports/inventory_messages_es_AR.properties create mode 100644 src/main/resources/com/unicenta/reports/inventory_messages_es_MX.properties create mode 100644 src/main/resources/com/unicenta/reports/inventory_messages_et.properties create mode 100644 src/main/resources/com/unicenta/reports/inventory_messages_fr.properties create mode 100644 src/main/resources/com/unicenta/reports/inventory_messages_hr.properties create mode 100644 src/main/resources/com/unicenta/reports/inventory_messages_it.properties create mode 100644 src/main/resources/com/unicenta/reports/inventory_messages_nl.properties create mode 100644 src/main/resources/com/unicenta/reports/labels_barcode_sheet.bs create mode 100644 src/main/resources/com/unicenta/reports/labels_barcode_sheet.jrxml create mode 100644 src/main/resources/com/unicenta/reports/labels_barcode_shelfedge.bs create mode 100644 src/main/resources/com/unicenta/reports/labels_barcode_shelfedge.jrxml create mode 100644 src/main/resources/com/unicenta/reports/labels_messages.properties create mode 100644 src/main/resources/com/unicenta/reports/labels_messages_al_SQ.properties create mode 100644 src/main/resources/com/unicenta/reports/labels_messages_ar.properties create mode 100644 src/main/resources/com/unicenta/reports/labels_messages_de.properties create mode 100644 src/main/resources/com/unicenta/reports/labels_messages_el.properties create mode 100644 src/main/resources/com/unicenta/reports/labels_messages_en_US.properties create mode 100644 src/main/resources/com/unicenta/reports/labels_messages_es.properties create mode 100644 src/main/resources/com/unicenta/reports/labels_messages_es_AR.properties create mode 100644 src/main/resources/com/unicenta/reports/labels_messages_es_MX.properties create mode 100644 src/main/resources/com/unicenta/reports/labels_messages_et.properties create mode 100644 src/main/resources/com/unicenta/reports/labels_messages_fr.properties create mode 100644 src/main/resources/com/unicenta/reports/labels_messages_hr.properties create mode 100644 src/main/resources/com/unicenta/reports/labels_messages_it.properties create mode 100644 src/main/resources/com/unicenta/reports/labels_messages_nl.properties create mode 100644 src/main/resources/com/unicenta/reports/labels_product.bs create mode 100644 src/main/resources/com/unicenta/reports/labels_product.jrxml create mode 100644 src/main/resources/com/unicenta/reports/logo.png create mode 100644 src/main/resources/com/unicenta/reports/products.bs create mode 100644 src/main/resources/com/unicenta/reports/products.jrxml create mode 100644 src/main/resources/com/unicenta/reports/products_catalog.bs create mode 100644 src/main/resources/com/unicenta/reports/products_messages.properties create mode 100644 src/main/resources/com/unicenta/reports/products_messages_al_SQ.properties create mode 100644 src/main/resources/com/unicenta/reports/products_messages_ar.properties create mode 100644 src/main/resources/com/unicenta/reports/products_messages_de.properties create mode 100644 src/main/resources/com/unicenta/reports/products_messages_el.properties create mode 100644 src/main/resources/com/unicenta/reports/products_messages_en_US.properties create mode 100644 src/main/resources/com/unicenta/reports/products_messages_es.properties create mode 100644 src/main/resources/com/unicenta/reports/products_messages_es_AR.properties create mode 100644 src/main/resources/com/unicenta/reports/products_messages_es_MX.properties create mode 100644 src/main/resources/com/unicenta/reports/products_messages_et.properties create mode 100644 src/main/resources/com/unicenta/reports/products_messages_fr.properties create mode 100644 src/main/resources/com/unicenta/reports/products_messages_hr.properties create mode 100644 src/main/resources/com/unicenta/reports/products_messages_it.properties create mode 100644 src/main/resources/com/unicenta/reports/products_messages_nl.properties create mode 100644 src/main/resources/com/unicenta/reports/salecatalog.bs create mode 100644 src/main/resources/com/unicenta/reports/salecatalog.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_cashflow.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_cashflow.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_cashregisterlog.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_cashregisterlog.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_categorysales.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_categorysales.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_categorysales_1.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_categorysales_1.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_categorysalesmysql.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_chart_piesalescat.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_chart_piesalescat.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_chart_pro_test.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_chart_pro_test.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_chart_productsales.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_chart_productsales.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_chart_sales.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_chart_sales.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_chart_timeseriesproduct.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_chart_timeseriesproduct.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_chart_top10.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_chart_top10.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_closedpos.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_closedpos.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_closedpos_1.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_closedpos_1.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_closedproducts.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_closedproducts.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_closedproducts_1.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_closedproducts_1.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_extendedcashregisterlog.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_extendedcashregisterlog.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_extproducts.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_extproducts.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_extproducts_1.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_messages.properties create mode 100644 src/main/resources/com/unicenta/reports/sales_messages_al_SQ.properties create mode 100644 src/main/resources/com/unicenta/reports/sales_messages_ar.properties create mode 100644 src/main/resources/com/unicenta/reports/sales_messages_de.properties create mode 100644 src/main/resources/com/unicenta/reports/sales_messages_el.properties create mode 100644 src/main/resources/com/unicenta/reports/sales_messages_en_US.properties create mode 100644 src/main/resources/com/unicenta/reports/sales_messages_es.properties create mode 100644 src/main/resources/com/unicenta/reports/sales_messages_es_AR.properties create mode 100644 src/main/resources/com/unicenta/reports/sales_messages_es_MX.properties create mode 100644 src/main/resources/com/unicenta/reports/sales_messages_et.properties create mode 100644 src/main/resources/com/unicenta/reports/sales_messages_fr.properties create mode 100644 src/main/resources/com/unicenta/reports/sales_messages_hr.properties create mode 100644 src/main/resources/com/unicenta/reports/sales_messages_it.properties create mode 100644 src/main/resources/com/unicenta/reports/sales_messages_nl.properties create mode 100644 src/main/resources/com/unicenta/reports/sales_payments.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_payments.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_productsalesprofit.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_productsalesprofit.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_productsalesprofit_1.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_productsalesprofit_1.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_saletaxes.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_saletaxes.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_taxcatsales.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_taxcatsales.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_taxcatsales_2.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_taxcatsales_2.jrxml create mode 100644 src/main/resources/com/unicenta/reports/sales_taxes.bs create mode 100644 src/main/resources/com/unicenta/reports/sales_taxes.jrxml create mode 100644 src/main/resources/com/unicenta/reports/suppliers.bs create mode 100644 src/main/resources/com/unicenta/reports/suppliers.jrxml create mode 100644 src/main/resources/com/unicenta/reports/suppliers_creditors.bs create mode 100644 src/main/resources/com/unicenta/reports/suppliers_creditors.jrxml create mode 100644 src/main/resources/com/unicenta/reports/suppliers_diary.bs create mode 100644 src/main/resources/com/unicenta/reports/suppliers_diary.jrxml create mode 100644 src/main/resources/com/unicenta/reports/suppliers_export.bs create mode 100644 src/main/resources/com/unicenta/reports/suppliers_export.jrxml create mode 100644 src/main/resources/com/unicenta/reports/suppliers_list.bs create mode 100644 src/main/resources/com/unicenta/reports/suppliers_list.jrxml create mode 100644 src/main/resources/com/unicenta/reports/suppliers_messages.properties create mode 100644 src/main/resources/com/unicenta/reports/suppliers_messages_en_US.properties create mode 100644 src/main/resources/com/unicenta/reports/suppliers_messages_es.properties create mode 100644 src/main/resources/com/unicenta/reports/suppliers_messages_fr.properties create mode 100644 src/main/resources/com/unicenta/reports/suppliers_products.bs create mode 100644 src/main/resources/com/unicenta/reports/suppliers_products.jrxml create mode 100644 src/main/resources/com/unicenta/reports/suppliers_sales.bs create mode 100644 src/main/resources/com/unicenta/reports/suppliers_sales.jrxml create mode 100644 src/main/resources/com/unicenta/reports/ticketsample.jrxml create mode 100644 src/main/resources/com/unicenta/reports/ticketsample_lines.jrxml create mode 100644 src/main/resources/com/unicenta/reports/tools_badprice.bs create mode 100644 src/main/resources/com/unicenta/reports/tools_badprice.jrxml create mode 100644 src/main/resources/com/unicenta/reports/tools_invalidcategory.bs create mode 100644 src/main/resources/com/unicenta/reports/tools_invalidcategory.jrxml create mode 100644 src/main/resources/com/unicenta/reports/tools_invaliddata.bs create mode 100644 src/main/resources/com/unicenta/reports/tools_invaliddata.jrxml create mode 100644 src/main/resources/com/unicenta/reports/tools_inventoryqtyupdate.bs create mode 100644 src/main/resources/com/unicenta/reports/tools_inventoryqtyupdate.jrxml create mode 100644 src/main/resources/com/unicenta/reports/tools_messages.properties create mode 100644 src/main/resources/com/unicenta/reports/tools_messages_al_SQ.properties create mode 100644 src/main/resources/com/unicenta/reports/tools_messages_de.properties create mode 100644 src/main/resources/com/unicenta/reports/tools_messages_en_US.properties create mode 100644 src/main/resources/com/unicenta/reports/tools_messages_es.properties create mode 100644 src/main/resources/com/unicenta/reports/tools_messages_fr.properties create mode 100644 src/main/resources/com/unicenta/reports/tools_messages_it.properties create mode 100644 src/main/resources/com/unicenta/reports/tools_messages_nl.properties create mode 100644 src/main/resources/com/unicenta/reports/tools_missingdata.bs create mode 100644 src/main/resources/com/unicenta/reports/tools_missingdata.jrxml create mode 100644 src/main/resources/com/unicenta/reports/tools_newproducts.bs create mode 100644 src/main/resources/com/unicenta/reports/tools_newproducts.jrxml create mode 100644 src/main/resources/com/unicenta/reports/tools_updatedprices.bs create mode 100644 src/main/resources/com/unicenta/reports/tools_updatedprices.jrxml create mode 100644 src/main/resources/com/unicenta/reports/users.bs create mode 100644 src/main/resources/com/unicenta/reports/users.jrxml create mode 100644 src/main/resources/com/unicenta/reports/users_messages.properties create mode 100644 src/main/resources/com/unicenta/reports/users_messages_ar.properties create mode 100644 src/main/resources/com/unicenta/reports/users_messages_de.properties create mode 100644 src/main/resources/com/unicenta/reports/users_messages_el.properties create mode 100644 src/main/resources/com/unicenta/reports/users_messages_en_US.properties create mode 100644 src/main/resources/com/unicenta/reports/users_messages_es.properties create mode 100644 src/main/resources/com/unicenta/reports/users_messages_es_AR.properties create mode 100644 src/main/resources/com/unicenta/reports/users_messages_es_MX.properties create mode 100644 src/main/resources/com/unicenta/reports/users_messages_et.properties create mode 100644 src/main/resources/com/unicenta/reports/users_messages_fr.properties create mode 100644 src/main/resources/com/unicenta/reports/users_messages_hr.properties create mode 100644 src/main/resources/com/unicenta/reports/users_messages_it.properties create mode 100644 src/main/resources/com/unicenta/reports/users_messages_nl.properties create mode 100644 src/main/resources/com/unicenta/reports/users_nosales.bs create mode 100644 src/main/resources/com/unicenta/reports/users_nosales.jrxml create mode 100644 src/main/resources/com/unicenta/reports/users_sales.bs create mode 100644 src/main/resources/com/unicenta/reports/users_sales.jrxml create mode 100644 src/main/resources/com/unicenta/reports/users_tips.bs create mode 100644 src/main/resources/com/unicenta/reports/users_tips.jrxml create mode 100644 src/main/resources/com/unicenta/reports/users_voids.bs create mode 100644 src/main/resources/com/unicenta/reports/users_voids.jrxml create mode 100644 src/main/resources/com/unicenta/reports/vouchers.bs create mode 100644 src/main/resources/com/unicenta/reports/vouchers.jrxml create mode 100644 src/main/resources/com/unicenta/reports/vouchers_messages.properties create mode 100644 src/main/resources/com/unicenta/reports/vouchers_messages_de.properties create mode 100644 src/main/resources/com/unicenta/reports/vouchers_messages_en_US.properties create mode 100644 src/main/resources/com/unicenta/reports/vouchers_messages_es.properties create mode 100644 src/main/resources/com/unicenta/reports/vouchers_messages_fr.properties create mode 100644 src/main/resources/com/unicenta/reports/vouchers_messages_nl.properties create mode 100644 src/main/resources/data_messages.properties create mode 100644 src/main/resources/data_messages_al_SQ.properties create mode 100644 src/main/resources/data_messages_ar.properties create mode 100644 src/main/resources/data_messages_da.properties create mode 100644 src/main/resources/data_messages_de.properties create mode 100644 src/main/resources/data_messages_el.properties create mode 100644 src/main/resources/data_messages_en_US.properties create mode 100644 src/main/resources/data_messages_es.properties create mode 100644 src/main/resources/data_messages_es_AR.properties create mode 100644 src/main/resources/data_messages_es_MX.properties create mode 100644 src/main/resources/data_messages_et.properties create mode 100644 src/main/resources/data_messages_fr.properties create mode 100644 src/main/resources/data_messages_hr.properties create mode 100644 src/main/resources/data_messages_it.properties create mode 100644 src/main/resources/data_messages_nl.properties create mode 100644 src/main/resources/data_messages_pt.properties create mode 100644 src/main/resources/data_messages_pt_BR.properties create mode 100644 src/main/resources/erp_messages.properties create mode 100644 src/main/resources/erp_messages_al_SQ.properties create mode 100644 src/main/resources/erp_messages_ar.properties create mode 100644 src/main/resources/erp_messages_da.properties create mode 100644 src/main/resources/erp_messages_de.properties create mode 100644 src/main/resources/erp_messages_el.properties create mode 100644 src/main/resources/erp_messages_en_US.properties create mode 100644 src/main/resources/erp_messages_es.properties create mode 100644 src/main/resources/erp_messages_es_AR.properties create mode 100644 src/main/resources/erp_messages_es_MX.properties create mode 100644 src/main/resources/erp_messages_fr.properties create mode 100644 src/main/resources/erp_messages_hr.properties create mode 100644 src/main/resources/erp_messages_it.properties create mode 100644 src/main/resources/erp_messages_nl.properties create mode 100644 src/main/resources/erp_messages_pt.properties create mode 100644 src/main/resources/erp_messages_pt_BR.properties create mode 100644 src/main/resources/fxml/OrderPop.fxml create mode 100644 src/main/resources/logback.groovy create mode 100644 src/main/resources/pos_messages.properties create mode 100644 src/main/resources/pos_messages_al_SQ.properties create mode 100644 src/main/resources/pos_messages_ar.properties create mode 100644 src/main/resources/pos_messages_da.properties create mode 100644 src/main/resources/pos_messages_de.properties create mode 100644 src/main/resources/pos_messages_el.properties create mode 100644 src/main/resources/pos_messages_en_US.properties create mode 100644 src/main/resources/pos_messages_es.properties create mode 100644 src/main/resources/pos_messages_es_AR.properties create mode 100644 src/main/resources/pos_messages_es_MX.properties create mode 100644 src/main/resources/pos_messages_et.properties create mode 100644 src/main/resources/pos_messages_fr.properties create mode 100644 src/main/resources/pos_messages_hr.properties create mode 100644 src/main/resources/pos_messages_it.properties create mode 100644 src/main/resources/pos_messages_nl.properties create mode 100644 src/main/resources/pos_messages_pt.properties create mode 100644 src/main/resources/pos_messages_pt_BR.properties create mode 100644 src/main/resources/styles/orderpop.css create mode 100644 src/other/Bonus/Barcode_3of9.zip create mode 100644 src/other/Bonus/FRE3OF9X.TTF create mode 100644 src/other/Bonus/Images/Clothing/bbcap.png create mode 100644 src/other/Bonus/Images/Clothing/clothing.png create mode 100644 src/other/Bonus/Images/Clothing/tshirt.jpg create mode 100644 src/other/Bonus/Images/Clothing/tshirt.png create mode 100644 src/other/Bonus/Images/Currency/AU_Dollar/coin.10cent.jpg create mode 100644 src/other/Bonus/Images/Currency/AU_Dollar/coin.10cent.png create mode 100644 src/other/Bonus/Images/Currency/AU_Dollar/coin.1aud.jpg create mode 100644 src/other/Bonus/Images/Currency/AU_Dollar/coin.1aud.png create mode 100644 src/other/Bonus/Images/Currency/AU_Dollar/coin.20cent.jpg create mode 100644 src/other/Bonus/Images/Currency/AU_Dollar/coin.20cent.png create mode 100644 src/other/Bonus/Images/Currency/AU_Dollar/coin.2aud.jpg create mode 100644 src/other/Bonus/Images/Currency/AU_Dollar/coin.2aud.png create mode 100644 src/other/Bonus/Images/Currency/AU_Dollar/coin.50cent.jpg create mode 100644 src/other/Bonus/Images/Currency/AU_Dollar/coin.50cent.png create mode 100644 src/other/Bonus/Images/Currency/AU_Dollar/coin.5cent.jpg create mode 100644 src/other/Bonus/Images/Currency/AU_Dollar/coin.5cent.png create mode 100644 src/other/Bonus/Images/Currency/AU_Dollar/note.100aud.jpg create mode 100644 src/other/Bonus/Images/Currency/AU_Dollar/note.10aud.jpg create mode 100644 src/other/Bonus/Images/Currency/AU_Dollar/note.20aud.jpg create mode 100644 src/other/Bonus/Images/Currency/AU_Dollar/note.50aud.jpg create mode 100644 src/other/Bonus/Images/Currency/AU_Dollar/note.5aud.jpg create mode 100644 src/other/Bonus/Images/Currency/GB_Sterling/coin.01.png create mode 100644 src/other/Bonus/Images/Currency/GB_Sterling/coin.02.png create mode 100644 src/other/Bonus/Images/Currency/GB_Sterling/coin.05.png create mode 100644 src/other/Bonus/Images/Currency/GB_Sterling/coin.1.png create mode 100644 src/other/Bonus/Images/Currency/GB_Sterling/coin.10.png create mode 100644 src/other/Bonus/Images/Currency/GB_Sterling/coin.2.png create mode 100644 src/other/Bonus/Images/Currency/GB_Sterling/coin.20.png create mode 100644 src/other/Bonus/Images/Currency/GB_Sterling/coin.50.png create mode 100644 src/other/Bonus/Images/Currency/GB_Sterling/note.10.png create mode 100644 src/other/Bonus/Images/Currency/GB_Sterling/note.20.png create mode 100644 src/other/Bonus/Images/Currency/GB_Sterling/note.5.png create mode 100644 src/other/Bonus/Images/Currency/GB_Sterling/note.50.png create mode 100644 src/other/Bonus/Images/Currency/Generic/.01.png create mode 100644 src/other/Bonus/Images/Currency/Generic/.02.png create mode 100644 src/other/Bonus/Images/Currency/Generic/.05.png create mode 100644 src/other/Bonus/Images/Currency/Generic/.10.png create mode 100644 src/other/Bonus/Images/Currency/Generic/.20.png create mode 100644 src/other/Bonus/Images/Currency/Generic/.25.png create mode 100644 src/other/Bonus/Images/Currency/Generic/.50.png create mode 100644 src/other/Bonus/Images/Currency/Generic/1.00.png create mode 100644 src/other/Bonus/Images/Currency/Generic/10.00.png create mode 100644 src/other/Bonus/Images/Currency/Generic/100.00.png create mode 100644 src/other/Bonus/Images/Currency/Generic/1000.00.png create mode 100644 src/other/Bonus/Images/Currency/Generic/2.00.png create mode 100644 src/other/Bonus/Images/Currency/Generic/20.00.png create mode 100644 src/other/Bonus/Images/Currency/Generic/200.00.png create mode 100644 src/other/Bonus/Images/Currency/Generic/5.00.png create mode 100644 src/other/Bonus/Images/Currency/Generic/50.00.png create mode 100644 src/other/Bonus/Images/Currency/Generic/500.00.png create mode 100644 src/other/Bonus/Images/Currency/Generic/Numbers/coin.01.png create mode 100644 src/other/Bonus/Images/Currency/Generic/Numbers/coin.05.png create mode 100644 src/other/Bonus/Images/Currency/Generic/Numbers/coin.1.png create mode 100644 src/other/Bonus/Images/Currency/Generic/Numbers/coin.10.png create mode 100644 src/other/Bonus/Images/Currency/Generic/Numbers/coin.2.png create mode 100644 src/other/Bonus/Images/Currency/Generic/Numbers/coin.20.png create mode 100644 src/other/Bonus/Images/Currency/Generic/Numbers/coin.25.png create mode 100644 src/other/Bonus/Images/Currency/Generic/Numbers/coin.50.png create mode 100644 src/other/Bonus/Images/Currency/Generic/Numbers/coin02.png create mode 100644 src/other/Bonus/Images/Currency/Generic/Numbers/note.1.png create mode 100644 src/other/Bonus/Images/Currency/Generic/Numbers/note.10.png create mode 100644 src/other/Bonus/Images/Currency/Generic/Numbers/note.100.png create mode 100644 src/other/Bonus/Images/Currency/Generic/Numbers/note.2.png create mode 100644 src/other/Bonus/Images/Currency/Generic/Numbers/note.20.png create mode 100644 src/other/Bonus/Images/Currency/Generic/Numbers/note.5.png create mode 100644 src/other/Bonus/Images/Currency/Generic/Numbers/note.50.png create mode 100644 src/other/Bonus/Images/Currency/Generic/bill1.png create mode 100644 src/other/Bonus/Images/Currency/Generic/bill10.png create mode 100644 src/other/Bonus/Images/Currency/Generic/bill100.png create mode 100644 src/other/Bonus/Images/Currency/Generic/bill1000.png create mode 100644 src/other/Bonus/Images/Currency/Generic/bill2.png create mode 100644 src/other/Bonus/Images/Currency/Generic/bill20.png create mode 100644 src/other/Bonus/Images/Currency/Generic/bill200.png create mode 100644 src/other/Bonus/Images/Currency/Generic/bill2000.png create mode 100644 src/other/Bonus/Images/Currency/Generic/bill5.png create mode 100644 src/other/Bonus/Images/Currency/Generic/bill50.png create mode 100644 src/other/Bonus/Images/Currency/Generic/bill500.png create mode 100644 src/other/Bonus/Images/Currency/Generic/bill5000.png create mode 100644 src/other/Bonus/Images/Currency/Generic/coin.01.png create mode 100644 src/other/Bonus/Images/Currency/Generic/coin.02.png create mode 100644 src/other/Bonus/Images/Currency/Generic/coin.05.png create mode 100644 src/other/Bonus/Images/Currency/Generic/coin.10.png create mode 100644 src/other/Bonus/Images/Currency/Generic/coin.20.png create mode 100644 src/other/Bonus/Images/Currency/Generic/coin.25.png create mode 100644 src/other/Bonus/Images/Currency/Generic/coin.50.png create mode 100644 src/other/Bonus/Images/Currency/Generic/coin1.png create mode 100644 src/other/Bonus/Images/Currency/Generic/coin10.png create mode 100644 src/other/Bonus/Images/Currency/Generic/coin100.png create mode 100644 src/other/Bonus/Images/Currency/Generic/coin2.png create mode 100644 src/other/Bonus/Images/Currency/Generic/coin20.png create mode 100644 src/other/Bonus/Images/Currency/Generic/coin5.png create mode 100644 src/other/Bonus/Images/Currency/Generic/coin50.png create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/1000kn.jpg create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/100kn.jpg create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/10kn.jpg create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/10lipacoin.jpg create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/10lipacoin.png create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/1kunacoin.jpg create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/1kunacoin.png create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/1lipacoin.jpg create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/1lipacoin.png create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/200kn.jpg create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/20kn.jpg create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/20lipacoin.jpg create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/20lipacoin.png create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/25kunacoin.jpg create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/25kunacoin.png create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/2kunacoin.jpg create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/2kunacoin.png create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/2lipacoin.jpg create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/2lipacoin.png create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/500kn.jpg create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/50kn.jpg create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/50lipacoin.jpg create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/50lipacoin.png create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/5kunacoin.jpg create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/5kunacoin.png create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/5lipacoin.jpg create mode 100644 src/other/Bonus/Images/Currency/HR_Kune/5lipacoin.png create mode 100644 src/other/Bonus/Images/Currency/US_Dollar/coin.01.png create mode 100644 src/other/Bonus/Images/Currency/US_Dollar/coin.05.png create mode 100644 src/other/Bonus/Images/Currency/US_Dollar/coin.1 create mode 100644 src/other/Bonus/Images/Currency/US_Dollar/coin.1.png create mode 100644 src/other/Bonus/Images/Currency/US_Dollar/coin.10.png create mode 100644 src/other/Bonus/Images/Currency/US_Dollar/coin.25.png create mode 100644 src/other/Bonus/Images/Currency/US_Dollar/coin.50.png create mode 100644 src/other/Bonus/Images/Currency/US_Dollar/note.1.png create mode 100644 src/other/Bonus/Images/Currency/US_Dollar/note.10.png create mode 100644 src/other/Bonus/Images/Currency/US_Dollar/note.100.png create mode 100644 src/other/Bonus/Images/Currency/US_Dollar/note.2.png create mode 100644 src/other/Bonus/Images/Currency/US_Dollar/note.20.png create mode 100644 src/other/Bonus/Images/Currency/US_Dollar/note.5.png create mode 100644 src/other/Bonus/Images/Currency/US_Dollar/note.50.png create mode 100644 src/other/Bonus/Images/Currency/euro/coin.01.png create mode 100644 src/other/Bonus/Images/Currency/euro/coin.02.png create mode 100644 src/other/Bonus/Images/Currency/euro/coin.05.png create mode 100644 src/other/Bonus/Images/Currency/euro/coin.1.png create mode 100644 src/other/Bonus/Images/Currency/euro/coin.10.png create mode 100644 src/other/Bonus/Images/Currency/euro/coin.2.png create mode 100644 src/other/Bonus/Images/Currency/euro/coin.20.png create mode 100644 src/other/Bonus/Images/Currency/euro/coin.50.png create mode 100644 src/other/Bonus/Images/Currency/euro/note.10.png create mode 100644 src/other/Bonus/Images/Currency/euro/note.20.png create mode 100644 src/other/Bonus/Images/Currency/euro/note.5.png create mode 100644 src/other/Bonus/Images/Currency/euro/note.50.png create mode 100644 src/other/Bonus/Images/Drink/Cocktails.jpg create mode 100644 src/other/Bonus/Images/Drink/americano.jpg create mode 100644 src/other/Bonus/Images/Drink/beer_bottle.jpg create mode 100644 src/other/Bonus/Images/Drink/cappuccino.jpg create mode 100644 src/other/Bonus/Images/Drink/cocktail.jpg create mode 100644 src/other/Bonus/Images/Drink/coke.jpg create mode 100644 src/other/Bonus/Images/Drink/fanta.jpg create mode 100644 src/other/Bonus/Images/Drink/minerals_applejuice.jpg create mode 100644 src/other/Bonus/Images/Drink/minerals_water.jpg create mode 100644 src/other/Bonus/Images/Drink/soft_coca.jpg create mode 100644 src/other/Bonus/Images/Drink/spirit.jpg create mode 100644 src/other/Bonus/Images/Drink/spirits_Whisky.jpg create mode 100644 src/other/Bonus/Images/Drink/sprite.jpg create mode 100644 src/other/Bonus/Images/Drink/wine_labels.jpg create mode 100644 src/other/Bonus/Images/Drink/wine_rose.jpg create mode 100644 src/other/Bonus/Images/Food/AlmondSlice.jpg create mode 100644 src/other/Bonus/Images/Food/americancheese.png create mode 100644 src/other/Bonus/Images/Food/apple.jpg create mode 100644 src/other/Bonus/Images/Food/bananas.jpg create mode 100644 src/other/Bonus/Images/Food/caesarsalad.jpg create mode 100644 src/other/Bonus/Images/Food/carbonara.jpg create mode 100644 src/other/Bonus/Images/Food/chickenstrips.jpg create mode 100644 src/other/Bonus/Images/Food/chickwings.jpg create mode 100644 src/other/Bonus/Images/Food/coffeebeans.jpg create mode 100644 src/other/Bonus/Images/Food/cookies.jpg create mode 100644 src/other/Bonus/Images/Food/dips.jpg create mode 100644 src/other/Bonus/Images/Food/food_asparagus.png create mode 100644 src/other/Bonus/Images/Food/food_burger.png create mode 100644 src/other/Bonus/Images/Food/food_burgers.jpg create mode 100644 src/other/Bonus/Images/Food/fries.png create mode 100644 src/other/Bonus/Images/Food/fusilli.jpg create mode 100644 src/other/Bonus/Images/Food/gardensalad.jpg create mode 100644 src/other/Bonus/Images/Food/garlicpizzabread.jpg create mode 100644 src/other/Bonus/Images/Food/girasoli.jpg create mode 100644 src/other/Bonus/Images/Food/haagen.gif create mode 100644 src/other/Bonus/Images/Food/hawaiian.jpg create mode 100644 src/other/Bonus/Images/Food/italiansalad.jpg create mode 100644 src/other/Bonus/Images/Food/lasagna.jpg create mode 100644 src/other/Bonus/Images/Food/margherita.jpg create mode 100644 src/other/Bonus/Images/Food/pasta.jpg create mode 100644 src/other/Bonus/Images/Food/pepperoni.jpg create mode 100644 src/other/Bonus/Images/Food/pizza1.jpg create mode 100644 src/other/Bonus/Images/Food/potatoskins.jpg create mode 100644 src/other/Bonus/Images/Food/potatowedges.jpg create mode 100644 src/other/Bonus/Images/Food/ravioli.jpg create mode 100644 src/other/Bonus/Images/Food/salad-01.png create mode 100644 src/other/Bonus/Images/Food/sauce.jpg create mode 100644 src/other/Bonus/Images/Food/spaghetti.jpg create mode 100644 src/other/Bonus/Images/Food/sponge.jpg create mode 100644 src/other/Bonus/Images/Food/strawberries.jpg create mode 100644 src/other/Bonus/Images/Food/subs.jpg create mode 100644 src/other/Bonus/Images/Food/subs_1.jpg create mode 100644 src/other/Bonus/Images/Food/tealeaves.jpg create mode 100644 src/other/Bonus/Images/Food/vegpizza.jpg create mode 100644 src/other/Bonus/Images/System/301-keyboard.png create mode 100644 src/other/Bonus/Images/System/cash.png create mode 100644 src/other/Bonus/Images/System/cashdrawer.png create mode 100644 src/other/Bonus/Images/System/empty.png create mode 100644 src/other/Bonus/Images/System/gplv3-127x51.png create mode 100644 src/other/Bonus/Images/System/grey_wash_wall_@940_580.png create mode 100644 src/other/Bonus/Images/System/grey_wash_wall_@940_588.png create mode 100644 src/other/Bonus/Images/System/grey_wash_wall_@950_594.png create mode 100644 src/other/Bonus/Images/System/grey_wash_wall_@960_600.png create mode 100644 src/other/Bonus/Images/System/heart.png create mode 100644 src/other/Bonus/Images/System/img.cashdrawer.png create mode 100644 src/other/Bonus/Images/System/img.discount.png create mode 100644 src/other/Bonus/Images/System/img.discount_b.png create mode 100644 src/other/Bonus/Images/System/img.keyboard_32.png create mode 100644 src/other/Bonus/Images/System/img.ticket_print.png create mode 100644 src/other/Bonus/Images/System/img.user.png create mode 100644 src/other/Bonus/Images/System/keyboard_48.png create mode 100644 src/other/Bonus/Images/System/kit_print.png create mode 100644 src/other/Bonus/Images/System/meetingrooms.jpg create mode 100644 src/other/Bonus/Images/System/no_photo.png create mode 100644 src/other/Bonus/Images/System/osi_reversing_logotype_color_to_white.png create mode 100644 src/other/Bonus/Images/System/osi_standard_logo.png create mode 100644 src/other/Bonus/Images/System/refundit.png create mode 100644 src/other/Bonus/Images/System/remote_print.png create mode 100644 src/other/Bonus/Images/System/restaurant_floor.png create mode 100644 src/other/Bonus/Images/System/restaurant_floor_sml.png create mode 100644 src/other/Bonus/Images/System/run_script.png create mode 100644 src/other/Bonus/Images/System/ticket_print.png create mode 100644 src/other/Bonus/Images/Tile/col_0.png create mode 100644 src/other/Bonus/Images/Tile/col_0_wide.png create mode 100644 src/other/Bonus/Images/Tile/col_1.png create mode 100644 src/other/Bonus/Images/Tile/col_10.png create mode 100644 src/other/Bonus/Images/Tile/col_10_wide.png create mode 100644 src/other/Bonus/Images/Tile/col_11.png create mode 100644 src/other/Bonus/Images/Tile/col_11_wide.png create mode 100644 src/other/Bonus/Images/Tile/col_12.png create mode 100644 src/other/Bonus/Images/Tile/col_12_wide.png create mode 100644 src/other/Bonus/Images/Tile/col_13.png create mode 100644 src/other/Bonus/Images/Tile/col_13_wide.png create mode 100644 src/other/Bonus/Images/Tile/col_14.png create mode 100644 src/other/Bonus/Images/Tile/col_14_wide.png create mode 100644 src/other/Bonus/Images/Tile/col_15.png create mode 100644 src/other/Bonus/Images/Tile/col_15_wide.png create mode 100644 src/other/Bonus/Images/Tile/col_16.png create mode 100644 src/other/Bonus/Images/Tile/col_16_wide.png create mode 100644 src/other/Bonus/Images/Tile/col_17.png create mode 100644 src/other/Bonus/Images/Tile/col_17_wide.png create mode 100644 src/other/Bonus/Images/Tile/col_18.png create mode 100644 src/other/Bonus/Images/Tile/col_18_wide.png create mode 100644 src/other/Bonus/Images/Tile/col_19.png create mode 100644 src/other/Bonus/Images/Tile/col_19_wide.png create mode 100644 src/other/Bonus/Images/Tile/col_1_wide.png create mode 100644 src/other/Bonus/Images/Tile/col_2.png create mode 100644 src/other/Bonus/Images/Tile/col_20.png create mode 100644 src/other/Bonus/Images/Tile/col_20_wide.png create mode 100644 src/other/Bonus/Images/Tile/col_2_wide.png create mode 100644 src/other/Bonus/Images/Tile/col_3.png create mode 100644 src/other/Bonus/Images/Tile/col_3_wide.png create mode 100644 src/other/Bonus/Images/Tile/col_4.png create mode 100644 src/other/Bonus/Images/Tile/col_4_wide.png create mode 100644 src/other/Bonus/Images/Tile/col_5.png create mode 100644 src/other/Bonus/Images/Tile/col_5_wide.png create mode 100644 src/other/Bonus/Images/Tile/col_6.png create mode 100644 src/other/Bonus/Images/Tile/col_6_wide.png create mode 100644 src/other/Bonus/Images/Tile/col_7.png create mode 100644 src/other/Bonus/Images/Tile/col_7_wide.png create mode 100644 src/other/Bonus/Images/Tile/col_8.png create mode 100644 src/other/Bonus/Images/Tile/col_8_wide.png create mode 100644 src/other/Bonus/Images/Tile/col_9.png create mode 100644 src/other/Bonus/Images/Tile/col_9_wide.png create mode 100644 src/other/Configs/payments_euro.txt create mode 100644 src/other/Configs/payments_full.txt create mode 100644 src/other/Configs/payments_uk.txt create mode 100644 src/other/Configs/payments_us.txt create mode 100644 src/other/Linux/i686-unknown-linux-gnu/librxtxParallel.so create mode 100644 src/other/Linux/i686-unknown-linux-gnu/librxtxSerial.so create mode 100644 src/other/Linux/ia64-unkown-linux-gnu/librxtxParallel.so create mode 100644 src/other/Linux/ia64-unkown-linux-gnu/librxtxParallel64.so create mode 100644 src/other/Linux/ia64-unkown-linux-gnu/librxtxSerial.so create mode 100644 src/other/Linux/ia64-unkown-linux-gnu/librxtxSerial64.so create mode 100644 src/other/Linux/x86_64-unknown-linux-gnu/librxtxParallel64.so create mode 100644 src/other/Linux/x86_64-unknown-linux-gnu/librxtxSerial64.so create mode 100644 src/other/Mac_OS_X/README create mode 100644 src/other/Mac_OS_X/librxtxSerial.jnilib create mode 100644 src/other/Mac_OS_X/librxtxSerial64.jnilib create mode 100644 src/other/Solaris/sparc-solaris/sparc32-sun-solaris2.8/librxtxSerial-2.1-7.so create mode 100644 src/other/Solaris/sparc-solaris/sparc32-sun-solaris2.8/librxtxSerial.so create mode 100644 src/other/Solaris/sparc-solaris/sparc64-sun-solaris2.8/librxtxSerial-2.1-7.so create mode 100644 src/other/Solaris/sparc-solaris/sparc64-sun-solaris2.8/librxtxSerial.so create mode 100644 src/other/Templates/US_Printer.PrintLastTicket.txt create mode 100644 src/other/Templates/US_Printer.ReprintTicket.txt create mode 100644 src/other/Templates/US_Printer.Ticket.txt create mode 100644 src/other/Templates/US_Printer.TicketLine.txt create mode 100644 src/other/Templates/US_Printer.TicketPreview.txt create mode 100644 src/other/Windows/i368-mingw32/README create mode 100644 src/other/Windows/i368-mingw32/rxtxParallel.dll create mode 100644 src/other/Windows/i368-mingw32/rxtxParallel64.dll create mode 100644 src/other/Windows/i368-mingw32/rxtxSerial.dll create mode 100644 src/other/Windows/i368-mingw32/rxtxSerial64.dll create mode 100644 src/other/images/uniCenta_splash_dark.png create mode 100644 src/other/images/unicentaopos.ico create mode 100644 src/other/images/unicentaopos.png create mode 100644 src/other/license/license.txt create mode 100644 src/scripts/configure.bat create mode 100644 src/scripts/configure.sh create mode 100644 src/scripts/start.bat create mode 100644 src/scripts/start.sh create mode 100644 src/test/java/com/unicenta/PackageScanTest.java create mode 100644 src/test/java/com/unicenta/data/loader/StaticSentenceTest.java create mode 100644 src/test/java/com/unicenta/pos/ticket/TicketInfoTest.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4e73779 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.idea/ +target/ +.vscode/ +*.iml +nb-configuration.xml +nbactions.xml +*.log diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..054ec78 --- /dev/null +++ b/pom.xml @@ -0,0 +1,588 @@ + + + 4.0.0 + + com.unicenta + unicentaopos + 5.0 + jar + + UTF-8 + 11 + 11 + + + + + org.xerial + sqlite-jdbc + 3.7.2 + + + + org.openjfx + javafx-base + 11 + + + org.openjfx + javafx-controls + 11 + + + org.openjfx + javafx-fxml + 11 + + + org.openjfx + javafx-graphics + 11 + + + org.openjfx + javafx-media + 11 + + + org.openjfx + javafx-swing + 11 + + + org.openjfx + javafx-web + 11 + + + org.mariadb.jdbc + mariadb-java-client + 2.7.0 + + + org.projectlombok + lombok + 1.18.6 + provided + + + ch.qos.logback + logback-classic + 1.2.2 + + + org.jfree + jcommon + 1.0.24 + + + org.jfree + jfreechart + 1.0.19 + + + + commons-beanutils + commons-beanutils + 1.9.3 + + + commons-digester + commons-digester + 2.1 + + + com.lowagie + itext + 2.1.7 + + + org.apache.poi + poi + 3.10.1 + + + net.sf.barcode4j + barcode4j + 2.1 + + + commons-codec + commons-codec + 1.10 + + + org.apache.velocity + velocity + 1.7 + + + oro + oro + 2.0.8 + + + commons-collections + commons-collections + 3.2.2 + + + commons-lang + commons-lang + 2.6 + + + org.beanshell + bsh + 2.0b4 + + + org.bidib.jbidib.org.qbang.rxtx + rxtxcomm + 2.2 + + + org.jpos + jpos + 2.0.10 + + + org.slf4j + slf4j-nop + + + org.slf4j + slf4j-api + + + + + + org.swinglabs.swingx + swingx-all + 1.6.5-1 + + + axis + axis + 1.4 + + + org.apache.axis + axis-jaxrpc + 1.4 + + + javax.xml.soap + saaj-api + 1.3.5 + + + axis + axis-wsdl4j + 1.5.1 + + + commons-discovery + commons-discovery + 0.5 + + + + org.swinglabs + swing-layout + 1.0.3 + + + net.sourceforge.javacsv + javacsv + 2.0 + + + org.netbeans.external + AbsoluteLayout + RELEASE82 + + + com.javapos + jpos + 1.13 + + + mysql + mysql-connector-java + 5.1.39 + + + org.apache.derby + derby + 10.14.2.0 + + + xml-apis + xml-apis + 1.0.b2 + + + + + org.apache.xmlgraphics + fop + 2.1 + + + net.sf.jasperreports + jasperreports + 6.4.0 + + + com.lowagie + itext + + + + + net.sf.jasperreports + jasperreports-fonts + 6.0.0 + + + ar.com.fdvs + DynamicJasper-core-fonts + 2.0 + + + + org.eclipse.jdt.core.compiler + ecj + 4.6.1 + + + + joda-time + joda-time + 2.9.7 + + + + + com.formdev + flatlaf-intellij-themes + 2.0.1 + + + + com.formdev + flatlaf + 1.6.5 + + + + com.formdev + flatlaf-swingx + 1.6.5 + + + org.reflections + reflections + 0.9.12 + + + + de.sciss + weblaf + 1.2.9 + + + org.slf4j + slf4j-nop + + + org.slf4j + slf4j-api + + + org.slf4j + slf4j-simple + + + + + com.unicenta + unicenta-plugins + 1.1 + + + uk.co.pos_apps + openbravo + 1.0-SNAPSHOT + + + com.gluonhq + charm-glisten + 6.2.2 + + + javax.xml.bind + jaxb-api + 2.3.0 + + + javax.persistence + persistence-api + 1.0.2 + + + com.dalsemi.onewire + OneWireAPI + 0.1 + + + + org.usb4java + usb4java + 1.2.0 + + + javax.usb + usb-api + 1.0.2 + + + org.jdatepicker + jdatepicker + 1.3.4 + + + + com.sleepycat + je + 5.0.73 + + + org.pushingpixels + trident + 1.4 + + + org.pushingpixels + substance + 7.1.00 + + + + org.postgresql + postgresql + 9.4.1208 + + + de.sciss + weblaf-ui + 2.1.3 + jar + + + + junit + junit + 4.12 + test + + + org.mockito + mockito-inline + 4.2.0 + + + org.mockito + mockito-junit-jupiter + 4.2.0 + test + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.10 + + + copy-dependencies + prepare-package + + copy-dependencies + + + ${project.build.directory}/lib + false + false + true + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + + + + true + lib/ + com.unicenta.pos.forms.StartPOS + + + unicenta-pos + ${project.version} + com.unicenta + unicenta.com + + + + + + maven-resources-plugin + 2.7 + + + copy-resources + validate + + copy-resources + + + ${project.build.directory} + + + ${basedir}/target/lib/Windows + ${basedir}/src/other/Windows + false + + + ${basedir}/target/lib/Linux + ${basedir}/src/other/Linux + false + + + ${basedir}/target/lib/Mac_OS_X + ${basedir}/src/other/Mac_OS_X + false + + + ${basedir}/target/ + ${basedir}/src/scripts + false + + + ${basedir}/target/Bonus + ${basedir}/src/other/Bonus + false + + + ${basedir}/target/Configs + ${basedir}/src/other/Configs + false + + + ${basedir}/target/Templates + ${basedir}/src/other/Templates + false + + + ${basedir}/target + ${basedir}/src/other/images + false + + + ${basedir}/target + ${basedir}/src/other/license + false + + + ${basedir}/target/reports/com + ${basedir}/src/main/resources/com + false + + + ${basedir}/target/locales + ${basedir}/src/main/resources + false + + com/** + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + true + true + + + + + + org.apache.maven.wagon + wagon-ftp + 2.10 + + + unicentaopos + + + + charm-glisten + charm-glisten Repository + https://nexus.gluonhq.com/nexus/content/repositories/releases/ + default + + + unicenta-repo + https://repo.unicenta.org/maven2/ + default + + + central + https://repo1.maven.org/maven2/ + default + + + + netbeans + NetBeans + https://netbeans.apidesign.org/maven2/ + + + + flatlaf + flatlaf + https://dev.webswing.org/public/nexus/repository/webswing-3rd-parties// + + + + + unicenta-repo + ftp://repo.unicenta.org/ + false + + + unicenta-opos + diff --git a/src/main/java/com/unicenta/basic/BasicException.java b/src/main/java/com/unicenta/basic/BasicException.java new file mode 100644 index 0000000..fed648f --- /dev/null +++ b/src/main/java/com/unicenta/basic/BasicException.java @@ -0,0 +1,58 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.basic; + +/** + * + * @author JG uniCenta + */ +public class BasicException extends java.lang.Exception { + + /** + * Creates a new instance of DataException without detail message. + */ + public BasicException() { + } + + /** + * + * @param msg + */ + public BasicException(String msg) { + super(msg); + } + + /** + * + * @param msg + * @param cause + */ + public BasicException(String msg, Throwable cause) { + super(msg, cause); + } + + /** + * + * @param cause + */ + public BasicException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/unicenta/beans/DateUtils.java b/src/main/java/com/unicenta/beans/DateUtils.java new file mode 100644 index 0000000..c412f5d --- /dev/null +++ b/src/main/java/com/unicenta/beans/DateUtils.java @@ -0,0 +1,121 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.beans; + +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +/** + * + * @author JG uniCenta + */ +public class DateUtils { + + /** Creates a new instance of DateUtils */ + private DateUtils() { + } + + /** + * + * @return + */ + public static Date getToday() { + // el dia de hoy sin horas ni nada. + return getToday(new Date()); + } + + /** + * + * @param d + * @return + */ + public static Date getToday(Date d) { + // el dia de hoy sin horas ni nada. + GregorianCalendar ddate = new GregorianCalendar(); + ddate.setTime(d); + GregorianCalendar ddateday = new GregorianCalendar(ddate.get(GregorianCalendar.YEAR), ddate.get(GregorianCalendar.MONTH), ddate.get(GregorianCalendar.DAY_OF_MONTH)); + return ddateday.getTime(); + } + + /** + * + * @return + */ + public static Date getTodayMinutes() { + // el dia de hoy sin horas ni nada. + return getTodayMinutes(new Date()); + } + + /** + * + * @param d + * @return + */ + public static Date getTodayMinutes(Date d) { + // el dia de hoy sin horas ni nada. + GregorianCalendar ddate = new GregorianCalendar(); + ddate.setTime(d); + GregorianCalendar ddateday = new GregorianCalendar(ddate.get(GregorianCalendar.YEAR), ddate.get(GregorianCalendar.MONTH), ddate.get(GregorianCalendar.DAY_OF_MONTH) + , ddate.get(GregorianCalendar.HOUR_OF_DAY), ddate.get(GregorianCalendar.MINUTE)); + return ddateday.getTime(); + } + + /** + * + * @param d + * @return + */ + public static Date getTodayHours(Date d) { + // el dia ajustado a las horeas + Calendar ddate = Calendar.getInstance(); + ddate.setTime(d); + + Calendar dNow = Calendar.getInstance(); + dNow.clear(); + dNow.set(ddate.get(Calendar.YEAR), ddate.get(Calendar.MONTH), ddate.get(Calendar.DAY_OF_MONTH) + , ddate.get(Calendar.HOUR_OF_DAY), 0, 0); + + return dNow.getTime(); + } + + /** + * + * @param day + * @param hour + * @return + */ + public static Date getDate(Date day, Date hour) { + + // Calculamos el dia actual con la hora escogida. + Calendar dDay = Calendar.getInstance(); + dDay.setTime(day); + Calendar dHour = Calendar.getInstance(); + dHour.setTime(hour); + + Calendar dNow = Calendar.getInstance(); + dNow.clear(); + dNow.set(dDay.get(Calendar.YEAR), dDay.get(Calendar.MONTH), dDay.get(Calendar.DAY_OF_MONTH) + , dHour.get(Calendar.HOUR_OF_DAY), dHour.get(Calendar.MINUTE), dHour.get(Calendar.SECOND)); + + return dNow.getTime(); + } + +} diff --git a/src/main/java/com/unicenta/beans/JCalendarDialog.form b/src/main/java/com/unicenta/beans/JCalendarDialog.form new file mode 100644 index 0000000..83063f6 --- /dev/null +++ b/src/main/java/com/unicenta/beans/JCalendarDialog.form @@ -0,0 +1,118 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/beans/JCalendarDialog.java b/src/main/java/com/unicenta/beans/JCalendarDialog.java new file mode 100644 index 0000000..e170d87 --- /dev/null +++ b/src/main/java/com/unicenta/beans/JCalendarDialog.java @@ -0,0 +1,274 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.beans; + +import java.awt.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.*; +import java.util.*; + +/** + * + * @author Adrian + */ +public class JCalendarDialog extends javax.swing.JDialog { + + // private static ResourceBundle m_Intl; + private static LocaleResources m_resources; + + private Date m_date; + private JCalendarPanel myCalendar = null; + private JTimePanel myTime = null; + + /** Creates new form JCalendarDialog + * @param parent + * @param modal */ + public JCalendarDialog(java.awt.Frame parent, boolean modal) { + super(parent, modal); + + if (m_resources == null) { + m_resources = new LocaleResources(); + m_resources.addBundleName("beans_messages"); + } else { + } + } + /** Creates new form JCalendarDialog + * @param parent + * @param modal */ + public JCalendarDialog(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + + if (m_resources != null) { + } else { + m_resources = new LocaleResources(); + m_resources.addBundleName("beans_messages"); + } + } + + private static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window) parent; + } else { + return getWindow(parent.getParent()); + } + } + + /** + * + * @param parent + * @param date + * @return + */ + public static Date showCalendarTimeHours(Component parent, Date date) { + return internalCalendarTime(parent, date == null ? DateUtils.getToday() : date, true); + } + + /** + * + * @param parent + * @param date + * @return + */ + public static Date showCalendarTime(Component parent, Date date) { + return internalCalendarTime(parent, date == null ? DateUtils.getTodayMinutes() : date, true); + } + + /** + * + * @param parent + * @param date + * @return + */ + public static Date showCalendar(Component parent, Date date) { + return internalCalendarTime(parent, date == null ? DateUtils.getTodayMinutes() : date, false); + } + + private static Date internalCalendarTime(Component parent, Date date, boolean bTimePanel) { + + Window window = getWindow(parent); + + JCalendarDialog myMsg; + if (window instanceof Frame) { + myMsg = new JCalendarDialog((Frame) window, true); + } else { + myMsg = new JCalendarDialog((Dialog) window, true); + } + + myMsg.initComponents(); + + Date d = date; + int dialogwidth = 400; + + myMsg.myCalendar = new JCalendarPanel(d); + myMsg.myCalendar.addPropertyChangeListener("Date", new JPanelCalendarChange(myMsg)); + myMsg.jPanelGrid.add(myMsg.myCalendar); + + if (bTimePanel) { + myMsg.myTime = new JTimePanel(d); + myMsg.myTime.addPropertyChangeListener("Date", new JPanelTimeChange(myMsg)); + myMsg.jPanelGrid.add(myMsg.myTime); + dialogwidth += 400; + } + + myMsg.getRootPane().setDefaultButton(myMsg.jcmdOK); + + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + myMsg.setBounds((screenSize.width - dialogwidth) / 2, (screenSize.height - 359) / 2, dialogwidth, 359); + + //myMsg.show(); + myMsg.m_date = null; + myMsg.setVisible(true); + return myMsg.m_date; + } + + private static class JPanelTimeChange implements PropertyChangeListener { + private final JCalendarDialog m_me; + public JPanelTimeChange(JCalendarDialog me) { + m_me = me; + } + @Override + public void propertyChange(PropertyChangeEvent evt) { + m_me.myCalendar.setDate(m_me.myTime.getDate()); + } + } + + private static class JPanelCalendarChange implements PropertyChangeListener { + private final JCalendarDialog m_me; + public JPanelCalendarChange(JCalendarDialog me) { + m_me = me; + } + @Override + public void propertyChange(PropertyChangeEvent evt) { + m_me.myTime.setDate(m_me.myCalendar.getDate()); + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jcmdOK = new javax.swing.JButton(); + jcmdCancel = new javax.swing.JButton(); + jPanel2 = new javax.swing.JPanel(); + jPanelGrid = new javax.swing.JPanel(); + + setTitle(m_resources.getString("title.calendar")); // NOI18N + setResizable(false); + addWindowListener(new java.awt.event.WindowAdapter() { + public void windowClosing(java.awt.event.WindowEvent evt) { + closeWindow(evt); + } + }); + + jPanel1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT)); + + jcmdOK.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jcmdOK.setText(m_resources.getString("button.ok")); // NOI18N + jcmdOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdOKActionPerformed(evt); + } + }); + jPanel1.add(jcmdOK); + + jcmdCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + jcmdCancel.setText(m_resources.getString("button.cancel")); // NOI18N + jcmdCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdCancelActionPerformed(evt); + } + }); + jPanel1.add(jcmdCancel); + + getContentPane().add(jPanel1, java.awt.BorderLayout.SOUTH); + + jPanel2.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel2.setLayout(new java.awt.BorderLayout()); + + jPanelGrid.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanelGrid.setLayout(new java.awt.GridLayout(1, 0, 5, 0)); + jPanel2.add(jPanelGrid, java.awt.BorderLayout.CENTER); + + getContentPane().add(jPanel2, java.awt.BorderLayout.CENTER); + }// //GEN-END:initComponents + + private void jcmdOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdOKActionPerformed + + GregorianCalendar dateresult; + + GregorianCalendar date1 = new GregorianCalendar(); + date1.setTime(myCalendar.getDate()); + + if (myTime == null) { + dateresult = new GregorianCalendar( + date1.get(GregorianCalendar.YEAR), + date1.get(GregorianCalendar.MONTH), + date1.get(GregorianCalendar.DAY_OF_MONTH)); + + } else { + GregorianCalendar date2 = new GregorianCalendar(); + date2.setTime(myTime.getDate()); + dateresult = new GregorianCalendar( + date1.get(GregorianCalendar.YEAR), + date1.get(GregorianCalendar.MONTH), + date1.get(GregorianCalendar.DAY_OF_MONTH), + date2.get(GregorianCalendar.HOUR_OF_DAY), + date2.get(GregorianCalendar.MINUTE)); + } + + m_date = dateresult.getTime(); + + setVisible(false); + dispose(); + }//GEN-LAST:event_jcmdOKActionPerformed + + private void jcmdCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdCancelActionPerformed + + setVisible(false); + dispose(); + }//GEN-LAST:event_jcmdCancelActionPerformed + + private void closeWindow(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_closeWindow + + setVisible(false); + dispose(); + }//GEN-LAST:event_closeWindow + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanelGrid; + private javax.swing.JButton jcmdCancel; + private javax.swing.JButton jcmdOK; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/beans/JCalendarPanel.form b/src/main/java/com/unicenta/beans/JCalendarPanel.form new file mode 100644 index 0000000..9aceef4 --- /dev/null +++ b/src/main/java/com/unicenta/beans/JCalendarPanel.form @@ -0,0 +1,134 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/beans/JCalendarPanel.java b/src/main/java/com/unicenta/beans/JCalendarPanel.java new file mode 100644 index 0000000..e8bb895 --- /dev/null +++ b/src/main/java/com/unicenta/beans/JCalendarPanel.java @@ -0,0 +1,376 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.beans; + +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.text.*; +import java.util.*; +import javax.swing.*; +import javax.swing.border.LineBorder; + +/** + * + * @author JG uniCenta + */ +public class JCalendarPanel extends javax.swing.JPanel { + + // private static ResourceBundle m_Intl; + private static LocaleResources m_resources; + + private static GregorianCalendar m_CalendarHelper = new GregorianCalendar(); // solo de ayuda + + private Date m_date; + private JButtonDate[] m_ListDates; + private JLabel[] m_jDays; + + private JButtonDate m_jCurrent; + private JButtonDate m_jBtnMonthInc; + private JButtonDate m_jBtnMonthDec; + private JButtonDate m_jBtnYearInc; + private JButtonDate m_jBtnYearDec; + private JButtonDate m_jBtnToday; + + private DateFormat fmtMonthYear = new SimpleDateFormat("MMMMM yyyy"); + + /** Creates new form JCalendarPanel2 */ + public JCalendarPanel() { + this(new Date()); + } + + /** + * + * @param dDate + */ + public JCalendarPanel(Date dDate) { + + super(); + + if (m_resources == null) { + m_resources = new LocaleResources(); + m_resources.addBundleName("beans_messages"); + } + + initComponents(); + initComponents2(); + +// m_CalendarHelper = new GregorianCalendar(); +// m_CalendarHelper.setTime(dDate); + m_date = dDate; + + // pintamos + renderMonth(); + renderDay(); + } + + /** + * + * @param dNewDate + */ + public void setDate(Date dNewDate) { + + // cambiamos la fecha + Date dOldDate = m_date; + m_date = dNewDate; + + // pintamos + renderMonth(); + renderDay(); + + // decimos al mundo que ha cambiado la propiedad fecha + firePropertyChange("Date", dOldDate, dNewDate); + } + + /** + * + * @return + */ + public Date getDate() { + return m_date; + } + + public void setEnabled(boolean bValue) { + + super.setEnabled(bValue); + + // pintamos + renderMonth(); + renderDay(); + } + + private void renderMonth() { + +// GregorianCalendar oCalRender = new GregorianCalendar(); +// oCalRender.setTime(m_CalendarHelper.getTime()); + + for (int j = 0; j < 7; j++) { + m_jDays[j].setEnabled(isEnabled()); + } + + // Borramos todos los dias + for(int i = 0; i < 42; i++) { + JButtonDate jAux = m_ListDates[i]; + jAux.DateInf = null; + jAux.setEnabled(false); + jAux.setText(null); + jAux.setForeground((Color)UIManager.getDefaults().get("TextPane.foreground")); + jAux.setBackground((Color)UIManager.getDefaults().get("TextPane.background")); + jAux.setBorder(null); + } + + if (m_date == null) { + m_jLblMonth.setEnabled(isEnabled()); + m_jLblMonth.setText(null); + } else { + m_CalendarHelper.setTime(m_date); + + m_jLblMonth.setEnabled(isEnabled()); + m_jLblMonth.setText(fmtMonthYear.format(m_CalendarHelper.getTime())); + + int iCurrentMonth = m_CalendarHelper.get(Calendar.MONTH); + m_CalendarHelper.set(Calendar.DAY_OF_MONTH, 1); + + while(m_CalendarHelper.get(Calendar.MONTH) == iCurrentMonth) { + + JButtonDate jAux = getLabelByDate(m_CalendarHelper.getTime()); + jAux.DateInf = m_CalendarHelper.getTime(); + jAux.setEnabled(isEnabled()); + jAux.setText(String.valueOf(m_CalendarHelper.get(Calendar.DAY_OF_MONTH))); + + m_CalendarHelper.add(Calendar.DATE, 1); + } + } + + m_jCurrent = null; + } + + private void renderDay() { + + m_jBtnToday.setEnabled(isEnabled()); + + if (m_date == null) { + m_jBtnMonthDec.setEnabled(false); + m_jBtnMonthInc.setEnabled(isEnabled()); + m_jBtnYearDec.setEnabled(isEnabled()); + m_jBtnYearInc.setEnabled(isEnabled()); + } else { + m_CalendarHelper.setTime(m_date); + + m_CalendarHelper.add(Calendar.MONTH, -1); + m_jBtnMonthDec.DateInf = m_CalendarHelper.getTime(); + m_jBtnMonthDec.setEnabled(isEnabled()); + m_CalendarHelper.add(Calendar.MONTH, 2); + m_jBtnMonthInc.DateInf = m_CalendarHelper.getTime(); + m_jBtnMonthInc.setEnabled(isEnabled()); + + m_CalendarHelper.setTime(m_date); + m_CalendarHelper.add(Calendar.YEAR, -1); + m_jBtnYearDec.DateInf = m_CalendarHelper.getTime(); + m_jBtnYearDec.setEnabled(isEnabled()); + m_CalendarHelper.add(Calendar.YEAR, 2); + m_jBtnYearInc.DateInf = m_CalendarHelper.getTime(); + m_jBtnYearInc.setEnabled(isEnabled()); + + if(m_jCurrent != null) { + m_jCurrent.setForeground((Color)UIManager.getDefaults().get("TextPane.foreground")); + m_jCurrent.setBackground((Color)UIManager.getDefaults().get("TextPane.background")); + m_jCurrent.setBorder(null); + } + + JButtonDate jAux = getLabelByDate(m_date); + jAux.setBackground((Color)UIManager.getDefaults().get("TextPane.selectionBackground")); + jAux.setForeground((Color)UIManager.getDefaults().get("TextPane.selectionForeground")); + jAux.setBorder(new LineBorder((Color)UIManager.getDefaults().get("TitledBorder.titleColor"))); + m_jCurrent = jAux; + } + } + + private JButtonDate getLabelByDate(Date d) { + + GregorianCalendar oCalRender = new GregorianCalendar(); + oCalRender.setTime(d); + int iDayOfMonth = oCalRender.get(Calendar.DAY_OF_MONTH); + + oCalRender.set(Calendar.DAY_OF_MONTH, 1); + + int iCol = oCalRender.get(Calendar.DAY_OF_WEEK) - oCalRender.getFirstDayOfWeek(); + if (iCol < 0) { + iCol += 7; + } + return m_ListDates[iCol + iDayOfMonth - 1]; + } + + private class DateClick implements ActionListener { + + public void actionPerformed(ActionEvent e) { + JButtonDate oLbl = (JButtonDate)e.getSource(); + if(oLbl.DateInf != null) { + setDate(oLbl.DateInf); + } + } + } + + private static class JButtonDate extends JButton { + + public Date DateInf; + + public JButtonDate(ActionListener datehandler) { + super(); + initComponent(); + addActionListener(datehandler); + } + public JButtonDate(String sText, ActionListener datehandler) { + super(sText); + initComponent(); + addActionListener(datehandler); + } + public JButtonDate(Icon icon, ActionListener datehandler) { + super(icon); + initComponent(); + addActionListener(datehandler); + } + + private void initComponent() { + DateInf = null; + setRequestFocusEnabled(false); + setFocusPainted(false); + setFocusable(false); + } + } + + private void initComponents2() { + + ActionListener dateclick = new DateClick(); + + m_jBtnYearDec = new JButtonDate(new ImageIcon(getClass().getResource("/com/unicenta/images/2leftarrow.png")), dateclick); + m_jBtnMonthDec = new JButtonDate(new ImageIcon(getClass().getResource("/com/unicenta/images/1leftarrow.png")), dateclick); + m_jBtnToday = new JButtonDate(m_resources.getString("button.Today"), dateclick); + m_jBtnMonthInc = new JButtonDate(new ImageIcon(getClass().getResource("/com/unicenta/images/1rightarrow.png")), dateclick); + m_jBtnYearInc = new JButtonDate(new ImageIcon(getClass().getResource("/com/unicenta/images/2rightarrow.png")), dateclick); + + m_jBtnToday.DateInf = new Date(); + m_jActions.add(m_jBtnYearDec); + m_jActions.add(m_jBtnMonthDec); + m_jActions.add(m_jBtnToday); + m_jActions.add(m_jBtnMonthInc); + m_jActions.add(m_jBtnYearInc); + + m_ListDates = new JButtonDate[42]; + for(int i = 0; i < 42; i++) { + JButtonDate jAux = new JButtonDate(dateclick); + // jAux.setFont(new Font("Dialog", 1, 24)); + jAux.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jAux.setText(null); + jAux.setOpaque(true); + jAux.setForeground((Color)UIManager.getDefaults().get("TextPane.foreground")); + jAux.setBackground((Color)UIManager.getDefaults().get("TextPane.background")); + jAux.setBorder(null); + m_ListDates[i] = jAux; + m_jDates.add(jAux); + } + + m_jDays = new JLabel[7]; + for(int iHead = 0; iHead < 7; iHead++) { + JLabel JAuxHeader = new JLabel(); + //JAuxHeader.setFont(new Font("Dialog", 1, 24)); + JAuxHeader.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + m_jDays[iHead] = JAuxHeader; + m_jWeekDays.add(JAuxHeader); + } + + DateFormat fmtWeekDay = new SimpleDateFormat("E"); + Calendar oCalRender = new GregorianCalendar(); + int iCol; + for (int j = 0; j < 7; j++) { + oCalRender.add(Calendar.DATE, 1); + iCol = oCalRender.get(Calendar.DAY_OF_WEEK) - oCalRender.getFirstDayOfWeek(); + if (iCol < 0) { + iCol += 7; + } + m_jDays[iCol].setText(fmtWeekDay.format(oCalRender.getTime())); + } + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + m_jMonth = new javax.swing.JPanel(); + m_jWeekDays = new javax.swing.JPanel(); + m_jDates = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + m_jLblMonth = new javax.swing.JLabel(); + jPanel3 = new javax.swing.JPanel(); + m_jActions = new javax.swing.JPanel(); + + setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N + setLayout(new java.awt.BorderLayout()); + + jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + jPanel1.setLayout(new java.awt.BorderLayout()); + + m_jMonth.setLayout(new java.awt.BorderLayout()); + + m_jWeekDays.setLayout(new java.awt.GridLayout(1, 7)); + m_jMonth.add(m_jWeekDays, java.awt.BorderLayout.NORTH); + + m_jDates.setBackground(javax.swing.UIManager.getDefaults().getColor("TextPane.background")); + m_jDates.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jDates.setLayout(new java.awt.GridLayout(6, 7)); + m_jMonth.add(m_jDates, java.awt.BorderLayout.CENTER); + + jPanel1.add(m_jMonth, java.awt.BorderLayout.CENTER); + + m_jLblMonth.setFont(new java.awt.Font("Dialog", 1, 14)); // NOI18N + jPanel2.add(m_jLblMonth); + + jPanel1.add(jPanel2, java.awt.BorderLayout.NORTH); + + add(jPanel1, java.awt.BorderLayout.CENTER); + + jPanel3.setLayout(new java.awt.BorderLayout()); + + m_jActions.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 5, 0, 5)); + m_jActions.setLayout(new java.awt.GridLayout(0, 1, 0, 5)); + jPanel3.add(m_jActions, java.awt.BorderLayout.NORTH); + + add(jPanel3, java.awt.BorderLayout.LINE_END); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel m_jActions; + private javax.swing.JPanel m_jDates; + private javax.swing.JLabel m_jLblMonth; + private javax.swing.JPanel m_jMonth; + private javax.swing.JPanel m_jWeekDays; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/beans/JClockPanel.form b/src/main/java/com/unicenta/beans/JClockPanel.form new file mode 100644 index 0000000..5c32496 --- /dev/null +++ b/src/main/java/com/unicenta/beans/JClockPanel.form @@ -0,0 +1,22 @@ + + +
+ + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/beans/JClockPanel.java b/src/main/java/com/unicenta/beans/JClockPanel.java new file mode 100644 index 0000000..8924fa4 --- /dev/null +++ b/src/main/java/com/unicenta/beans/JClockPanel.java @@ -0,0 +1,252 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.beans; + +import java.awt.Color; +import java.awt.GradientPaint; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Paint; +import java.awt.RenderingHints; +import java.awt.geom.AffineTransform; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +/** + * + * @author JG uniCenta + */ +public class JClockPanel extends javax.swing.JPanel { + + private static Calendar m_calendar = new GregorianCalendar(); // solo de ayuda... + + private Date m_date; + private boolean m_bSeconds; + private long m_lPeriod; + + /** Creates new form JClockPanel */ + public JClockPanel() { + this(true); + } + + /** + * + * @param bSeconds + */ + public JClockPanel(boolean bSeconds) { + + initComponents(); + + m_bSeconds = bSeconds; + m_date = null; + m_lPeriod = 0L; + } + + /** + * + * @param bValue + */ + public void setSecondsVisible(boolean bValue) { + m_bSeconds = bValue; + repaint(); + } + + /** + * + * @return + */ + public boolean isSecondsVisible() { + return m_bSeconds; + } + + /** + * + * @param period + */ + public void setPeriod(long period) { + if (period >= 0L) { + m_lPeriod = period; + repaint(); + } + } + + /** + * + * @return + */ + public long getPeriod() { + return m_lPeriod; + } + + /** + * + * @param dDate + */ + public void setTime(Date dDate){ + m_date = dDate; + repaint(); + } + + /** + * + * @return + */ + public Date getTime() { + return m_date; + } + + @Override + public void paintComponent(Graphics g) { + + super.paintComponent(g); + + int width = getWidth(); + int height = getHeight(); + + double dhour = 0.0; + double dminute = 0.0; + double dsecond = 0.0; + + // Calculo los atributos de la hora que voy a pintar + if (m_date != null) { + m_calendar.setTime(m_date); + dhour = (double) m_calendar.get(Calendar.HOUR_OF_DAY); + dminute = (double) m_calendar.get(Calendar.MINUTE); + dsecond = (double) m_calendar.get(Calendar.SECOND); + } + + Graphics2D g2 = (Graphics2D) g; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + // guardo los valores iniciales + Paint oldPainter = g2.getPaint(); + AffineTransform oldt = g2.getTransform(); + + // pinto el fondo +// g2.setPaint(new GradientPaint(0, 0, Color.WHITE, width, 0, Color.LIGHT_GRAY)); +// g2.fill(g2.getClip()); + + // Calculo el centro y el tamano del reloj + int icenterx = width / 2; + int icentery = height / 2; + int iradius = Math.min(icenterx, icentery); + + // Centro las coordenadas y ajusto la transformacion del tamano del reloj + g2.transform(AffineTransform.getTranslateInstance(icenterx, icentery)); + g2.transform(AffineTransform.getScaleInstance(iradius / 1100.0 , iradius / 1100.0)); + AffineTransform mytrans = g2.getTransform(); + + // Pinto la esfera del reloj; + g2.setPaint(this.isEnabled() + ? new GradientPaint(-1200, -1200, Color.BLUE, 1200, 1200, Color.CYAN) + : new GradientPaint(-1200, -1200, Color.GRAY, 1200, 1200, Color.LIGHT_GRAY)); + g2.fillOval(-1000, -1000, 2000, 2000); + g2.setPaint(this.isEnabled() + ? new GradientPaint(-1200, -1200, Color.CYAN, 1200, 1200, Color.BLUE) + : new GradientPaint(-1200, -1200, Color.LIGHT_GRAY, 1200, 1200, Color.GRAY)); + g2.fillOval(-900, -900, 1800, 1800); + g2.setColor(Color.BLACK); + g2.drawOval(-1000, -1000, 2000, 2000); + + // Pinto las marcas pequenas, los minutos + for (int i = 0; i < 60; i++) { + g2.setColor(Color.WHITE); + g2.fillRect(900, -5 , 50, 10); + g2.transform(AffineTransform.getRotateInstance(Math.PI / 30.0)); + } + + // Pinto las marcas grandes, las horas. + g2.setTransform(mytrans); + for (int i = 0; i < 12; i++) { + g2.setColor(Color.WHITE); + g2.fillRect(800, -15 , 150, 30); + // g2.setColor(Color.BLACK); + // g2.drawRect(800, -15 , 150, 30); + g2.transform(AffineTransform.getRotateInstance(Math.PI / 6.0)); + } + + if (m_date != null) { + // Aguja de las horas + g2.setTransform(mytrans); + g2.transform(AffineTransform.getRotateInstance((dhour + dminute / 60.0) * Math.PI / 6.0)); // Poner hora + + if (m_lPeriod > 0L) { // pintamos la marca del periodo... + // dibujo un arco con el periodo seleccionado... + int iArc = (int) (m_lPeriod / 120000L); + g2.setColor(new Color(255, 255, 255, 100)); + g2.fillArc(-1000, -1000, 2000, 2000, 90 - iArc, iArc); + g2.setColor(Color.DARK_GRAY); + g2.drawArc(-1000, -1000, 2000, 2000, 90 - iArc, iArc); + } else { + // la aguja de las horas + g2.setColor(Color.WHITE); + g2.fillPolygon(new int[]{0, -35, 0, 35}, new int[]{100, 0, -600, 0}, 4); + g2.setColor(Color.DARK_GRAY); + g2.drawPolygon(new int[]{0, -35, 0, 35}, new int[]{100, 0, -600, 0}, 4); + + // Aguja de los minutos + g2.setTransform(mytrans); + g2.transform(AffineTransform.getRotateInstance((dminute) * Math.PI / 30.0)); // Poner minutos + g2.setColor(Color.WHITE); + g2.fillPolygon(new int[]{0, -35, 0, 35}, new int[]{100, 0, -900, 0}, 4); + g2.setColor(Color.DARK_GRAY); + g2.drawPolygon(new int[]{0, -35, 0, 35}, new int[]{100, 0, -900, 0}, 4); + + // Aguja de los segundos + if (m_bSeconds) { + g2.setTransform(mytrans); + g2.transform(AffineTransform.getRotateInstance(dsecond * Math.PI / 30.0)); // Poner segundos + g2.setColor(Color.YELLOW); + g2.fillPolygon(new int[]{-15, 0, 15}, new int[]{200, -900, 200}, 3); + g2.setColor(Color.DARK_GRAY); + g2.drawPolygon(new int[]{-15, 0, 15}, new int[]{200, -900, 200}, 3); + + g2.setTransform(mytrans); + g2.setColor(Color.YELLOW); + g2.fillOval(-25, -25, 50, 50); + g2.setColor(Color.DARK_GRAY); + g2.drawOval(-25, -25, 50, 50); + } + } + } + + // Pinto el tornillo central + g2.setColor(Color.WHITE); + g2.fillOval(-10, -10, 20, 20); + g2.setColor(Color.BLACK); + g2.drawOval(-10, -10, 20, 20); + + // restauro los valores iniciales + g2.setTransform(oldt); + g2.setPaint(oldPainter); + } + + // //GEN-BEGIN:initComponents + private void initComponents() { + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/beans/JFlowPanel.java b/src/main/java/com/unicenta/beans/JFlowPanel.java new file mode 100644 index 0000000..c47a7f1 --- /dev/null +++ b/src/main/java/com/unicenta/beans/JFlowPanel.java @@ -0,0 +1,214 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.beans; + +import java.awt.Component; +import java.awt.ComponentOrientation; +import java.awt.Dimension; +import java.awt.Rectangle; +import javax.swing.JPanel; +import javax.swing.JViewport; +import javax.swing.Scrollable; +import javax.swing.SwingConstants; + +/** + * + * @author JG uniCenta + */ +public class JFlowPanel extends JPanel implements Scrollable { + + private int hgap = 5; + private int vgap = 5; + + /** + * + */ + public JFlowPanel() { + this(5, 5); + } + + /** + * + * @param hgap + * @param vgap + */ + public JFlowPanel(int hgap, int vgap) { + this.hgap = hgap; + this.vgap = vgap; + } + + /** + * + * @param iValue + */ + public void setHorizontalGap(int iValue) { + hgap = iValue; + } + + /** + * + * @return + */ + public int getHorizontalGap() { + return hgap; + } + + /** + * + * @param iValue + */ + public void setVerticalGap(int iValue) { + vgap = iValue; + } + + /** + * + * @param iValue + * @return + */ + public int getVerticalGap(int iValue) { + return vgap; + } + + private Dimension calculateFlowLayout(boolean bDoChilds) { + Dimension dim = new Dimension(0, hgap); + + int maxWidth; + if (getParent() != null && getParent() instanceof JViewport) { + JViewport viewport = (JViewport) getParent(); + maxWidth = viewport.getExtentSize().width; + } else if (getParent() != null){ + maxWidth = getParent().getWidth(); + } else { + maxWidth = getWidth(); + } + + synchronized (getTreeLock()) { + int compCount = getComponentCount(); + int maxRowWidth = 0; + int maxRowHeight = 0; + int x = 0; + + for (int i = 0 ; i < compCount ; i++) { + Component m = getComponent(i); + if (m.isVisible()) { + Dimension d = m.getPreferredSize(); + if (x == 0 || (x + hgap + d.width + hgap) <= maxWidth) { + // continuamos con esta linea + x += hgap; + if (bDoChilds) { + m.setBounds(getPosition(x, maxWidth - d.width), dim.height, d.width, d.height); + } + x += d.width; + if (d.height > maxRowHeight) { + maxRowHeight = d.height; + } + } else { + // nueva linea + dim.height += maxRowHeight + vgap; + if (bDoChilds) { + m.setBounds(getPosition(hgap, maxWidth - d.width), dim.height, d.width, d.height); + } + if (x > maxRowWidth) { + maxRowWidth = x; + } + x = hgap + d.width; + maxRowHeight = d.height; + } + } + } + + // calculamos la ultima linea. + dim.height += maxRowHeight + vgap; + if (x > maxRowWidth) { + maxRowWidth = x; + } + dim.width = maxRowWidth; + } + return dim; + } + + private int getPosition(int x, int width) { + if (getComponentOrientation() == ComponentOrientation.RIGHT_TO_LEFT) { + return width - x ; + } else { + return x; + } + } + + public Dimension getPreferredSize() { + return calculateFlowLayout(false); + } + public Dimension getMinimumSize() { + return calculateFlowLayout(false); + } + public Dimension getMaximumSize() { + return calculateFlowLayout(false); + } + public Dimension getPreferredScrollableViewportSize() { + return calculateFlowLayout(false); + } + + public void doLayout() { + calculateFlowLayout(true); + } + + public boolean getScrollableTracksViewportHeight() { + return (getParent().getHeight() > getPreferredSize().height); + } + + public boolean getScrollableTracksViewportWidth() { + return (getParent().getWidth() > getPreferredSize().width); + } + + public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { + if (getComponentCount() == 0) { + return orientation == SwingConstants.HORIZONTAL ? hgap : vgap; + } else { + return orientation == SwingConstants.HORIZONTAL + ? getComponent(0).getWidth() + hgap + : getComponent(0).getHeight() + vgap; + } + } + + public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { + if (getComponentCount() == 0) { + return orientation == SwingConstants.HORIZONTAL ? hgap : vgap; + } else { + if (orientation == SwingConstants.HORIZONTAL) { + int hunit = getComponent(0).getWidth() + hgap; + return (visibleRect.width / hunit) * hunit; + } else { + int vunit = getComponent(0).getHeight() + vgap; + return (visibleRect.width / vunit) * vunit; + } + } + } + + public void setEnabled(boolean value) { + synchronized (getTreeLock()) { + int compCount = getComponentCount(); + for (int i = 0 ; i < compCount ; i++) { + getComponent(i).setEnabled(value); + } + } + super.setEnabled(value); + } +} diff --git a/src/main/java/com/unicenta/beans/JGuestsPop.form b/src/main/java/com/unicenta/beans/JGuestsPop.form new file mode 100644 index 0000000..6aadfdc --- /dev/null +++ b/src/main/java/com/unicenta/beans/JGuestsPop.form @@ -0,0 +1,175 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/beans/JGuestsPop.java b/src/main/java/com/unicenta/beans/JGuestsPop.java new file mode 100644 index 0000000..5b4bfb0 --- /dev/null +++ b/src/main/java/com/unicenta/beans/JGuestsPop.java @@ -0,0 +1,226 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta - joint with Jacinto Rodriguez +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.beans; + +import com.unicenta.basic.BasicException; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.*; +import java.awt.*; + +/** + * Jun 2018 + * @author Jack Gerrard uniCenta + */ +@Slf4j +public class JGuestsPop extends javax.swing.JDialog { + + private static LocaleResources m_resources; + + private Integer m_value; + + /** Creates new form JDinerPop + * @param parent + * @param modal */ + public JGuestsPop(java.awt.Frame parent, boolean modal) { + super(parent, modal); + init(); + } + + /** Creates new form JDinerPop + * @param parent + * @param modal */ + public JGuestsPop(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + init(); + } + + private void init() { + + if (m_resources == null) { + m_resources = new LocaleResources(); + m_resources.addBundleName("beans_messages"); + } + + initComponents(); + getRootPane().setDefaultButton(jcmdOK); + + m_jnumber.addEditorKeys(m_jKeys); + m_jnumber.reset(); + m_jnumber.setValueInteger(1); + m_jnumber.activate(); +// m_jnumber.setVisible(false); + + m_jPanelTitle.setBorder(RoundedBorder.createGradientBorder()); + + m_value = null; + } + + private void setTitle(String title, String message, Icon icon) { + setTitle(title); + m_lblMessage.setText(message); + m_lblMessage.setIcon(icon); + } + + public static Integer showEditNumber(Component parent, String title) { + return showEditNumber(parent, title, null, null); + } + public static Integer showEditNumber(Component parent, String title, String message) { + return showEditNumber(parent, title, message, null); + } + public static Integer showEditNumber(Component parent, String title, String message, Icon icon) { + + Window window = SwingUtilities.windowForComponent(parent); + + JGuestsPop myMsg; + if (window instanceof Frame) { + myMsg = new JGuestsPop((Frame) window, true); + } else { + myMsg = new JGuestsPop((Dialog) window, true); + } + + myMsg.setTitle(title, message, icon); + myMsg.setVisible(true); + return myMsg.m_value; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel2 = new javax.swing.JPanel(); + jPanelGrid = new javax.swing.JPanel(); + jPanel3 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel4 = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + m_jnumber = new com.unicenta.editor.JEditorDoublePositive(); + jcmdOK = new javax.swing.JButton(); + m_jPanelTitle = new javax.swing.JPanel(); + m_lblMessage = new javax.swing.JLabel(); + + setResizable(false); + addWindowListener(new java.awt.event.WindowAdapter() { + public void windowClosing(java.awt.event.WindowEvent evt) { + formWindowClosing(evt); + } + }); + + jPanel2.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel2.setLayout(new java.awt.BorderLayout()); + + jPanel3.setLayout(new javax.swing.BoxLayout(jPanel3, javax.swing.BoxLayout.Y_AXIS)); + jPanel3.add(m_jKeys); + + jPanel4.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel4.setLayout(new java.awt.BorderLayout()); + + jPanel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + + m_jnumber.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jnumber.setPreferredSize(new java.awt.Dimension(130, 30)); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(m_jnumber, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(m_jnumber, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(20, Short.MAX_VALUE)) + ); + + jPanel4.add(jPanel1, java.awt.BorderLayout.LINE_START); + + jcmdOK.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jcmdOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdOK.setPreferredSize(new java.awt.Dimension(80, 45)); + jcmdOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdOKActionPerformed(evt); + } + }); + jPanel4.add(jcmdOK, java.awt.BorderLayout.CENTER); + + jPanel3.add(jPanel4); + + jPanelGrid.add(jPanel3); + + jPanel2.add(jPanelGrid, java.awt.BorderLayout.CENTER); + + getContentPane().add(jPanel2, java.awt.BorderLayout.CENTER); + + m_jPanelTitle.setLayout(new java.awt.BorderLayout()); + + m_lblMessage.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPanelTitle.add(m_lblMessage, java.awt.BorderLayout.CENTER); + + getContentPane().add(m_jPanelTitle, java.awt.BorderLayout.NORTH); + + setSize(new java.awt.Dimension(328, 409)); + setLocationRelativeTo(null); + }// //GEN-END:initComponents + + private void jcmdOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdOKActionPerformed + + try { + m_value = m_jnumber.getValueInteger(); + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + setVisible(false); + dispose(); + + }//GEN-LAST:event_jcmdOKActionPerformed + + private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing + + setVisible(false); + dispose(); + + }//GEN-LAST:event_formWindowClosing + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanelGrid; + private javax.swing.JButton jcmdOK; + private com.unicenta.editor.JEditorKeys m_jKeys; + private javax.swing.JPanel m_jPanelTitle; + private com.unicenta.editor.JEditorDoublePositive m_jnumber; + private javax.swing.JLabel m_lblMessage; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/beans/JNumberDialog.form b/src/main/java/com/unicenta/beans/JNumberDialog.form new file mode 100644 index 0000000..9169f94 --- /dev/null +++ b/src/main/java/com/unicenta/beans/JNumberDialog.form @@ -0,0 +1,241 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/beans/JNumberDialog.java b/src/main/java/com/unicenta/beans/JNumberDialog.java new file mode 100644 index 0000000..25246e0 --- /dev/null +++ b/src/main/java/com/unicenta/beans/JNumberDialog.java @@ -0,0 +1,300 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.beans; + +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.Window; +import javax.swing.Icon; +import javax.swing.SwingUtilities; + +/** + * + * @author adrian + */ +public class JNumberDialog extends javax.swing.JDialog { + + private static LocaleResources m_resources; + + private Double m_value; + + /** Creates new form JNumberDialog + * @param parent + * @param modal */ + public JNumberDialog(java.awt.Frame parent, boolean modal) { + super(parent, modal); + init(); + } + + /** Creates new form JNumberDialog + * @param parent + * @param modal */ + public JNumberDialog(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + init(); + } + + public JNumberDialog() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + private void init() { + + if (m_resources == null) { + m_resources = new LocaleResources(); + m_resources.addBundleName("beans_messages"); + } + + initComponents(); + getRootPane().setDefaultButton(jcmdOK); + + m_jnumber.addEditorKeys(m_jKeys); + m_jnumber.reset(); + m_jnumber.setDoubleValue(0.0); + m_jnumber.activate(); + + m_jPanelTitle.setBorder(RoundedBorder.createGradientBorder()); + + m_value = null; + } + + private void setTitle(String title, String message, Icon icon) { + setTitle(title); + m_lblMessage.setText(message); + m_lblMessage.setIcon(icon); + } + + /** + * + * @param parent + * @param title + * @return + */ + public static Double showEditNumber(Component parent, String title) { + return showEditNumber(parent, title, null, null); + } + + /** + * + * @param parent + * @param title + * @param message + * @return + */ + public static Double showEditNumber(Component parent, String title, String message) { + return showEditNumber(parent, title, message, null); + } + + /** + * + * @param parent + * @param title + * @param message + * @param icon + * @return + */ + public static Double showEditNumber(Component parent, String title, String message, Icon icon) { + + Window window = SwingUtilities.windowForComponent(parent); + + JNumberDialog myMsg; + if (window instanceof Frame) { + myMsg = new JNumberDialog((Frame) window, true); + } else { + myMsg = new JNumberDialog((Dialog) window, true); + } + + myMsg.setTitle(title, message, icon); + myMsg.setVisible(true); + return myMsg.m_value; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jcmdCancel = new javax.swing.JButton(); + jcmdOK = new javax.swing.JButton(); + jPanel2 = new javax.swing.JPanel(); + jPanelGrid = new javax.swing.JPanel(); + jPanel3 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel4 = new javax.swing.JPanel(); + m_jnumber = new com.unicenta.editor.JEditorDoublePositive(); + m_jPanelTitle = new javax.swing.JPanel(); + m_lblMessage = new javax.swing.JLabel(); + + setPreferredSize(new java.awt.Dimension(310, 410)); + setResizable(false); + addWindowListener(new java.awt.event.WindowAdapter() { + public void windowClosing(java.awt.event.WindowEvent evt) { + formWindowClosing(evt); + } + }); + + jPanel1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT)); + + jcmdCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + jcmdCancel.setText(m_resources.getString("button.cancel")); // NOI18N + jcmdCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdCancelActionPerformed(evt); + } + }); + jPanel1.add(jcmdCancel); + + jcmdOK.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jcmdOK.setText(m_resources.getString("button.ok")); // NOI18N + jcmdOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdOKActionPerformed(evt); + } + }); + jPanel1.add(jcmdOK); + + jPanel2.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel2.setLayout(new java.awt.BorderLayout()); + + jPanelGrid.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanelGrid.setPreferredSize(new java.awt.Dimension(300, 320)); + + jPanel3.setPreferredSize(new java.awt.Dimension(300, 350)); + jPanel3.setLayout(new javax.swing.BoxLayout(jPanel3, javax.swing.BoxLayout.Y_AXIS)); + + m_jKeys.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jKeys.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jKeysActionPerformed(evt); + } + }); + jPanel3.add(m_jKeys); + + jPanel4.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel4.setMinimumSize(new java.awt.Dimension(110, 30)); + jPanel4.setPreferredSize(new java.awt.Dimension(142, 30)); + jPanel4.setLayout(new java.awt.BorderLayout()); + + m_jnumber.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jnumber.setMinimumSize(new java.awt.Dimension(100, 20)); + m_jnumber.setPreferredSize(new java.awt.Dimension(132, 20)); + jPanel4.add(m_jnumber, java.awt.BorderLayout.PAGE_START); + + jPanel3.add(jPanel4); + + javax.swing.GroupLayout jPanelGridLayout = new javax.swing.GroupLayout(jPanelGrid); + jPanelGrid.setLayout(jPanelGridLayout); + jPanelGridLayout.setHorizontalGroup( + jPanelGridLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelGridLayout.createSequentialGroup() + .addGap(16, 16, 16) + .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + jPanelGridLayout.setVerticalGroup( + jPanelGridLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelGridLayout.createSequentialGroup() + .addGap(5, 5, 5) + .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, 331, Short.MAX_VALUE) + .addGap(0, 0, 0)) + ); + + jPanel2.add(jPanelGrid, java.awt.BorderLayout.CENTER); + + m_jPanelTitle.setLayout(new java.awt.BorderLayout()); + + m_lblMessage.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_lblMessage.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createMatteBorder(0, 0, 1, 0, java.awt.Color.darkGray), javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5))); + m_jPanelTitle.add(m_lblMessage, java.awt.BorderLayout.CENTER); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jPanelTitle, javax.swing.GroupLayout.PREFERRED_SIZE, 342, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, 342, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 342, javax.swing.GroupLayout.PREFERRED_SIZE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(m_jPanelTitle, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, 346, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + + setSize(new java.awt.Dimension(358, 479)); + setLocationRelativeTo(null); + }// //GEN-END:initComponents + + private void jcmdOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdOKActionPerformed + + + m_value = m_jnumber.getDoubleValue(); + setVisible(false); + dispose(); + + + }//GEN-LAST:event_jcmdOKActionPerformed + + private void jcmdCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdCancelActionPerformed + + setVisible(false); + dispose(); + + }//GEN-LAST:event_jcmdCancelActionPerformed + + private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing + + setVisible(false); + dispose(); + + }//GEN-LAST:event_formWindowClosing + + private void m_jKeysActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jKeysActionPerformed + + }//GEN-LAST:event_m_jKeysActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanelGrid; + private javax.swing.JButton jcmdCancel; + private javax.swing.JButton jcmdOK; + private com.unicenta.editor.JEditorKeys m_jKeys; + private javax.swing.JPanel m_jPanelTitle; + private com.unicenta.editor.JEditorDoublePositive m_jnumber; + private javax.swing.JLabel m_lblMessage; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/beans/JNumberEvent.java b/src/main/java/com/unicenta/beans/JNumberEvent.java new file mode 100644 index 0000000..12458a3 --- /dev/null +++ b/src/main/java/com/unicenta/beans/JNumberEvent.java @@ -0,0 +1,51 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.beans; + +import java.util.EventObject; + +/** + * + * @author adrianromero + * @version + */ +public class JNumberEvent extends EventObject { + + private char m_cKey; + + /** + * + * @param source + * @param cKey + */ + public JNumberEvent(Object source, char cKey) { + super(source); + m_cKey = cKey; + } + + /** + * + * @return + */ + public char getKey() { + return m_cKey; + } + +} diff --git a/src/main/java/com/unicenta/beans/JNumberEventListener.java b/src/main/java/com/unicenta/beans/JNumberEventListener.java new file mode 100644 index 0000000..268e064 --- /dev/null +++ b/src/main/java/com/unicenta/beans/JNumberEventListener.java @@ -0,0 +1,35 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.beans; + +import java.util.EventListener; +/** + * + * @author adrian romero + * @version + */ +public interface JNumberEventListener extends EventListener { + + /** + * + * @param e + */ + public void keyPerformed(JNumberEvent e); +} diff --git a/src/main/java/com/unicenta/beans/JNumberKeys.form b/src/main/java/com/unicenta/beans/JNumberKeys.form new file mode 100644 index 0000000..4259836 --- /dev/null +++ b/src/main/java/com/unicenta/beans/JNumberKeys.form @@ -0,0 +1,452 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/beans/JNumberKeys.java b/src/main/java/com/unicenta/beans/JNumberKeys.java new file mode 100644 index 0000000..83c5645 --- /dev/null +++ b/src/main/java/com/unicenta/beans/JNumberKeys.java @@ -0,0 +1,501 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.beans; + +import java.awt.ComponentOrientation; +import java.util.Enumeration; +import java.util.Vector; + +/** + * + * @author JG uniCenta + */ +public class JNumberKeys extends javax.swing.JPanel { + + private Vector m_Listeners = new Vector(); + + private boolean minusenabled = true; + private boolean equalsenabled = true; + + /** Creates new form JNumberKeys */ + public JNumberKeys() { + initComponents (); + + m_jKey0.addActionListener(new MyKeyNumberListener('0')); + m_jKey1.addActionListener(new MyKeyNumberListener('1')); + m_jKey2.addActionListener(new MyKeyNumberListener('2')); + m_jKey3.addActionListener(new MyKeyNumberListener('3')); + m_jKey4.addActionListener(new MyKeyNumberListener('4')); + m_jKey5.addActionListener(new MyKeyNumberListener('5')); + m_jKey6.addActionListener(new MyKeyNumberListener('6')); + m_jKey7.addActionListener(new MyKeyNumberListener('7')); + m_jKey8.addActionListener(new MyKeyNumberListener('8')); + m_jKey9.addActionListener(new MyKeyNumberListener('9')); + m_jKeyDot.addActionListener(new MyKeyNumberListener('.')); + m_jMultiply.addActionListener(new MyKeyNumberListener('*')); + m_jCE.addActionListener(new MyKeyNumberListener('\u007f')); + m_jPlus.addActionListener(new MyKeyNumberListener('+')); + m_jMinus.addActionListener(new MyKeyNumberListener('-')); + m_jEquals.addActionListener(new MyKeyNumberListener('=')); + } + + /** + * + * @param value + */ + public void setNumbersOnly(boolean value) { + m_jEquals.setVisible(value); + m_jMinus.setVisible(value); + m_jPlus.setVisible(value); + m_jMultiply.setVisible(value); + } + + @Override + public void setEnabled(boolean b) { + super.setEnabled(b); + + m_jKey0.setEnabled(b); + m_jKey1.setEnabled(b); + m_jKey2.setEnabled(b); + m_jKey3.setEnabled(b); + m_jKey4.setEnabled(b); + m_jKey5.setEnabled(b); + m_jKey6.setEnabled(b); + m_jKey7.setEnabled(b); + m_jKey8.setEnabled(b); + m_jKey9.setEnabled(b); + m_jKeyDot.setEnabled(b); + m_jMultiply.setEnabled(b); + m_jCE.setEnabled(b); + m_jPlus.setEnabled(b); + m_jMinus.setEnabled(minusenabled && b); + m_jEquals.setEnabled(equalsenabled && b); + } + + @Override + public void setComponentOrientation(ComponentOrientation o) { + // Nothing to change + } + + /** + * + * @param b + */ + public void setMinusEnabled(boolean b) { + minusenabled = b; + m_jMinus.setEnabled(minusenabled && isEnabled()); + } + + /** + * + * @return + */ + public boolean isMinusEnabled() { + return minusenabled; + } + + /** + * + * @param b + */ + public void setEqualsEnabled(boolean b) { + equalsenabled = b; + m_jEquals.setEnabled(equalsenabled && isEnabled()); + } + + /** + * + * @return + */ + public boolean isEqualsEnabled() { + return equalsenabled; + } + + /** + * + * @param enabled + */ + public void dotIs00(boolean enabled) { + if (enabled) { + m_jKeyDot.setIcon(new javax.swing.ImageIcon(getClass() + .getResource("/com/unicenta/images/btn00.png"))); + } + } + + /** + * + * @return + */ + public boolean isNumbersOnly() { + return m_jEquals.isVisible(); + } + + /** + * + * @param listener + */ + public void addJNumberEventListener(JNumberEventListener listener) { + m_Listeners.add(listener); + } + + /** + * + * @param listener + */ + public void removeJNumberEventListener(JNumberEventListener listener) { + m_Listeners.remove(listener); + } + + private class MyKeyNumberListener implements java.awt.event.ActionListener { + + private final char m_cCad; + + public MyKeyNumberListener(char cCad){ + m_cCad = cCad; + } + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + + JNumberEvent oEv = new JNumberEvent(JNumberKeys.this, m_cCad); + JNumberEventListener oListener; + + for (Enumeration e = m_Listeners.elements(); e.hasMoreElements();) { + oListener = (JNumberEventListener) e.nextElement(); + oListener.keyPerformed(oEv); + } + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the FormEditor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + m_jCE = new javax.swing.JButton(); + m_jMultiply = new javax.swing.JButton(); + m_jMinus = new javax.swing.JButton(); + m_jPlus = new javax.swing.JButton(); + m_jKey9 = new javax.swing.JButton(); + m_jKey8 = new javax.swing.JButton(); + m_jKey7 = new javax.swing.JButton(); + m_jKey4 = new javax.swing.JButton(); + m_jKey5 = new javax.swing.JButton(); + m_jKey6 = new javax.swing.JButton(); + m_jKey3 = new javax.swing.JButton(); + m_jKey2 = new javax.swing.JButton(); + m_jKey1 = new javax.swing.JButton(); + m_jKey0 = new javax.swing.JButton(); + m_jKeyDot = new javax.swing.JButton(); + m_jEquals = new javax.swing.JButton(); + + setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + setMinimumSize(new java.awt.Dimension(193, 200)); + setPreferredSize(new java.awt.Dimension(193, 200)); + setLayout(new java.awt.GridBagLayout()); + + m_jCE.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btnce.png"))); // NOI18N + m_jCE.setFocusPainted(false); + m_jCE.setFocusable(false); + m_jCE.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jCE.setMaximumSize(new java.awt.Dimension(66, 36)); + m_jCE.setMinimumSize(new java.awt.Dimension(66, 36)); + m_jCE.setPreferredSize(new java.awt.Dimension(66, 36)); + m_jCE.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0); + add(m_jCE, gridBagConstraints); + + m_jMultiply.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btnmult.png"))); // NOI18N + m_jMultiply.setFocusPainted(false); + m_jMultiply.setFocusable(false); + m_jMultiply.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jMultiply.setMaximumSize(new java.awt.Dimension(42, 36)); + m_jMultiply.setMinimumSize(new java.awt.Dimension(42, 36)); + m_jMultiply.setPreferredSize(new java.awt.Dimension(42, 36)); + m_jMultiply.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0); + add(m_jMultiply, gridBagConstraints); + + m_jMinus.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btnminus.png"))); // NOI18N + m_jMinus.setFocusPainted(false); + m_jMinus.setFocusable(false); + m_jMinus.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jMinus.setMaximumSize(new java.awt.Dimension(42, 36)); + m_jMinus.setMinimumSize(new java.awt.Dimension(42, 36)); + m_jMinus.setPreferredSize(new java.awt.Dimension(42, 36)); + m_jMinus.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 0); + add(m_jMinus, gridBagConstraints); + + m_jPlus.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btnplus.png"))); // NOI18N + m_jPlus.setFocusPainted(false); + m_jPlus.setFocusable(false); + m_jPlus.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jPlus.setPreferredSize(new java.awt.Dimension(42, 36)); + m_jPlus.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridheight = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + add(m_jPlus, gridBagConstraints); + + m_jKey9.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn9.png"))); // NOI18N + m_jKey9.setFocusPainted(false); + m_jKey9.setFocusable(false); + m_jKey9.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKey9.setMaximumSize(new java.awt.Dimension(42, 36)); + m_jKey9.setMinimumSize(new java.awt.Dimension(42, 36)); + m_jKey9.setPreferredSize(new java.awt.Dimension(42, 36)); + m_jKey9.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(m_jKey9, gridBagConstraints); + + m_jKey8.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn8.png"))); // NOI18N + m_jKey8.setFocusPainted(false); + m_jKey8.setFocusable(false); + m_jKey8.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKey8.setMaximumSize(new java.awt.Dimension(42, 36)); + m_jKey8.setMinimumSize(new java.awt.Dimension(42, 36)); + m_jKey8.setPreferredSize(new java.awt.Dimension(42, 36)); + m_jKey8.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(m_jKey8, gridBagConstraints); + + m_jKey7.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn7.png"))); // NOI18N + m_jKey7.setFocusPainted(false); + m_jKey7.setFocusable(false); + m_jKey7.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKey7.setMaximumSize(new java.awt.Dimension(42, 36)); + m_jKey7.setMinimumSize(new java.awt.Dimension(42, 36)); + m_jKey7.setPreferredSize(new java.awt.Dimension(42, 36)); + m_jKey7.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(m_jKey7, gridBagConstraints); + + m_jKey4.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn4.png"))); // NOI18N + m_jKey4.setFocusPainted(false); + m_jKey4.setFocusable(false); + m_jKey4.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKey4.setMaximumSize(new java.awt.Dimension(42, 36)); + m_jKey4.setMinimumSize(new java.awt.Dimension(42, 36)); + m_jKey4.setPreferredSize(new java.awt.Dimension(42, 36)); + m_jKey4.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(m_jKey4, gridBagConstraints); + + m_jKey5.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn5.png"))); // NOI18N + m_jKey5.setFocusPainted(false); + m_jKey5.setFocusable(false); + m_jKey5.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKey5.setMaximumSize(new java.awt.Dimension(42, 36)); + m_jKey5.setMinimumSize(new java.awt.Dimension(42, 36)); + m_jKey5.setPreferredSize(new java.awt.Dimension(42, 36)); + m_jKey5.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(m_jKey5, gridBagConstraints); + + m_jKey6.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn6.png"))); // NOI18N + m_jKey6.setFocusPainted(false); + m_jKey6.setFocusable(false); + m_jKey6.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKey6.setMaximumSize(new java.awt.Dimension(42, 36)); + m_jKey6.setMinimumSize(new java.awt.Dimension(42, 36)); + m_jKey6.setPreferredSize(new java.awt.Dimension(42, 36)); + m_jKey6.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(m_jKey6, gridBagConstraints); + + m_jKey3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn3.png"))); // NOI18N + m_jKey3.setFocusPainted(false); + m_jKey3.setFocusable(false); + m_jKey3.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKey3.setMaximumSize(new java.awt.Dimension(42, 36)); + m_jKey3.setMinimumSize(new java.awt.Dimension(42, 36)); + m_jKey3.setPreferredSize(new java.awt.Dimension(42, 36)); + m_jKey3.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(m_jKey3, gridBagConstraints); + + m_jKey2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn2.png"))); // NOI18N + m_jKey2.setFocusPainted(false); + m_jKey2.setFocusable(false); + m_jKey2.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKey2.setMaximumSize(new java.awt.Dimension(42, 36)); + m_jKey2.setMinimumSize(new java.awt.Dimension(42, 36)); + m_jKey2.setPreferredSize(new java.awt.Dimension(42, 36)); + m_jKey2.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(m_jKey2, gridBagConstraints); + + m_jKey1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn1.png"))); // NOI18N + m_jKey1.setFocusPainted(false); + m_jKey1.setFocusable(false); + m_jKey1.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKey1.setMaximumSize(new java.awt.Dimension(42, 36)); + m_jKey1.setMinimumSize(new java.awt.Dimension(42, 36)); + m_jKey1.setPreferredSize(new java.awt.Dimension(42, 36)); + m_jKey1.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(m_jKey1, gridBagConstraints); + + m_jKey0.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn0.png"))); // NOI18N + m_jKey0.setFocusPainted(false); + m_jKey0.setFocusable(false); + m_jKey0.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKey0.setMaximumSize(new java.awt.Dimension(42, 36)); + m_jKey0.setMinimumSize(new java.awt.Dimension(42, 36)); + m_jKey0.setPreferredSize(new java.awt.Dimension(42, 36)); + m_jKey0.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 4; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(5, 0, 0, 0); + add(m_jKey0, gridBagConstraints); + + m_jKeyDot.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btndot.png"))); // NOI18N + m_jKeyDot.setFocusPainted(false); + m_jKeyDot.setFocusable(false); + m_jKeyDot.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKeyDot.setMaximumSize(new java.awt.Dimension(42, 36)); + m_jKeyDot.setMinimumSize(new java.awt.Dimension(42, 36)); + m_jKeyDot.setPreferredSize(new java.awt.Dimension(42, 36)); + m_jKeyDot.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(5, 5, 0, 0); + add(m_jKeyDot, gridBagConstraints); + + m_jEquals.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btnequals.png"))); // NOI18N + m_jEquals.setFocusPainted(false); + m_jEquals.setFocusable(false); + m_jEquals.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jEquals.setPreferredSize(new java.awt.Dimension(42, 36)); + m_jEquals.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 3; + gridBagConstraints.gridheight = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + add(m_jEquals, gridBagConstraints); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton m_jCE; + private javax.swing.JButton m_jEquals; + private javax.swing.JButton m_jKey0; + private javax.swing.JButton m_jKey1; + private javax.swing.JButton m_jKey2; + private javax.swing.JButton m_jKey3; + private javax.swing.JButton m_jKey4; + private javax.swing.JButton m_jKey5; + private javax.swing.JButton m_jKey6; + private javax.swing.JButton m_jKey7; + private javax.swing.JButton m_jKey8; + private javax.swing.JButton m_jKey9; + private javax.swing.JButton m_jKeyDot; + private javax.swing.JButton m_jMinus; + private javax.swing.JButton m_jMultiply; + private javax.swing.JButton m_jPlus; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/beans/JNumberPop.form b/src/main/java/com/unicenta/beans/JNumberPop.form new file mode 100644 index 0000000..d8b98d9 --- /dev/null +++ b/src/main/java/com/unicenta/beans/JNumberPop.form @@ -0,0 +1,175 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/beans/JNumberPop.java b/src/main/java/com/unicenta/beans/JNumberPop.java new file mode 100644 index 0000000..c51224f --- /dev/null +++ b/src/main/java/com/unicenta/beans/JNumberPop.java @@ -0,0 +1,237 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta - joint with Jacinto Rodriguez +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.beans; + +import com.unicenta.basic.BasicException; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.*; +import java.awt.*; + +/** + * Dec 2017 + * @author Jack Gerarrd uniCenta + */ +@Slf4j +public class JNumberPop extends javax.swing.JDialog { + + private static LocaleResources m_resources; + + private Integer m_value; + + /** Creates new form JNumberDialog + * @param parent + * @param modal */ + public JNumberPop(java.awt.Frame parent, boolean modal) { + super(parent, modal); + init(); + } + + /** Creates new form JNumberDialog + * @param parent + * @param modal */ + public JNumberPop(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + init(); + } + + private void init() { + + if (m_resources == null) { + m_resources = new LocaleResources(); + m_resources.addBundleName("beans_messages"); + } + + initComponents(); + getRootPane().setDefaultButton(jcmdOK); + + m_jnumber.addEditorKeys(m_jKeys); + m_jnumber.reset(); + m_jnumber.setValueInteger(1); + m_jnumber.activate(); + m_jnumber.setVisible(false); + + m_jPanelTitle.setBorder(RoundedBorder.createGradientBorder()); + + m_value = null; + } + + private void setTitle(String title, String message, Icon icon) { + setTitle(title); + m_lblMessage.setText(message); + m_lblMessage.setIcon(icon); + } + + public static Integer showEditNumber(Component parent, String title) { + return showEditNumber(parent, title, null, null); + } + public static Integer showEditNumber(Component parent, String title, String message) { + return showEditNumber(parent, title, message, null); + } + public static Integer showEditNumber(Component parent, String title, String message, Icon icon) { + + Window window = SwingUtilities.windowForComponent(parent); + + JNumberPop myMsg; + if (window instanceof Frame) { + myMsg = new JNumberPop((Frame) window, true); + } else { + myMsg = new JNumberPop((Dialog) window, true); + } + + myMsg.setTitle(title, message, icon); + myMsg.setVisible(true); + return myMsg.m_value; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel2 = new javax.swing.JPanel(); + jPanelGrid = new javax.swing.JPanel(); + jPanel3 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel4 = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + m_jnumber = new com.unicenta.editor.JEditorDoublePositive(); + jcmdOK = new javax.swing.JButton(); + m_jPanelTitle = new javax.swing.JPanel(); + m_lblMessage = new javax.swing.JLabel(); + + setResizable(false); + addWindowListener(new java.awt.event.WindowAdapter() { + public void windowClosing(java.awt.event.WindowEvent evt) { + formWindowClosing(evt); + } + }); + + jPanel2.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel2.setLayout(new java.awt.BorderLayout()); + + jPanel3.setLayout(new javax.swing.BoxLayout(jPanel3, javax.swing.BoxLayout.Y_AXIS)); + + m_jKeys.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jKeysActionPerformed(evt); + } + }); + jPanel3.add(m_jKeys); + + jPanel4.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel4.setLayout(new java.awt.BorderLayout()); + + jPanel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + + m_jnumber.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(m_jnumber, javax.swing.GroupLayout.PREFERRED_SIZE, 115, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(95, 95, 95)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(m_jnumber, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(20, Short.MAX_VALUE)) + ); + + jPanel4.add(jPanel1, java.awt.BorderLayout.LINE_START); + + jcmdOK.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jcmdOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdOK.setPreferredSize(new java.awt.Dimension(80, 45)); + jcmdOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdOKActionPerformed(evt); + } + }); + jPanel4.add(jcmdOK, java.awt.BorderLayout.CENTER); + + jPanel3.add(jPanel4); + + jPanelGrid.add(jPanel3); + + jPanel2.add(jPanelGrid, java.awt.BorderLayout.CENTER); + + getContentPane().add(jPanel2, java.awt.BorderLayout.CENTER); + + m_jPanelTitle.setLayout(new java.awt.BorderLayout()); + + m_lblMessage.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPanelTitle.add(m_lblMessage, java.awt.BorderLayout.CENTER); + + getContentPane().add(m_jPanelTitle, java.awt.BorderLayout.NORTH); + + setSize(new java.awt.Dimension(328, 409)); + setLocationRelativeTo(null); + }// //GEN-END:initComponents + + private void jcmdOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdOKActionPerformed + + + try { + m_value = m_jnumber.getValueInteger(); + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + setVisible(false); + dispose(); + + + }//GEN-LAST:event_jcmdOKActionPerformed + + private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing + + setVisible(false); + dispose(); + + }//GEN-LAST:event_formWindowClosing + + private void m_jKeysActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jKeysActionPerformed + + }//GEN-LAST:event_m_jKeysActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanelGrid; + private javax.swing.JButton jcmdOK; + private com.unicenta.editor.JEditorKeys m_jKeys; + private javax.swing.JPanel m_jPanelTitle; + private com.unicenta.editor.JEditorDoublePositive m_jnumber; + private javax.swing.JLabel m_lblMessage; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/beans/JPasswordDialog.form b/src/main/java/com/unicenta/beans/JPasswordDialog.form new file mode 100644 index 0000000..6a3e437 --- /dev/null +++ b/src/main/java/com/unicenta/beans/JPasswordDialog.form @@ -0,0 +1,204 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/beans/JPasswordDialog.java b/src/main/java/com/unicenta/beans/JPasswordDialog.java new file mode 100644 index 0000000..4ca0d60 --- /dev/null +++ b/src/main/java/com/unicenta/beans/JPasswordDialog.java @@ -0,0 +1,266 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.beans; + +import java.awt.*; +import javax.swing.*; + +public class JPasswordDialog extends javax.swing.JDialog { + + private static LocaleResources m_resources; + + private String m_sPassword; + + /** Creates new form JPasswordDialog + * @param parent + * @param modal */ + public JPasswordDialog(java.awt.Frame parent, boolean modal) { + super(parent, modal); + init(); + } + /** Creates new form JPasswordDialog + * @param parent + * @param modal */ + public JPasswordDialog(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + init(); + } + + private void init() { + + if (m_resources == null) { + m_resources = new LocaleResources(); + m_resources.addBundleName("beans_messages"); + } + + initComponents(); + getRootPane().setDefaultButton(jcmdOK); + + m_jpassword.addEditorKeys(m_jKeys); + m_jpassword.reset(); + m_jpassword.activate(); + + m_jPanelTitle.setBorder(RoundedBorder.createGradientBorder()); + + m_sPassword = null; + } + + private void setTitle(String title, String message, Icon icon) { + setTitle(title); + m_lblMessage.setText(message); + m_lblMessage.setIcon(icon); + } + + private static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window) parent; + } else { + return getWindow(parent.getParent()); + } + } + + /** + * + * @param parent + * @param title + * @return + */ + public static String showEditPassword(Component parent, String title) { + return showEditPassword(parent, title, null, null); + } + + /** + * + * @param parent + * @param title + * @param message + * @return + */ + public static String showEditPassword(Component parent, String title, String message) { + return showEditPassword(parent, title, message, null); + } + + /** + * + * @param parent + * @param title + * @param message + * @param icon + * @return + */ + public static String showEditPassword(Component parent, String title, String message, Icon icon) { + + Window window = getWindow(parent); + + JPasswordDialog myMsg; + if (window instanceof Frame) { + myMsg = new JPasswordDialog((Frame) window, true); + } else { + myMsg = new JPasswordDialog((Dialog) window, true); + } + + myMsg.setTitle(title, message, icon); + myMsg.setVisible(true); + return myMsg.m_sPassword; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jcmdCancel = new javax.swing.JButton(); + jcmdOK = new javax.swing.JButton(); + jPanel2 = new javax.swing.JPanel(); + jPanelGrid = new javax.swing.JPanel(); + jPanel3 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel4 = new javax.swing.JPanel(); + m_jpassword = new com.unicenta.editor.JEditorPassword(); + m_jPanelTitle = new javax.swing.JPanel(); + m_lblMessage = new javax.swing.JLabel(); + + setPreferredSize(new java.awt.Dimension(320, 450)); + setResizable(false); + addWindowListener(new java.awt.event.WindowAdapter() { + public void windowClosing(java.awt.event.WindowEvent evt) { + closeWindow(evt); + } + }); + + jPanel1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT)); + + jcmdCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + jcmdCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdCancel.setPreferredSize(new java.awt.Dimension(80, 45)); + jcmdCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdCancelActionPerformed(evt); + } + }); + jPanel1.add(jcmdCancel); + + jcmdOK.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jcmdOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdOK.setPreferredSize(new java.awt.Dimension(80, 45)); + jcmdOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdOKActionPerformed(evt); + } + }); + jPanel1.add(jcmdOK); + + getContentPane().add(jPanel1, java.awt.BorderLayout.SOUTH); + + jPanel2.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel2.setPreferredSize(new java.awt.Dimension(320, 390)); + jPanel2.setLayout(new java.awt.BorderLayout()); + + jPanelGrid.setPreferredSize(new java.awt.Dimension(310, 380)); + + jPanel3.setPreferredSize(new java.awt.Dimension(300, 350)); + jPanel3.setLayout(new javax.swing.BoxLayout(jPanel3, javax.swing.BoxLayout.Y_AXIS)); + + m_jKeys.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jKeysActionPerformed(evt); + } + }); + jPanel3.add(m_jKeys); + + jPanel4.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel4.setPreferredSize(new java.awt.Dimension(120, 30)); + jPanel4.setLayout(new java.awt.BorderLayout()); + + m_jpassword.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jpassword.setPreferredSize(new java.awt.Dimension(110, 30)); + jPanel4.add(m_jpassword, java.awt.BorderLayout.CENTER); + + jPanel3.add(jPanel4); + + jPanelGrid.add(jPanel3); + + jPanel2.add(jPanelGrid, java.awt.BorderLayout.CENTER); + + getContentPane().add(jPanel2, java.awt.BorderLayout.CENTER); + + m_jPanelTitle.setLayout(new java.awt.BorderLayout()); + + m_lblMessage.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createMatteBorder(0, 0, 1, 0, java.awt.Color.darkGray), javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5))); + m_jPanelTitle.add(m_lblMessage, java.awt.BorderLayout.CENTER); + + getContentPane().add(m_jPanelTitle, java.awt.BorderLayout.NORTH); + + setSize(new java.awt.Dimension(308, 489)); + setLocationRelativeTo(null); + }// //GEN-END:initComponents + + private void jNumberKeys21KeyPerformed(com.unicenta.beans.JNumberEvent evt) {//GEN-FIRST:event_jNumberKeys21KeyPerformed + + }//GEN-LAST:event_jNumberKeys21KeyPerformed + + private void jcmdOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdOKActionPerformed + + m_sPassword = m_jpassword.getPassword(); + setVisible(false); + dispose(); + + }//GEN-LAST:event_jcmdOKActionPerformed + + private void jcmdCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdCancelActionPerformed + + setVisible(false); + dispose(); + + }//GEN-LAST:event_jcmdCancelActionPerformed + + private void closeWindow(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_closeWindow + + setVisible(false); + dispose(); + + }//GEN-LAST:event_closeWindow + + private void m_jKeysActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jKeysActionPerformed + }//GEN-LAST:event_m_jKeysActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanelGrid; + private javax.swing.JButton jcmdCancel; + private javax.swing.JButton jcmdOK; + private com.unicenta.editor.JEditorKeys m_jKeys; + private javax.swing.JPanel m_jPanelTitle; + private com.unicenta.editor.JEditorPassword m_jpassword; + private javax.swing.JLabel m_lblMessage; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/beans/JTimePanel.form b/src/main/java/com/unicenta/beans/JTimePanel.form new file mode 100644 index 0000000..8257d83 --- /dev/null +++ b/src/main/java/com/unicenta/beans/JTimePanel.form @@ -0,0 +1,92 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/beans/JTimePanel.java b/src/main/java/com/unicenta/beans/JTimePanel.java new file mode 100644 index 0000000..d03776c --- /dev/null +++ b/src/main/java/com/unicenta/beans/JTimePanel.java @@ -0,0 +1,387 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.beans; + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JButton; + +/** + * + * @author JG uniCenta + */ +public class JTimePanel extends javax.swing.JPanel { + + /** + * + */ + public final static int BUTTONS_ALL = 3; + + /** + * + */ + public final static int BUTTONS_HOUR = 1; + + /** + * + */ + public final static int BUTTONS_MINUTE = 2; + + private DateFormat fmtTime = DateFormat.getTimeInstance(DateFormat.SHORT); + + private JClockPanel m_jclock; + private Date m_dMinDate; + private Date m_dMaxDate; + + private JButtonDate m_jbtnplushour = null; + private JButtonDate m_jbtnminushour = null; + private JButtonDate m_jbtnplusfifteen = null; + private JButtonDate m_jbtnminusfifteen = null; + private JButtonDate m_jbtnplusminute = null; + private JButtonDate m_jbtnminusminute = null; + + /** Creates new form JTimePanel */ + public JTimePanel() { + this(null, BUTTONS_ALL); + } + + /** + * + * @param dDate + */ + public JTimePanel(Date dDate) { + this(dDate, BUTTONS_ALL); + } + + /** + * + * @param dDate + * @param iButtons + */ + public JTimePanel(Date dDate, int iButtons) { + super(); + + initComponents(); + + m_jclock = new JClockPanel(false); + jPanel2.add(m_jclock, BorderLayout.CENTER); + + + GregorianCalendar c; + DateFormat f = new SimpleDateFormat("H:mm"); + + ActionListener dateclick = new DateClick(); + + if ((iButtons & BUTTONS_HOUR) > 0) { + c = new GregorianCalendar(1900, 0, 0, 1, 0); + m_jbtnplushour = new JButtonDate(f.format(c.getTime()), new ImageIcon(getClass().getResource("/com/unicenta/images/2rightarrow.png")), dateclick); + m_jactions.add(m_jbtnplushour); + } + + if ((iButtons & BUTTONS_MINUTE) > 0) { + c = new GregorianCalendar(1900, 0, 0, 0, 15); + m_jbtnplusfifteen = new JButtonDate(f.format(c.getTime()), new ImageIcon(getClass().getResource("/com/unicenta/images/1rightarrow.png")), dateclick); + m_jactions.add(m_jbtnplusfifteen); + } + + if ((iButtons & BUTTONS_MINUTE) > 0) { + c = new GregorianCalendar(1900, 0, 0, 0, 1); + m_jbtnplusminute = new JButtonDate(f.format(c.getTime()), new ImageIcon(getClass().getResource("/com/unicenta/images/1rightarrow.png")), dateclick); + m_jactions.add(m_jbtnplusminute); + } +// c = new GregorianCalendar(1900, 0, 0, 0, 0); +// m_jbtnmidnight = new JButtonDate(f.format(c.getTime()), dateclick); +// m_jactions.add(m_jbtnmidnight); + + if ((iButtons & BUTTONS_MINUTE) > 0) { + c = new GregorianCalendar(1900, 0, 0, 0, 1); + m_jbtnminusminute = new JButtonDate(f.format(c.getTime()), new ImageIcon(getClass().getResource("/com/unicenta/images/1leftarrow.png")), dateclick); + m_jactions.add(m_jbtnminusminute); + } + + if ((iButtons & BUTTONS_MINUTE) > 0) { + c = new GregorianCalendar(1900, 0, 0, 0, 15); + m_jbtnminusfifteen = new JButtonDate(f.format(c.getTime()), new ImageIcon(getClass().getResource("/com/unicenta/images/1leftarrow.png")), dateclick); + m_jactions.add(m_jbtnminusfifteen); + } + + if ((iButtons & BUTTONS_HOUR) > 0) { + c = new GregorianCalendar(1900, 0, 0, 1, 0); + m_jbtnminushour = new JButtonDate(f.format(c.getTime()), new ImageIcon(getClass().getResource("/com/unicenta/images/2leftarrow.png")), dateclick); + m_jactions.add(m_jbtnminushour); + } + + m_dMinDate = null; + m_dMaxDate = null; + m_jclock.setTime(dDate); + renderTime(); + } + + /** + * + */ + public void setDateMidNight() { + setDate(new GregorianCalendar(1900, 0, 0, 0, 0).getTime()); + } + + /** + * + * @param dNewDate + */ + public void setDate(Date dNewDate) { + + Date dOldDate = m_jclock.getTime(); + if (((dNewDate == null && dOldDate != null) || (dNewDate != null && !dNewDate.equals(dOldDate))) + && checkDates(dNewDate)) { + m_jclock.setTime(dNewDate); + renderTime(); + firePropertyChange("Date", dOldDate, dNewDate); // decimos al mundo que ha cambiado la propiedad fecha + } + } + + private boolean checkDates(Date dDate) { + return dDate == null || (m_dMaxDate == null || m_dMaxDate.compareTo(dDate) > 0) && (m_dMinDate == null || m_dMinDate.compareTo(dDate) <= 0); + } + + /** + * + * @return + */ + public Date getDate() { + return m_jclock.getTime(); + } + + /** + * + * @param dMinDate + * @param dMaxDate + */ + public void setCheckDates(Date dMinDate, Date dMaxDate) { + + m_dMinDate = dMinDate; + m_dMaxDate = dMaxDate; + setDate(null); + renderTime(); // este quiza sobra. + } + + @Override + public void setEnabled(boolean bValue) { + + super.setEnabled(bValue); + renderTime(); + } + + /** + * + * @param period + */ + public void setPeriod(long period) { + m_jclock.setPeriod(period); + renderTime(); + } + + private void renderTime() { + + Date dDate = m_jclock.getTime(); + if (dDate == null) { + if (m_jbtnplushour != null) { + m_jbtnplushour.setEnabled(false); + } + if (m_jbtnminushour != null) { + m_jbtnminushour.setEnabled(false); + } + if (m_jbtnplusfifteen != null) { + m_jbtnplusfifteen.setEnabled(false); + } + if (m_jbtnminusfifteen != null) { + m_jbtnminusfifteen.setEnabled(false); + } + if (m_jbtnplusminute != null) { + m_jbtnplusminute.setEnabled(false); + } + if (m_jbtnminusminute != null) { + m_jbtnminusminute.setEnabled(false); + } + m_jlblTime.setText(" "); + m_jlblSeparator.setVisible(false); + m_jlblTime2.setVisible(false); + m_jtime.revalidate(); + } else { + GregorianCalendar oCalRender = new GregorianCalendar(); + oCalRender.setTime(dDate); + // int iDay = oCalRender.get(Calendar.DAY_OF_MONTH); + + oCalRender.add(Calendar.HOUR_OF_DAY, 1); + if (m_jbtnplushour != null) { + m_jbtnplushour.DateInf = oCalRender.getTime(); + m_jbtnplushour.setEnabled(isEnabled() && checkDates(oCalRender.getTime())); + } + oCalRender.add(Calendar.HOUR_OF_DAY, -2); + if (m_jbtnminushour != null) { + m_jbtnminushour.DateInf = oCalRender.getTime(); + m_jbtnminushour.setEnabled(isEnabled() && checkDates(oCalRender.getTime())); + } + + oCalRender.setTime(dDate); + + oCalRender.add(Calendar.MINUTE, 15); + if (m_jbtnplusfifteen != null) { + m_jbtnplusfifteen.DateInf = oCalRender.getTime(); + m_jbtnplusfifteen.setEnabled(isEnabled() && checkDates(oCalRender.getTime())); + } + oCalRender.add(Calendar.MINUTE, -30); + if (m_jbtnminusfifteen != null) { + m_jbtnminusfifteen.DateInf = oCalRender.getTime(); + m_jbtnminusfifteen.setEnabled(isEnabled() && checkDates(oCalRender.getTime())); + } + oCalRender.setTime(dDate); + + oCalRender.add(Calendar.MINUTE, 1); + if (m_jbtnplusminute != null) { + m_jbtnplusminute.DateInf = oCalRender.getTime(); + m_jbtnplusminute.setEnabled(isEnabled() && checkDates(oCalRender.getTime())); + } + oCalRender.add(Calendar.MINUTE, -2); + if (m_jbtnminusminute != null) { + m_jbtnminusminute.DateInf = oCalRender.getTime(); + m_jbtnminusminute.setEnabled(isEnabled() && checkDates(oCalRender.getTime())); + } + + if (m_jclock.getPeriod() > 0L) { + // damos el periodo + m_jlblTime.setText(fmtTime.format(dDate)); + m_jlblTime2.setText(fmtTime.format(new Date(dDate.getTime() + m_jclock.getPeriod()))); + m_jlblSeparator.setVisible(true); + m_jlblTime2.setVisible(true); + m_jtime.revalidate(); + } else { + // es una hora normal + m_jlblTime.setText(fmtTime.format(dDate)); + m_jlblSeparator.setVisible(false); + m_jlblTime2.setVisible(false); + m_jtime.revalidate(); + } + } + + m_jclock.setEnabled(isEnabled()); + } + + private class DateClick implements ActionListener { + + @Override + public void actionPerformed(ActionEvent e) { + JButtonDate oLbl = (JButtonDate)e.getSource(); + if(oLbl.DateInf != null) { + setDate(oLbl.DateInf); + } + } + } + + private static class JButtonDate extends JButton { + + public Date DateInf; + + public JButtonDate(ActionListener datehandler) { + super(); + initComponent(); + addActionListener(datehandler); + } + + public JButtonDate(String sText, ActionListener datehandler) { + super(sText); + initComponent(); + addActionListener(datehandler); + } + + public JButtonDate(String sText, Icon ico, ActionListener datehandler) { + super(sText, ico); + initComponent(); + addActionListener(datehandler); + } + + private void initComponent() { + DateInf = null; + setRequestFocusEnabled(false); + setFocusPainted(false); + setFocusable(false); + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + m_jactions = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + m_jtime = new javax.swing.JPanel(); + m_jlblTime = new javax.swing.JLabel(); + m_jlblSeparator = new javax.swing.JLabel(); + m_jlblTime2 = new javax.swing.JLabel(); + + setLayout(new java.awt.BorderLayout()); + + jPanel1.setLayout(new java.awt.BorderLayout()); + + m_jactions.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 5, 0, 5)); + m_jactions.setLayout(new java.awt.GridLayout(0, 1, 0, 5)); + jPanel1.add(m_jactions, java.awt.BorderLayout.NORTH); + + add(jPanel1, java.awt.BorderLayout.LINE_END); + + jPanel2.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + jPanel2.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel2.setLayout(new java.awt.BorderLayout()); + + m_jtime.add(m_jlblTime); + + m_jlblSeparator.setText(" - "); + m_jtime.add(m_jlblSeparator); + m_jtime.add(m_jlblTime2); + + jPanel2.add(m_jtime, java.awt.BorderLayout.NORTH); + + add(jPanel2, java.awt.BorderLayout.CENTER); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel m_jactions; + private javax.swing.JLabel m_jlblSeparator; + private javax.swing.JLabel m_jlblTime; + private javax.swing.JLabel m_jlblTime2; + private javax.swing.JPanel m_jtime; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/beans/LocaleResources.java b/src/main/java/com/unicenta/beans/LocaleResources.java new file mode 100644 index 0000000..71bb28d --- /dev/null +++ b/src/main/java/com/unicenta/beans/LocaleResources.java @@ -0,0 +1,127 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.beans; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.text.MessageFormat; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +/** + * + * @author adrian + */ +public class LocaleResources { + + private List m_resources; + private ClassLoader m_localeloader; + + /** Creates a new instance of LocaleResources */ + public LocaleResources() { +// m_resources = new LinkedList(); + m_resources = new LinkedList<>(); + + File fuserdir = new File(System.getProperty("user.dir")); + File fresources = new File(fuserdir, "locales"); + try { + m_localeloader = URLClassLoader.newInstance( + new URL[] { fresources.toURI().toURL() }, + Thread.currentThread().getContextClassLoader()); + } catch (MalformedURLException e) { + m_localeloader = Thread.currentThread().getContextClassLoader(); + } + } + + public ResourceBundle getBundle(String bundlename) { + return ResourceBundle.getBundle(bundlename, Locale.getDefault(), m_localeloader); + } + + /** + * + * @param bundlename + */ + + public void addBundleName(String bundlename) { +// m_resources.add(getBundle(bundlename)); + m_resources.add(ResourceBundle.getBundle(bundlename)); + } + + /** + * + * @param sKey + * @return + */ + public String getString(String sKey) { + + if (sKey == null) { + return null; + } else { + for (ResourceBundle r : m_resources) { + try { + return r.getString(sKey); + } catch (MissingResourceException e) { + // Next + } + } + + // MissingResourceException in all ResourceBundle + return "** " + sKey + " **"; + } + } + + /** + * + * @param sKey + * @param sValues + * @return + */ + public String getString(String sKey, Object ... sValues) { + + if (sKey == null) { + return null; + } else { + for (ResourceBundle r : m_resources) { + try { + return MessageFormat.format(r.getString(sKey), sValues); + } catch (MissingResourceException e) { + // Next + } + } + + // MissingResourceException in all ResourceBundle + StringBuilder sreturn = new StringBuilder(); + sreturn.append("** "); + sreturn.append(sKey); + for (Object value : sValues) { + sreturn.append(" < "); + sreturn.append(value.toString()); + } + sreturn.append("** "); + + return sreturn.toString(); + } + } +} diff --git a/src/main/java/com/unicenta/beans/RoundedBorder.java b/src/main/java/com/unicenta/beans/RoundedBorder.java new file mode 100644 index 0000000..92560b4 --- /dev/null +++ b/src/main/java/com/unicenta/beans/RoundedBorder.java @@ -0,0 +1,268 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.beans; + +import java.awt.*; +import javax.swing.border.AbstractBorder; +import javax.swing.border.Border; + +/** + * + * @author JG uniCenta + */ +public class RoundedBorder extends AbstractBorder { + + private static Border blackLine; + private static Border grayLine; + private static Border gradientBorder; + + /** + * + */ + protected Color colorBorder; + + /** + * + */ + protected Color colorgradient; + + /** + * + */ + protected int roundedRadius; + + /** + * + */ + protected float thickness; + + /** + * + */ + protected boolean filled; + + private float ftop; + private float fbottom; + private float ftopinset; + private float fbottominset; + + /** + * + * @return + */ + public static Border createBlackLineBorder() { + if (blackLine == null) { + blackLine = new RoundedBorder(Color.BLACK); + } + return blackLine; + } + + /** + * + * @return + */ + public static Border createGrayLineBorder() { + if (grayLine == null) { + grayLine = new RoundedBorder(Color.GRAY); + } + return grayLine; + } + + /** + * + * @return + */ + public static Border createGradientBorder() { + if (gradientBorder == null) { + gradientBorder = new RoundedBorder(Color.GRAY, 0f, 8, false, false); + } + return gradientBorder; + } + + /** + * + * @param colorBorder + */ + public RoundedBorder(Color colorBorder) { + this(colorBorder, Color.WHITE, 1f, 0, true, true); + } + + /** + * + * @param colorBorder + * @param thickness + */ + public RoundedBorder(Color colorBorder, float thickness) { + this(colorBorder, Color.WHITE, thickness, 0, true, true); + } + + /** + * + * @param colorBorder + * @param thickness + * @param roundedRadius + */ + public RoundedBorder(Color colorBorder, float thickness, int roundedRadius) { + this(colorBorder, Color.WHITE, thickness, roundedRadius, true, true); + } + + /** + * + * @param colorBorder + * @param thickness + * @param roundedRadius + * @param btopborder + * @param bbottomborder + */ + public RoundedBorder(Color colorBorder, float thickness, int roundedRadius, boolean btopborder, boolean bbottomborder) { + this(colorBorder, Color.WHITE, thickness, roundedRadius, btopborder, bbottomborder); + } + + /** + * + * @param colorBorder + * @param colorgradient + * @param thickness + * @param roundedRadius + * @param btopborder + * @param bbottomborder + */ + public RoundedBorder(Color colorBorder, Color colorgradient, float thickness, int roundedRadius, boolean btopborder, boolean bbottomborder) { + + this.colorBorder = colorBorder; + this.colorgradient = colorgradient; + this.thickness = thickness; + this.roundedRadius = roundedRadius; + this.filled = true; + + ftop = btopborder ? 0f : thickness + roundedRadius; + fbottom = bbottomborder ? 0f : thickness + roundedRadius; + ftopinset = btopborder ? 0f : thickness; // para los bordes a derecha e izquierda + fbottominset = bbottomborder ? 0f : thickness; // para los bordes a derecha e izquierda + } + + @Override + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + + Graphics2D g2d = (Graphics2D) g; + + Object oldAntialias = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + Stroke oldStroke = g2d.getStroke(); + Paint oldColor = g2d.getPaint(); + + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + float imedium = thickness; + + if (filled) { + if (c.getComponentOrientation() == ComponentOrientation.RIGHT_TO_LEFT) { + g2d.setPaint(new GradientPaint(0, 0, c.getBackground(), width, 0, colorgradient)); + } else { + g2d.setPaint(new GradientPaint(0, 0, colorgradient, width, 0, c.getBackground())); + } + g2d.fillRoundRect( + (int) (x + thickness), + (int) (y + thickness - ftop), + (int) (width - thickness - thickness), + (int) (height - thickness - thickness + ftop + fbottom), + (int) (roundedRadius * 2 - imedium), + (int) (roundedRadius * 2 - imedium)); + } + + if (thickness > 0f) { + g2d.setStroke(new BasicStroke(thickness)); + g2d.setPaint(colorBorder); + g2d.drawRoundRect( + (int) (x), + (int) (y - ftop), + (int) (width- thickness), + (int) (height - thickness + ftop + fbottom), + roundedRadius * 2, + roundedRadius * 2); + } + + g2d.setPaint(oldColor); + g2d.setStroke(oldStroke); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAntialias); + } + + @Override + public Insets getBorderInsets(Component c) { + +// // Los bordes estan arriba y abajo +// return new Insets( +// (int)(0.5 + thickness + roundedRadius - ftop), +// (int)(0.5 + thickness), +// (int)(0.5 + thickness + roundedRadius - fbottom), +// (int)(0.5 + thickness)); + + // Los bordes estan a derecha y a izquierda + return new Insets( + (int)(0.5 + thickness - ftopinset), + (int)(0.5 + thickness + roundedRadius), + (int)(0.5 + thickness - fbottominset), + (int)(0.5 + thickness + roundedRadius)); + } + + @Override + public Insets getBorderInsets(Component c, Insets insets) { + +// insets.top = (int)(0.5 + thickness + roundedRadius - ftop); +// insets.left =(int)(0.5 + thickness); +// insets.bottom = (int)(0.5 + thickness + roundedRadius - fbottom); +// insets.right = (int)(0.5 + thickness); + + insets.top = (int)(0.5 + thickness - ftopinset); + insets.left =(int)(0.5 + thickness + roundedRadius); + insets.bottom = (int)(0.5 + thickness - fbottominset); + insets.right = (int)(0.5 + thickness + roundedRadius); + + return insets; + } + + /** + * + * @return + */ + public Color getLineColor() { + return colorBorder; + } + + /** + * + * @return + */ + public float getThickness() { + return thickness; + } + + /** + * + * @return + */ + public boolean isFilled() { + return filled; + } + + @Override + public boolean isBorderOpaque() { + return true; + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/data/gui/ComboBoxValModel.java b/src/main/java/com/unicenta/data/gui/ComboBoxValModel.java new file mode 100644 index 0000000..c24a661 --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/ComboBoxValModel.java @@ -0,0 +1,184 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.gui; + +import com.unicenta.data.loader.IKeyGetter; +import com.unicenta.data.loader.KeyGetterBuilder; +import java.util.*; +import javax.swing.*; + +/** + * + * @author adrian + */ +public class ComboBoxValModel extends AbstractListModel implements ComboBoxModel { + + private List m_aData; + private IKeyGetter m_keygetter; + private Object m_selected; + + /** Creates a new instance of ComboBoxValModel + * @param aData + * @param keygetter */ + public ComboBoxValModel(List aData, IKeyGetter keygetter) { + m_aData = aData; + m_keygetter = keygetter; + m_selected = null; + } + + /** + * + * @param aData + */ + public ComboBoxValModel(List aData) { + this(aData, KeyGetterBuilder.INSTANCE); + } + + /** + * + * @param keygetter + */ + public ComboBoxValModel(IKeyGetter keygetter) { + this(new ArrayList(), keygetter); + } + + /** + * + */ + public ComboBoxValModel() { + this(new ArrayList(), KeyGetterBuilder.INSTANCE); + } + + /** + * + * @param c + */ + public void add(Object c) { + m_aData.add(c); + } + + /** + * + * @param c + */ + public void del(Object c) { + m_aData.remove(c); + } + + /** + * + * @param index + * @param c + */ + public void add(int index, Object c) { + m_aData.add(index, c); + } + + /** + * + * @param aData + */ + public void refresh(List aData) { + m_aData = aData; + m_selected = null; + } + + /** + * + * @return + */ + public Object getSelectedKey() { + if (m_selected == null) { + return null; + } else { + return m_keygetter.getKey(m_selected); // Si casca, excepcion parriba + } + } + + /** + * + * @return + */ + public String getSelectedText() { + if (m_selected == null) { + return null; + } else { + return m_selected.toString(); + } + } + + /** + * + * @param aKey + */ + public void setSelectedKey(Object aKey) { + setSelectedItem(getElementByKey(aKey)); + } + + /** + * + */ + public void setSelectedFirst() { + m_selected = (m_aData.isEmpty()) ? null : m_aData.get(0); + } + + /** + * + * @param aKey + * @return + */ + public Object getElementByKey(Object aKey) { + if (aKey != null) { + Iterator it = m_aData.iterator(); + while (it.hasNext()) { + Object value = it.next(); + if (aKey.equals(m_keygetter.getKey(value))) { + return value; + } + } + } + return null; + } + + @Override + public Object getElementAt(int index) { + return m_aData.get(index); + } + + @Override + public Object getSelectedItem() { + return m_selected; + } + + @Override + public int getSize() { + return m_aData.size(); + } + + @Override + public void setSelectedItem(Object anItem) { + + if ((m_selected != null && !m_selected.equals(anItem)) || m_selected == null && anItem != null) { + m_selected = anItem; + fireContentsChanged(this, -1, -1); + } + } + +} diff --git a/src/main/java/com/unicenta/data/gui/CompoundIcon.java b/src/main/java/com/unicenta/data/gui/CompoundIcon.java new file mode 100644 index 0000000..b69f1e6 --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/CompoundIcon.java @@ -0,0 +1,57 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.gui; + +import javax.swing.Icon; + +/** + * + * @author adrian + */ +public class CompoundIcon implements Icon { + + private Icon m_icon1; + private Icon m_icon2; + + /** Creates a new instance of CompoundIcon + * @param icon1 + * @param icon2 */ + public CompoundIcon(Icon icon1, Icon icon2) { + m_icon1 = icon1; + m_icon2 = icon2; + } + + @Override + public int getIconHeight() { + return Math.max(m_icon1.getIconHeight(), m_icon2.getIconHeight()); + } + + @Override + public int getIconWidth() { + return m_icon1.getIconWidth() + m_icon2.getIconWidth(); + } + + @Override + public void paintIcon(java.awt.Component c, java.awt.Graphics g, int x, int y) { + m_icon1.paintIcon(c, g, x, y); + m_icon2.paintIcon(c, g, x + m_icon1.getIconWidth(), y); + } + +} diff --git a/src/main/java/com/unicenta/data/gui/FindInfo.java b/src/main/java/com/unicenta/data/gui/FindInfo.java new file mode 100644 index 0000000..4d63f09 --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/FindInfo.java @@ -0,0 +1,149 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.gui; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.Vectorer; +import com.unicenta.data.user.Finder; +import java.util.regex.*; + +/** + * + * @author JG uniCenta + */ +public class FindInfo implements Finder { + + /** + * + */ + public static final int MATCH_STARTFIELD = 0; + public static final int MATCH_WHOLEFIELD = 1; + public static final int MATCH_ANYPARTFIELD = 2; + public static final int MATCH_REGEXP = 3; + + private String m_sTextCompare; + private Pattern m_TextPattern; + + private String m_sText; // Texto a buscar + private int m_iField; // Campo de busqueda + private int m_iMatch; // Tipo de busqueda + private boolean m_bMatchCase; // Mayusculas / Minusculas + + private Vectorer m_vec; + + /** Creates a new instance of FindInfo + * @param vec + * @param sText + * @param iField + * @param iMatch + * @param bMatchCase */ + public FindInfo(Vectorer vec, String sText, int iField, boolean bMatchCase, int iMatch) { + m_vec = vec; + m_sText = sText; + m_iField = iField; + m_bMatchCase = bMatchCase; + m_iMatch = iMatch; + + if (iMatch == MATCH_REGEXP) { + m_TextPattern = m_bMatchCase + ? Pattern.compile(m_sText) + : Pattern.compile(m_sText, Pattern.CASE_INSENSITIVE); + } else { + m_sTextCompare = m_bMatchCase + ? m_sText + : m_sText.toUpperCase(); + } + } + + /** Creates a new instance of FindInfo + * @param vec */ + public FindInfo(Vectorer vec) { + this(vec, "", 0, true, MATCH_ANYPARTFIELD); + } + + /** + * + * @return + */ + public Vectorer getVectorer() { + return m_vec; + } + + /** + * + * @return + */ + public String getText() { + return m_sText; + } + + /** + * + * @return + */ + public int getField() { + return m_iField; + } + + /** + * + * @return + */ + public boolean isMatchCase() { + return m_bMatchCase; + } + + /** + * + * @return + */ + public int getMatch() { + return m_iMatch; + } + + /** + * + * @param obj + * @return + * @throws BasicException + */ + public boolean match(Object obj) throws BasicException { + + String[] v = m_vec.getValues(obj); + + String sField = m_bMatchCase + ? v[m_iField] + : v[m_iField].toUpperCase(); + + switch (m_iMatch) { + case MATCH_STARTFIELD: + return sField.startsWith(m_sTextCompare); + case MATCH_WHOLEFIELD: + return sField.equals(m_sTextCompare); + case MATCH_ANYPARTFIELD: + return sField.contains(m_sTextCompare); + case MATCH_REGEXP: + return m_TextPattern.matcher(sField).matches(); + default: + return false; + } + } + +} diff --git a/src/main/java/com/unicenta/data/gui/JCounter.form b/src/main/java/com/unicenta/data/gui/JCounter.form new file mode 100644 index 0000000..e3aa037 --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JCounter.form @@ -0,0 +1,60 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/data/gui/JCounter.java b/src/main/java/com/unicenta/data/gui/JCounter.java new file mode 100644 index 0000000..06e25cf --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JCounter.java @@ -0,0 +1,104 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.gui; + +import javax.swing.*; +import com.unicenta.format.Formats; +import com.unicenta.data.user.BrowseListener; +import com.unicenta.data.user.BrowsableEditableData; +import com.unicenta.data.user.StateListener; + +/** + * + * @author adrianromero + */ +public class JCounter extends JPanel implements BrowseListener, StateListener { + + /** Creates new form JCounter + * @param bd */ + public JCounter(BrowsableEditableData bd) { + initComponents(); + bd.addBrowseListener(this); + bd.addStateListener(this); + } + + /** + * + * @param iState + */ + public void updateState(int iState) { + if (iState == BrowsableEditableData.ST_INSERT) { + // Insert + jlblIndex.setText("*"); + } + } + + /** + * + * @param iIndex + * @param iCounter + */ + public void updateIndex(int iIndex, int iCounter) { + + if (iIndex >= 0 && iIndex < iCounter) { + jlblIndex.setText(Formats.INT.formatValue(new Integer(iIndex + 1))); + } else { + jlblIndex.setText("-"); + } + jlblCounter.setText(Formats.INT.formatValue(new Integer(iCounter))); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jlblIndex = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + jlblCounter = new javax.swing.JLabel(); + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setMaximumSize(new java.awt.Dimension(80, 20)); + setMinimumSize(new java.awt.Dimension(80, 20)); + setPreferredSize(new java.awt.Dimension(80, 20)); + + jlblIndex.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jlblIndex.setText("XX"); + add(jlblIndex); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText("/"); + add(jLabel2); + + jlblCounter.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jlblCounter.setText("XX"); + add(jlblCounter); + }// //GEN-END:initComponents + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jlblCounter; + private javax.swing.JLabel jlblIndex; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/data/gui/JFind.form b/src/main/java/com/unicenta/data/gui/JFind.form new file mode 100644 index 0000000..ed48e25 --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JFind.form @@ -0,0 +1,232 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/data/gui/JFind.java b/src/main/java/com/unicenta/data/gui/JFind.java new file mode 100644 index 0000000..e10c4f6 --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JFind.java @@ -0,0 +1,269 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.gui; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.LocalRes; +import com.unicenta.data.loader.Vectorer; +import java.awt.*; +import javax.swing.*; + +/** + * + * @author JG uniCenta + */ +public class JFind extends JDialog { + + private FindInfo m_FindInfo; + private Vectorer m_vec; + + /** Creates new form JFind */ + private JFind(java.awt.Frame parent, boolean modal) { + super(parent, modal); + } + /** Creates new form JFind */ + private JFind(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + } + + private FindInfo init(FindInfo lastFindInfo) throws BasicException { + + initComponents(); + + getRootPane().setDefaultButton(jcmdOK); + + // El texto + m_jFind.setText(lastFindInfo.getText()); + // Pinto la caja + m_jWhere.removeAllItems(); + for (int i = 0; i < lastFindInfo.getVectorer().getHeaders().length; i++) { + m_jWhere.addItem(lastFindInfo.getVectorer().getHeaders()[i]); + } + m_jWhere.setSelectedIndex(lastFindInfo.getField()); + // El Match + m_jMatch.removeAllItems(); + m_jMatch.addItem(LocalRes.getIntString("list.startfield")); + m_jMatch.addItem(LocalRes.getIntString("list.wholefield")); + m_jMatch.addItem(LocalRes.getIntString("list.anypart")); + m_jMatch.addItem(LocalRes.getIntString("list.re")); + m_jMatch.setSelectedIndex(lastFindInfo.getMatch()); + // El case + m_jMatchCase.setSelected(lastFindInfo.isMatchCase()); + + m_vec = lastFindInfo.getVectorer(); + + m_FindInfo = null; + + //show(); + setVisible(true); + + return m_FindInfo; + } + + private static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window)parent; + } else { + return getWindow(parent.getParent()); + } + } + + /** + * + * @param parent + * @param lastFindInfo + * @return + * @throws BasicException + */ + public static FindInfo showMessage(Component parent, FindInfo lastFindInfo) throws BasicException { + + Window window = getWindow(parent); + + JFind myMsg; + if (window instanceof Frame) { + myMsg = new JFind((Frame) window, true); + } else { + myMsg = new JFind((Dialog) window, true); + } + return myMsg.init(lastFindInfo); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + m_jFind = new javax.swing.JTextField(); + jLabel2 = new javax.swing.JLabel(); + m_jWhere = new javax.swing.JComboBox(); + jLabel3 = new javax.swing.JLabel(); + m_jMatch = new javax.swing.JComboBox(); + m_jMatchCase = new javax.swing.JCheckBox(); + jPanel2 = new javax.swing.JPanel(); + jcmdCancel = new javax.swing.JButton(); + jcmdOK = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(LocalRes.getIntString("title.find")); // NOI18N + setResizable(false); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(LocalRes.getIntString("label.findwhat")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jFind.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jFind.setPreferredSize(new java.awt.Dimension(250, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(LocalRes.getIntString("label.where")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jWhere.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jWhere.setPreferredSize(new java.awt.Dimension(250, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(LocalRes.getIntString("label.match")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jMatch.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jMatch.setPreferredSize(new java.awt.Dimension(250, 30)); + + m_jMatchCase.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jMatchCase.setText(LocalRes.getIntString("label.casesensitive")); // NOI18N + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) + .addComponent(m_jFind, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) + .addComponent(m_jWhere, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jMatchCase, javax.swing.GroupLayout.PREFERRED_SIZE, 230, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jMatch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addContainerGap()) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jFind, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jWhere, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jMatch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jMatchCase) + .addContainerGap()) + ); + + getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER); + + jPanel2.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT)); + + jcmdCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + jcmdCancel.setText(LocalRes.getIntString("button.cancel")); // NOI18N + jcmdCancel.setPreferredSize(new java.awt.Dimension(110, 45)); + jcmdCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdCancelActionPerformed(evt); + } + }); + jPanel2.add(jcmdCancel); + + jcmdOK.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jcmdOK.setText(LocalRes.getIntString("button.OK")); // NOI18N + jcmdOK.setMaximumSize(new java.awt.Dimension(65, 33)); + jcmdOK.setMinimumSize(new java.awt.Dimension(65, 33)); + jcmdOK.setPreferredSize(new java.awt.Dimension(110, 45)); + jcmdOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdOKActionPerformed(evt); + } + }); + jPanel2.add(jcmdOK); + + getContentPane().add(jPanel2, java.awt.BorderLayout.SOUTH); + + setSize(new java.awt.Dimension(434, 251)); + setLocationRelativeTo(null); + }// //GEN-END:initComponents + + private void jcmdCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdCancelActionPerformed + + dispose(); + + }//GEN-LAST:event_jcmdCancelActionPerformed + + private void jcmdOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdOKActionPerformed + + m_FindInfo = new FindInfo(m_vec, + m_jFind.getText(), + m_jWhere.getSelectedIndex(), + m_jMatchCase.isSelected(), + m_jMatch.getSelectedIndex()); + + dispose(); + + }//GEN-LAST:event_jcmdOKActionPerformed + + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JButton jcmdCancel; + private javax.swing.JButton jcmdOK; + private javax.swing.JTextField m_jFind; + private javax.swing.JComboBox m_jMatch; + private javax.swing.JCheckBox m_jMatchCase; + private javax.swing.JComboBox m_jWhere; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/data/gui/JImageEditor.form b/src/main/java/com/unicenta/data/gui/JImageEditor.form new file mode 100644 index 0000000..d423fbf --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JImageEditor.form @@ -0,0 +1,184 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/data/gui/JImageEditor.java b/src/main/java/com/unicenta/data/gui/JImageEditor.java new file mode 100644 index 0000000..2bac7e7 --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JImageEditor.java @@ -0,0 +1,444 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.gui; + +import com.unicenta.data.loader.LocalRes; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import javax.imageio.ImageIO; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JFileChooser; +import javax.swing.JOptionPane; +import javax.swing.filechooser.FileFilter; + +/** + * + * @author JG uniCenta + */ +public class JImageEditor extends javax.swing.JPanel { + + private Dimension m_maxsize; + private ZoomIcon m_icon; + private BufferedImage m_Img = null; + + private static File m_fCurrentDirectory = null; + private static NumberFormat m_percentformat = new DecimalFormat("#,##0.##%"); + + /** Creates new form JImageEditor */ + public JImageEditor() { + initComponents(); + + m_Img = null; + m_maxsize = null; + m_icon = new ZoomIcon(); + m_jImage.setIcon(m_icon); + m_jPercent.setText(m_percentformat.format(m_icon.getZoom())); + privateSetEnabled(isEnabled()); + } + + /** + * + * @param size + */ + public void setMaxDimensions(Dimension size) { + m_maxsize = size; + } + + /** + * + * @return + */ + public Dimension getMaxDimensions() { + return m_maxsize; + } + + @Override + public void setEnabled(boolean value) { + + privateSetEnabled(value); + super.setEnabled(value); + } + + private void privateSetEnabled(boolean value) { + m_jbtnopen.setEnabled(value); + m_jbtnclose.setEnabled(value && (m_Img != null)); + m_jbtnzoomin.setEnabled(value && (m_Img != null)); + m_jbtnzoomout.setEnabled(value && (m_Img != null)); + m_jPercent.setEnabled(value && (m_Img != null)); + m_jScr.setEnabled(value && (m_Img != null)); + } + + /** + * + * @param img + */ + public void setImage(BufferedImage img) { + BufferedImage oldimg = m_Img; + m_Img = img; + m_icon.setIcon(m_Img == null ? null : new ImageIcon(m_Img)); + + m_jPercent.setText(m_percentformat.format(m_icon.getZoom())); + + m_jImage.revalidate(); + m_jScr.revalidate(); + m_jScr.repaint(); + + privateSetEnabled(isEnabled()); + + firePropertyChange("image", oldimg, m_Img); + } + + /** + * + * @return + */ + public BufferedImage getImage() { + return m_Img; + } + + /** + * + * @return + */ + public double getZoom() { + return m_icon.getZoom(); + } + + /** + * + * @param zoom + */ + public void setZoom(double zoom) { + double oldzoom = m_icon.getZoom(); + m_icon.setZoom(zoom); + + m_jPercent.setText(m_percentformat.format(m_icon.getZoom())); + + m_jImage.revalidate(); + m_jScr.revalidate(); + m_jScr.repaint(); + + firePropertyChange("zoom", oldzoom, zoom); + } + + /** + * + */ + public void incZoom() { + double zoom = m_icon.getZoom(); + setZoom(zoom > 4.0 ? 8.0 : zoom * 2.0); + } + + /** + * + */ + public void decZoom() { + double zoom = m_icon.getZoom(); + setZoom(zoom < 0.5 ? 0.25 : zoom / 2.0); + } + + /** + * + */ + public void doLoad() { + JFileChooser fc = new JFileChooser(m_fCurrentDirectory); + + fc.addChoosableFileFilter(new ExtensionsFilter(LocalRes.getIntString("label.imagefiles"), "png", "gif", "jpg", "jpeg", "bmp")); + + if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { + try { + BufferedImage img = ImageIO.read(fc.getSelectedFile()); + if (img != null) { + // compruebo que no exceda el tamano maximo. + if (m_maxsize != null && (img.getHeight() > m_maxsize.height || img.getWidth() > m_maxsize.width)) { + if (JOptionPane.showConfirmDialog(this, + LocalRes.getIntString("message.resizeimage"), + LocalRes.getIntString("title.editor"), + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { + // Redimensionamos la imagen para que se ajuste + img = resizeImage(img); + } + } + setImage(img); + m_fCurrentDirectory = fc.getCurrentDirectory(); + } + } catch (IOException eIO) { + } + } + } + + private BufferedImage resizeImage(BufferedImage img) { + + int myheight = img.getHeight(); + int mywidth = img.getWidth(); + + if (myheight > m_maxsize.height) { + mywidth = (int) (mywidth * m_maxsize.height / myheight); + myheight = m_maxsize.height; + } + if (mywidth > m_maxsize.width) { + myheight = (int) (myheight * m_maxsize.width / mywidth); + mywidth = m_maxsize.width; + } + + BufferedImage thumb = new BufferedImage(mywidth, myheight, BufferedImage.TYPE_4BYTE_ABGR); + + double scalex = (double) mywidth / (double) img.getWidth(null); + double scaley = (double) myheight / (double) img.getHeight(null); + + Graphics2D g2d = thumb.createGraphics(); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + //g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); + g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + + g2d.setColor(new Color(0, 0, 0, 0)); // Transparent + + g2d.fillRect(0, 0, mywidth, myheight); + if (scalex < scaley) { + g2d.drawImage(img, 0,(int) ((myheight - img.getHeight(null) * scalex) / 2.0) + , mywidth, (int) (img.getHeight(null) * scalex), null); + } else { + g2d.drawImage(img, (int) ((mywidth - img.getWidth(null) * scaley) / 2.0), 0 + , (int) (img.getWidth(null) * scaley), myheight, null); + } + g2d.dispose(); + + return thumb; + } + + private static class ZoomIcon implements Icon { + + private Icon ico; + private double zoom; + + public ZoomIcon() { + this.ico = null; + this.zoom = 1.0; + } + @Override + public int getIconHeight() { + return ico == null ? 0 : (int) (zoom * ico.getIconHeight()); + } + @Override + public int getIconWidth() { + return ico == null ? 0 : (int) (zoom * ico.getIconWidth()); + } + @Override + public void paintIcon(Component c, Graphics g, int x, int y) { + if (ico != null) { + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + AffineTransform oldt = g2d.getTransform(); + g2d.transform(AffineTransform.getScaleInstance(zoom, zoom)); + ico.paintIcon(c, g2d, (int) (x / zoom), (int) (y / zoom)); + g2d.setTransform(oldt); + } + } + public void setIcon(Icon ico) { + this.ico = ico; + this.zoom = 1.0; + } + public void setZoom(double zoom) { + this.zoom = zoom; + } + public double getZoom() { + return zoom; + } + } + private static class ExtensionsFilter extends FileFilter { + + private String message; + private String[] extensions; + + public ExtensionsFilter(String message, String... extensions) { + this.message = message; + this.extensions = extensions; + } + + @Override + public boolean accept(java.io.File f) { + if (f.isDirectory()) { + return true; + } else { + String sFileName = f.getName(); + int ipos = sFileName.lastIndexOf('.'); + if (ipos >= 0) { + String sExt = sFileName.substring(ipos + 1); + for(String s : extensions) { + if (s.equalsIgnoreCase(sExt)) { + return true; + } + } + } + return false; + } + } + + @Override + public String getDescription() { + return message; + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + m_jScr = new javax.swing.JScrollPane(); + m_jImage = new javax.swing.JLabel(); + jPanel1 = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + m_jbtnopen = new javax.swing.JButton(); + m_jbtnclose = new javax.swing.JButton(); + m_jbtnzoomin = new javax.swing.JButton(); + m_jPercent = new javax.swing.JLabel(); + m_jbtnzoomout = new javax.swing.JButton(); + + setBackground(new java.awt.Color(255, 255, 255)); + setOpaque(false); + setLayout(new java.awt.BorderLayout()); + + m_jScr.setBackground(new java.awt.Color(255, 255, 255)); + m_jScr.setOpaque(false); + + m_jImage.setBackground(new java.awt.Color(255, 255, 255)); + m_jImage.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + m_jImage.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/no_photo.png"))); // NOI18N + m_jImage.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + m_jScr.setViewportView(m_jImage); + + add(m_jScr, java.awt.BorderLayout.CENTER); + + jPanel1.setBackground(new java.awt.Color(255, 255, 255)); + jPanel1.setOpaque(false); + jPanel1.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout()); + + jPanel2.setBackground(new java.awt.Color(255, 255, 255)); + jPanel2.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 5, 0, 5)); + jPanel2.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel2.setOpaque(false); + jPanel2.setLayout(new java.awt.GridLayout(0, 1, 0, 2)); + + m_jbtnopen.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/camera.png"))); // NOI18N + m_jbtnopen.setToolTipText("Open Folder"); + m_jbtnopen.setPreferredSize(new java.awt.Dimension(50, 45)); + m_jbtnopen.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtnopenActionPerformed(evt); + } + }); + jPanel2.add(m_jbtnopen); + + m_jbtnclose.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/fileclose.png"))); // NOI18N + m_jbtnclose.setToolTipText("Remove Picture"); + m_jbtnclose.setPreferredSize(new java.awt.Dimension(50, 45)); + m_jbtnclose.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtncloseActionPerformed(evt); + } + }); + jPanel2.add(m_jbtnclose); + + m_jbtnzoomin.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/viewmag+.png"))); // NOI18N + m_jbtnzoomin.setToolTipText("Zoom In"); + m_jbtnzoomin.setPreferredSize(new java.awt.Dimension(50, 45)); + m_jbtnzoomin.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtnzoominActionPerformed(evt); + } + }); + jPanel2.add(m_jbtnzoomin); + + m_jPercent.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jPercent.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jPercent.setOpaque(true); + m_jPercent.setPreferredSize(new java.awt.Dimension(10, 30)); + jPanel2.add(m_jPercent); + + m_jbtnzoomout.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/viewmag-.png"))); // NOI18N + m_jbtnzoomout.setToolTipText("Zoom Out"); + m_jbtnzoomout.setPreferredSize(new java.awt.Dimension(50, 45)); + m_jbtnzoomout.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtnzoomoutActionPerformed(evt); + } + }); + jPanel2.add(m_jbtnzoomout); + + jPanel1.add(jPanel2, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, -1, -1)); + + add(jPanel1, java.awt.BorderLayout.LINE_END); + }// //GEN-END:initComponents + + private void m_jbtnzoomoutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtnzoomoutActionPerformed + + decZoom(); + + }//GEN-LAST:event_m_jbtnzoomoutActionPerformed + + private void m_jbtnzoominActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtnzoominActionPerformed + + incZoom(); + + }//GEN-LAST:event_m_jbtnzoominActionPerformed + + private void m_jbtncloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtncloseActionPerformed + + setImage(null); + + }//GEN-LAST:event_m_jbtncloseActionPerformed + + private void m_jbtnopenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtnopenActionPerformed + + doLoad(); + + }//GEN-LAST:event_m_jbtnopenActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JLabel m_jImage; + private javax.swing.JLabel m_jPercent; + private javax.swing.JScrollPane m_jScr; + private javax.swing.JButton m_jbtnclose; + private javax.swing.JButton m_jbtnopen; + private javax.swing.JButton m_jbtnzoomin; + private javax.swing.JButton m_jbtnzoomout; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/data/gui/JImageViewerCustomer.form b/src/main/java/com/unicenta/data/gui/JImageViewerCustomer.form new file mode 100644 index 0000000..c5e4fcd --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JImageViewerCustomer.form @@ -0,0 +1,131 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/data/gui/JImageViewerCustomer.java b/src/main/java/com/unicenta/data/gui/JImageViewerCustomer.java new file mode 100644 index 0000000..77a17f7 --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JImageViewerCustomer.java @@ -0,0 +1,395 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.gui; + +import com.unicenta.data.loader.LocalRes; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import javax.imageio.ImageIO; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JFileChooser; +import javax.swing.JOptionPane; +import javax.swing.filechooser.FileFilter; + +/** + * + * @author JG uniCenta + */ +public class JImageViewerCustomer extends javax.swing.JPanel { + + private Dimension m_maxsize; + private final ZoomIcon m_icon; + private BufferedImage m_Img = null; + + private static File m_fCurrentDirectory = null; + private static final NumberFormat m_percentformat = new DecimalFormat("#,##0.##%"); + + public JImageViewerCustomer() { + initComponents(); + + m_Img = null; + m_maxsize = null; + m_icon = new ZoomIcon(); + m_jImage.setIcon(m_icon); + m_jPercent.setText(m_percentformat.format(m_icon.getZoom())); + privateSetEnabled(isEnabled()); + } + + /** + * + * @param size + */ + public void setMaxDimensions(Dimension size) { + m_maxsize = size; + } + + /** + * + * @return + */ + public Dimension getMaxDimensions() { + return m_maxsize; + } + + @Override + public void setEnabled(boolean value) { + + privateSetEnabled(value); + super.setEnabled(value); + } + + private void privateSetEnabled(boolean value) { + m_jbtnzoomin.setEnabled(value && (m_Img != null)); + m_jbtnzoomout.setEnabled(value && (m_Img != null)); + m_jPercent.setEnabled(value && (m_Img != null)); + m_jScr.setEnabled(value && (m_Img != null)); + } + + /** + * + * @param img + */ + public void setImage(BufferedImage img) { + BufferedImage oldimg = m_Img; + m_Img = img; + m_icon.setIcon(m_Img == null ? null : new ImageIcon(m_Img)); + + m_jPercent.setText(m_percentformat.format(m_icon.getZoom())); + + m_jImage.revalidate(); + m_jScr.revalidate(); + m_jScr.repaint(); + + privateSetEnabled(isEnabled()); + + firePropertyChange("image", oldimg, m_Img); + } + + /** + * + * @return + */ + public BufferedImage getImage() { + return m_Img; + } + + /** + * + * @return + */ + public double getZoom() { + return m_icon.getZoom(); + } + + /** + * + * @param zoom + */ + public void setZoom(double zoom) { + double oldzoom = m_icon.getZoom(); + m_icon.setZoom(zoom); + + m_jPercent.setText(m_percentformat.format(m_icon.getZoom())); + + m_jImage.revalidate(); + m_jScr.revalidate(); + m_jScr.repaint(); + + firePropertyChange("zoom", oldzoom, zoom); + } + + /** + * + */ + public void incZoom() { + double zoom = m_icon.getZoom(); + setZoom(zoom > 4.0 ? 8.0 : zoom * 2.0); + } + + /** + * + */ + public void decZoom() { + double zoom = m_icon.getZoom(); + setZoom(zoom < 0.5 ? 0.25 : zoom / 2.0); + } + + /** + * + */ + public void doLoad() { + JFileChooser fc = new JFileChooser(m_fCurrentDirectory); + + fc.addChoosableFileFilter(new ExtensionsFilter( + LocalRes.getIntString("label.imagefiles"), "png", "gif", "jpg", "jpeg", "bmp")); + + if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { + try { + BufferedImage img = ImageIO.read(fc.getSelectedFile()); + if (img != null) { + // compruebo que no exceda el tamano maximo. + if (m_maxsize != null && (img.getHeight() > m_maxsize.height || img.getWidth() > m_maxsize.width)) { + if (JOptionPane.showConfirmDialog(this, + LocalRes.getIntString("message.resizeimage"), + LocalRes.getIntString("title.editor"), + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { + // Redimensionamos la imagen para que se ajuste + img = resizeImage(img); + } + } + setImage(img); + m_fCurrentDirectory = fc.getCurrentDirectory(); + } + } catch (IOException eIO) { + } + } + } + + private BufferedImage resizeImage(BufferedImage img) { + + int myheight = img.getHeight(); + int mywidth = img.getWidth(); + + if (myheight > m_maxsize.height) { + mywidth = (int) (mywidth * m_maxsize.height / myheight); + myheight = m_maxsize.height; + } + if (mywidth > m_maxsize.width) { + myheight = (int) (myheight * m_maxsize.width / mywidth); + mywidth = m_maxsize.width; + } + + BufferedImage thumb = new BufferedImage(mywidth, myheight, BufferedImage.TYPE_4BYTE_ABGR); + + double scalex = (double) mywidth / (double) img.getWidth(null); + double scaley = (double) myheight / (double) img.getHeight(null); + + Graphics2D g2d = thumb.createGraphics(); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + + g2d.setColor(new Color(0, 0, 0, 0)); + + g2d.fillRect(0, 0, mywidth, myheight); + if (scalex < scaley) { + g2d.drawImage(img, 0,(int) ((myheight - img.getHeight(null) * scalex) / 2.0) + , mywidth, (int) (img.getHeight(null) * scalex), null); + } else { + g2d.drawImage(img, (int) ((mywidth - img.getWidth(null) * scaley) / 2.0), 0 + , (int) (img.getWidth(null) * scaley), myheight, null); + } + g2d.dispose(); + + return thumb; + } + + private static class ZoomIcon implements Icon { + + private Icon ico; + private double zoom; + + public ZoomIcon() { + this.ico = null; + this.zoom = 1.0; + } + @Override + public int getIconHeight() { + return ico == null ? 0 : (int) (zoom * ico.getIconHeight()); + } + @Override + public int getIconWidth() { + return ico == null ? 0 : (int) (zoom * ico.getIconWidth()); + } + @Override + public void paintIcon(Component c, Graphics g, int x, int y) { + if (ico != null) { + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + AffineTransform oldt = g2d.getTransform(); + g2d.transform(AffineTransform.getScaleInstance(zoom, zoom)); + ico.paintIcon(c, g2d, (int) (x / zoom), (int) (y / zoom)); + g2d.setTransform(oldt); + } + } + public void setIcon(Icon ico) { + this.ico = ico; + this.zoom = 1.0; + } + public void setZoom(double zoom) { + this.zoom = zoom; + } + public double getZoom() { + return zoom; + } + } + private static class ExtensionsFilter extends FileFilter { + + private final String message; + private final String[] extensions; + + public ExtensionsFilter(String message, String... extensions) { + this.message = message; + this.extensions = extensions; + } + + @Override + public boolean accept(java.io.File f) { + if (f.isDirectory()) { + return true; + } else { + String sFileName = f.getName(); + int ipos = sFileName.lastIndexOf('.'); + if (ipos >= 0) { + String sExt = sFileName.substring(ipos + 1); + for(String s : extensions) { + if (s.equalsIgnoreCase(sExt)) { + return true; + } + } + } + return false; + } + } + + @Override + public String getDescription() { + return message; + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + m_jScr = new javax.swing.JScrollPane(); + m_jImage = new javax.swing.JLabel(); + jPanel1 = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + m_jbtnzoomin = new javax.swing.JButton(); + m_jPercent = new javax.swing.JLabel(); + m_jbtnzoomout = new javax.swing.JButton(); + + setLayout(new java.awt.BorderLayout()); + + m_jImage.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + m_jImage.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/no_photo.png"))); // NOI18N + m_jImage.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + m_jScr.setViewportView(m_jImage); + + add(m_jScr, java.awt.BorderLayout.CENTER); + + jPanel1.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout()); + + jPanel2.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 5, 0, 5)); + jPanel2.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel2.setLayout(new java.awt.GridLayout(0, 1, 0, 2)); + + m_jbtnzoomin.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/viewmag+.png"))); // NOI18N + m_jbtnzoomin.setToolTipText("Zoom In"); + m_jbtnzoomin.setPreferredSize(new java.awt.Dimension(50, 45)); + m_jbtnzoomin.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtnzoominActionPerformed(evt); + } + }); + jPanel2.add(m_jbtnzoomin); + + m_jPercent.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jPercent.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jPercent.setOpaque(true); + m_jPercent.setPreferredSize(new java.awt.Dimension(10, 30)); + jPanel2.add(m_jPercent); + + m_jbtnzoomout.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/viewmag-.png"))); // NOI18N + m_jbtnzoomout.setToolTipText("Zoom Out"); + m_jbtnzoomout.setPreferredSize(new java.awt.Dimension(50, 45)); + m_jbtnzoomout.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtnzoomoutActionPerformed(evt); + } + }); + jPanel2.add(m_jbtnzoomout); + + jPanel1.add(jPanel2, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, -1, -1)); + + add(jPanel1, java.awt.BorderLayout.LINE_END); + }// //GEN-END:initComponents + + private void m_jbtnzoomoutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtnzoomoutActionPerformed + + decZoom(); + + }//GEN-LAST:event_m_jbtnzoomoutActionPerformed + + private void m_jbtnzoominActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtnzoominActionPerformed + + incZoom(); + + }//GEN-LAST:event_m_jbtnzoominActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JLabel m_jImage; + private javax.swing.JLabel m_jPercent; + private javax.swing.JScrollPane m_jScr; + private javax.swing.JButton m_jbtnzoomin; + private javax.swing.JButton m_jbtnzoomout; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/data/gui/JImageViewerProduct.form b/src/main/java/com/unicenta/data/gui/JImageViewerProduct.form new file mode 100644 index 0000000..c5e4fcd --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JImageViewerProduct.form @@ -0,0 +1,131 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/data/gui/JImageViewerProduct.java b/src/main/java/com/unicenta/data/gui/JImageViewerProduct.java new file mode 100644 index 0000000..c0029ef --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JImageViewerProduct.java @@ -0,0 +1,395 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.gui; + +import com.unicenta.data.loader.LocalRes; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import javax.imageio.ImageIO; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JFileChooser; +import javax.swing.JOptionPane; +import javax.swing.filechooser.FileFilter; + +/** + * + * @author JG uniCenta + */ +public class JImageViewerProduct extends javax.swing.JPanel { + + private Dimension m_maxsize; + private final ZoomIcon m_icon; + private BufferedImage m_Img = null; + + private static File m_fCurrentDirectory = null; + private static final NumberFormat m_percentformat = new DecimalFormat("#,##0.##%"); + + public JImageViewerProduct() { + initComponents(); + + m_Img = null; + m_maxsize = null; + m_icon = new ZoomIcon(); + m_jImage.setIcon(m_icon); + m_jPercent.setText(m_percentformat.format(m_icon.getZoom())); + privateSetEnabled(isEnabled()); + } + + /** + * + * @param size + */ + public void setMaxDimensions(Dimension size) { + m_maxsize = size; + } + + /** + * + * @return + */ + public Dimension getMaxDimensions() { + return m_maxsize; + } + + @Override + public void setEnabled(boolean value) { + + privateSetEnabled(value); + super.setEnabled(value); + } + + private void privateSetEnabled(boolean value) { + m_jbtnzoomin.setEnabled(value && (m_Img != null)); + m_jbtnzoomout.setEnabled(value && (m_Img != null)); + m_jPercent.setEnabled(value && (m_Img != null)); + m_jScr.setEnabled(value && (m_Img != null)); + } + + /** + * + * @param img + */ + public void setImage(BufferedImage img) { + BufferedImage oldimg = m_Img; + m_Img = img; + m_icon.setIcon(m_Img == null ? null : new ImageIcon(m_Img)); + + m_jPercent.setText(m_percentformat.format(m_icon.getZoom())); + + m_jImage.revalidate(); + m_jScr.revalidate(); + m_jScr.repaint(); + + privateSetEnabled(isEnabled()); + + firePropertyChange("image", oldimg, m_Img); + } + + /** + * + * @return + */ + public BufferedImage getImage() { + return m_Img; + } + + /** + * + * @return + */ + public double getZoom() { + return m_icon.getZoom(); + } + + /** + * + * @param zoom + */ + public void setZoom(double zoom) { + double oldzoom = m_icon.getZoom(); + m_icon.setZoom(zoom); + + m_jPercent.setText(m_percentformat.format(m_icon.getZoom())); + + m_jImage.revalidate(); + m_jScr.revalidate(); + m_jScr.repaint(); + + firePropertyChange("zoom", oldzoom, zoom); + } + + /** + * + */ + public void incZoom() { + double zoom = m_icon.getZoom(); + setZoom(zoom > 4.0 ? 8.0 : zoom * 2.0); + } + + /** + * + */ + public void decZoom() { + double zoom = m_icon.getZoom(); + setZoom(zoom < 0.5 ? 0.25 : zoom / 2.0); + } + + /** + * + */ + public void doLoad() { + JFileChooser fc = new JFileChooser(m_fCurrentDirectory); + + fc.addChoosableFileFilter(new ExtensionsFilter( + LocalRes.getIntString("label.imagefiles"), "png", "gif", "jpg", "jpeg", "bmp")); + + if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { + try { + BufferedImage img = ImageIO.read(fc.getSelectedFile()); + if (img != null) { + // compruebo que no exceda el tamano maximo. + if (m_maxsize != null && (img.getHeight() > m_maxsize.height || img.getWidth() > m_maxsize.width)) { + if (JOptionPane.showConfirmDialog(this, + LocalRes.getIntString("message.resizeimage"), + LocalRes.getIntString("title.editor"), + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { + // Redimensionamos la imagen para que se ajuste + img = resizeImage(img); + } + } + setImage(img); + m_fCurrentDirectory = fc.getCurrentDirectory(); + } + } catch (IOException eIO) { + } + } + } + + private BufferedImage resizeImage(BufferedImage img) { + + int myheight = img.getHeight(); + int mywidth = img.getWidth(); + + if (myheight > m_maxsize.height) { + mywidth = (int) (mywidth * m_maxsize.height / myheight); + myheight = m_maxsize.height; + } + if (mywidth > m_maxsize.width) { + myheight = (int) (myheight * m_maxsize.width / mywidth); + mywidth = m_maxsize.width; + } + + BufferedImage thumb = new BufferedImage(mywidth, myheight, BufferedImage.TYPE_4BYTE_ABGR); + + double scalex = (double) mywidth / (double) img.getWidth(null); + double scaley = (double) myheight / (double) img.getHeight(null); + + Graphics2D g2d = thumb.createGraphics(); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + + g2d.setColor(new Color(0, 0, 0, 0)); + + g2d.fillRect(0, 0, mywidth, myheight); + if (scalex < scaley) { + g2d.drawImage(img, 0,(int) ((myheight - img.getHeight(null) * scalex) / 2.0) + , mywidth, (int) (img.getHeight(null) * scalex), null); + } else { + g2d.drawImage(img, (int) ((mywidth - img.getWidth(null) * scaley) / 2.0), 0 + , (int) (img.getWidth(null) * scaley), myheight, null); + } + g2d.dispose(); + + return thumb; + } + + private static class ZoomIcon implements Icon { + + private Icon ico; + private double zoom; + + public ZoomIcon() { + this.ico = null; + this.zoom = 1.0; + } + @Override + public int getIconHeight() { + return ico == null ? 0 : (int) (zoom * ico.getIconHeight()); + } + @Override + public int getIconWidth() { + return ico == null ? 0 : (int) (zoom * ico.getIconWidth()); + } + @Override + public void paintIcon(Component c, Graphics g, int x, int y) { + if (ico != null) { + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + AffineTransform oldt = g2d.getTransform(); + g2d.transform(AffineTransform.getScaleInstance(zoom, zoom)); + ico.paintIcon(c, g2d, (int) (x / zoom), (int) (y / zoom)); + g2d.setTransform(oldt); + } + } + public void setIcon(Icon ico) { + this.ico = ico; + this.zoom = 1.0; + } + public void setZoom(double zoom) { + this.zoom = zoom; + } + public double getZoom() { + return zoom; + } + } + private static class ExtensionsFilter extends FileFilter { + + private final String message; + private final String[] extensions; + + public ExtensionsFilter(String message, String... extensions) { + this.message = message; + this.extensions = extensions; + } + + @Override + public boolean accept(java.io.File f) { + if (f.isDirectory()) { + return true; + } else { + String sFileName = f.getName(); + int ipos = sFileName.lastIndexOf('.'); + if (ipos >= 0) { + String sExt = sFileName.substring(ipos + 1); + for(String s : extensions) { + if (s.equalsIgnoreCase(sExt)) { + return true; + } + } + } + return false; + } + } + + @Override + public String getDescription() { + return message; + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + m_jScr = new javax.swing.JScrollPane(); + m_jImage = new javax.swing.JLabel(); + jPanel1 = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + m_jbtnzoomin = new javax.swing.JButton(); + m_jPercent = new javax.swing.JLabel(); + m_jbtnzoomout = new javax.swing.JButton(); + + setLayout(new java.awt.BorderLayout()); + + m_jImage.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + m_jImage.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/no_photo.png"))); // NOI18N + m_jImage.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + m_jScr.setViewportView(m_jImage); + + add(m_jScr, java.awt.BorderLayout.CENTER); + + jPanel1.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout()); + + jPanel2.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 5, 0, 5)); + jPanel2.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel2.setLayout(new java.awt.GridLayout(0, 1, 0, 2)); + + m_jbtnzoomin.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/viewmag+.png"))); // NOI18N + m_jbtnzoomin.setToolTipText("Zoom In"); + m_jbtnzoomin.setPreferredSize(new java.awt.Dimension(50, 45)); + m_jbtnzoomin.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtnzoominActionPerformed(evt); + } + }); + jPanel2.add(m_jbtnzoomin); + + m_jPercent.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jPercent.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jPercent.setOpaque(true); + m_jPercent.setPreferredSize(new java.awt.Dimension(10, 30)); + jPanel2.add(m_jPercent); + + m_jbtnzoomout.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/viewmag-.png"))); // NOI18N + m_jbtnzoomout.setToolTipText("Zoom Out"); + m_jbtnzoomout.setPreferredSize(new java.awt.Dimension(50, 45)); + m_jbtnzoomout.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtnzoomoutActionPerformed(evt); + } + }); + jPanel2.add(m_jbtnzoomout); + + jPanel1.add(jPanel2, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, -1, -1)); + + add(jPanel1, java.awt.BorderLayout.LINE_END); + }// //GEN-END:initComponents + + private void m_jbtnzoomoutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtnzoomoutActionPerformed + + decZoom(); + + }//GEN-LAST:event_m_jbtnzoomoutActionPerformed + + private void m_jbtnzoominActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtnzoominActionPerformed + + incZoom(); + + }//GEN-LAST:event_m_jbtnzoominActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JLabel m_jImage; + private javax.swing.JLabel m_jPercent; + private javax.swing.JScrollPane m_jScr; + private javax.swing.JButton m_jbtnzoomin; + private javax.swing.JButton m_jbtnzoomout; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/data/gui/JLabelDirty.java b/src/main/java/com/unicenta/data/gui/JLabelDirty.java new file mode 100644 index 0000000..5f5af25 --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JLabelDirty.java @@ -0,0 +1,52 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.gui; + +import com.unicenta.data.user.DirtyListener; +import com.unicenta.data.user.DirtyManager; +import javax.swing.*; + +/** + * + * @author JG uniCenta + */ +public class JLabelDirty extends JLabel { + + private static Icon m_IconModif = null; + private static Icon m_IconNull = null; + + /** Creates a new instance of JDirtyPicture + * @param dm */ + public JLabelDirty(DirtyManager dm) { + + if (m_IconModif == null) { + m_IconModif = new ImageIcon(getClass().getResource("/com/unicenta/images/edit.png")); + } + if (m_IconNull == null) { + m_IconNull = new NullIcon(16, 16); + } + + dm.addDirtyListener(new DirtyListener() { + public void changedDirty(boolean bDirty) { + setIcon(bDirty ? m_IconModif : m_IconNull); + } + }); + } +} diff --git a/src/main/java/com/unicenta/data/gui/JListData.form b/src/main/java/com/unicenta/data/gui/JListData.form new file mode 100644 index 0000000..41b5032 --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JListData.form @@ -0,0 +1,117 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/data/gui/JListData.java b/src/main/java/com/unicenta/data/gui/JListData.java new file mode 100644 index 0000000..f9f5de0 --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JListData.java @@ -0,0 +1,175 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.gui; + +import java.util.*; + +/** + * + * @author JG uniCenta + */ +public class JListData extends javax.swing.JDialog { + + private Object m_selected; + + /** Creates new form JListData + * @param parent */ + public JListData(java.awt.Frame parent) { + super(parent, true); + initComponents(); + + getRootPane().setDefaultButton(m_jOK); + } + + /** + * + * @param data + * @return + */ + public Object showList(List data) { + + return showList(new MyListData(data)); + } + + /** + * + * @param model + * @return + */ + public Object showList(javax.swing.ListModel model) { + + m_jData.setModel(model); + m_selected = null; + + setVisible(true); + //show(); + + return m_selected; + } + + private static class MyListData extends javax.swing.AbstractListModel { + + private List m_data; + + public MyListData(List data) { + m_data = data; + } + + @Override + public Object getElementAt(int index) { + return m_data.get(index); + } + + @Override + public int getSize() { + return m_data.size(); + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + m_jOK = new javax.swing.JButton(); + m_jCancel = new javax.swing.JButton(); + jScrollPane1 = new javax.swing.JScrollPane(); + m_jData = new javax.swing.JList(); + jToolBar1 = new javax.swing.JToolBar(); + jButton1 = new javax.swing.JButton(); + jButton2 = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + + jPanel1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT)); + + m_jOK.setText("Accept"); + m_jOK.setMaximumSize(new java.awt.Dimension(65, 33)); + m_jOK.setMinimumSize(new java.awt.Dimension(65, 33)); + m_jOK.setPreferredSize(new java.awt.Dimension(65, 33)); + m_jOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jOKActionPerformed(evt); + } + }); + jPanel1.add(m_jOK); + + m_jCancel.setText("Cancel"); + m_jCancel.setMaximumSize(new java.awt.Dimension(65, 33)); + m_jCancel.setMinimumSize(new java.awt.Dimension(65, 33)); + m_jCancel.setPreferredSize(new java.awt.Dimension(65, 33)); + m_jCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jCancelActionPerformed(evt); + } + }); + jPanel1.add(m_jCancel); + + getContentPane().add(jPanel1, java.awt.BorderLayout.SOUTH); + + m_jData.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jData.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); + jScrollPane1.setViewportView(m_jData); + + getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER); + + jToolBar1.setFloatable(false); + + jButton1.setText("jButton1"); + jToolBar1.add(jButton1); + + jButton2.setText("jButton2"); + jToolBar1.add(jButton2); + + getContentPane().add(jToolBar1, java.awt.BorderLayout.NORTH); + + setSize(new java.awt.Dimension(264, 337)); + setLocationRelativeTo(null); + }// //GEN-END:initComponents + + private void m_jCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jCancelActionPerformed + + dispose(); + }//GEN-LAST:event_m_jCancelActionPerformed + + private void m_jOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jOKActionPerformed + + m_selected = m_jData.getSelectedValue(); + + dispose(); + }//GEN-LAST:event_m_jOKActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + private javax.swing.JButton jButton2; + private javax.swing.JPanel jPanel1; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JToolBar jToolBar1; + private javax.swing.JButton m_jCancel; + private javax.swing.JList m_jData; + private javax.swing.JButton m_jOK; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/data/gui/JListNavigator.form b/src/main/java/com/unicenta/data/gui/JListNavigator.form new file mode 100644 index 0000000..c80ac1e --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JListNavigator.form @@ -0,0 +1,54 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/data/gui/JListNavigator.java b/src/main/java/com/unicenta/data/gui/JListNavigator.java new file mode 100644 index 0000000..10822dc --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JListNavigator.java @@ -0,0 +1,150 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.gui; + +import java.awt.Dimension; +import java.awt.Rectangle; +import javax.swing.ListCellRenderer; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.LocalRes; +import com.unicenta.data.user.BrowsableEditableData; +import com.unicenta.data.user.BrowseListener; + +/** + * + * @author JG uniCenta + */ +public class JListNavigator extends javax.swing.JPanel implements BrowseListener, ListSelectionListener { + + /** + * + */ + protected BrowsableEditableData m_bd; + + /** Creates new form JListBrowse + * @param bd */ + public JListNavigator(BrowsableEditableData bd) { + this(bd, false); + } + + /** + * + * @param bd + * @param bTouchable + */ + public JListNavigator(BrowsableEditableData bd, boolean bTouchable) { + + m_bd = bd; + + initComponents(); + +// if (bTouchable) { + jScrollPane1.getVerticalScrollBar().setPreferredSize(new Dimension(35, 35)); + jScrollPane1.getHorizontalScrollBar().setPreferredSize(new Dimension(35, 35)); + jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); + jScrollPane1.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); +// } + + + m_jlist.addListSelectionListener(this); + m_jlist.setModel(m_bd.getListModel()); + + m_bd.addBrowseListener(this); + } + + /** + * + * @param cellRenderer + */ + public void setCellRenderer(ListCellRenderer cellRenderer) { + m_jlist.setCellRenderer(cellRenderer); + } + + /** + * + * @param iIndex + * @param iCounter + */ + @Override + public void updateIndex(int iIndex, int iCounter) { + + if (iIndex >= 0 && iIndex < iCounter) { + m_jlist.setSelectedIndex(iIndex); + } else { + m_jlist.setSelectedIndex(-1); + } + } + + @Override + public void valueChanged(ListSelectionEvent evt) { + + if (!evt.getValueIsAdjusting()) { + int i = m_jlist.getSelectedIndex(); + if (i >= 0) { + if (!m_bd.isAdjusting()) { + + try { + m_bd.moveTo(i); + } catch (BasicException eD) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, LocalRes.getIntString("message.nomove"), eD); + msg.show(this); + } + } + Rectangle oRect = m_jlist.getCellBounds(i, i); + m_jlist.scrollRectToVisible(oRect); + } + } + } + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jScrollPane1 = new javax.swing.JScrollPane(); + m_jlist = new javax.swing.JList(); + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setPreferredSize(new java.awt.Dimension(300, 2)); + setLayout(new java.awt.BorderLayout()); + + jScrollPane1.setAutoscrolls(true); + jScrollPane1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + + m_jlist.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jlist.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); + m_jlist.setFocusable(false); + m_jlist.setRequestFocusEnabled(false); + jScrollPane1.setViewportView(m_jlist); + + add(jScrollPane1, java.awt.BorderLayout.CENTER); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JList m_jlist; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/data/gui/JMessageDialog.form b/src/main/java/com/unicenta/data/gui/JMessageDialog.form new file mode 100644 index 0000000..1c4d13d --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JMessageDialog.form @@ -0,0 +1,180 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/data/gui/JMessageDialog.java b/src/main/java/com/unicenta/data/gui/JMessageDialog.java new file mode 100644 index 0000000..2b2fbe6 --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JMessageDialog.java @@ -0,0 +1,249 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.gui; + +import com.unicenta.data.loader.LocalRes; +import java.awt.*; +import javax.swing.*; +/** + * + * @author adrian + */ +public class JMessageDialog extends javax.swing.JDialog { + + /** Creates new form JMessageDialog */ + private JMessageDialog(java.awt.Frame parent, boolean modal) { + super(parent, modal); + } + /** Creates new form JMessageDialog */ + private JMessageDialog(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + } + + private static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window) parent; + } else { + return getWindow(parent.getParent()); + } + } + + /** + * + * @param parent + * @param inf + */ + public static void showMessage(Component parent, MessageInf inf) { + + Window window = getWindow(parent); + + JMessageDialog myMsg; + if (window instanceof Frame) { + myMsg = new JMessageDialog((Frame) window, true); + } else { + myMsg = new JMessageDialog((Dialog) window, true); + } + + myMsg.initComponents(); + myMsg.applyComponentOrientation(parent.getComponentOrientation()); + myMsg.jscrException.setVisible(false); + myMsg.getRootPane().setDefaultButton(myMsg.jcmdOK); + + myMsg.jlblIcon.setIcon(inf.getSignalWordIcon()); + myMsg.jlblErrorCode.setText(inf.getErrorCodeMsg()); + myMsg.jlblMessage.setText("" + inf.getMessageMsg()); + + // Capturamos el texto de la excepcion... + if (inf.getCause() == null) { + myMsg.jtxtException.setText(null); + } else { + StringBuilder sb = new StringBuilder(); + + if (inf.getCause() instanceof Throwable) { + Throwable t = (Throwable) inf.getCause(); + while (t != null) { + sb.append(t.getClass().getName()); + sb.append(": \n"); + sb.append(t.getMessage()); + sb.append("\n\n"); + t = t.getCause(); + } + } else if (inf.getCause() instanceof Throwable[]) { + Throwable[] m_aExceptions = (Throwable[]) inf.getCause(); + for (int i = 0; i < m_aExceptions.length; i++) { + sb.append(m_aExceptions[i].getClass().getName()); + sb.append(": \n"); + sb.append(m_aExceptions[i].getMessage()); + sb.append("\n\n"); + } + } else if (inf.getCause() instanceof Object[]) { + Object [] m_aObjects = (Object []) inf.getCause(); + for (int i = 0; i < m_aObjects.length; i++) { + sb.append(m_aObjects[i].toString()); + sb.append("\n\n"); + } + } else if (inf.getCause() instanceof String) { + sb.append(inf.getCause().toString()); + } else { + sb.append(inf.getCause().getClass().getName()); + sb.append(": \n"); + sb.append(inf.getCause().toString()); + } + myMsg.jtxtException.setText(sb.toString()); + } + myMsg.jtxtException.setCaretPosition(0); + + //myMsg.show(); + myMsg.setVisible(true); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel4 = new javax.swing.JPanel(); + jlblErrorCode = new javax.swing.JLabel(); + jlblMessage = new javax.swing.JLabel(); + jscrException = new javax.swing.JScrollPane(); + jtxtException = new javax.swing.JTextArea(); + jlblIcon = new javax.swing.JLabel(); + jPanel3 = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + jcmdOK = new javax.swing.JButton(); + jcmdMore = new javax.swing.JButton(); + + setTitle(LocalRes.getIntString("title.message")); // NOI18N + setResizable(false); + addWindowListener(new java.awt.event.WindowAdapter() { + public void windowClosing(java.awt.event.WindowEvent evt) { + closeDialog(evt); + } + }); + + jPanel4.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel4.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel4.setLayout(new javax.swing.BoxLayout(jPanel4, javax.swing.BoxLayout.Y_AXIS)); + + jlblErrorCode.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jlblErrorCode.setText("jlblErrorCode"); + jPanel4.add(jlblErrorCode); + + jlblMessage.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jlblMessage.setText("jlblMessage"); + jlblMessage.setVerticalAlignment(javax.swing.SwingConstants.TOP); + jlblMessage.setMinimumSize(new java.awt.Dimension(200, 100)); + jlblMessage.setPreferredSize(new java.awt.Dimension(200, 100)); + jPanel4.add(jlblMessage); + + jscrException.setAlignmentX(0.0F); + + jtxtException.setEditable(false); + jtxtException.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jscrException.setViewportView(jtxtException); + + jPanel4.add(jscrException); + + getContentPane().add(jPanel4, java.awt.BorderLayout.CENTER); + + jlblIcon.setVerticalAlignment(javax.swing.SwingConstants.TOP); + jlblIcon.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10)); + getContentPane().add(jlblIcon, java.awt.BorderLayout.LINE_START); + + jPanel3.setLayout(new java.awt.BorderLayout()); + + jcmdOK.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdOK.setText(LocalRes.getIntString("button.OK")); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jcmdOK.setActionCommand(bundle.getString("button.OK")); // NOI18N + jcmdOK.setMaximumSize(new java.awt.Dimension(65, 33)); + jcmdOK.setMinimumSize(new java.awt.Dimension(65, 33)); + jcmdOK.setPreferredSize(new java.awt.Dimension(65, 33)); + jcmdOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdOKActionPerformed(evt); + } + }); + jPanel2.add(jcmdOK); + + jcmdMore.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdMore.setText(LocalRes.getIntString("button.information")); // NOI18N + jcmdMore.setMaximumSize(new java.awt.Dimension(65, 33)); + jcmdMore.setMinimumSize(new java.awt.Dimension(65, 33)); + jcmdMore.setPreferredSize(new java.awt.Dimension(65, 33)); + jcmdMore.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdMoreActionPerformed(evt); + } + }); + jPanel2.add(jcmdMore); + + jPanel3.add(jPanel2, java.awt.BorderLayout.LINE_END); + + getContentPane().add(jPanel3, java.awt.BorderLayout.SOUTH); + + setSize(new java.awt.Dimension(455, 277)); + setLocationRelativeTo(null); + }// //GEN-END:initComponents + + private void jcmdMoreActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdMoreActionPerformed + + // Add your handling code here: + jcmdMore.setEnabled(false); + jscrException.setVisible(true); + setSize(getWidth(), 310); +// JG 25 May 2013 change for JDK 7 + validate(); +// validateTree(); + + }//GEN-LAST:event_jcmdMoreActionPerformed + + private void jcmdOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdOKActionPerformed + // Add your handling code here: + setVisible(false); + dispose(); + }//GEN-LAST:event_jcmdOKActionPerformed + + /** Closes the dialog */ + private void closeDialog(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_closeDialog + setVisible(false); + dispose(); + }//GEN-LAST:event_closeDialog + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JButton jcmdMore; + private javax.swing.JButton jcmdOK; + private javax.swing.JLabel jlblErrorCode; + private javax.swing.JLabel jlblIcon; + private javax.swing.JLabel jlblMessage; + private javax.swing.JScrollPane jscrException; + private javax.swing.JTextArea jtxtException; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/data/gui/JNavigator.form b/src/main/java/com/unicenta/data/gui/JNavigator.form new file mode 100644 index 0000000..e30e205 --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JNavigator.form @@ -0,0 +1,22 @@ + + +
+ + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/data/gui/JNavigator.java b/src/main/java/com/unicenta/data/gui/JNavigator.java new file mode 100644 index 0000000..8251719 --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JNavigator.java @@ -0,0 +1,372 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.gui; + +import java.util.*; +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.ComparatorCreator; +import com.unicenta.data.loader.LocalRes; +import com.unicenta.data.loader.Vectorer; +import com.unicenta.data.user.BrowseListener; +import com.unicenta.data.user.BrowsableEditableData; +import com.unicenta.data.user.StateListener; + +/** + * + * @author JG uniCenta + */ +public class JNavigator extends javax.swing.JPanel implements BrowseListener, StateListener { + + /** + * + */ + public final static int BUTTONS_ALL = 0; + + /** + * + */ + public final static int BUTTONS_NONAVIGATE = 1; + + /** + * + */ + protected BrowsableEditableData m_bd; + + /** + * + */ + protected ComparatorCreator m_cc; + + /** + * + */ + protected FindInfo m_LastFindInfo; + + private javax.swing.JButton jbtnFind = null; + private javax.swing.JButton jbtnSort = null; + private javax.swing.JButton jbtnFirst = null; + private javax.swing.JButton jbtnLast = null; + private javax.swing.JButton jbtnNext = null; + private javax.swing.JButton jbtnPrev = null; + private javax.swing.JButton jbtnRefresh = null; + private javax.swing.JButton jbtnReload = null; + + /** Creates new form JNavigator + * @param bd + * @param vec + * @param cc + * @param iButtons */ + public JNavigator(BrowsableEditableData bd, Vectorer vec, ComparatorCreator cc, int iButtons) { + + initComponents(); + + if (iButtons == BUTTONS_ALL) { + jbtnFirst = new javax.swing.JButton(); + jbtnFirst.setPreferredSize(new java.awt.Dimension(60,45)); + jbtnFirst.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/2leftarrow.png"))); + jbtnFirst.setMargin(new java.awt.Insets(2, 2, 2, 2)); + jbtnFirst.setFocusPainted(false); + jbtnFirst.setFocusable(false); + jbtnFirst.setRequestFocusEnabled(false); + jbtnFirst.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnFirstActionPerformed(evt); + } + }); + add(jbtnFirst); + } + + if (iButtons == BUTTONS_ALL) { + jbtnPrev = new javax.swing.JButton(); + jbtnPrev.setPreferredSize(new java.awt.Dimension(60,45)); + jbtnPrev.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/1leftarrow.png"))); + jbtnPrev.setMargin(new java.awt.Insets(2, 2, 2, 2)); + jbtnPrev.setFocusPainted(false); + jbtnPrev.setFocusable(false); + jbtnPrev.setRequestFocusEnabled(false); + jbtnPrev.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnPrevActionPerformed(evt); + } + }); + add(jbtnPrev); + } + + jbtnRefresh = new javax.swing.JButton(); + jbtnRefresh.setPreferredSize(new java.awt.Dimension(60,45)); + jbtnRefresh.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/1downarrow.png"))); + jbtnRefresh.setMargin(new java.awt.Insets(2, 2, 2, 2)); + jbtnRefresh.setFocusPainted(false); + jbtnRefresh.setFocusable(false); + jbtnRefresh.setRequestFocusEnabled(false); + jbtnRefresh.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnRefreshActionPerformed(evt); + } + }); + add(jbtnRefresh); + + if (iButtons == BUTTONS_ALL) { + jbtnNext = new javax.swing.JButton(); + jbtnNext.setPreferredSize(new java.awt.Dimension(60,45)); + jbtnNext.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/1rightarrow.png"))); + jbtnNext.setMargin(new java.awt.Insets(2, 2, 2, 2)); + jbtnNext.setFocusPainted(false); + jbtnNext.setFocusable(false); + jbtnNext.setRequestFocusEnabled(false); + jbtnNext.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnNextActionPerformed(evt); + } + }); + add(jbtnNext); + } + + if (iButtons == BUTTONS_ALL) { + jbtnLast = new javax.swing.JButton(); + jbtnLast.setPreferredSize(new java.awt.Dimension(60,45)); + jbtnLast.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/2rightarrow.png"))); + jbtnLast.setMargin(new java.awt.Insets(2, 2, 2, 2)); + jbtnLast.setFocusPainted(false); + jbtnLast.setFocusable(false); + jbtnLast.setRequestFocusEnabled(false); + jbtnLast.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnLastActionPerformed(evt); + } + }); + add(jbtnLast); + } + + add(new javax.swing.JSeparator()); + + if (bd.canLoadData()) { + jbtnReload = new javax.swing.JButton(); + jbtnReload.setPreferredSize(new java.awt.Dimension(60,45)); + jbtnReload.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reload.png"))); + jbtnReload.setMargin(new java.awt.Insets(2, 2, 2, 2)); + jbtnReload.setFocusPainted(false); + jbtnReload.setFocusable(false); + jbtnReload.setRequestFocusEnabled(false); + jbtnReload.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnReloadActionPerformed(evt); + } + }); + add(jbtnReload); + + add(new javax.swing.JSeparator()); + } + + if (vec == null) { + m_LastFindInfo = null; + } else { + m_LastFindInfo = new FindInfo(vec); + jbtnFind = new javax.swing.JButton(); + jbtnFind.setPreferredSize(new java.awt.Dimension(60,45)); + jbtnFind.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/search24.png"))); + jbtnFind.setMargin(new java.awt.Insets(2, 2, 2, 2)); + jbtnFind.setFocusPainted(false); + jbtnFind.setFocusable(false); + jbtnFind.setRequestFocusEnabled(false); + jbtnFind.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnFindActionPerformed(evt); + } + }); + add(jbtnFind); + } + + m_cc = cc; + if (m_cc != null) { + jbtnSort = new javax.swing.JButton(); + jbtnSort.setPreferredSize(new java.awt.Dimension(60,45)); + jbtnSort.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/sort_incr.png"))); + jbtnSort.setMargin(new java.awt.Insets(2, 2, 2, 2)); + jbtnSort.setFocusPainted(false); + jbtnSort.setFocusable(false); + jbtnSort.setRequestFocusEnabled(false); + jbtnSort.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnSortActionPerformed(evt); + } + }); + add(jbtnSort); + } + + m_bd = bd; + bd.addBrowseListener(this); + bd.addStateListener(this); + } + + /** + * + * @param bd + */ + public JNavigator(BrowsableEditableData bd) { + this(bd, null, null, BUTTONS_ALL); + } + + /** + * + * @param bd + * @param vec + * @param cc + */ + public JNavigator(BrowsableEditableData bd, Vectorer vec, ComparatorCreator cc) { + this(bd, vec, cc, BUTTONS_ALL); + } + + /** + * + * @param iState + */ + public void updateState(int iState) { + if (iState == BrowsableEditableData.ST_INSERT || iState == BrowsableEditableData.ST_DELETE) { + // Insert o Delete + if (jbtnFirst != null) jbtnFirst.setEnabled(false); + if (jbtnPrev != null) jbtnPrev.setEnabled(false); + if (jbtnNext != null) jbtnNext.setEnabled(false); + if (jbtnLast != null) jbtnLast.setEnabled(false); + if (jbtnRefresh != null) jbtnRefresh.setEnabled(true); + } + } + + /** + * + * @param iIndex + * @param iCounter + */ + public void updateIndex(int iIndex, int iCounter) { + + if (iIndex >= 0 && iIndex < iCounter) { + // Reposicionamiento + if (jbtnFirst != null) jbtnFirst.setEnabled(iIndex > 0); + if (jbtnPrev != null) jbtnPrev.setEnabled(iIndex > 0); + if (jbtnNext != null) jbtnNext.setEnabled(iIndex < iCounter - 1); + if (jbtnLast != null) jbtnLast.setEnabled(iIndex < iCounter - 1); + if (jbtnRefresh != null) jbtnRefresh.setEnabled(true); + } else { + // EOF + if (jbtnFirst != null) jbtnFirst.setEnabled(false); + if (jbtnPrev != null) jbtnPrev.setEnabled(false); + if (jbtnNext != null) jbtnNext.setEnabled(false); + if (jbtnLast != null) jbtnLast.setEnabled(false); + if (jbtnRefresh != null) jbtnRefresh.setEnabled(false); + } + } + + private void jbtnSortActionPerformed(java.awt.event.ActionEvent evt) { + try { + Comparator c = JSort.showMessage(this, m_cc); + if (c != null) { + m_bd.sort(c); + } + } catch (BasicException eD) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, LocalRes.getIntString("message.nolistdata"), eD); + msg.show(this); + } + } + + private void jbtnFindActionPerformed(java.awt.event.ActionEvent evt) { + + try { + FindInfo newFindInfo = JFind.showMessage(this, m_LastFindInfo); + if (newFindInfo != null) { + m_LastFindInfo = newFindInfo; + + int index = m_bd.findNext(newFindInfo); + if (index < 0) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, LocalRes.getIntString("message.norecord")); + msg.show(this); + } else { + m_bd.moveTo(index); + } + } + } catch (BasicException eD) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, LocalRes.getIntString("message.nolistdata"), eD); + msg.show(this); + } + } + + private void jbtnRefreshActionPerformed(java.awt.event.ActionEvent evt) { + + m_bd.actionReloadCurrent(this); + } + + private void jbtnReloadActionPerformed(java.awt.event.ActionEvent evt) { + + try { + m_bd.actionLoad(); + } catch (BasicException eD) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, LocalRes.getIntString("message.noreload"), eD); + msg.show(this); + } + } + + private void jbtnLastActionPerformed(java.awt.event.ActionEvent evt) { + + try { + m_bd.moveLast(); + } catch (BasicException eD) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, LocalRes.getIntString("message.nomove"), eD); + msg.show(this); + } + } + + private void jbtnFirstActionPerformed(java.awt.event.ActionEvent evt) { + + try{ + m_bd.moveFirst(); + } catch (BasicException eD) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, LocalRes.getIntString("message.nomove"), eD); + msg.show(this); + } + } + + private void jbtnPrevActionPerformed(java.awt.event.ActionEvent evt) { + try { + m_bd.movePrev(); + } catch (BasicException eD) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, LocalRes.getIntString("message.nomove"), eD); + msg.show(this); + } + } + + private void jbtnNextActionPerformed(java.awt.event.ActionEvent evt) { + try { + m_bd.moveNext(); + } catch (BasicException eD) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, LocalRes.getIntString("message.nomove"), eD); + msg.show(this); + } + } + + // //GEN-BEGIN:initComponents + private void initComponents() { + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + }// //GEN-END:initComponents + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/data/gui/JSaver.form b/src/main/java/com/unicenta/data/gui/JSaver.form new file mode 100644 index 0000000..5dc9645 --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JSaver.form @@ -0,0 +1,106 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/java/com/unicenta/data/gui/JSaver.java b/src/main/java/com/unicenta/data/gui/JSaver.java new file mode 100644 index 0000000..95daaaa --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JSaver.java @@ -0,0 +1,189 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.gui; + +import java.util.*; +import javax.swing.*; +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.LocalRes; +import com.unicenta.data.user.BrowsableEditableData; +import com.unicenta.data.user.StateListener; + +/** + * + * @author JG uniCenta + */ +public class JSaver extends JPanel implements StateListener { + + /** + * + */ + protected BrowsableEditableData m_bd; + + /** Creates new form JSaver + * @param bd */ + public JSaver(BrowsableEditableData bd) { + + initComponents(); + + m_bd = bd; + + // m_bd.addBrowseListener(this); + m_bd.addStateListener(this); + } + + /** + * + * @param iState + */ + @Override + public void updateState(int iState) { + switch (iState) { + case BrowsableEditableData.ST_INSERT: + jbtnNew.setEnabled(m_bd.canInsertData()); + jbtnDelete.setEnabled(false); + jbtnSave.setEnabled(m_bd.canInsertData()); + break; + case BrowsableEditableData.ST_DELETE: + jbtnNew.setEnabled(m_bd.canInsertData()); + jbtnDelete.setEnabled(false); + jbtnSave.setEnabled(m_bd.canDeleteData()); + break; + case BrowsableEditableData.ST_NORECORD: + jbtnNew.setEnabled(m_bd.canInsertData()); + jbtnDelete.setEnabled(false); + jbtnSave.setEnabled(false); + break; + case BrowsableEditableData.ST_UPDATE: + jbtnNew.setEnabled(m_bd.canInsertData()); + jbtnDelete.setEnabled(m_bd.canDeleteData()); + jbtnSave.setEnabled(m_bd.canUpdateData()); + break; + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jbtnNew = new javax.swing.JButton(); + jbtnDelete = new javax.swing.JButton(); + jbtnSave = new javax.swing.JButton(); + + jbtnNew.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/editnew.png"))); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jbtnNew.setToolTipText(bundle.getString("tooltip.addnew")); // NOI18N + jbtnNew.setFocusPainted(false); + jbtnNew.setFocusable(false); + jbtnNew.setMargin(new java.awt.Insets(2, 2, 2, 2)); + jbtnNew.setPreferredSize(new java.awt.Dimension(60, 45)); + jbtnNew.setRequestFocusEnabled(false); + jbtnNew.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnNewActionPerformed(evt); + } + }); + + jbtnDelete.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/sale_delete.png"))); // NOI18N + jbtnDelete.setToolTipText(bundle.getString("tooltip.delete")); // NOI18N + jbtnDelete.setFocusPainted(false); + jbtnDelete.setFocusable(false); + jbtnDelete.setMargin(new java.awt.Insets(2, 2, 2, 2)); + jbtnDelete.setPreferredSize(new java.awt.Dimension(60, 45)); + jbtnDelete.setRequestFocusEnabled(false); + jbtnDelete.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnDeleteActionPerformed(evt); + } + }); + + jbtnSave.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/filesave.png"))); // NOI18N + jbtnSave.setToolTipText(bundle.getString("tooltip.save")); // NOI18N + jbtnSave.setFocusPainted(false); + jbtnSave.setFocusable(false); + jbtnSave.setMargin(new java.awt.Insets(2, 2, 2, 2)); + jbtnSave.setPreferredSize(new java.awt.Dimension(60, 45)); + jbtnSave.setRequestFocusEnabled(false); + jbtnSave.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnSaveActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jbtnNew, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jbtnDelete, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jbtnSave, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jbtnNew, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jbtnDelete, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jbtnSave, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + ); + }// //GEN-END:initComponents + + private void jbtnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnSaveActionPerformed + try { + m_bd.saveData(); + + } catch (BasicException eD) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, LocalRes.getIntString("message.nosave"), eD); + msg.show(this); + } + }//GEN-LAST:event_jbtnSaveActionPerformed + + private void jbtnDeleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnDeleteActionPerformed + try { + m_bd.actionDelete(); + } catch (BasicException eD) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, LocalRes.getIntString("message.nodelete"), eD); + msg.show(this); + } + }//GEN-LAST:event_jbtnDeleteActionPerformed + + private void jbtnNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnNewActionPerformed + try { + m_bd.actionInsert(); + } catch (BasicException eD) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, LocalRes.getIntString("message.nonew"), eD); + msg.show(this); + } + }//GEN-LAST:event_jbtnNewActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jbtnDelete; + private javax.swing.JButton jbtnNew; + private javax.swing.JButton jbtnSave; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/data/gui/JSort.form b/src/main/java/com/unicenta/data/gui/JSort.form new file mode 100644 index 0000000..98593ac --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JSort.form @@ -0,0 +1,221 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/data/gui/JSort.java b/src/main/java/com/unicenta/data/gui/JSort.java new file mode 100644 index 0000000..dc3456a --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/JSort.java @@ -0,0 +1,270 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.gui; + +import javax.swing.*; +import java.awt.*; +import java.util.Comparator; +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.ComparatorCreator; +import com.unicenta.data.loader.LocalRes; + +/** + * + * @author JG uniCenta + */ +public class JSort extends JDialog { + + private ComparatorCreator m_cc; + private Comparator m_Comparator; + + private JSort(java.awt.Frame parent, boolean modal) { + super(parent, modal); + } + + private JSort(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + } + + private Comparator init(ComparatorCreator cc) throws BasicException { + + initComponents(); + + getRootPane().setDefaultButton(jcmdOK); + + m_cc = cc; + + String[] sHeaders = m_cc.getHeaders(); + + m_jSort1.removeAllItems(); + m_jSort1.addItem(""); + for (int i = 0; i < sHeaders.length; i++) { + m_jSort1.addItem(sHeaders[i]); + } + m_jSort1.setSelectedItem(0); + + m_jSort2.removeAllItems(); + m_jSort2.addItem(""); + for (int i = 0; i < sHeaders.length; i++) { + m_jSort2.addItem(sHeaders[i]); + } + m_jSort2.setSelectedItem(0); + + m_jSort3.removeAllItems(); + m_jSort3.addItem(""); + for (int i = 0; i < sHeaders.length; i++) { + m_jSort3.addItem(sHeaders[i]); + } + m_jSort3.setSelectedItem(0); + + m_Comparator = null; + setVisible(true); + return m_Comparator; + } + + private static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window)parent; + } else { + return getWindow(parent.getParent()); + } + } + + /** + * + * @param parent + * @param cc + * @return + * @throws BasicException + */ + public static Comparator showMessage(Component parent, ComparatorCreator cc) throws BasicException { + + Window window = getWindow(parent); + + JSort myMsg; + if (window instanceof Frame) { + myMsg = new JSort((Frame) window, true); + } else { + myMsg = new JSort((Dialog) window, true); + } + return myMsg.init(cc); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jLabel2 = new javax.swing.JLabel(); + m_jSort1 = new javax.swing.JComboBox(); + jLabel3 = new javax.swing.JLabel(); + m_jSort2 = new javax.swing.JComboBox(); + jLabel4 = new javax.swing.JLabel(); + m_jSort3 = new javax.swing.JComboBox(); + jPanel2 = new javax.swing.JPanel(); + jcmdCancel = new javax.swing.JButton(); + jcmdOK = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(LocalRes.getIntString("caption.sort")); // NOI18N + setResizable(false); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(LocalRes.getIntString("label.sortby")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jSort1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSort1.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(LocalRes.getIntString("label.andby")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jSort2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSort2.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(LocalRes.getIntString("label.andby")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jSort3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSort3.setPreferredSize(new java.awt.Dimension(200, 30)); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(m_jSort1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(m_jSort2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(m_jSort3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jSort1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jSort2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jSort3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + ); + + getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER); + + jPanel2.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT)); + + jcmdCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + jcmdCancel.setText(LocalRes.getIntString("button.cancel")); // NOI18N + jcmdCancel.setMaximumSize(new java.awt.Dimension(65, 33)); + jcmdCancel.setMinimumSize(new java.awt.Dimension(65, 33)); + jcmdCancel.setPreferredSize(new java.awt.Dimension(110, 45)); + jcmdCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdCancelActionPerformed(evt); + } + }); + jPanel2.add(jcmdCancel); + + jcmdOK.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jcmdOK.setText(LocalRes.getIntString("button.OK")); // NOI18N + jcmdOK.setMaximumSize(new java.awt.Dimension(65, 33)); + jcmdOK.setMinimumSize(new java.awt.Dimension(65, 33)); + jcmdOK.setPreferredSize(new java.awt.Dimension(110, 45)); + jcmdOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdOKActionPerformed(evt); + } + }); + jPanel2.add(jcmdOK); + + getContentPane().add(jPanel2, java.awt.BorderLayout.SOUTH); + + setSize(new java.awt.Dimension(396, 234)); + setLocationRelativeTo(null); + }// //GEN-END:initComponents + + private void jcmdCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdCancelActionPerformed + + dispose(); + + }//GEN-LAST:event_jcmdCancelActionPerformed + + private void jcmdOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdOKActionPerformed + + int iSort1 = m_jSort1.getSelectedIndex(); + int iSort2 = m_jSort2.getSelectedIndex(); + int iSort3 = m_jSort3.getSelectedIndex(); + + if (iSort1 > 0 && iSort2 == 0 && iSort3 == 0) { + m_Comparator = m_cc.createComparator(new int[] {iSort1 - 1}); + dispose(); + } else if (iSort1 > 0 && iSort2 > 0 && iSort3 == 0) { + m_Comparator = m_cc.createComparator(new int[] {iSort1 - 1, iSort2 - 1}); + dispose(); + } else if (iSort1 > 0 && iSort2 > 0 && iSort3 > 0) { + m_Comparator = m_cc.createComparator(new int[] {iSort1 - 1, iSort2 - 1, iSort3 - 1}); + dispose(); + } else { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, LocalRes.getIntString("message.nosort")); + msg.show(this); + } + + }//GEN-LAST:event_jcmdOKActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JButton jcmdCancel; + private javax.swing.JButton jcmdOK; + private javax.swing.JComboBox m_jSort1; + private javax.swing.JComboBox m_jSort2; + private javax.swing.JComboBox m_jSort3; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/data/gui/ListCellRendererBasic.java b/src/main/java/com/unicenta/data/gui/ListCellRendererBasic.java new file mode 100644 index 0000000..8b591bc --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/ListCellRendererBasic.java @@ -0,0 +1,49 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.gui; + +import com.unicenta.data.loader.IRenderString; +import java.awt.*; +import javax.swing.*; + +/** + * + * @author JG uniCenta + */ +public class ListCellRendererBasic extends DefaultListCellRenderer { + + private IRenderString m_renderer; + + /** Creates a new instance of ListCellRendererBasic + * @param renderer */ + public ListCellRendererBasic(IRenderString renderer) { + m_renderer = renderer; + } + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, null, index, isSelected, cellHasFocus); + + String s = m_renderer.getRenderString(value); + setText((s == null || s.equals("")) ? " " : s); // Un espacio en caso de nulo para que no deja la celda chiquitita. + return this; + } + +} diff --git a/src/main/java/com/unicenta/data/gui/ListKeyed.java b/src/main/java/com/unicenta/data/gui/ListKeyed.java new file mode 100644 index 0000000..b0e412f --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/ListKeyed.java @@ -0,0 +1,55 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.gui; + +import com.unicenta.data.loader.IKeyed; +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author adrianromero + * @param + */ +public class ListKeyed extends ArrayList { + + /** + * + * @param list + */ + public ListKeyed(List list) { + this.addAll(list); + } + + /** + * + * @param key + * @return + */ + public K get(Object key) { + + for (K elem : this) { + if ((key == null && elem.getKey() == null) || (key != null && key.equals(elem.getKey()))) { + return elem; + } + } + return null; + } +} diff --git a/src/main/java/com/unicenta/data/gui/ListQBFModelNumber.java b/src/main/java/com/unicenta/data/gui/ListQBFModelNumber.java new file mode 100644 index 0000000..ae3f2b4 --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/ListQBFModelNumber.java @@ -0,0 +1,141 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + + +package com.unicenta.data.gui; + +import com.unicenta.data.loader.QBFCompareEnum; +import javax.swing.AbstractListModel; +import javax.swing.ComboBoxModel; +/** + * + * @author adrian + */ +public class ListQBFModelNumber extends AbstractListModel implements ComboBoxModel { + +private Object[] m_items; +private Object m_sel; + +/** Creates a new instance of ListQBFModelNumber + * @param items */ +// public ListQBFModelNumber() { +// private ListQBFModelNumber(Object... items) { + public ListQBFModelNumber(Object... items) { + m_items = items; + m_sel = m_items[0]; + } + +// m_items = new Object[] { + + /** + * + * @return + */ + public static ListQBFModelNumber getMandatoryString() { + return new ListQBFModelNumber( + QBFCompareEnum.COMP_NONE, + QBFCompareEnum.COMP_EQUALS, + QBFCompareEnum.COMP_RE, + QBFCompareEnum.COMP_DISTINCT, +// QBFCompareEnum.COMP_GREATER, + QBFCompareEnum.COMP_GREATER, + QBFCompareEnum.COMP_LESS, +// QBFCompareEnum.COMP_GREATEROREQUALS, + QBFCompareEnum.COMP_GREATEROREQUALS, + QBFCompareEnum.COMP_LESSOREQUALS + ); + } + + /** + * + * @return + */ + public static ListQBFModelNumber getMandatoryNumber() { + return new ListQBFModelNumber( + QBFCompareEnum.COMP_NONE, + QBFCompareEnum.COMP_EQUALS, + QBFCompareEnum.COMP_DISTINCT, + QBFCompareEnum.COMP_GREATER, + QBFCompareEnum.COMP_LESS, + QBFCompareEnum.COMP_GREATEROREQUALS, + QBFCompareEnum.COMP_LESSOREQUALS + ); + } + + /** + * + * @return + */ + public static ListQBFModelNumber getNonMandatoryString() { + return new ListQBFModelNumber( + QBFCompareEnum.COMP_NONE, + QBFCompareEnum.COMP_EQUALS, + QBFCompareEnum.COMP_RE, + QBFCompareEnum.COMP_DISTINCT, + QBFCompareEnum.COMP_GREATER, + QBFCompareEnum.COMP_LESS, + QBFCompareEnum.COMP_GREATEROREQUALS, + QBFCompareEnum.COMP_LESSOREQUALS, + QBFCompareEnum.COMP_ISNULL, +// QBFCompareEnum.COMP_ISNOTNULL, +// }; +// m_sel = m_items[0]; + QBFCompareEnum.COMP_ISNOTNULL + ); + } + + /** + * + * @return + */ + public static ListQBFModelNumber getNonMandatoryNumber() { + return new ListQBFModelNumber( + QBFCompareEnum.COMP_NONE, + QBFCompareEnum.COMP_EQUALS, + QBFCompareEnum.COMP_DISTINCT, + QBFCompareEnum.COMP_GREATER, + QBFCompareEnum.COMP_LESS, + QBFCompareEnum.COMP_GREATEROREQUALS, + QBFCompareEnum.COMP_LESSOREQUALS, + QBFCompareEnum.COMP_ISNULL, + QBFCompareEnum.COMP_ISNOTNULL + ); + } + + @Override + public Object getElementAt(int index) { + + return m_items[index]; + } + + @Override + public int getSize() { + return m_items.length; + } + + @Override + public Object getSelectedItem() { + return m_sel; + } + + @Override + public void setSelectedItem(Object anItem) { + m_sel = anItem; + } +} diff --git a/src/main/java/com/unicenta/data/gui/MessageInf.java b/src/main/java/com/unicenta/data/gui/MessageInf.java new file mode 100644 index 0000000..11b4db6 --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/MessageInf.java @@ -0,0 +1,224 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.gui; + +import com.unicenta.data.loader.LocalRes; +import java.awt.*; +import javax.swing.*; + +/** + * + * @author JG uniCenta + */ +public class MessageInf { + + // SIGNAL_WORD'S + + /** + * + */ + public final static int SGN_DANGER = 0xFF000000; // Death or serious injury will occur + + /** + * + */ + public final static int SGN_WARNING = 0xFE000000; // Death or serious injury may occur + + /** + * + */ + public final static int SGN_CAUTION = 0xFD000000; // Minor or moderate injury may occur + + /** + * + */ + public final static int SGN_NOTICE = 0xFC000000; // Damage to property may occur + + /** + * + */ + public final static int SGN_IMPORTANT = 0xFA000000; // Operating or maintenance instructions or additional information + + /** + * + */ + public final static int SGN_SUCCESS = 0xFB000000; + + // ERROR_CLASS'ES + + /** + * + */ + public final static int CLS_GENERIC = 0x00000000; + + // ERROR_CODE'S + + // VARIABLES + private int m_iMsgNumber; // = SIGNAL_WORD (0xFF000000) | ERROR_CLASS (0x00FF0000) | ERROR_CODE (0x0000FFFF) + private String m_sHazard; + private String m_sConsequences; + private String m_sAvoiding; + + // CAUSE + private Object m_eCause; + + /** Creates a new instance of MessageInf + * @param iSignalWord + * @param sHazard + * @param e */ + public MessageInf(int iSignalWord, String sHazard, Object e) { +// m_iMsgNumber = iSignalWord | CLS_GENERIC; + m_iMsgNumber = iSignalWord; + m_sHazard = sHazard; + m_sConsequences = ""; + m_sAvoiding = ""; + m_eCause = e; + } + /** Creates a new instance of MessageInf + * @param iSignalWord + * @param sHazard */ + public MessageInf(int iSignalWord, String sHazard) { + this (iSignalWord, sHazard, null); + } + + /** Creates a new instance of MessageInf + * @param e */ + public MessageInf(Throwable e) { + this(SGN_WARNING, e.getLocalizedMessage(), e); + } + + /** + * + * @param parent + */ + public void show(Component parent) { + JMessageDialog.showMessage(parent, this); + } + + /** + * + * @return + */ + public Object getCause() { + return m_eCause; + } + + /** + * + * @return + */ + public int getSignalWord() { + return m_iMsgNumber & 0xFF000000; + } + + /** + * + * @return + */ + public Icon getSignalWordIcon() { + int iSignalWord = getSignalWord(); + if (iSignalWord == SGN_DANGER) { + return UIManager.getIcon("OptionPane.errorIcon"); + } else if (iSignalWord == SGN_WARNING) { + return UIManager.getIcon("OptionPane.warningIcon"); + } else if (iSignalWord == SGN_CAUTION) { + return UIManager.getIcon("OptionPane.warningIcon"); + } else if (iSignalWord == SGN_NOTICE) { + return UIManager.getIcon("OptionPane.informationIcon"); + } else if (iSignalWord == SGN_IMPORTANT) { + return UIManager.getIcon("OptionPane.informationIcon"); + } else if (iSignalWord == SGN_SUCCESS) { + return UIManager.getIcon("OptionPane.informationIcon"); + } else { + return UIManager.getIcon("OptionPane.questionIcon"); + } + } + + /** + * + * @return + */ + public String getErrorCodeMsg() { + + StringBuilder sb = new StringBuilder(); + int iSignalWord = getSignalWord(); + if (iSignalWord == SGN_DANGER) { + sb.append("DNG_"); + } else if (iSignalWord == SGN_WARNING) { + sb.append("WRN_"); + } else if (iSignalWord == SGN_CAUTION) { + sb.append("CAU_"); + } else if (iSignalWord == SGN_NOTICE) { + sb.append("NOT_"); + } else if (iSignalWord == SGN_IMPORTANT) { + sb.append("IMP_"); + } else if (iSignalWord == SGN_SUCCESS) { + sb.append("INF_"); + } else { + sb.append("UNK_"); + } + sb.append(toHex((m_iMsgNumber & 0x00FF0000) >> 16, 2)); + sb.append('_'); + sb.append(toHex(m_iMsgNumber & 0x0000FFFF, 4)); + return sb.toString(); + } + + private String toHex(int i, int iChars) { + String s = Integer.toHexString(i); + return s.length() >= iChars ? s : fillString(iChars - s.length()) + s; + } + + private String fillString(int iChars) { + char[] aStr = new char[iChars]; + for (int i = 0; i < aStr.length; i++) { + aStr[i] = '0'; + } + return new String(aStr); + } + + /** + * + * @return + */ + public String getMessageMsg() { + + StringBuilder sb = new StringBuilder(); + int iSignalWord = getSignalWord(); + if (iSignalWord == SGN_DANGER) { + sb.append(LocalRes.getIntString("sgn.danger")); + } else if (iSignalWord == SGN_WARNING) { + sb.append(LocalRes.getIntString("sgn.warning")); + } else if (iSignalWord == SGN_CAUTION) { + sb.append(LocalRes.getIntString("sgn.caution")); + } else if (iSignalWord == SGN_NOTICE) { + sb.append(LocalRes.getIntString("sgn.notice")); + } else if (iSignalWord == SGN_IMPORTANT) { + sb.append(LocalRes.getIntString("sgn.important")); + } else if (iSignalWord == SGN_SUCCESS) { + sb.append(LocalRes.getIntString("sgn.success")); + } else { + sb.append(LocalRes.getIntString("sgn.unknown")); + } + sb.append(m_sHazard); + sb.append(m_sConsequences); + sb.append(m_sAvoiding); + return sb.toString(); + } +} diff --git a/src/main/java/com/unicenta/data/gui/NullIcon.java b/src/main/java/com/unicenta/data/gui/NullIcon.java new file mode 100644 index 0000000..1599c9d --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/NullIcon.java @@ -0,0 +1,55 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.gui; + +import javax.swing.Icon; + +/** + * + * @author adrian + */ +public class NullIcon implements Icon { + + private int m_iWidth; + private int m_iHeight; + + /** Creates a new instance of NullIcon + * @param width + * @param height */ + public NullIcon(int width, int height) { + m_iWidth = width; + m_iHeight = height; + } + + @Override + public int getIconHeight() { + return m_iHeight; + } + + @Override + public int getIconWidth() { + return m_iWidth; + } + + @Override + public void paintIcon(java.awt.Component c, java.awt.Graphics g, int x, int y) { + } + +} diff --git a/src/main/java/com/unicenta/data/gui/TableRendererBasic.java b/src/main/java/com/unicenta/data/gui/TableRendererBasic.java new file mode 100644 index 0000000..925180f --- /dev/null +++ b/src/main/java/com/unicenta/data/gui/TableRendererBasic.java @@ -0,0 +1,52 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.gui; + +import com.unicenta.format.Formats; +import java.awt.Component; +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.table.DefaultTableCellRenderer; + +/** + * + * @author JG uniCenta + */ +public class TableRendererBasic extends DefaultTableCellRenderer { + + private Formats[] m_aFormats; + + /** Creates a new instance of TableRendererBasic + * @param aFormats */ + public TableRendererBasic(Formats[] aFormats) { + m_aFormats = aFormats; + } + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column){ + + JLabel aux = (JLabel) super.getTableCellRendererComponent(table, null, isSelected, hasFocus, row, column); + + aux.setText(m_aFormats[column].formatValue(value)); + aux.setHorizontalAlignment(m_aFormats[column].getAlignment()); + + return aux; + } +} diff --git a/src/main/java/com/unicenta/data/loader/BaseSentence.java b/src/main/java/com/unicenta/data/loader/BaseSentence.java new file mode 100644 index 0000000..1993f2e --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/BaseSentence.java @@ -0,0 +1,275 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author JG uniCenta + */ +public abstract class BaseSentence implements SentenceList, SentenceFind, SentenceExec { + + // Funciones de bajo nivel + + /** + * + * @param params + * @return + * @throws BasicException + */ + public abstract DataResultSet openExec(Object params) throws BasicException; + + /** + * + * @return + * @throws BasicException + */ + public abstract DataResultSet moreResults() throws BasicException; + + /** + * + * @throws BasicException + */ + public abstract void closeExec() throws BasicException; + + // Funciones + + /** + * + * @return + * @throws BasicException + */ + @Override + public final int exec() throws BasicException { + return exec((Object) null); + } + + /** + * + * @param params + * @return + * @throws BasicException + */ + @Override + public final int exec(Object... params) throws BasicException { + return exec((Object) params); + } + + /** + * + * @param params + * @return + * @throws BasicException + */ + @Override + public final int exec(Object params) throws BasicException { + DataResultSet SRS = openExec(params); + if (SRS == null) { + throw new BasicException(LocalRes.getIntString("exception.noupdatecount")); + } + int iResult = SRS.updateCount(); + SRS.close(); + closeExec(); + return iResult; + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public final List list() throws BasicException { + return list((Object) null); + } + + /** + * + * @param params + * @return + * @throws BasicException + */ + @Override + public final List list(Object... params) throws BasicException { + return list((Object) params); + } + + /** + * + * @param params + * @return + * @throws BasicException + */ + @Override + public final List list(Object params) throws BasicException { + // En caso de error o lanza un pepinazo en forma de DataException + DataResultSet SRS = openExec(params); + List aSO = fetchAll(SRS); + SRS.close(); + closeExec(); + return aSO; + } + + /** + * + * @param offset + * @param length + * @return + * @throws BasicException + */ + @Override + public final List listPage(int offset, int length) throws BasicException { + return listPage(null, offset, length); + } + + /** + * + * @param params + * @param offset + * @param length + * @return + * @throws BasicException + */ + @Override + public final List listPage(Object params, int offset, int length) throws BasicException { + // En caso de error o lanza un pepinazo en forma de DataException + DataResultSet SRS = openExec(params); + List aSO = fetchPage(SRS, offset, length); + SRS.close(); + closeExec(); + return aSO; + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public final Object find() throws BasicException { + return find((Object) null); + } + + /** + * + * @param params + * @return + * @throws BasicException + */ + @Override + public final Object find(Object... params) throws BasicException { + return find((Object) params); + } + + /** + * + * @param params + * @return + * @throws BasicException + */ + @Override + public final Object find(Object params) throws BasicException { + // En caso de error o lanza un pepinazo en forma de SQLException + DataResultSet SRS = openExec(params); + Object obj = fetchOne(SRS); + SRS.close(); + closeExec(); + return obj; + } + + // Utilidades + + /** + * + * @param SRS + * @return + * @throws BasicException + */ + public final List fetchAll(DataResultSet SRS) throws BasicException { + if (SRS == null) { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + List aSO = new ArrayList(); + while (SRS.next()) { + aSO.add(SRS.getCurrent()); + } + return aSO; + } + + // Utilidades + + /** + * + * @param SRS + * @param offset + * @param length + * @return + * @throws BasicException + */ + public final List fetchPage(DataResultSet SRS, int offset, int length) throws BasicException { + + if (SRS == null) { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + if (offset < 0 || length < 0) { + throw new BasicException(LocalRes.getIntString("exception.nonegativelimits")); + } + + // Skip los primeros que no me importan + while (offset > 0 && SRS.next()) { + offset--; + } + + // me traigo tantos como me han dicho + List aSO = new ArrayList(); + if (offset == 0) { + while (length > 0 && SRS.next()) { + length--; + aSO.add(SRS.getCurrent()); + } + } + return aSO; + } + + /** + * + * @param SRS + * @return + * @throws BasicException + */ + public final Object fetchOne(DataResultSet SRS) throws BasicException { + + if (SRS == null) { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + if (SRS.next()) { + return SRS.getCurrent(); + } else { + return null; + } + } + + } diff --git a/src/main/java/com/unicenta/data/loader/BasicSentenceEnum.java b/src/main/java/com/unicenta/data/loader/BasicSentenceEnum.java new file mode 100644 index 0000000..4e18085 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/BasicSentenceEnum.java @@ -0,0 +1,89 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author adrian + */ +public class BasicSentenceEnum implements SentenceEnum { + + BaseSentence sent; + DataResultSet SRS; + + /** Creates a new instance of AbstractSentenceEnum + * @param sent */ + public BasicSentenceEnum(BaseSentence sent) { + this.sent = sent; + this.SRS = null; + } + + /** + * + * @throws BasicException + */ + public void load() throws BasicException { + load(null); + } + + /** + * + * @param params + * @throws BasicException + */ + public void load(Object params) throws BasicException { + SRS = sent.openExec(params); + } + + /** + * + * @return + * @throws BasicException + */ + public Object getCurrent() throws BasicException { + if (SRS == null) { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + return SRS.getCurrent(); + } + + /** + * + * @return + * @throws BasicException + */ + public boolean next() throws BasicException { + if (SRS == null) { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + if (SRS.next()) { + return true; + } else { + SRS.close(); + SRS = null; + sent.closeExec(); + return false; + } + } +} diff --git a/src/main/java/com/unicenta/data/loader/BatchSentence.java b/src/main/java/com/unicenta/data/loader/BatchSentence.java new file mode 100644 index 0000000..8eb9d7f --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/BatchSentence.java @@ -0,0 +1,345 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * + * @author JG uniCenta + */ +public abstract class BatchSentence extends BaseSentence { + + /** + * + */ + protected Session m_s; + + /** + * + */ + protected HashMap m_parameters; + + /** Creates a new instance of BatchSentence + * @param s */ + public BatchSentence(Session s) { + m_s = s; + m_parameters = new HashMap<>(); + } + + /** + * + * @param name + * @param replacement + */ + public void putParameter(String name, String replacement) { + m_parameters.put(name, replacement); + } + + /** + * + * @return + * @throws BasicException + */ + protected abstract Reader getReader() throws BasicException; + + /** + * + */ + public class ExceptionsResultSet implements DataResultSet { + + List l; + int m_iIndex; + + /** + * + * @param l + */ + public ExceptionsResultSet(List l) { + this.l = l; + m_iIndex = -1; + } + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + @Override + public Integer getInt(int columnIndex) throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + @Override + public String getString(int columnIndex) throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + @Override + public Double getDouble(int columnIndex) throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + @Override + public Boolean getBoolean(int columnIndex) throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + @Override + public java.util.Date getTimestamp(int columnIndex) throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + //public java.io.InputStream getBinaryStream(int columnIndex) throws DataException; + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + @Override + public byte[] getBytes(int columnIndex) throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + @Override + public Object getObject(int columnIndex) throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + // public int getColumnCount() throws DataException; + + /** + * + * @return + * @throws BasicException + */ + @Override + public DataField[] getDataField() throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object getCurrent() throws BasicException { + if (m_iIndex < 0 || m_iIndex >= l.size()) { + throw new BasicException(LocalRes.getIntString("exception.outofbounds")); + } else { + return l.get(m_iIndex); + } + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public boolean next() throws BasicException { + return ++m_iIndex < l.size(); + } + + /** + * + * @throws BasicException + */ + @Override + public void close() throws BasicException { + } + + /** + * + * @return + */ + @Override + public int updateCount() { + return 0; + } + } + + /** + * + * @throws BasicException + */ + @Override + public final void closeExec() throws BasicException { + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public final DataResultSet moreResults() throws BasicException { + return null; + } + + /** + * + * @param params + * @return + * @throws BasicException + */ + @Override + public DataResultSet openExec(Object params) throws BasicException { + + BufferedReader br = new BufferedReader(getReader()); + + String sLine; + StringBuffer sSentence = new StringBuffer(); + List aExceptions = new ArrayList(); + + try { + while ((sLine = br.readLine()) != null) { + sLine = sLine.trim(); + if (!sLine.equals("") && !sLine.startsWith("--")) { + // No es un comentario ni linea vacia + if (sLine.endsWith(";")) { + // ha terminado la sentencia + sSentence.append(sLine.substring(0, sLine.length() - 1)); + + // File parameters + Pattern pattern = Pattern.compile("\\$(\\w+)\\{([^}]*)\\}"); + Matcher matcher = pattern.matcher(sSentence.toString()); + List paramlist = new ArrayList(); + + // Replace all occurrences of pattern in input + StringBuffer buf = new StringBuffer(); + while (matcher.find()) { + if ("FILE".equals(matcher.group(1))) { + paramlist.add(ImageUtils.getBytesFromResource(matcher.group(2))); + matcher.appendReplacement(buf, "?"); + } else { + String replacement = m_parameters.get(matcher.group(1)); + if (replacement == null) { + matcher.appendReplacement(buf, Matcher.quoteReplacement(matcher.group(0))); + } else { + paramlist.add(replacement); + matcher.appendReplacement(buf, "?"); + } + } + } + matcher.appendTail(buf); + + // La disparo + try { + BaseSentence sent; + if (paramlist.isEmpty()) { + sent = new StaticSentence(m_s, buf.toString()); + sent.exec(); + } else { + sent = new PreparedSentence(m_s, buf.toString(), SerializerWriteBuilder.INSTANCE); + sent.exec(new VarParams(paramlist)); + } + } catch (BasicException eD) { + aExceptions.add(eD); + } + sSentence = new StringBuffer(); + + } else { + // la sentencia continua en la linea siguiente + sSentence.append(sLine); + } + } + } + + br.close(); + + } catch (IOException eIO) { + throw new BasicException(LocalRes.getIntString("exception.noreadfile"), eIO); + } + + if (sSentence.length() > 0) { + // ha quedado una sentencia inacabada + aExceptions.add(new BasicException(LocalRes.getIntString("exception.nofinishedfile"))); + } + + return new ExceptionsResultSet(aExceptions); + } + + private static class VarParams implements SerializableWrite { + + private List l; + + public VarParams(List l) { + this.l = l; + } + + @Override + public void writeValues(DataWrite dp) throws BasicException { + for (int i = 0; i < l.size(); i++) { + Object v = l.get(i); + if (v instanceof String) { + dp.setString(i + 1, (String) v); + } else if (v instanceof byte[]) { + dp.setBytes(i + 1, (byte[]) l.get(i)); + } else { + dp.setObject(i + 1, v); + } + } + } + } +} diff --git a/src/main/java/com/unicenta/data/loader/BatchSentenceResource.java b/src/main/java/com/unicenta/data/loader/BatchSentenceResource.java new file mode 100644 index 0000000..0027584 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/BatchSentenceResource.java @@ -0,0 +1,63 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import com.unicenta.basic.BasicException; +import java.io.UnsupportedEncodingException; + +/** + * + * @author adrianromero + */ +public class BatchSentenceResource extends BatchSentence { + + private String m_sResScript; + + /** Creates a new instance of BatchSentenceResource + * @param s + * @param resscript */ + public BatchSentenceResource(Session s, String resscript) { + super(s); + m_sResScript = resscript; + } + + /** + * + * @return + * @throws BasicException + */ + protected Reader getReader() throws BasicException { + + InputStream in = BatchSentenceResource.class.getResourceAsStream(m_sResScript); + + if (in == null) { + throw new BasicException(LocalRes.getIntString("exception.nosentencesfile")); + } else { + try { + return new InputStreamReader(in, "UTF-8"); + } catch (UnsupportedEncodingException ex) { + throw new BasicException(LocalRes.getIntString("exception.nosentencesfile"), ex); + } + } + } +} diff --git a/src/main/java/com/unicenta/data/loader/BatchSentenceScript.java b/src/main/java/com/unicenta/data/loader/BatchSentenceScript.java new file mode 100644 index 0000000..b0ea0e2 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/BatchSentenceScript.java @@ -0,0 +1,51 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + + +package com.unicenta.data.loader; + +import java.io.Reader; +import com.unicenta.basic.BasicException; + +/** + * + * @author adrianromero + */ +public class BatchSentenceScript extends BatchSentence { + + private String m_sScript; + + /** Creates a new instance of BatchSentenceScript + * @param s + * @param script */ + public BatchSentenceScript(Session s, String script) { + super(s); + m_sScript = script; + } + + /** + * + * @return + * @throws BasicException + */ + protected Reader getReader() throws BasicException { + + return new java.io.StringReader(m_sScript); + } +} diff --git a/src/main/java/com/unicenta/data/loader/CompanyDetails.java b/src/main/java/com/unicenta/data/loader/CompanyDetails.java new file mode 100644 index 0000000..71c0ce0 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/CompanyDetails.java @@ -0,0 +1,63 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + + +import com.unicenta.pos.forms.AppConfig; +import java.io.*; + +/** + * + * @author JG uniCenta + */ +public class CompanyDetails { + private String db_url; + private String db_user; + private String db_password; + private File m_config; + private Session session; + + /** + * + */ + public CompanyDetails() { + + AppConfig config = new AppConfig(m_config); +} + + /** + * + * @param config + */ + public void loadProperties(AppConfig config) { + + db_url=(config.getProperty("db.url")); + db_user=(config.getProperty("db_user")); + db_password=(config.getProperty("db.password")); +} + + /** + * + * @return + */ + public String getUser() { + return db_user; + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/data/loader/ComparatorCreator.java b/src/main/java/com/unicenta/data/loader/ComparatorCreator.java new file mode 100644 index 0000000..b760a10 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/ComparatorCreator.java @@ -0,0 +1,42 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import java.util.Comparator; + +/** + * + * @author JG uniCenta + */ +public interface ComparatorCreator { + + /** + * + * @return + */ + public String[] getHeaders(); + + /** + * + * @param index + * @return + */ + public Comparator createComparator(int[] index); +} diff --git a/src/main/java/com/unicenta/data/loader/ComparatorCreatorBasic.java b/src/main/java/com/unicenta/data/loader/ComparatorCreatorBasic.java new file mode 100644 index 0000000..e179cb4 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/ComparatorCreatorBasic.java @@ -0,0 +1,117 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import java.util.Comparator; + +/** + * + * @author JG uniCenta + */ +public class ComparatorCreatorBasic implements ComparatorCreator { + + private String[] m_sHeaders; + private Datas[] m_aDatas; + private int[] m_iAvailableIndexes; + + /** Creates a new instance of ComparatorCreatorBasic + * @param sHeaders + * @param aDatas + * @param iAvailableIndexes */ + public ComparatorCreatorBasic(String[] sHeaders, Datas[] aDatas, int[] iAvailableIndexes) { + + m_sHeaders = sHeaders; + m_aDatas = aDatas; + m_iAvailableIndexes = iAvailableIndexes; + } + + /** + * + * @param sHeaders + * @param aDatas + */ + public ComparatorCreatorBasic(String[] sHeaders, Datas[] aDatas) { + m_sHeaders = sHeaders; + m_aDatas = aDatas; + m_iAvailableIndexes = new int[aDatas.length]; + for (int i = 0; i < aDatas.length; i++) { + m_iAvailableIndexes[i] = i; + } + } + + /** + * + * @return + */ + public String[] getHeaders() { + + String[] sTempHeaders = new String[m_iAvailableIndexes.length]; + + for (int i = 0; i < m_iAvailableIndexes.length; i++) { + sTempHeaders[i] = m_sHeaders[m_iAvailableIndexes[i]]; + } + return sTempHeaders; + } + + /** + * + * @param aiOrderBy + * @return + */ + public Comparator createComparator(int[] aiOrderBy) { + return new ComparatorBasic(aiOrderBy); + } + + /** + * + */ + public class ComparatorBasic implements Comparator { + + private int[] m_aiOrderBy; + + /** Creates a new instance of ComparatorBasic + * @param aiOrderBy */ + public ComparatorBasic(int[] aiOrderBy) { + m_aiOrderBy = aiOrderBy; + } + public int compare(Object o1, Object o2) { + if (o1 == null) { + if (o2 == null) { + return 0; + } else { + return -1; + } + } else if (o2 == null) { + return +1; + } else { + // ninguno de los dos es nulo... + Object[] ao1 = (Object[]) o1; + Object[] ao2 = (Object[]) o2; + for (int i = 0; i < m_aiOrderBy.length; i++) { + int result = m_aDatas[m_iAvailableIndexes[m_aiOrderBy[i]]].compare(ao1[m_iAvailableIndexes[m_aiOrderBy[i]]], ao2[m_iAvailableIndexes[m_aiOrderBy[i]]]); + if (result != 0) { + return result; + } + } + return 0; + } + } + } +} diff --git a/src/main/java/com/unicenta/data/loader/DataField.java b/src/main/java/com/unicenta/data/loader/DataField.java new file mode 100644 index 0000000..ddf1ce8 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/DataField.java @@ -0,0 +1,46 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +/** + * + * @author JG uniCenta + */ +public class DataField { + + /** Creates a new instance of DataField */ + public DataField() { + } + + /** + * + */ + public String Name; + + /** + * + */ + public int Size; + + /** + * + */ + public int Type; +} diff --git a/src/main/java/com/unicenta/data/loader/DataParams.java b/src/main/java/com/unicenta/data/loader/DataParams.java new file mode 100644 index 0000000..68f33e8 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/DataParams.java @@ -0,0 +1,121 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; +import java.util.Date; + +/** + * + * @author adrianromero + */ +public abstract class DataParams implements DataWrite { + + /** + * + */ + protected DataWrite dw; + + /** + * + * @throws BasicException + */ + public abstract void writeValues() throws BasicException; + + /** + * + * @param paramIndex + * @param iValue + * @throws BasicException + */ + public void setInt(int paramIndex, Integer iValue) throws BasicException { + dw.setInt(paramIndex, iValue); + } + + public void setString(int paramIndex, String sValue) throws BasicException { + dw.setString(paramIndex, sValue); + } + + /** + * + * @param paramIndex + * @param dValue + * @throws BasicException + */ + public void setDouble(int paramIndex, Double dValue) throws BasicException { + dw.setDouble(paramIndex, dValue); + } + + /** + * + * @param paramIndex + * @param bValue + * @throws BasicException + */ + public void setBoolean(int paramIndex, Boolean bValue) throws BasicException { + dw.setBoolean(paramIndex, bValue); + } + + /** + * + * @param paramIndex + * @param dValue + * @throws BasicException + */ + public void setTimestamp(int paramIndex, Date dValue) throws BasicException { + dw.setTimestamp(paramIndex, dValue); + } + + /** + * + * @param paramIndex + * @param value + * @throws BasicException + */ + public void setBytes(int paramIndex, byte[] value) throws BasicException { + dw.setBytes(paramIndex, value); + } + + /** + * + * @param paramIndex + * @param value + * @throws BasicException + */ + public void setObject(int paramIndex, Object value) throws BasicException { + dw.setObject(paramIndex, value); + } + + /** + * + * @return + */ + public DataWrite getDataWrite() { + return dw; + } + + /** + * + * @param dw + */ + public void setDataWrite(DataWrite dw) { + this.dw = dw; + } +} diff --git a/src/main/java/com/unicenta/data/loader/DataRead.java b/src/main/java/com/unicenta/data/loader/DataRead.java new file mode 100644 index 0000000..a80fa96 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/DataRead.java @@ -0,0 +1,96 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author adrian + */ +public interface DataRead { + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + public Integer getInt(int columnIndex) throws BasicException; + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + public String getString(int columnIndex) throws BasicException; + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + public Double getDouble(int columnIndex) throws BasicException; + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + public Boolean getBoolean(int columnIndex) throws BasicException; + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + public java.util.Date getTimestamp(int columnIndex) throws BasicException; + + //public java.io.InputStream getBinaryStream(int columnIndex) throws DataException; + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + public byte[] getBytes(int columnIndex) throws BasicException; + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + public Object getObject(int columnIndex) throws BasicException ; + +// public int getColumnCount() throws DataException; + + /** + * + * @return + * @throws BasicException + */ + public DataField[] getDataField() throws BasicException; +} diff --git a/src/main/java/com/unicenta/data/loader/DataResultSet.java b/src/main/java/com/unicenta/data/loader/DataResultSet.java new file mode 100644 index 0000000..cca22f3 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/DataResultSet.java @@ -0,0 +1,56 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public interface DataResultSet extends DataRead { + + /** + * + * @return + * @throws BasicException + */ + public Object getCurrent() throws BasicException; + + /** + * + * @return + * @throws BasicException + */ + public boolean next() throws BasicException; + + /** + * + * @throws BasicException + */ + public void close() throws BasicException; + + /** + * + * @return + * @throws BasicException + */ + public int updateCount() throws BasicException; +} diff --git a/src/main/java/com/unicenta/data/loader/DataWrite.java b/src/main/java/com/unicenta/data/loader/DataWrite.java new file mode 100644 index 0000000..606d6bb --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/DataWrite.java @@ -0,0 +1,86 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author adrian + */ +public interface DataWrite { + + /** + * + * @param paramIndex + * @param iValue + * @throws BasicException + */ + public void setInt(int paramIndex, Integer iValue) throws BasicException; + /** + * + * @param paramIndex + * @param sValue + * @throws BasicException + */ + public void setString(int paramIndex, String sValue) throws BasicException; + + /** + * + * @param paramIndex + * @param dValue + * @throws BasicException + */ + public void setDouble(int paramIndex, Double dValue) throws BasicException; + + /** + * + * @param paramIndex + * @param bValue + * @throws BasicException + */ + public void setBoolean(int paramIndex, Boolean bValue) throws BasicException; + + /** + * + * @param paramIndex + * @param dValue + * @throws BasicException + */ + public void setTimestamp(int paramIndex, java.util.Date dValue) throws BasicException; + + //public void setBinaryStream(int paramIndex, java.io.InputStream in, int length) throws DataException; + + /** + * + * @param paramIndex + * @param value + * @throws BasicException + */ + public void setBytes(int paramIndex, byte[] value) throws BasicException; + + /** + * + * @param paramIndex + * @param value + * @throws BasicException + */ + public void setObject(int paramIndex, Object value) throws BasicException; +} diff --git a/src/main/java/com/unicenta/data/loader/DataWriteUtils.java b/src/main/java/com/unicenta/data/loader/DataWriteUtils.java new file mode 100644 index 0000000..faaa098 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/DataWriteUtils.java @@ -0,0 +1,156 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import java.sql.Timestamp; +import java.util.Date; +import java.text.DateFormat; +import java.text.SimpleDateFormat; + +/** + * + * @author adrian + */ +public class DataWriteUtils { + + + /** Creates a new instance of DataWriteUtils */ + public DataWriteUtils() { + } + + /** + * + * @param obj + * @return + */ + public static String getSQLValue(Object obj) { + if (obj == null) { + return "NULL"; + } else if (obj instanceof Double) { + return getSQLValue((Double) obj); + } else if (obj instanceof Integer) { + return getSQLValue((Integer) obj); + } else if (obj instanceof Boolean) { + return getSQLValue((Boolean) obj); + } else if (obj instanceof String) { + return getSQLValue((String) obj); + } else if (obj instanceof Date) { + return getSQLValue((Date) obj); + } else { + return getSQLValue(obj.toString()); + } + } + + /** + * + * @param iValue + * @return + */ + public static String getSQLValue(Integer iValue) { + if (iValue == null) { + return "NULL"; + } else { + return iValue.toString(); + } + } + + /** + * + * @param dValue + * @return + */ + public static String getSQLValue(Double dValue) { + if (dValue == null) { + return "NULL"; + } else { + return dValue.toString(); + } + } + + /** + * + * @param bValue + * @return + */ + public static String getSQLValue(Boolean bValue) { + if (bValue == null) { + return "NULL"; + } else { + return bValue.booleanValue() ? "TRUE" : "FALSE"; + } + } + + /** + * + * @param sValue + * @return + */ + public static String getSQLValue(String sValue) { + if (sValue == null) { + return "NULL"; + } else { + return '\'' + getEscaped(sValue) + '\''; + } + } + + /** + * + * @param dValue + * @return + */ + public static String getSQLValue(Date dValue) { + if (dValue == null) { + return "NULL"; + } else { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String date = sdf.format(dValue); + return "'"+date+"'"; + } + } + + /** + * + * @param sValue + * @return + */ + public static String getEscaped(String sValue) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < sValue.length(); i++) { + switch (sValue.charAt(i)) { + case '\\': + sb.append("\\\\"); + break; + case '\'': + sb.append("\\'"); + break; + case '\n': + sb.append("\\n"); + break; + case '\r': + sb.append("\\r"); + break; + default: + sb.append(sValue.charAt(i)); + break; + } + } + return sb.toString(); + } + } diff --git a/src/main/java/com/unicenta/data/loader/Datas.java b/src/main/java/com/unicenta/data/loader/Datas.java new file mode 100644 index 0000000..81db461 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/Datas.java @@ -0,0 +1,388 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; + +/** + * @author JG uniCenta + */ +public abstract class Datas { + + /** + * + */ + public final static Datas INT = new DatasINT(); + + /** + * + */ + public final static Datas STRING = new DatasSTRING(); + + /** + * + */ + public final static Datas DOUBLE = new DatasDOUBLE(); + + /** + * + */ + public final static Datas BOOLEAN = new DatasBOOLEAN(); + + /** + * + */ + public final static Datas TIMESTAMP = new DatasTIMESTAMP(); + + /** + * + */ + public final static Datas BYTES = new DatasBYTES(); + + /** + * + */ + public final static Datas IMAGE = new DatasIMAGE(); + //public final static Datas INPUTSTREAM = new DatasINPUTSTREAM(); + + /** + * + */ + public final static Datas OBJECT = new DatasOBJECT(); + + /** + * + */ + public final static Datas SERIALIZABLE = new DatasSERIALIZABLE(); + + /** + * + */ + public final static Datas NULL = new DatasNULL(); + + private static DateFormat tsf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + + /** + * Creates a new instance of Datas + */ + private Datas() { + } + + /** + * @param dr + * @param i + * @return + * @throws BasicException + */ + public abstract Object getValue(DataRead dr, int i) throws BasicException; + + /** + * @param dw + * @param i + * @param value + * @throws BasicException + */ + public abstract void setValue(DataWrite dw, int i, Object value) throws BasicException; + + /** + * @return + */ + public abstract Class getClassValue(); + + /** + * @param value + * @return + */ + protected abstract String toStringAbstract(Object value); + + /** + * @param o1 + * @param o2 + * @return + */ + protected abstract int compareAbstract(Object o1, Object o2); + + /** + * @param value + * @return + */ + public String toString(Object value) { + if (value == null) { + return "null"; + } else { + return toStringAbstract(value); + } + } + + /** + * @param o1 + * @param o2 + * @return + */ + public int compare(Object o1, Object o2) { + if (o1 == null) { + if (o2 == null) { + return 0; + } else { + return -1; + } + } else if (o2 == null) { + return +1; + } else { + return compareAbstract(o1, o2); + } + } + + private static final class DatasINT extends Datas { + public Object getValue(DataRead dr, int i) throws BasicException { + return dr.getInt(i); + } + + public void setValue(DataWrite dw, int i, Object value) throws BasicException { + dw.setInt(i, (Integer) value); + } + + public Class getClassValue() { + return java.lang.Integer.class; + } + + protected String toStringAbstract(Object value) { + return ((Integer) value).toString(); + } + + protected int compareAbstract(Object o1, Object o2) { + return ((Integer) o1).compareTo((Integer) o2); + } + } + + private static final class DatasSTRING extends Datas { + public Object getValue(DataRead dr, int i) throws BasicException { + return dr.getString(i); + } + + public void setValue(DataWrite dw, int i, Object value) throws BasicException { + dw.setString(i, (String) value); + } + + public Class getClassValue() { + return java.lang.String.class; + } + + protected String toStringAbstract(Object value) { + return "\'" + DataWriteUtils.getEscaped((String) value) + "\'"; + } + + protected int compareAbstract(Object o1, Object o2) { + return ((String) o1).compareTo((String) o2); + } + } + + private static final class DatasDOUBLE extends Datas { + public Object getValue(DataRead dr, int i) throws BasicException { + return dr.getDouble(i); + } + + public void setValue(DataWrite dw, int i, Object value) throws BasicException { + dw.setDouble(i, (Double) value); + } + + public Class getClassValue() { + return java.lang.Double.class; + } + + protected String toStringAbstract(Object value) { + return ((Double) value).toString(); + } + + protected int compareAbstract(Object o1, Object o2) { + return ((Double) o1).compareTo((Double) o2); + } + } + + private static final class DatasBOOLEAN extends Datas { + public Object getValue(DataRead dr, int i) throws BasicException { + return dr.getBoolean(i); + } + + public void setValue(DataWrite dw, int i, Object value) throws BasicException { + dw.setBoolean(i, (Boolean) value); + } + + public Class getClassValue() { + return java.lang.Boolean.class; + } + + protected String toStringAbstract(Object value) { + return ((Boolean) value).toString(); + } + + protected int compareAbstract(Object o1, Object o2) { + return ((Boolean) o1).compareTo((Boolean) o2); + } + } + + private static final class DatasTIMESTAMP extends Datas { + public Object getValue(DataRead dr, int i) throws BasicException { + return dr.getTimestamp(i); + } + + public void setValue(DataWrite dw, int i, Object value) throws BasicException { + dw.setTimestamp(i, (java.util.Date) value); + } + + public Class getClassValue() { + return java.util.Date.class; + } + + protected String toStringAbstract(Object value) { + return tsf.format(value); + } + + protected int compareAbstract(Object o1, Object o2) { + return ((java.util.Date) o1).compareTo((java.util.Date) o2); + } + } + + private static final class DatasBYTES extends Datas { + public Object getValue(DataRead dr, int i) throws BasicException { + return dr.getBytes(i); + } + + public void setValue(DataWrite dw, int i, Object value) throws BasicException { + dw.setBytes(i, (byte[]) value); + } + + public Class getClassValue() { + return byte[].class; + } + + protected String toStringAbstract(Object value) { + return "0x" + ImageUtils.bytes2hex((byte[]) value); + } + + protected int compareAbstract(Object o1, Object o2) { + throw new UnsupportedOperationException(); + } + } + + private static final class DatasIMAGE extends Datas { + @Override + public Object getValue(DataRead dr, int i) throws BasicException { + return ImageUtils.readImage(dr.getBytes(i)); + } + + @Override + public void setValue(DataWrite dw, int i, Object value) throws BasicException { + dw.setBytes(i, ImageUtils.writeImage((java.awt.image.BufferedImage) value)); + } + + @Override + public Class getClassValue() { + return java.awt.image.BufferedImage.class; + } + + @Override + protected String toStringAbstract(Object value) { + return "0x" + ImageUtils.bytes2hex(ImageUtils.writeImage((java.awt.image.BufferedImage) value)); + } + + @Override + protected int compareAbstract(Object o1, Object o2) { + throw new UnsupportedOperationException(); + } + } + + // private static final class DatasINPUTSTREAM extends Datas { +// public Object getValue(DataRead dr, int i) throws DataException { +// byte[] b = dr.getBytes(i); +// return b == null ? null : new java.io.ByteArrayInputStream(b); +// } +// public void setValue(DataWrite dw, int i, Object value) throws DataException { +// } +// } + private static final class DatasOBJECT extends Datas { + public Object getValue(DataRead dr, int i) throws BasicException { + return dr.getObject(i); + } + + public void setValue(DataWrite dw, int i, Object value) throws BasicException { + dw.setObject(i, value); + } + + public Class getClassValue() { + return java.lang.Object.class; + } + + protected String toStringAbstract(Object value) { + return "0x" + ImageUtils.bytes2hex(ImageUtils.writeSerializable(value)); + } + + protected int compareAbstract(Object o1, Object o2) { + throw new UnsupportedOperationException(); + } + } + + private static final class DatasSERIALIZABLE extends Datas { + public Object getValue(DataRead dr, int i) throws BasicException { + return ImageUtils.readSerializable(dr.getBytes(i)); + } + + public void setValue(DataWrite dw, int i, Object value) throws BasicException { + dw.setBytes(i, ImageUtils.writeSerializable(value)); + } + + public Class getClassValue() { + return java.lang.Object.class; + } + + protected String toStringAbstract(Object value) { + return "0x" + ImageUtils.bytes2hex(ImageUtils.writeSerializable(value)); + } + + protected int compareAbstract(Object o1, Object o2) { + throw new UnsupportedOperationException(); + } + } + + private static final class DatasNULL extends Datas { + public Object getValue(DataRead dr, int i) throws BasicException { + return null; + } + + public void setValue(DataWrite dw, int i, Object value) throws BasicException { + // No asigno null, no asigno nada. + } + + public Class getClassValue() { + return java.lang.Object.class; + } + + protected String toStringAbstract(Object value) { + return "null"; + } + + protected int compareAbstract(Object o1, Object o2) { + throw new UnsupportedOperationException(); + } + } +} diff --git a/src/main/java/com/unicenta/data/loader/IKeyGetter.java b/src/main/java/com/unicenta/data/loader/IKeyGetter.java new file mode 100644 index 0000000..f24cc1b --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/IKeyGetter.java @@ -0,0 +1,34 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +/** + * + * @author JG uniCenta + */ +public interface IKeyGetter { + + /** + * + * @param value + * @return + */ + public Object getKey(Object value); +} diff --git a/src/main/java/com/unicenta/data/loader/IKeyed.java b/src/main/java/com/unicenta/data/loader/IKeyed.java new file mode 100644 index 0000000..b7f7431 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/IKeyed.java @@ -0,0 +1,35 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +/** + * + * @author adrianromero + * Created on 27 de febrero de 2007, 22:08 + * + */ +public interface IKeyed { + + /** + * + * @return + */ + public Object getKey(); +} diff --git a/src/main/java/com/unicenta/data/loader/IRenderString.java b/src/main/java/com/unicenta/data/loader/IRenderString.java new file mode 100644 index 0000000..f656c8f --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/IRenderString.java @@ -0,0 +1,34 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +/** + * + * @author JG uniCenta + */ +public interface IRenderString { + + /** + * + * @param value + * @return + */ + public String getRenderString(Object value); +} diff --git a/src/main/java/com/unicenta/data/loader/ISQLBuilderStatic.java b/src/main/java/com/unicenta/data/loader/ISQLBuilderStatic.java new file mode 100644 index 0000000..6d17064 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/ISQLBuilderStatic.java @@ -0,0 +1,38 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public interface ISQLBuilderStatic { + + /** + * + * @param sw + * @param params + * @return + * @throws BasicException + */ + public String getSQL(SerializerWrite sw, Object params) throws BasicException; +} diff --git a/src/main/java/com/unicenta/data/loader/ImageUtils.java b/src/main/java/com/unicenta/data/loader/ImageUtils.java new file mode 100644 index 0000000..ab9cbef --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/ImageUtils.java @@ -0,0 +1,245 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import java.io.*; +import javax.imageio.ImageIO; +import java.awt.image.*; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.Properties; + +/** + * + * @author JG uniCenta + */ +public class ImageUtils { + + private static char[] HEXCHARS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + + /** Creates a new instance of ImageUtils */ + private ImageUtils() { + } + + private static byte[] readStream(InputStream in) throws IOException { + byte[] buffer = new byte[1024]; + byte[] resource = new byte[0]; + int n; + + while ((n = in.read(buffer)) != -1) { + byte[] b = new byte[resource.length + n]; + System.arraycopy(resource, 0, b, 0, resource.length); + System.arraycopy(buffer, 0, b, resource.length, n); + resource = b; + } + return resource; + } + + /** + * + * @param file + * @return + */ + public static byte[] getBytesFromResource(String file) { + + InputStream in = ImageUtils.class.getResourceAsStream(file); + + if (in == null) { + return null; + } else { + try { + return ImageUtils.readStream(in); + } catch (IOException e) { + return new byte[0]; + } finally { + try { + in.close(); + } catch (IOException e) { + } + } + } + } + + /** + * + * @param file + * @return + */ + public static BufferedImage readImageFromResource(String file) { + return readImage(getBytesFromResource(file)); + } + + /** + * + * @param url + * @return + */ + public static BufferedImage readImage(String url) { + try { + return readImage(new URL(url)); + } catch (MalformedURLException e) { + return null; + } + } + + /** + * + * @param url + * @return + */ + public static BufferedImage readImage(URL url) { + + InputStream in = null; + + try { + URLConnection urlConnection = url.openConnection(); + in = urlConnection.getInputStream(); + return readImage(readStream(in)); + } catch (IOException e) { + return null; + } finally { + try { + if (in != null) { + in.close(); + } + } catch (IOException e) { + } + } + } + + /** + * + * @param b + * @return + */ + public static BufferedImage readImage(byte[] b) { + if (b == null) { + return null; + } else { + try { + return ImageIO.read(new ByteArrayInputStream(b)); + } catch(IOException e) { + return null; + } + } + } + + /** + * + * @param img + * @return + */ + public static byte[] writeImage(BufferedImage img) { + if (img == null) { + return null; + } else { + try { + ByteArrayOutputStream b = new ByteArrayOutputStream(); + ImageIO.write(img, "png", b); + b.flush(); + b.close(); + return b.toByteArray(); + } catch(IOException e) { + return null; + } + } + } + + /** + * + * @param b + * @return + */ + public static Object readSerializable(byte[] b) { + if (b == null) { + return null; + } else { + try { + ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(b)); + Object obj = in.readObject(); + in.close(); + return obj; + } catch (ClassNotFoundException eCNF) { + //logger.error("Cannot create lists object", eCNF); + return null; + } catch (IOException eIO) { + //logger.error("Cannot load lists file", eIO); + return null; + } + } + } + + /** + * + * @param o + * @return + */ + public static byte[] writeSerializable(Object o) { + + if (o == null) { + return null; + } else { + try { + ByteArrayOutputStream b = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(b); + out.writeObject(o); + out.flush(); + out.close(); + return b.toByteArray(); + } catch (IOException eIO) { + eIO.printStackTrace(); + return null; + } + } + } + + /** + * + * @param b + * @return + */ + public static Properties readProperties(byte b[]) { + Properties prop = new Properties(); + try { + if (b != null) { + prop.loadFromXML(new ByteArrayInputStream(b)); + } + } catch (IOException e) { + } + return prop; + } + + /** + * + * @param binput + * @return + */ + public static String bytes2hex(byte[] binput) { + + StringBuilder s = new StringBuilder(binput.length *2); + for (int i = 0; i < binput.length; i++) { + byte b = binput[i]; + s.append(HEXCHARS[(b & 0xF0) >> 4]); + s.append(HEXCHARS[b & 0x0F]); + } + return s.toString(); + } +} diff --git a/src/main/java/com/unicenta/data/loader/ImportSentence.java b/src/main/java/com/unicenta/data/loader/ImportSentence.java new file mode 100644 index 0000000..0c96b4f --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/ImportSentence.java @@ -0,0 +1,62 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author adrian + */ +public class ImportSentence extends BaseSentence { + + /** Creates a new instance of ImportSentence */ + public ImportSentence() { + } + + /** + * + * @throws BasicException + */ + @Override + public void closeExec() throws BasicException { + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public DataResultSet moreResults() throws BasicException { + return null; + } + + /** + * + * @param params + * @return + * @throws BasicException + */ + @Override + public DataResultSet openExec(Object params) throws BasicException { + return null; + } +} diff --git a/src/main/java/com/unicenta/data/loader/JDBCSentence.java b/src/main/java/com/unicenta/data/loader/JDBCSentence.java new file mode 100644 index 0000000..f399909 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/JDBCSentence.java @@ -0,0 +1,236 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; +import java.sql.*; + +/** + * + * @author JG uniCenta + */ +public abstract class JDBCSentence extends BaseSentence { + + // Conexion + // protected Connection m_c; + + /** + * + */ + protected Session session; + + /** Creates a new instance of BaseSentence + * @param session */ + public JDBCSentence(Session session) { + super(); + this.session = session; + } + + /** + * + */ + protected static final class JDBCDataResultSet implements DataResultSet { + + private ResultSet m_rs; + private SerializerRead m_serread; +// private int m_iColumnCount; + + /** + * + * @param rs + * @param serread + */ + public JDBCDataResultSet(ResultSet rs, SerializerRead serread) { + m_rs = rs; + m_serread = serread; +// m_iColumnCount = -1; + } + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + public Integer getInt(int columnIndex) throws BasicException { + try { + int iValue = m_rs.getInt(columnIndex); + return m_rs.wasNull() ? null : new Integer(iValue); + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + public String getString(int columnIndex) throws BasicException { + try { + return m_rs.getString(columnIndex); + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + public Double getDouble(int columnIndex) throws BasicException { + try { + double dValue = m_rs.getDouble(columnIndex); + return m_rs.wasNull() ? null : new Double(dValue); + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + public Boolean getBoolean(int columnIndex) throws BasicException { + try { + boolean bValue = m_rs.getBoolean(columnIndex); + return m_rs.wasNull() ? null : new Boolean(bValue); + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + public java.util.Date getTimestamp(int columnIndex) throws BasicException { + try { + java.sql.Timestamp ts = m_rs.getTimestamp(columnIndex); + return ts == null ? null : new java.util.Date(ts.getTime()); + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + public byte[] getBytes(int columnIndex) throws BasicException { + try { + return m_rs.getBytes(columnIndex); + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + public Object getObject(int columnIndex) throws BasicException { + try { + return m_rs.getObject(columnIndex); + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } + + /** + * + * @return + * @throws BasicException + */ + public DataField[] getDataField() throws BasicException { + try { + ResultSetMetaData md = m_rs.getMetaData(); + DataField[] df = new DataField[md.getColumnCount()]; + for (int i = 0; i < df.length; i++) { + df[i] = new DataField(); + df[i].Name = md.getColumnName(i + 1); + df[i].Size = md.getColumnDisplaySize(i + 1); + df[i].Type = md.getColumnType(i + 1); + } + return df; + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object getCurrent() throws BasicException { + return m_serread.readValues(this); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public boolean next() throws BasicException { + try { + return m_rs.next(); + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } + + /** + * + * @throws BasicException + */ + @Override + public void close() throws BasicException { + try { + m_rs.close(); + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public int updateCount() throws BasicException { + return -1; // es decir somos datos. + } + } +} diff --git a/src/main/java/com/unicenta/data/loader/KeyGetterBasic.java b/src/main/java/com/unicenta/data/loader/KeyGetterBasic.java new file mode 100644 index 0000000..3f63b95 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/KeyGetterBasic.java @@ -0,0 +1,54 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + + +package com.unicenta.data.loader; + +/** + * + * @author adrian + */ +public class KeyGetterBasic implements IKeyGetter { + + private int [] m_aElems; + + /** Creates a new instance of KeyGetterBasic + * @param aElems */ + public KeyGetterBasic(int[] aElems) { + m_aElems = aElems; + } + + /** + * + * @param value + * @return + */ + public Object getKey(Object value) { + if (value == null) { + return null; + } else { + Object[] avalue = (Object []) value; + Object[] akey = new Object[m_aElems.length]; + for (int i = 0; i < m_aElems.length; i++) { + akey[i] = avalue[m_aElems[i]]; + } + return akey; + } + } +} diff --git a/src/main/java/com/unicenta/data/loader/KeyGetterBuilder.java b/src/main/java/com/unicenta/data/loader/KeyGetterBuilder.java new file mode 100644 index 0000000..b0c78fe --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/KeyGetterBuilder.java @@ -0,0 +1,51 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +/** + * + * @author adrianromero + * Created on 27 de febrero de 2007, 22:09 + * + */ +public class KeyGetterBuilder implements IKeyGetter { + + /** + * + */ + public final static IKeyGetter INSTANCE = new KeyGetterBuilder(); + + /** Creates a new instance of KeyGetterBuilder */ + public KeyGetterBuilder() { + } + + /** + * + * @param value + * @return + */ + @Override + public Object getKey(Object value) { + + return (value == null) + ? null + : ((IKeyed) value).getKey(); + } +} diff --git a/src/main/java/com/unicenta/data/loader/KeyGetterFirst.java b/src/main/java/com/unicenta/data/loader/KeyGetterFirst.java new file mode 100644 index 0000000..444c98c --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/KeyGetterFirst.java @@ -0,0 +1,50 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +/** + * + * @author adrian + */ +public class KeyGetterFirst implements IKeyGetter { + + private final int [] m_aElems; + + /** Creates a new instance of KeyGetterBasic + * @param aElems */ + public KeyGetterFirst(int[] aElems) { + m_aElems = aElems; + } + + /** + * + * @param value + * @return + */ + @Override + public Object getKey(Object value) { + if (value == null) { + return null; + } else { + Object[] avalue = (Object []) value; + return avalue[m_aElems[0]]; + } + } +} diff --git a/src/main/java/com/unicenta/data/loader/LocalRes.java b/src/main/java/com/unicenta/data/loader/LocalRes.java new file mode 100644 index 0000000..5d8fa67 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/LocalRes.java @@ -0,0 +1,51 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import java.util.MissingResourceException; +import com.unicenta.beans.LocaleResources; + +/** + * + * @author JG uniCenta + */ +public class LocalRes { + + // private static ResourceBundle m_Intl; + private static LocaleResources m_resources; + + static { + m_resources = new LocaleResources(); + m_resources.addBundleName("data_messages"); + } + + /** Creates a new instance of LocalRes */ + private LocalRes() { + } + + /** + * + * @param sKey + * @return + */ + public static String getIntString(String sKey) { + return m_resources.getString(sKey); + } +} diff --git a/src/main/java/com/unicenta/data/loader/MetaSentence.java b/src/main/java/com/unicenta/data/loader/MetaSentence.java new file mode 100644 index 0000000..20b3abd --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/MetaSentence.java @@ -0,0 +1,212 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import java.sql.*; +import java.util.*; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public class MetaSentence extends JDBCSentence { + + private String m_sSentence; + + /** + * + */ + protected SerializerRead m_SerRead = null; + + /** + * + */ + protected SerializerWrite m_SerWrite = null; + + /** Creates a new instance of MetaDataSentence + * @param s + * @param sSentence + * @param serwrite + * @param serread */ + public MetaSentence(Session s, String sSentence, SerializerWrite serwrite, SerializerRead serread) { + super(s); + m_sSentence = sSentence; + m_SerWrite = serwrite; + m_SerRead = serread; + } + + /** + * + * @param s + * @param sSentence + * @param serread + */ + public MetaSentence(Session s, String sSentence, SerializerRead serread) { + this(s, sSentence, null, serread); + } + + private static class MetaParameter implements DataWrite { + + private ArrayList m_aParams; + + /** Creates a new instance of MetaParameter */ + public MetaParameter() { + m_aParams = new ArrayList(); + } + + public void setDouble(int paramIndex, Double dValue) throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.noparamtype")); + } + public void setBoolean(int paramIndex, Boolean bValue) throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.noparamtype")); + } + public void setInt(int paramIndex, Integer iValue) throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.noparamtype")); + } + public void setString(int paramIndex, String sValue) throws BasicException { + ensurePlace(paramIndex - 1); + m_aParams.set(paramIndex - 1, sValue); + } + public void setTimestamp(int paramIndex, java.util.Date dValue) throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.noparamtype")); + } +// public void setBinaryStream(int paramIndex, java.io.InputStream in, int length) throws DataException { +// throw new DataException("Param type not allowed"); +// } + public void setBytes(int paramIndex, byte[] value) throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.noparamtype")); + } + public void setObject(int paramIndex, Object value) throws BasicException { + setString(paramIndex, (value == null) ? null : value.toString()); + } + + public String getString(int index) { + return (String) m_aParams.get(index); + } + + private void ensurePlace(int i) { + m_aParams.ensureCapacity(i); + while (i >= m_aParams.size()){ + m_aParams.add(null); + } + } + } + + /** + * + * @param params + * @return + * @throws BasicException + */ + public DataResultSet openExec(Object params) throws BasicException { + + closeExec(); + + try { + DatabaseMetaData db = session.getConnection().getMetaData(); + + MetaParameter mp = new MetaParameter(); + if (params != null) { + // si m_SerWrite fuera null deberiamos cascar + m_SerWrite.writeValues(mp, params); + } + + // Catalogs Has Schemas Has Objects + + // Lo generico de la base de datos + if ("getCatalogs".equals(m_sSentence)) { + return new JDBCDataResultSet(db.getCatalogs(), m_SerRead); + } else if ("getSchemas".equals(m_sSentence)) { + return new JDBCDataResultSet(db.getSchemas(), m_SerRead); + } else if ("getTableTypes".equals(m_sSentence)) { + return new JDBCDataResultSet(db.getTableTypes(), m_SerRead); + } else if ("getTypeInfo".equals(m_sSentence)) { + return new JDBCDataResultSet(db.getTypeInfo(), m_SerRead); + + // Los objetos por catalogo, esquema + + // Los tipos definidos por usuario + } else if ("getUDTs".equals(m_sSentence)) { + return new JDBCDataResultSet(db.getUDTs(mp.getString(0), mp.getString(1), null, null), m_SerRead); + } else if ("getSuperTypes".equals(m_sSentence)) { + return new JDBCDataResultSet(db.getSuperTypes(mp.getString(0), mp.getString(1), mp.getString(2)), m_SerRead); + + // Los atributos + } else if ("getAttributes".equals(m_sSentence)) { + return new JDBCDataResultSet(db.getAttributes(mp.getString(0), mp.getString(1), null, null), m_SerRead); + + // Las Tablas y sus objetos relacionados + } else if ("getTables".equals(m_sSentence)) { + return new JDBCDataResultSet(db.getTables(mp.getString(0), mp.getString(1), null, null), m_SerRead); + } else if ("getSuperTables".equals(m_sSentence)) { + return new JDBCDataResultSet(db.getSuperTables(mp.getString(0), mp.getString(1), mp.getString(2)), m_SerRead); + } else if ("getTablePrivileges".equals(m_sSentence)) { + return new JDBCDataResultSet(db.getTablePrivileges(mp.getString(0), mp.getString(1), mp.getString(2)), m_SerRead); + } else if ("getBestRowIdentifier".equals(m_sSentence)) { + return new JDBCDataResultSet(db.getBestRowIdentifier(mp.getString(0), mp.getString(1), mp.getString(2), 0, true), m_SerRead); + } else if ("getPrimaryKeys".equals(m_sSentence)) { + return new JDBCDataResultSet(db.getPrimaryKeys(mp.getString(0), mp.getString(1), mp.getString(2)), m_SerRead); + } else if ("getColumnPrivileges".equals(m_sSentence)) { + return new JDBCDataResultSet(db.getColumnPrivileges(mp.getString(0), mp.getString(1), mp.getString(2), null), m_SerRead); + } else if ("getColumns".equals(m_sSentence)) { + return new JDBCDataResultSet(db.getColumns(mp.getString(0), mp.getString(1), mp.getString(2), null), m_SerRead); + } else if ("getVersionColumns".equals(m_sSentence)) { + return new JDBCDataResultSet(db.getVersionColumns(mp.getString(0), mp.getString(1), mp.getString(2)), m_SerRead); + } else if ("getIndexInfo".equals(m_sSentence)) { + return new JDBCDataResultSet(db.getIndexInfo(mp.getString(0), mp.getString(1), mp.getString(2), false, false), m_SerRead); + } else if ("getExportedKeys".equals(m_sSentence)) { + return new JDBCDataResultSet(db.getExportedKeys(mp.getString(0), mp.getString(1), mp.getString(2)), m_SerRead); + } else if ("getImportedKeys".equals(m_sSentence)) { + return new JDBCDataResultSet(db.getImportedKeys(mp.getString(0), mp.getString(1), mp.getString(2)), m_SerRead); + } else if ("getCrossReference".equals(m_sSentence)) { + return new JDBCDataResultSet(db.getCrossReference(mp.getString(0), mp.getString(1), mp.getString(2), null, null, null), m_SerRead); + + // Los procedimientos y sus objetos relacionados + } else if ("getProcedures".equals(m_sSentence)) { + return new JDBCDataResultSet(db.getProcedures(mp.getString(0), mp.getString(1), null), m_SerRead); + } else if ("getProcedureColumns".equals(m_sSentence)) { + return new JDBCDataResultSet(db.getProcedureColumns(mp.getString(0), mp.getString(1), mp.getString(2), null), m_SerRead); + + } else { + return null; + } + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } + + /** + * + * @throws BasicException + */ + public void closeExec() throws BasicException { + } + + /** + * + * @return + * @throws BasicException + */ + public DataResultSet moreResults() throws BasicException { + return null; + } +} diff --git a/src/main/java/com/unicenta/data/loader/NormalBuilder.java b/src/main/java/com/unicenta/data/loader/NormalBuilder.java new file mode 100644 index 0000000..9c1dbc4 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/NormalBuilder.java @@ -0,0 +1,136 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import java.util.*; +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public class NormalBuilder implements ISQLBuilderStatic { + + public String sentence; + + /** Creates a new instance of NormalBuilder + * @param sSentence */ + public NormalBuilder(String sSentence) { + sentence = sSentence; + } + + /** + * + * @param write + * @param params + * @return + * @throws BasicException + */ + @Override + public String getSQL(SerializerWrite write, Object params) throws BasicException { + + NormalParameter normalParameter = new NormalParameter(sentence); + if (write != null) { + write.writeValues(normalParameter, params); + } + return normalParameter.getSentence(); + } + private static class NormalParameter implements DataWrite { + + private String m_sSentence; + private ArrayList m_aParams; // of String + + public NormalParameter(String sSentence) { + m_sSentence = sSentence; + m_aParams = new ArrayList(); + } + + @Override + public void setDouble(int paramIndex, Double dValue) throws BasicException { + ensurePlace(paramIndex - 1); + m_aParams.set(paramIndex - 1, DataWriteUtils.getSQLValue(dValue)); + } + + @Override + public void setBoolean(int paramIndex, Boolean bValue) throws BasicException { + ensurePlace(paramIndex - 1); + m_aParams.set(paramIndex - 1, DataWriteUtils.getSQLValue(bValue)); + } + @Override + public void setInt(int paramIndex, Integer iValue) throws BasicException { + ensurePlace(paramIndex - 1); + m_aParams.set(paramIndex - 1, DataWriteUtils.getSQLValue(iValue)); + } + + @Override + public void setString(int paramIndex, String sValue) throws BasicException { + ensurePlace(paramIndex - 1); + m_aParams.set(paramIndex - 1, DataWriteUtils.getSQLValue(sValue)); + } + + @Override + public void setTimestamp(int paramIndex, java.util.Date dValue) throws BasicException { + ensurePlace(paramIndex - 1); + m_aParams.set(paramIndex - 1, DataWriteUtils.getSQLValue(dValue)); + } +// public void setBinaryStream(int paramIndex, java.io.InputStream in, int length) throws DataException{ +// throw new DataException("Param type not allowed"); +// } + @Override + public void setBytes(int paramIndex, byte[] value) throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.noparamtype")); + } + @Override + public void setObject(int paramIndex, Object value) throws BasicException { + ensurePlace(paramIndex - 1); + m_aParams.set(paramIndex - 1, DataWriteUtils.getSQLValue(value)); + } + + private void ensurePlace(int i) { + m_aParams.ensureCapacity(i); + while (i >= m_aParams.size()){ + m_aParams.add(null); + } + } + + public String getSentence() { + + StringBuilder sNewSentence = new StringBuilder(); + int iCount = 0; + int iPos; + int iLast = 0; + while ((iPos = m_sSentence.indexOf('?', iLast)) > 0) { + sNewSentence.append(m_sSentence.substring(iLast, iPos)); + if (iCount < m_aParams.size() && m_aParams.get(iCount) != null) { + // el valor que viene + sNewSentence.append(m_aParams.get(iCount)); + } else { + // nulo + sNewSentence.append(DataWriteUtils.getSQLValue((Object) null)); + } + iCount++; + iLast = iPos + 1; + } + sNewSentence.append(m_sSentence.substring(iLast)); + + return sNewSentence.toString(); // sustituida + } + } +} diff --git a/src/main/java/com/unicenta/data/loader/PreparedSentence.java b/src/main/java/com/unicenta/data/loader/PreparedSentence.java new file mode 100644 index 0000000..4d870c1 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/PreparedSentence.java @@ -0,0 +1,250 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; +import lombok.extern.slf4j.Slf4j; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.sql.Types; + +/** + * + * @author adrianromero + */ +@Slf4j +public class PreparedSentence extends JDBCSentence { + + + private String m_sentence; + + /** + * + */ + protected SerializerWrite m_SerWrite = null; + + /** + * + */ + protected SerializerRead m_SerRead = null; + + // Estado + private PreparedStatement m_Stmt; + + /** + * + * @param s + * @param sentence + * @param serwrite + * @param serread + */ + public PreparedSentence(Session s, String sentence, SerializerWrite serwrite, SerializerRead serread) { + super(s); + m_sentence = sentence; + m_SerWrite = serwrite; + m_SerRead = serread; + m_Stmt = null; + } + + /** + * + * @param s + * @param sentence + * @param serwrite + */ + public PreparedSentence(Session s, String sentence, SerializerWrite serwrite) { + this(s, sentence, serwrite, null); + } + + /** + * + * @param s + * @param sentence + */ + public PreparedSentence(Session s, String sentence) { + this(s, sentence, null, null); + } + + private static final class PreparedSentencePars implements DataWrite { + + private PreparedStatement m_ps; + + /** Creates a new instance of SQLParameter */ + PreparedSentencePars(PreparedStatement ps) { + m_ps = ps; + } + + @Override + public void setInt(int paramIndex, Integer iValue) throws BasicException { + try { + m_ps.setObject(paramIndex, iValue, Types.INTEGER); + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } + @Override + public void setString(int paramIndex, String sValue) throws BasicException { + try { + m_ps.setString(paramIndex, sValue); + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } + @Override + public void setDouble(int paramIndex, Double dValue) throws BasicException { + try { + m_ps.setObject(paramIndex, dValue, Types.DOUBLE); + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } + @Override + public void setBoolean(int paramIndex, Boolean bValue) throws BasicException { + try { + if (bValue == null) { + m_ps.setObject(paramIndex, null); + } else { + m_ps.setBoolean(paramIndex, bValue.booleanValue()); + } + // m_ps.setObject(paramIndex, bValue, Types.BOOLEAN); + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } + @Override + public void setTimestamp(int paramIndex, java.util.Date dValue) throws BasicException { + try { + m_ps.setObject(paramIndex, dValue == null ? null : new Timestamp(dValue.getTime()), Types.TIMESTAMP); + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } +// public void setBinaryStream(int paramIndex, java.io.InputStream in, int length) throws DataException { +// try { +// m_ps.setBinaryStream(paramIndex, in, length); +// } catch (SQLException eSQL) { +// throw new DataException(eSQL); +// } +// } + @Override + public void setBytes(int paramIndex, byte[] value) throws BasicException { + try { + m_ps.setBytes(paramIndex, value); + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } + @Override + public void setObject(int paramIndex, Object value) throws BasicException { + try { + m_ps.setObject(paramIndex, value); + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } + } + + /** + * + * @param params + * @return + * @throws BasicException + */ + @Override + public DataResultSet openExec(Object params) throws BasicException { + // true -> un resultset + // false -> un updatecount (si -1 entonces se acabo) + + closeExec(); + + try { + log.debug("Executing prepared SQL: {}", m_sentence); + + m_Stmt = session.getConnection().prepareStatement(m_sentence); + + if (m_SerWrite != null) { + // si m_SerWrite fuera null deberiamos cascar. + PreparedSentencePars preparedSentencePars = new PreparedSentencePars(m_Stmt); + m_SerWrite.writeValues(preparedSentencePars, params); + } + + if (m_Stmt.execute()) { + return new JDBCDataResultSet(m_Stmt.getResultSet(), m_SerRead); + } else { + int iUC = m_Stmt.getUpdateCount(); + if (iUC < 0) { + return null; + } else { + return new SentenceUpdateResultSet(iUC); + } + } + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public final DataResultSet moreResults() throws BasicException { + // true -> un resultset + // false -> un updatecount (si -1 entonces se acabo) + + try { + if (m_Stmt.getMoreResults()){ + // tenemos resultset + return new JDBCDataResultSet(m_Stmt.getResultSet(), m_SerRead); + } else { + // tenemos updatecount o si devuelve -1 ya no hay mas + int iUC = m_Stmt.getUpdateCount(); + if (iUC < 0) { + return null; + } else { + return new SentenceUpdateResultSet(iUC); + } + } + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } + + /** + * + * @throws BasicException + */ + @Override + public final void closeExec() throws BasicException { + + if (m_Stmt != null) { + try { + m_Stmt.close(); + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } finally { + m_Stmt = null; + } + } + } +} diff --git a/src/main/java/com/unicenta/data/loader/QBFBuilder.java b/src/main/java/com/unicenta/data/loader/QBFBuilder.java new file mode 100644 index 0000000..621b18b --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/QBFBuilder.java @@ -0,0 +1,201 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author adrian + */ +public class QBFBuilder implements ISQLBuilderStatic { + + private final String m_sSentNullFilter; // la sentencia que se devuelve cuando el filtro es vacio + private final String m_sSentBeginPart; // La sentencia que se devuelve es m_sSentBeginPart + ( filtro ) + m_sSentEndPart + private final String m_sSentEndPart; + + private final String[] m_asFindFields; + +// /** Creates a new instance of QBFBuilder */ +// public QBFBuilder(TableDefinition tb, String[] asFindFields) { +// StringBuilder sent = new StringBuilder(); +// sent.append("select "); +// for (int i = 0; i < tb.getFields().length; i ++) { +// if (i > 0) { +// sent.append(", "); +// } +// sent.append(tb.getFields()[i]); +// } +// sent.append(" from "); +// sent.append(tb.getTableName()); +// m_sSentNullFilter = sent.toString(); +// sent.append(" where "); +// m_sSentBeginPart = sent.toString(); +// m_sSentEndPart = ""; +// m_asFindFields = asFindFields; +// } + + /** + * + * @param sSentence + * @param asFindFields + */ + public QBFBuilder(String sSentence, String[] asFindFields) { + int iPos = sSentence.indexOf("?(QBF_FILTER)"); + if (iPos < 0) { + m_sSentBeginPart = sSentence; + m_sSentEndPart = ""; + m_sSentNullFilter = sSentence; + } else { + m_sSentBeginPart = sSentence.substring(0, iPos); + m_sSentEndPart = sSentence.substring(iPos + 13); + m_sSentNullFilter = m_sSentBeginPart + "(1=1)" + m_sSentEndPart; + } + m_asFindFields = asFindFields; + } + + /** + * + * @param sw + * @param params + * @return + * @throws BasicException + */ + @Override + public String getSQL(SerializerWrite sw, Object params) throws BasicException { + + QBFParameter mydw = new QBFParameter(m_asFindFields); + if (sw == null || params == null) { + return m_sSentNullFilter; + } else { + sw.writeValues(mydw, params); + String sFilter = mydw.getFilter(); + if (sFilter.length() == 0) { + return m_sSentNullFilter; // no hay filtro + } else { + return m_sSentBeginPart + "(" + sFilter + ")" + m_sSentEndPart; // incluimos el filtro + } + } + } + + private static class QBFParameter implements DataWrite { + + private final String[] m_asFindFields; + private final QBFCompareEnum[] m_aiCondFields; + private final String[] m_aParams; + + public QBFParameter(String[] asFindFields) { + m_asFindFields = asFindFields; + m_aiCondFields = new QBFCompareEnum[asFindFields.length]; + m_aParams = new String[asFindFields.length]; + + for( int i = 0; i < m_aParams.length; i++) { + m_aParams[i] = DataWriteUtils.getSQLValue((Object) null); + } + } + + @Override + public void setDouble(int paramIndex, Double dValue) throws BasicException { + if ((paramIndex - 1) % 2 == 0) { + throw new BasicException(LocalRes.getIntString("exception.nocompare")); + } else { + m_aParams[(paramIndex - 1) / 2] = DataWriteUtils.getSQLValue(dValue); + } + } + @Override + public void setBoolean(int paramIndex, Boolean bValue) throws BasicException { + if ((paramIndex - 1) % 2 == 0) { + throw new BasicException(LocalRes.getIntString("exception.nocompare")); + } else { + m_aParams[(paramIndex - 1) / 2] = DataWriteUtils.getSQLValue(bValue); + } + } + @Override + public void setInt(int paramIndex, Integer iValue) throws BasicException { + if ((paramIndex - 1) % 2 == 0) { + throw new BasicException(LocalRes.getIntString("exception.nocompare")); + } else { + m_aParams[(paramIndex - 1) / 2] = DataWriteUtils.getSQLValue(iValue); + } + } + @Override + public void setString(int paramIndex, String sValue) throws BasicException { + if ((paramIndex - 1) % 2 == 0) { + throw new BasicException(LocalRes.getIntString("exception.nocompare")); + } else { + m_aParams[(paramIndex - 1) / 2] = DataWriteUtils.getSQLValue(sValue); + } + } + @Override + public void setTimestamp(int paramIndex, java.util.Date dValue) throws BasicException { + if ((paramIndex - 1) % 2 == 0) { + throw new BasicException(LocalRes.getIntString("exception.nocompare")); + } else { + m_aParams[(paramIndex - 1) / 2] = DataWriteUtils.getSQLValue(dValue); + } + } +// public void setBinaryStream(int paramIndex, java.io.InputStream in, int length) throws DataException{ +// if ((paramIndex - 1) % 2 == 0) { +// throw new DataException("Expected comparator for QBF"); +// } else { +// throw new DataException("Param type not allowed"); +// } +// } + @Override + public void setBytes(int paramIndex, byte[] value) throws BasicException { + if ((paramIndex - 1) % 2 == 0) { + throw new BasicException(LocalRes.getIntString("exception.nocompare")); + } else { + throw new BasicException("Param type not allowed"); + } + } + @Override + public void setObject(int paramIndex, Object value) throws BasicException { + if ((paramIndex - 1) % 2 == 0) { + if (value instanceof QBFCompareEnum) { + m_aiCondFields[(paramIndex - 1) / 2] = (QBFCompareEnum) value; + } else { + throw new BasicException(LocalRes.getIntString("exception.nocompare")); + } + } else { + m_aParams[(paramIndex - 1) / 2] = DataWriteUtils.getSQLValue(value); + } + } + + public String getFilter() { + // El retorno debe ser siempre una expresion valida puesto que no se donde sera insertada. + + StringBuilder sFilter = new StringBuilder(); + + String sItem; + for (int i = 0; i < m_asFindFields.length; i ++) { + sItem = m_aiCondFields[i].getExpression(m_asFindFields[i], m_aParams[i]); + if (sItem != null) { + if (sFilter.length() > 0) { + sFilter.append(" AND "); + } + sFilter.append(sItem); + } + } + + return sFilter.toString(); + } + } +} diff --git a/src/main/java/com/unicenta/data/loader/QBFCompareEnum.java b/src/main/java/com/unicenta/data/loader/QBFCompareEnum.java new file mode 100644 index 0000000..34cd421 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/QBFCompareEnum.java @@ -0,0 +1,140 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +/** + * + * @author adrian + */ +public abstract class QBFCompareEnum { + + /** + * + */ + public final static QBFCompareEnum COMP_NONE = new QBFCompareEnum(0, "qbf.none") { + @Override + public String getExpression(String sField, String sSQLValue) { return null; } + }; + + /** + * + */ + public final static QBFCompareEnum COMP_ISNULL = new QBFCompareEnum(1, "qbf.null") { + @Override + public String getExpression(String sField, String sSQLValue) { return sField + " IS NULL"; } + }; + + /** + * + */ + public final static QBFCompareEnum COMP_ISNOTNULL = new QBFCompareEnum(2, "qbf.notnull") { + @Override + public String getExpression(String sField, String sSQLValue) { return sField + " IS NOT NULL"; } + }; + + /** + * + */ + public final static QBFCompareEnum COMP_RE = new QBFCompareEnum(3, "qbf.re") { + @Override + public String getExpression(String sField, String sSQLValue) { return sField + " LIKE " + sSQLValue; } + }; + + /** + * + */ + public final static QBFCompareEnum COMP_EQUALS = new QBFCompareEnum(3, "qbf.equals") { + @Override + public String getExpression(String sField, String sSQLValue) { return sField + " = " + sSQLValue; } + }; + + /** + * + */ + public final static QBFCompareEnum COMP_DISTINCT = new QBFCompareEnum(4, "qbf.distinct") { + @Override + public String getExpression(String sField, String sSQLValue) { return sField + " <> " + sSQLValue; } + }; + + /** + * + */ + public final static QBFCompareEnum COMP_GREATER = new QBFCompareEnum(5, "qbf.greater") { + @Override + public String getExpression(String sField, String sSQLValue) { return sField + " > " + sSQLValue; } + }; + + /** + * + */ + public final static QBFCompareEnum COMP_LESS = new QBFCompareEnum(6, "qbf.less") { + @Override + public String getExpression(String sField, String sSQLValue) { return sField + " < " + sSQLValue; } + }; + + /** + * + */ + public final static QBFCompareEnum COMP_GREATEROREQUALS = new QBFCompareEnum(7, "qbf.greaterequals") { + @Override + public String getExpression(String sField, String sSQLValue) { return sField + " >= " + sSQLValue; } + }; + + /** + * + */ + public final static QBFCompareEnum COMP_LESSOREQUALS = new QBFCompareEnum(8, "qbf.lessequals") { + @Override + public String getExpression(String sField, String sSQLValue) { return sField + " <= " + sSQLValue; } + }; +// public final static QBFCompareEnum COMP_STARTSWITH = new QBFCompareEnum(9, "qbf.startswith") { +// public String getExpression(String sField, String sSQLValue) { return sField + " LIKE " ... + sSQLValue; } +// }; +// public final static int COMP_ENDSWITH = 12; +// public final static int COMP_CONTAINS = 13; + + private final int m_iValue; + private final String m_sKey; + + private QBFCompareEnum(int iValue, String sKey) { + m_iValue = iValue; + m_sKey = sKey; + } + + /** + * + * @return + */ + public int getCompareInt() { + return m_iValue; + } + @Override + public String toString() { + return LocalRes.getIntString(m_sKey); + } + + /** + * + * @param sField + * @param sSQLValue + * @return + */ + public abstract String getExpression(String sField, String sSQLValue); +} diff --git a/src/main/java/com/unicenta/data/loader/RenderStringBasic.java b/src/main/java/com/unicenta/data/loader/RenderStringBasic.java new file mode 100644 index 0000000..3e905d8 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/RenderStringBasic.java @@ -0,0 +1,65 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.format.Formats; + +/** + * + * @author adrian + */ +public class RenderStringBasic implements IRenderString { + + private Formats[] m_aFormats; + private int[] m_aiIndex; + + /** Creates a new instance of StringnizerBasic + * @param fmts + * @param aiIndex */ + public RenderStringBasic(Formats[] fmts, int[] aiIndex) { + m_aFormats = fmts; + m_aiIndex = aiIndex; + } + + /** + * + * @param value + * @return + */ + public String getRenderString(Object value) { + + if (value == null) { + return null; + } else { + Object [] avalue = (Object[]) value; + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < m_aiIndex.length; i++) { + if (i > 0) { + sb.append(" - "); + } + sb.append(m_aFormats[m_aiIndex[i]].formatValue(avalue[m_aiIndex[i]])); + } + + return sb.toString(); + } + } + +} diff --git a/src/main/java/com/unicenta/data/loader/SentenceEnum.java b/src/main/java/com/unicenta/data/loader/SentenceEnum.java new file mode 100644 index 0000000..158c898 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SentenceEnum.java @@ -0,0 +1,56 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public interface SentenceEnum { + + /** + * + * @throws BasicException + */ + public void load() throws BasicException; + + /** + * + * @param params + * @throws BasicException + */ + public void load(Object params) throws BasicException; + + /** + * + * @return + * @throws BasicException + */ + public Object getCurrent() throws BasicException; + + /** + * + * @return + * @throws BasicException + */ + public boolean next() throws BasicException; +} diff --git a/src/main/java/com/unicenta/data/loader/SentenceExec.java b/src/main/java/com/unicenta/data/loader/SentenceExec.java new file mode 100644 index 0000000..c12f57b --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SentenceExec.java @@ -0,0 +1,52 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public interface SentenceExec { + + /** + * + * @return + * @throws BasicException + */ + public int exec() throws BasicException; + + /** + * + * @param params + * @return + * @throws BasicException + */ + public int exec(Object params) throws BasicException; + + /** + * + * @param params + * @return + * @throws BasicException + */ + public int exec(Object... params) throws BasicException; +} diff --git a/src/main/java/com/unicenta/data/loader/SentenceExecAdapter.java b/src/main/java/com/unicenta/data/loader/SentenceExecAdapter.java new file mode 100644 index 0000000..4443b0b --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SentenceExecAdapter.java @@ -0,0 +1,56 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public abstract class SentenceExecAdapter implements SentenceExec { + + /** + * + * @return + * @throws BasicException + */ + public int exec() throws BasicException { + return exec((Object) null); + } + + /** + * + * @param params + * @return + * @throws BasicException + */ + public int exec(Object... params) throws BasicException { + return exec((Object) params); + } + + /** + * + * @param params + * @return + * @throws BasicException + */ + public abstract int exec(Object params) throws BasicException; +} diff --git a/src/main/java/com/unicenta/data/loader/SentenceExecTransaction.java b/src/main/java/com/unicenta/data/loader/SentenceExecTransaction.java new file mode 100644 index 0000000..dfc164c --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SentenceExecTransaction.java @@ -0,0 +1,86 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author adrianromero + * Created on February 6, 2007, 4:06 PM + * + */ +public abstract class SentenceExecTransaction implements SentenceExec { + + private Session m_s; + + /** + * + * @param s + */ + public SentenceExecTransaction(Session s) { + m_s = s; + } + + /** + * + * @return + * @throws BasicException + */ + public final int exec() throws BasicException { + return exec((Object) null); + } + + /** + * + * @param params + * @return + * @throws BasicException + */ + public final int exec(Object... params) throws BasicException { + return exec((Object) params); + } + + /** + * + * @param params + * @return + * @throws BasicException + */ + public final int exec(final Object params) throws BasicException { + + Transaction t = new Transaction(m_s) { + public Integer transact() throws BasicException{ + return execInTransaction(params); + } + }; + + return t.execute(); + } + + /** + * + * @param params + * @return + * @throws BasicException + */ + protected abstract int execInTransaction(Object params) throws BasicException; +} + diff --git a/src/main/java/com/unicenta/data/loader/SentenceFind.java b/src/main/java/com/unicenta/data/loader/SentenceFind.java new file mode 100644 index 0000000..c18e880 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SentenceFind.java @@ -0,0 +1,52 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public interface SentenceFind { + + /** + * + * @return + * @throws BasicException + */ + public Object find() throws BasicException; + + /** + * + * @param params + * @return + * @throws BasicException + */ + public Object find(Object params) throws BasicException; + + /** + * + * @param params + * @return + * @throws BasicException + */ + public Object find(Object... params) throws BasicException; +} diff --git a/src/main/java/com/unicenta/data/loader/SentenceList.java b/src/main/java/com/unicenta/data/loader/SentenceList.java new file mode 100644 index 0000000..edd7ab0 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SentenceList.java @@ -0,0 +1,72 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; +import java.util.List; + +/** + * + * @author JG uniCenta + */ +public interface SentenceList { + + /** + * + * @return + * @throws BasicException + */ + public List list() throws BasicException; + + /** + * + * @param params + * @return + * @throws BasicException + */ + public List list(Object... params) throws BasicException; + + /** + * + * @param params + * @return + * @throws BasicException + */ + public List list(Object params) throws BasicException; + + /** + * + * @param offset + * @param length + * @return + * @throws BasicException + */ + public List listPage(int offset, int length) throws BasicException; + + /** + * + * @param params + * @param offset + * @param length + * @return + * @throws BasicException + */ + public List listPage(Object params, int offset, int length) throws BasicException; +} diff --git a/src/main/java/com/unicenta/data/loader/SentenceUpdateResultSet.java b/src/main/java/com/unicenta/data/loader/SentenceUpdateResultSet.java new file mode 100644 index 0000000..8d4847b --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SentenceUpdateResultSet.java @@ -0,0 +1,154 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author adrian + */ +public class SentenceUpdateResultSet implements DataResultSet { + + private int m_iUpdateCount; + + /** Creates a new instance of UpdateResultSet + * @param iUpdateCount */ + public SentenceUpdateResultSet(int iUpdateCount) { + m_iUpdateCount = iUpdateCount; + } + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + public Integer getInt(int columnIndex) throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + public String getString(int columnIndex) throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + public Double getDouble(int columnIndex) throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + public Boolean getBoolean(int columnIndex) throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + public java.util.Date getTimestamp(int columnIndex) throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + //public java.io.InputStream getBinaryStream(int columnIndex) throws DataException; + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + public byte[] getBytes(int columnIndex) throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + /** + * + * @param columnIndex + * @return + * @throws BasicException + */ + public Object getObject(int columnIndex) throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + +// public int getColumnCount() throws DataException; + + /** + * + * @return + * @throws BasicException + */ + public DataField[] getDataField() throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + /** + * + * @return + * @throws BasicException + */ + public Object getCurrent() throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + /** + * + * @return + * @throws BasicException + */ + public boolean next() throws BasicException { + throw new BasicException(LocalRes.getIntString("exception.nodataset")); + } + + /** + * + * @throws BasicException + */ + public void close() throws BasicException { + } + + /** + * + * @return + * @throws BasicException + */ + public int updateCount() throws BasicException { + return m_iUpdateCount; + } +} diff --git a/src/main/java/com/unicenta/data/loader/SequenceForDerby.java b/src/main/java/com/unicenta/data/loader/SequenceForDerby.java new file mode 100644 index 0000000..719f1c7 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SequenceForDerby.java @@ -0,0 +1,75 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public class SequenceForDerby extends BaseSentence { + + private BaseSentence sent1; + private BaseSentence sent2; + + /** Creates a new instance of SequenceForMySQL + * @param s + * @param sSeqTable */ + public SequenceForDerby(Session s, String sSeqTable) { + + sent1 = new StaticSentence(s, "UPDATE " + sSeqTable + " SET ID = (SELECT ID FROM "+ sSeqTable +")+1 "); + sent2 = new StaticSentence(s, "SELECT ID from PICKUP_NUMBER", null, SerializerReadInteger.INSTANCE); + } + + + // Funciones de bajo nivel + + /** + * + * @param params + * @return + * @throws BasicException + */ + @Override + public DataResultSet openExec(Object params) throws BasicException { + sent1.exec(); + return sent2.openExec(null); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public DataResultSet moreResults() throws BasicException { + return sent2.moreResults(); + } + + /** + * + * @throws BasicException + */ + @Override + public void closeExec() throws BasicException { + sent2.closeExec(); + } +} diff --git a/src/main/java/com/unicenta/data/loader/SequenceForMySQL.java b/src/main/java/com/unicenta/data/loader/SequenceForMySQL.java new file mode 100644 index 0000000..b6d2092 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SequenceForMySQL.java @@ -0,0 +1,71 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public class SequenceForMySQL extends BaseSentence { + + private BaseSentence sent1; + private BaseSentence sent2; + + /** Creates a new instance of SequenceForMySQL + * @param s + * @param sSeqTable */ + public SequenceForMySQL(Session s, String sSeqTable) { + + sent1 = new StaticSentence(s, "UPDATE " + sSeqTable + " SET ID = LAST_INSERT_ID(ID + 1)"); + sent2 = new StaticSentence(s, "SELECT LAST_INSERT_ID()", null, SerializerReadInteger.INSTANCE); + } + + // Funciones de bajo nivel + + /** + * + * @param params + * @return + * @throws BasicException + */ + public DataResultSet openExec(Object params) throws BasicException { + sent1.exec(); + return sent2.openExec(null); + } + + /** + * + * @return + * @throws BasicException + */ + public DataResultSet moreResults() throws BasicException { + return sent2.moreResults(); + } + + /** + * + * @throws BasicException + */ + public void closeExec() throws BasicException { + sent2.closeExec(); + } +} diff --git a/src/main/java/com/unicenta/data/loader/SequenceForSQLite.java b/src/main/java/com/unicenta/data/loader/SequenceForSQLite.java new file mode 100644 index 0000000..30202e6 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SequenceForSQLite.java @@ -0,0 +1,48 @@ +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +public class SequenceForSQLite extends BaseSentence { + + private BaseSentence sent1; + private BaseSentence sent2; + + /** Creates a new instance of SequenceForMySQL + * @param s + * @param sSeqTable */ + public SequenceForSQLite(Session s, String sSeqTable) { + + sent1 = new StaticSentence(s, "UPDATE " + sSeqTable + " SET ID = last_insert_rowid()+1"); + sent2 = new StaticSentence(s, "SELECT last_insert_rowid()", null, SerializerReadInteger.INSTANCE); + } + + // Funciones de bajo nivel + + /** + * + * @param params + * @return + * @throws BasicException + */ + public DataResultSet openExec(Object params) throws BasicException { + sent1.exec(); + return sent2.openExec(null); + } + + /** + * + * @return + * @throws BasicException + */ + public DataResultSet moreResults() throws BasicException { + return sent2.moreResults(); + } + + /** + * + * @throws BasicException + */ + public void closeExec() throws BasicException { + sent2.closeExec(); + } +} diff --git a/src/main/java/com/unicenta/data/loader/SerializableBuilder.java b/src/main/java/com/unicenta/data/loader/SerializableBuilder.java new file mode 100644 index 0000000..a3e8003 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializableBuilder.java @@ -0,0 +1,33 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +/** + * + * @author JG uniCenta + */ +public interface SerializableBuilder { + + /** + * + * @return + */ + public SerializableRead createNew(); +} diff --git a/src/main/java/com/unicenta/data/loader/SerializableRead.java b/src/main/java/com/unicenta/data/loader/SerializableRead.java new file mode 100644 index 0000000..2a5e706 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializableRead.java @@ -0,0 +1,36 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public interface SerializableRead { + + /** + * + * @param dr + * @throws BasicException + */ + public void readValues(DataRead dr) throws BasicException; +} diff --git a/src/main/java/com/unicenta/data/loader/SerializableWrite.java b/src/main/java/com/unicenta/data/loader/SerializableWrite.java new file mode 100644 index 0000000..05c45cb --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializableWrite.java @@ -0,0 +1,36 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public interface SerializableWrite { + + /** + * + * @param dp + * @throws BasicException + */ + public void writeValues(DataWrite dp) throws BasicException; +} diff --git a/src/main/java/com/unicenta/data/loader/SerializerRead.java b/src/main/java/com/unicenta/data/loader/SerializerRead.java new file mode 100644 index 0000000..5a981f6 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializerRead.java @@ -0,0 +1,37 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author adrian + */ +public interface SerializerRead { + + /** + * + * @param dr + * @return + * @throws BasicException + */ + public Object readValues(DataRead dr) throws BasicException; +} diff --git a/src/main/java/com/unicenta/data/loader/SerializerReadBasic.java b/src/main/java/com/unicenta/data/loader/SerializerReadBasic.java new file mode 100644 index 0000000..ecabb83 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializerReadBasic.java @@ -0,0 +1,52 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public class SerializerReadBasic implements SerializerRead { + + private Datas[] m_classes; + + /** Creates a new instance of SerializerReadBasic + * @param classes */ + public SerializerReadBasic(Datas[] classes) { + m_classes = classes; + } + + /** + * + * @param dr + * @return + * @throws BasicException + */ + public Object readValues(DataRead dr) throws BasicException { + + Object[] m_values = new Object[m_classes.length]; + for (int i = 0; i < m_classes.length; i++) { + m_values[i] = m_classes[i].getValue(dr, i + 1); + } + return m_values; + } +} diff --git a/src/main/java/com/unicenta/data/loader/SerializerReadBuilder.java b/src/main/java/com/unicenta/data/loader/SerializerReadBuilder.java new file mode 100644 index 0000000..c403ca5 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializerReadBuilder.java @@ -0,0 +1,50 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author adrian + */ +public class SerializerReadBuilder implements SerializerRead { + + private SerializableBuilder m_sb; + + /** Creates a new instance of SerializerReadBuilder + * @param sb */ + public SerializerReadBuilder(SerializableBuilder sb) { + m_sb = sb; + } + + /** + * + * @param dr + * @return + * @throws BasicException + */ + public Object readValues(DataRead dr) throws BasicException { + SerializableRead sr = m_sb.createNew(); + sr.readValues(dr); + return sr; + } + +} diff --git a/src/main/java/com/unicenta/data/loader/SerializerReadBytes.java b/src/main/java/com/unicenta/data/loader/SerializerReadBytes.java new file mode 100644 index 0000000..9ea2561 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializerReadBytes.java @@ -0,0 +1,48 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author Adrian + */ +public class SerializerReadBytes implements SerializerRead { + + /** + * + */ + public static final SerializerRead INSTANCE = new SerializerReadBytes(); + + /** Creates a new instance of SerializerReadBytes */ + private SerializerReadBytes() { + } + + /** + * + * @param dr + * @return + * @throws BasicException + */ + public Object readValues(DataRead dr) throws BasicException { + return Datas.BYTES.getValue(dr,1); + } +} diff --git a/src/main/java/com/unicenta/data/loader/SerializerReadClass.java b/src/main/java/com/unicenta/data/loader/SerializerReadClass.java new file mode 100644 index 0000000..13e64ef --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializerReadClass.java @@ -0,0 +1,55 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public class SerializerReadClass implements SerializerRead { + + private final Class m_clazz; + + /** Creates a new instance of DefaultSerializerRead + * @param clazz */ + public SerializerReadClass(Class clazz) { + m_clazz = clazz; + } + + /** + * + * @param dr + * @return + * @throws BasicException + */ + @Override + public Object readValues(DataRead dr) throws BasicException { + try { + SerializableRead sr = (SerializableRead) m_clazz.newInstance(); + sr.readValues(dr); + return sr; +// JG 16 May 12 use multicatch + } catch (java.lang.InstantiationException | IllegalAccessException | ClassCastException eIns) { + return null; + } + } +} diff --git a/src/main/java/com/unicenta/data/loader/SerializerReadDate.java b/src/main/java/com/unicenta/data/loader/SerializerReadDate.java new file mode 100644 index 0000000..eafada8 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializerReadDate.java @@ -0,0 +1,50 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author James Bolongan + */ + +public class SerializerReadDate implements SerializerRead { + + /** + * + */ + public static final SerializerRead INSTANCE = new SerializerReadDate(); + + /** Creates a new instance of SerializerReadImage */ + private SerializerReadDate() { + } + + /** + * + * @param dr + * @return + * @throws BasicException + */ + @Override + public Object readValues(DataRead dr) throws BasicException { + return Datas.TIMESTAMP.getValue(dr, 1); + } +} diff --git a/src/main/java/com/unicenta/data/loader/SerializerReadDouble.java b/src/main/java/com/unicenta/data/loader/SerializerReadDouble.java new file mode 100644 index 0000000..359961a --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializerReadDouble.java @@ -0,0 +1,48 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public class SerializerReadDouble implements SerializerRead { + + /** + * + */ + public static final SerializerRead INSTANCE = new SerializerReadDouble(); + + /** Creates a new instance of SerializerReadInteger */ + public SerializerReadDouble() { + } + + /** + * + * @param dr + * @return + * @throws BasicException + */ + public Object readValues(DataRead dr) throws BasicException { + return Datas.DOUBLE.getValue(dr,1); + } +} diff --git a/src/main/java/com/unicenta/data/loader/SerializerReadImage.java b/src/main/java/com/unicenta/data/loader/SerializerReadImage.java new file mode 100644 index 0000000..9b01377 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializerReadImage.java @@ -0,0 +1,49 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public class SerializerReadImage implements SerializerRead { + + /** + * + */ + public static final SerializerRead INSTANCE = new SerializerReadImage(); + + /** Creates a new instance of SerializerReadImage */ + private SerializerReadImage() { + } + + /** + * + * @param dr + * @return + * @throws BasicException + */ + public Object readValues(DataRead dr) throws BasicException { + return Datas.IMAGE.getValue(dr,1); + } + +} diff --git a/src/main/java/com/unicenta/data/loader/SerializerReadInteger.java b/src/main/java/com/unicenta/data/loader/SerializerReadInteger.java new file mode 100644 index 0000000..ad990aa --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializerReadInteger.java @@ -0,0 +1,48 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public class SerializerReadInteger implements SerializerRead { + + /** + * + */ + public static final SerializerRead INSTANCE = new SerializerReadInteger(); + + /** Creates a new instance of SerializerReadInteger */ + private SerializerReadInteger() { + } + + /** + * + * @param dr + * @return + * @throws BasicException + */ + public Object readValues(DataRead dr) throws BasicException { + return Datas.INT.getValue(dr,1); + } +} diff --git a/src/main/java/com/unicenta/data/loader/SerializerReadString.java b/src/main/java/com/unicenta/data/loader/SerializerReadString.java new file mode 100644 index 0000000..2730d82 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializerReadString.java @@ -0,0 +1,48 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public class SerializerReadString implements SerializerRead { + + /** + * + */ + public static final SerializerRead INSTANCE = new SerializerReadString(); + + /** Creates a new instance of SerializerReadImage */ + private SerializerReadString() { + } + + /** + * + * @param dr + * @return + * @throws BasicException + */ + public Object readValues(DataRead dr) throws BasicException { + return Datas.STRING.getValue(dr,1); + } +} diff --git a/src/main/java/com/unicenta/data/loader/SerializerReadUTF8.java b/src/main/java/com/unicenta/data/loader/SerializerReadUTF8.java new file mode 100644 index 0000000..3c18f82 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializerReadUTF8.java @@ -0,0 +1,52 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public class SerializerReadUTF8 implements SerializerRead { + + /** + * + */ + public static final SerializerRead INSTANCE = new SerializerReadUTF8(); + + /** Creates a new instance of SerializerReadImage */ + private SerializerReadUTF8() { + } + + /** + * + * @param dr + * @return + * @throws BasicException + */ + public Object readValues(DataRead dr) throws BasicException { + try { + return new String((byte[]) Datas.BYTES.getValue(dr,1), "UTF-8"); + } catch (java.io.UnsupportedEncodingException e) { + return null; + } + } +} diff --git a/src/main/java/com/unicenta/data/loader/SerializerWrite.java b/src/main/java/com/unicenta/data/loader/SerializerWrite.java new file mode 100644 index 0000000..7e1f21e --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializerWrite.java @@ -0,0 +1,38 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + * @param + */ +public interface SerializerWrite { + + /** + * + * @param dp + * @param obj + * @throws BasicException + */ + public void writeValues(DataWrite dp, T obj) throws BasicException; +} diff --git a/src/main/java/com/unicenta/data/loader/SerializerWriteBasic.java b/src/main/java/com/unicenta/data/loader/SerializerWriteBasic.java new file mode 100644 index 0000000..8a36fd3 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializerWriteBasic.java @@ -0,0 +1,52 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public class SerializerWriteBasic implements SerializerWrite { + + private Datas[] m_classes; + + /** Creates a new instance of SerializerWriteBasic + * @param classes */ + public SerializerWriteBasic(Datas... classes) { + m_classes = classes; + } + + /** + * + * @param dp + * @param obj + * @throws BasicException + */ + @Override + public void writeValues(DataWrite dp, Object[] obj) throws BasicException { + + for (int i = 0; i < m_classes.length; i++) { + m_classes[i].setValue(dp, i + 1, obj[i]); + } + } + +} diff --git a/src/main/java/com/unicenta/data/loader/SerializerWriteBasicComposed.java b/src/main/java/com/unicenta/data/loader/SerializerWriteBasicComposed.java new file mode 100644 index 0000000..fc15519 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializerWriteBasicComposed.java @@ -0,0 +1,55 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public class SerializerWriteBasicComposed implements SerializerWrite { + + private Datas[][] m_classes; + + /** Creates a new instance of SerializerWriteComposed + * @param classes */ + public SerializerWriteBasicComposed(Datas[]... classes) { + m_classes = classes; + } + + /** + * + * @param dp + * @param obj + * @throws BasicException + */ + public void writeValues(DataWrite dp, Object[] obj) throws BasicException { + + int index = 0; + for (int i = 0; i < m_classes.length; i++) { + Object[] val = (Object[]) obj[i]; + for (int j = 0; j < m_classes[i].length; j++) { + index++; + m_classes[i][j].setValue(dp, index, val[j]); + } + } + } +} diff --git a/src/main/java/com/unicenta/data/loader/SerializerWriteBasicExt.java b/src/main/java/com/unicenta/data/loader/SerializerWriteBasicExt.java new file mode 100644 index 0000000..1c3e4bb --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializerWriteBasicExt.java @@ -0,0 +1,55 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public class SerializerWriteBasicExt implements SerializerWrite { + + private Datas[] m_classes; + private int[] m_index; + + /** Creates a new instance of SerializerWriteBasic + * @param classes + * @param index */ + public SerializerWriteBasicExt(Datas[] classes, int[] index) { + m_classes = classes; + m_index = index; + } + + /** + * + * @param dp + * @param obj + * @throws BasicException + */ + @Override + public void writeValues(DataWrite dp, Object[] obj) throws BasicException { + + for (int i = 0; i < m_index.length; i++) { + m_classes[m_index[i]].setValue(dp, i + 1, obj[m_index[i]]); + } + } + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/data/loader/SerializerWriteBuilder.java b/src/main/java/com/unicenta/data/loader/SerializerWriteBuilder.java new file mode 100644 index 0000000..fdac78c --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializerWriteBuilder.java @@ -0,0 +1,48 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public class SerializerWriteBuilder implements SerializerWrite { + + /** + * + */ + public static final SerializerWrite INSTANCE = new SerializerWriteBuilder(); + + /** Creates a new instance of SerializerWriteBuilder */ + private SerializerWriteBuilder() { + } + + /** + * + * @param dp + * @param obj + * @throws BasicException + */ + public void writeValues(DataWrite dp, SerializableWrite obj) throws BasicException { + obj.writeValues(dp); + } +} diff --git a/src/main/java/com/unicenta/data/loader/SerializerWriteComposed.java b/src/main/java/com/unicenta/data/loader/SerializerWriteComposed.java new file mode 100644 index 0000000..95a5b27 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializerWriteComposed.java @@ -0,0 +1,115 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * + * @author JG uniCenta + */ +public class SerializerWriteComposed implements SerializerWrite { + + private List serwrites = new ArrayList(); + + /** Creates a new instance of SerializerWriteComposed */ + public SerializerWriteComposed() { + } + + /** + * + * @param sw + */ + public void add(SerializerWrite sw) { + serwrites.add(sw); + } + + /** + * + * @param dp + * @param obj + * @throws BasicException + */ + public void writeValues(DataWrite dp, Object obj) throws BasicException { + + Object[] a = (Object[]) obj; + DataWriteComposed dpc = new DataWriteComposed(dp); + + int i = 0; + for (SerializerWrite sw : serwrites) { + dpc.next(); + sw.writeValues(dpc, a[i++]); + } + } + + private static class DataWriteComposed implements DataWrite { + + private DataWrite dp; + private int offset = 0; + private int max = 0; + + public DataWriteComposed(DataWrite dp) { + this.dp = dp; + } + + public void next() { + offset = max; + } + + public void setInt(int paramIndex, Integer iValue) throws BasicException { + dp.setInt(offset + paramIndex, iValue); + max = Math.max(max, offset + paramIndex); + } + + public void setString(int paramIndex, String sValue) throws BasicException { + dp.setString(offset + paramIndex, sValue); + max = Math.max(max, offset + paramIndex); + } + + public void setDouble(int paramIndex, Double dValue) throws BasicException { + dp.setDouble(offset + paramIndex, dValue); + max = Math.max(max, offset + paramIndex); + } + + public void setBoolean(int paramIndex, Boolean bValue) throws BasicException { + dp.setBoolean(offset + paramIndex, bValue); + max = Math.max(max, offset + paramIndex); + } + + public void setTimestamp(int paramIndex, Date dValue) throws BasicException { + dp.setTimestamp(offset + paramIndex, dValue); + max = Math.max(max, offset + paramIndex); + } + + public void setBytes(int paramIndex, byte[] value) throws BasicException { + dp.setBytes(offset + paramIndex, value); + max = Math.max(max, offset + paramIndex); + } + + public void setObject(int paramIndex, Object value) throws BasicException { + dp.setObject(offset + paramIndex, value); + max = Math.max(max, offset + paramIndex); + } + } + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/data/loader/SerializerWriteInteger.java b/src/main/java/com/unicenta/data/loader/SerializerWriteInteger.java new file mode 100644 index 0000000..e994774 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializerWriteInteger.java @@ -0,0 +1,48 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public class SerializerWriteInteger implements SerializerWrite { + + /** + * + */ + public static final SerializerWrite INSTANCE = new SerializerWriteInteger(); + + /** Creates a new instance of SerializerWriteInteger */ + private SerializerWriteInteger() { + } + + /** + * + * @param dp + * @param obj + * @throws BasicException + */ + public void writeValues(DataWrite dp, Integer obj) throws BasicException { + Datas.INT.setValue(dp, 1, obj); + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/data/loader/SerializerWriteParams.java b/src/main/java/com/unicenta/data/loader/SerializerWriteParams.java new file mode 100644 index 0000000..0cc800b --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializerWriteParams.java @@ -0,0 +1,47 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author adrianromero + */ +public class SerializerWriteParams implements SerializerWrite{ + + /** + * + */ + public static final SerializerWrite INSTANCE = new SerializerWriteParams(); + + /** + * + * @param dp + * @param obj + * @throws BasicException + */ + @Override + public void writeValues(DataWrite dp, DataParams obj) throws BasicException { + obj.setDataWrite(dp); + obj.writeValues(); + obj.setDataWrite(null); + } +} diff --git a/src/main/java/com/unicenta/data/loader/SerializerWriteString.java b/src/main/java/com/unicenta/data/loader/SerializerWriteString.java new file mode 100644 index 0000000..43766d8 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SerializerWriteString.java @@ -0,0 +1,58 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +import java.lang.reflect.Array; + +/** + * + * @author JG uniCenta + */ +public class SerializerWriteString implements SerializerWrite { + + /** + * + */ + public static final SerializerWrite INSTANCE = new SerializerWriteString(); + + /** Creates a new instance of SerializerWriteString */ + private SerializerWriteString() { + } + + /** + * + * @param dp + * @param obj + * @throws BasicException + */ + public void writeValues(DataWrite dp, Object obj) throws BasicException { + if (obj instanceof Object[]){ + for (int i = 0 ; i < ((Object[]) obj).length ; i++) { + Datas.STRING.setValue(dp, i+1, ((Object[]) obj)[i]); + } + } + else { + Datas.STRING.setValue(dp, 1, obj); + } + + } +} diff --git a/src/main/java/com/unicenta/data/loader/Session.java b/src/main/java/com/unicenta/data/loader/Session.java new file mode 100644 index 0000000..e743796 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/Session.java @@ -0,0 +1,213 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright © 2009-2020 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +/** + * + * @author adrianromero + * Created on February 6, 2007, 4:06 PM + * + */ +public final class Session { + + private final String m_surl; + private final String m_sappuser; + private final String m_spassword; + + private Connection m_c; + private boolean m_bInTransaction; + + /** + * + */ + public final SessionDB DB; + + /** Creates a new instance of Session + * @param url + * @param user + * @param password + * @throws java.sql.SQLException */ + public Session(String url, String user, String password) throws SQLException { + m_surl = url; + m_sappuser = user; + m_spassword = password; + + m_c = null; + m_bInTransaction = false; + + connect(); // no lazy connection + + DB = getDiff(); + } + + /** + * + * @throws SQLException + */ + public void connect() throws SQLException { + + // primero cerramos si no estabamos cerrados + close(); + + // creamos una nueva conexion. + m_c = (m_sappuser == null && m_spassword == null) + ? DriverManager.getConnection(m_surl) + : DriverManager.getConnection(m_surl, m_sappuser, m_spassword); + m_c.setAutoCommit(true); + m_bInTransaction = false; + } + + /** + * + */ + public void close() { + + if (m_c != null) { + try { + if (m_bInTransaction) { + m_bInTransaction = false; // lo primero salimos del estado + m_c.rollback(); + m_c.setAutoCommit(true); + } + m_c.close(); + } catch (SQLException e) { + // me la como + } finally { + m_c = null; + } + } + } + + /** + * + * @return + * @throws SQLException + */ + public Connection getConnection() throws SQLException { + + if (!m_bInTransaction) { + ensureConnection(); + } + return m_c; + } + + /** + * + * @throws SQLException + */ + public void begin() throws SQLException { + + if (m_bInTransaction) { + throw new SQLException("Already in transaction"); + } else { + ensureConnection(); + m_c.setAutoCommit(false); + m_bInTransaction = true; + } + } + + /** + * + * @throws SQLException + */ + public void commit() throws SQLException { + if (m_bInTransaction) { + m_bInTransaction = false; // lo primero salimos del estado + m_c.commit(); + m_c.setAutoCommit(true); + } else { + throw new SQLException("Transaction not started"); + } + } + + /** + * + * @throws SQLException + */ + public void rollback() throws SQLException { + if (m_bInTransaction) { + m_bInTransaction = false; // lo primero salimos del estado + m_c.rollback(); + m_c.setAutoCommit(true); + } else { + throw new SQLException("Transaction not started"); + } + } + + /** + * + * @return + */ + public boolean isTransaction() { + return m_bInTransaction; + } + + private void ensureConnection() throws SQLException { + // solo se invoca si isTransaction == false + + boolean bclosed; + try { + bclosed = m_c == null || m_c.isClosed(); + } catch (SQLException e) { + bclosed = true; + } + + // reconnect if closed + if (bclosed) { + connect(); + } + } + + /** + * + * @return + * @throws SQLException + */ + public String getURL() throws SQLException { + return getConnection().getMetaData().getURL(); + } + + private SessionDB getDiff() throws SQLException { + + String sdbmanager = getConnection().getMetaData().getDatabaseProductName(); + switch (sdbmanager) { + case "SQLite": + return new SessionDBSQLite(); + case "MariaDB": + return new SessionDBMariaDB(); + case "HSQL Database Engine": + return new SessionDBHSQLDB(); + case "MySQL": + return new SessionDBMySQL(); + case "PostgreSQL": + return new SessionDBPostgreSQL(); + case "Oracle": + return new SessionDBOracle(); + case "Apache Derby": + return new SessionDBDerby(); + default: + return new SessionDBGeneric(sdbmanager); + } + } +} diff --git a/src/main/java/com/unicenta/data/loader/SessionDB.java b/src/main/java/com/unicenta/data/loader/SessionDB.java new file mode 100644 index 0000000..ffce53c --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SessionDB.java @@ -0,0 +1,76 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +/** + * + * @author adrianromero + */ +public interface SessionDB { + + /** + * + * @return + */ + public String TRUE(); + + /** + * + * @return + */ + public String FALSE(); + + /** + * + * @return + */ + public String INTEGER_NULL(); + + /** + * + * @return + */ + public String CHAR_NULL(); + + /** + * + * @return + */ + public String getName(); + + /** + * + * @param s + * @param sequence + * @return + */ + public SentenceFind getSequenceSentence(Session s, String sequence); + + /** + * + * @param s + * @param sequence + * @return + */ + public SentenceFind resetSequenceSentence(Session s, String sequence); + +} + + diff --git a/src/main/java/com/unicenta/data/loader/SessionDBDerby.java b/src/main/java/com/unicenta/data/loader/SessionDBDerby.java new file mode 100644 index 0000000..2a4e7ac --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SessionDBDerby.java @@ -0,0 +1,94 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +/** + * + * @author adrianromero + */ +public class SessionDBDerby implements SessionDB { + + /** + * + * @return + */ + @Override + public String TRUE() { + return "1"; + } + + /** + * + * @return + */ + @Override + public String FALSE() { + return "0"; + } + + /** + * + * @return + */ + @Override + public String INTEGER_NULL() { + return "CAST(NULL AS INTEGER)"; + } + + /** + * + * @return + */ + @Override + public String CHAR_NULL() { + return "CAST(NULL AS CHAR)"; + } + + /** + * + * @return + */ + @Override + public String getName() { + return "Derby"; + } + + /** + * + * @param s + * @param sequence + * @return + */ + @Override + public SentenceFind getSequenceSentence(Session s, String sequence) { + return new SequenceForDerby(s, sequence); + } + + /** + * + * @param s + * @param sequence + * @return + */ + @Override + public SentenceFind resetSequenceSentence(Session s, String sequence) { + return new SequenceForDerby(s, sequence); +} +} diff --git a/src/main/java/com/unicenta/data/loader/SessionDBGeneric.java b/src/main/java/com/unicenta/data/loader/SessionDBGeneric.java new file mode 100644 index 0000000..831c593 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SessionDBGeneric.java @@ -0,0 +1,97 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +/** + * + * @author adrianromero + */ +public class SessionDBGeneric implements SessionDB { + + private String name; + + /** + * + * @param name + */ + public SessionDBGeneric(String name) { + this.name = name; + } + + /** + * + * @return + */ + public String TRUE() { + return "TRUE"; + } + + /** + * + * @return + */ + public String FALSE() { + return "FALSE"; + } + + /** + * + * @return + */ + public String INTEGER_NULL() { + return "CAST(NULL AS INTEGER)"; + } + + /** + * + * @return + */ + public String CHAR_NULL() { + return "CAST(NULL AS CHAR)"; + } + + /** + * + * @return + */ + public String getName() { + return name; + } + + /** + * + * @param s + * @param sequence + * @return + */ + public SentenceFind getSequenceSentence(Session s, String sequence) { + return new StaticSentence(s, "SELECT NEXTVAL('" + sequence + "')", null, SerializerReadInteger.INSTANCE); + } + + /** + * + * @param s + * @param sequence + * @return + */ + public SentenceFind resetSequenceSentence(Session s, String sequence){ + return new StaticSentence(s, "ALTER SEQUENCE " + sequence + " RESTART WITH 0", null, SerializerReadInteger.INSTANCE); +} +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/data/loader/SessionDBHSQLDB.java b/src/main/java/com/unicenta/data/loader/SessionDBHSQLDB.java new file mode 100644 index 0000000..bae03b6 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SessionDBHSQLDB.java @@ -0,0 +1,94 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +/** + * + * @author adrianromero + */ +public class SessionDBHSQLDB implements SessionDB { + + /** + * + * @return + */ + @Override + public String TRUE() { + return "TRUE"; + } + + /** + * + * @return + */ + @Override + public String FALSE() { + return "FALSE"; + } + + /** + * + * @return + */ + @Override + public String INTEGER_NULL() { + return "CAST(NULL AS INTEGER)"; + } + + /** + * + * @return + */ + @Override + public String CHAR_NULL() { + return "CAST(NULL AS CHAR)"; + } + + /** + * + * @return + */ + @Override + public String getName() { + return "HSQLDB"; + } + + /** + * + * @param s + * @param sequence + * @return + */ + @Override + public SentenceFind getSequenceSentence(Session s, String sequence) { + return new StaticSentence(s, "CALL NEXT VALUE FOR " + sequence, null, SerializerReadInteger.INSTANCE); + } + + /** + * + * @param s + * @param sequence + * @return + */ + @Override + public SentenceFind resetSequenceSentence(Session s, String sequence) { + return new StaticSentence(s, "CALL NEXT VALUE FOR " + sequence, null, SerializerReadInteger.INSTANCE); + } +} diff --git a/src/main/java/com/unicenta/data/loader/SessionDBMariaDB.java b/src/main/java/com/unicenta/data/loader/SessionDBMariaDB.java new file mode 100644 index 0000000..62e1a1e --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SessionDBMariaDB.java @@ -0,0 +1,89 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +/** + * + * @author adrianromero + */ +public class SessionDBMariaDB implements SessionDB { + + /** + * + * @return + */ + public String TRUE() { + return "TRUE"; + } + + /** + * + * @return + */ + public String FALSE() { + return "FALSE"; + } + + /** + * + * @return + */ + public String INTEGER_NULL() { + return "CAST(NULL AS UNSIGNED INTEGER)"; + } + + /** + * + * @return + */ + public String CHAR_NULL() { + return "CAST(NULL AS CHAR)"; + } + + /** + * + * @return + */ + public String getName() { + return "MariaDB"; + } + + /** + * + * @param s + * @param sequence + * @return + */ + @Override + public SentenceFind getSequenceSentence(Session s, String sequence) { + return new SequenceForMySQL(s, sequence); + } + + /** + * + * @param s + * @param sequence + * @return + */ + @Override + public SentenceFind resetSequenceSentence(Session s, String sequence) { + return new SequenceForMySQL(s, "UPDATE pickup_number SET ID=1"); + } +} diff --git a/src/main/java/com/unicenta/data/loader/SessionDBMySQL.java b/src/main/java/com/unicenta/data/loader/SessionDBMySQL.java new file mode 100644 index 0000000..0ca7aa6 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SessionDBMySQL.java @@ -0,0 +1,89 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +/** + * + * @author adrianromero + */ +public class SessionDBMySQL implements SessionDB { + + /** + * + * @return + */ + public String TRUE() { + return "TRUE"; + } + + /** + * + * @return + */ + public String FALSE() { + return "FALSE"; + } + + /** + * + * @return + */ + public String INTEGER_NULL() { + return "CAST(NULL AS UNSIGNED INTEGER)"; + } + + /** + * + * @return + */ + public String CHAR_NULL() { + return "CAST(NULL AS CHAR)"; + } + + /** + * + * @return + */ + public String getName() { + return "MySQL"; + } + + /** + * + * @param s + * @param sequence + * @return + */ + @Override + public SentenceFind getSequenceSentence(Session s, String sequence) { + return new SequenceForMySQL(s, sequence); + } + + /** + * + * @param s + * @param sequence + * @return + */ + @Override + public SentenceFind resetSequenceSentence(Session s, String sequence) { + return new SequenceForMySQL(s, "UPDATE pickup_number SET ID=1"); + } +} diff --git a/src/main/java/com/unicenta/data/loader/SessionDBOracle.java b/src/main/java/com/unicenta/data/loader/SessionDBOracle.java new file mode 100644 index 0000000..475f4eb --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SessionDBOracle.java @@ -0,0 +1,87 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +/** + * + * @author adrianromero + */ +public class SessionDBOracle implements SessionDB { + + /** + * + * @return + */ + public String TRUE() { + return "1"; + } + + /** + * + * @return + */ + public String FALSE() { + return "0"; + } + + /** + * + * @return + */ + public String INTEGER_NULL() { + return "CAST(NULL AS INTEGER)"; + } + + /** + * + * @return + */ + public String CHAR_NULL() { + return "CAST(NULL AS CHAR)"; + } + + /** + * + * @return + */ + public String getName() { + return "Oracle"; + } + + /** + * + * @param s + * @param sequence + * @return + */ + public SentenceFind getSequenceSentence(Session s, String sequence) { + return new StaticSentence(s, "SELECT " + sequence + ".NEXTVAL FROM DUAL", null, SerializerReadInteger.INSTANCE); + } + + /** + * + * @param s + * @param sequence + * @return + */ + public SentenceFind resetSequenceSentence(Session s, String sequence) { + return new StaticSentence(s, "SELECT " + sequence + ".NEXTVAL FROM DUAL", null, SerializerReadInteger.INSTANCE); + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/data/loader/SessionDBPostgreSQL.java b/src/main/java/com/unicenta/data/loader/SessionDBPostgreSQL.java new file mode 100644 index 0000000..ca589b2 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SessionDBPostgreSQL.java @@ -0,0 +1,94 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +/** + * + * @author adrianromero + */ +public class SessionDBPostgreSQL implements SessionDB { + + /** + * + * @return + */ + @Override + public String TRUE() { + return "True"; + } + + /** + * + * @return + */ + @Override + public String FALSE() { + return "False"; + } + + /** + * + * @return + */ + @Override + public String INTEGER_NULL() { + return "CAST(NULL AS INTEGER)"; + } + + /** + * + * @return + */ + @Override + public String CHAR_NULL() { + return "CAST(NULL AS CHAR)"; + } + + /** + * + * @return + */ + @Override + public String getName() { + return "PostgreSQL"; + } + + /** + * + * @param s + * @param sequence + * @return + */ + @Override + public SentenceFind getSequenceSentence(Session s, String sequence) { + return new StaticSentence(s, "SELECT NEXTVAL('" + sequence + "')", null, SerializerReadInteger.INSTANCE); + } + + /** + * + * @param s + * @param sequence + * @return + */ + @Override + public SentenceFind resetSequenceSentence(Session s, String sequence){ + return new StaticSentence(s, "ALTER SEQUENCE " + sequence + " RESTART WITH '0'", null, SerializerReadInteger.INSTANCE); + } +} diff --git a/src/main/java/com/unicenta/data/loader/SessionDBSQLite.java b/src/main/java/com/unicenta/data/loader/SessionDBSQLite.java new file mode 100644 index 0000000..34d6ce1 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SessionDBSQLite.java @@ -0,0 +1,70 @@ +package com.unicenta.data.loader; + +/** + * + * @author adrianromero + */ +public class SessionDBSQLite implements SessionDB { + + /** + * + * @return + */ + public String TRUE() { + return "1"; + } + + /** + * + * @return + */ + public String FALSE() { + return "0"; + } + + /** + * + * @return + */ + public String INTEGER_NULL() { + return "CAST(NULL AS UNSIGNED INTEGER)"; + } + + /** + * + * @return + */ + public String CHAR_NULL() { + return "CAST(NULL AS CHAR)"; + } + + /** + * + * @return + */ + public String getName() { + return "SQLite"; + } + + /** + * + * @param s + * @param sequence + * @return + */ + @Override + public SentenceFind getSequenceSentence(Session s, String sequence) { + return new SequenceForSQLite(s, sequence); + } + + /** + * + * @param s + * @param sequence + * @return + */ + @Override + public SentenceFind resetSequenceSentence(Session s, String sequence) { + return new SequenceForSQLite(s, "UPDATE pickup_number SET ID=1"); + } +} diff --git a/src/main/java/com/unicenta/data/loader/SimpleBuilder.java b/src/main/java/com/unicenta/data/loader/SimpleBuilder.java new file mode 100644 index 0000000..a116eca --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/SimpleBuilder.java @@ -0,0 +1,49 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author adrian + */ +public class SimpleBuilder implements ISQLBuilderStatic { + + private String m_sSentence; + + /** Creates a new instance of SimpleBuilder + * @param sSentence */ + public SimpleBuilder(String sSentence) { + m_sSentence = sSentence; + } + + /** + * + * @param sw + * @param params + * @return + * @throws BasicException + */ + public String getSQL(SerializerWrite sw, Object params) throws BasicException { + return m_sSentence; + } + +} diff --git a/src/main/java/com/unicenta/data/loader/StaticSentence.java b/src/main/java/com/unicenta/data/loader/StaticSentence.java new file mode 100644 index 0000000..e7661d0 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/StaticSentence.java @@ -0,0 +1,224 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; +import lombok.extern.slf4j.Slf4j; + +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author adrianromero + */ +@Slf4j +public class StaticSentence extends JDBCSentence { + + + private ISQLBuilderStatic iSQLBuilder; + + /** + * + */ + protected SerializerWrite m_SerWrite = null; + + /** + * + */ + protected SerializerRead m_SerRead = null; + + // Estado + private Statement statement; + + /** + * Creates a new instance of StaticSentence + * + * @param s + * @param sentence + * @param serread + * @param serwrite + */ + public StaticSentence(Session s, ISQLBuilderStatic sentence, SerializerWrite serwrite, SerializerRead serread) { + super(s); + iSQLBuilder = sentence; + m_SerWrite = serwrite; + m_SerRead = serread; + statement = null; + } + + /** + * Creates a new instance of StaticSentence + * + * @param s + * @param sentence + */ + public StaticSentence(Session s, ISQLBuilderStatic sentence) { + this(s, sentence, null, null); + } + + /** + * Creates a new instance of StaticSentence + * + * @param s + * @param sentence + * @param serwrite + */ + public StaticSentence(Session s, ISQLBuilderStatic sentence, SerializerWrite serwrite) { + this(s, sentence, serwrite, null); + } + + /** + * Creates a new instance of StaticSentence + * + * @param s + * @param sentence + * @param serread + * @param serwrite + */ + public StaticSentence(Session s, String sentence, SerializerWrite serwrite, SerializerRead serread) { + this(s, new NormalBuilder(sentence), serwrite, serread); + } + + /** + * Creates a new instance of StaticSentence + * + * @param s + * @param sentence + * @param serwrite + */ + public StaticSentence(Session s, String sentence, SerializerWrite serwrite) { + this(s, new NormalBuilder(sentence), serwrite, null); + } + + /** + * Creates a new instance of StaticSentence + * + * @param s + * @param sentence + */ + public StaticSentence(Session s, String sentence) { + this(s, new NormalBuilder(sentence), null, null); + } + + public String fixSqliteDate(String sql) { + + try { + if (session.getURL().contains("sqlite") && sql.contains("{ts '")) { + StringBuilder sqliteSQL = new StringBuilder(); + + Pattern date = Pattern.compile("(?<=ts ).*(?=})"); + Matcher matchPattern = date.matcher(sql); + + if (matchPattern.find()) { + sqliteSQL.append(sql.replaceAll("\\{.*}", matchPattern.group(0))); + } + + return sqliteSQL.toString(); + } + + } + catch (Exception e) { + log.error("Error fixing sql for sqlite {}", e.getMessage()); + return sql; + } + return sql; + } + /** + * @param params + * @return + * @throws BasicException + */ + @Override + public DataResultSet openExec(Object params) throws BasicException { + // true -> un resultset + // false -> un updatecount (si -1 entonces se acabo) + + closeExec(); + + try { + + String sentence = fixSqliteDate(iSQLBuilder.getSQL(m_SerWrite, params)); + //String sentence = iSQLBuilder.getSQL(m_SerWrite, params); + + statement = session.getConnection().createStatement(); + + log.debug("Executing static SQL: {}", sentence); + + if (statement.execute(sentence)) { + return new JDBCDataResultSet(statement.getResultSet(), m_SerRead); + } else { + int iUC = statement.getUpdateCount(); + if (iUC < 0) { + return null; + } else { + return new SentenceUpdateResultSet(iUC); + } + } + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } + + /** + * @throws BasicException + */ + @Override + public void closeExec() throws BasicException { + + if (statement != null) { + try { + statement.close(); + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } finally { + statement = null; + } + } + } + + /** + * @return + * @throws BasicException + */ + @Override + public DataResultSet moreResults() throws BasicException { + + try { + if (statement.getMoreResults()) { + // tenemos resultset + return new JDBCDataResultSet(statement.getResultSet(), m_SerRead); + } else { + // tenemos updatecount o si devuelve -1 ya no hay mas + int iUC = statement.getUpdateCount(); + if (iUC < 0) { + return null; + } else { + return new SentenceUpdateResultSet(iUC); + } + } + } catch (SQLException eSQL) { + throw new BasicException(eSQL); + } + } + +} diff --git a/src/main/java/com/unicenta/data/loader/TableDefinition.java b/src/main/java/com/unicenta/data/loader/TableDefinition.java new file mode 100644 index 0000000..4bde5f8 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/TableDefinition.java @@ -0,0 +1,349 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.format.Formats; + +/** + * + * @author JG uniCenta + */ +public class TableDefinition { + + private Session m_s; + private String tablename; + + private String[] fieldname; + private String[] fieldtran; + private Datas[] fielddata; + private Formats[] fieldformat; + + private int[] idinx; + + + /** Creates a new instance of TableDefinition + * @param s + * @param fieldformat + * @param tablename + * @param fieldname + * @param fieldtran + * @param idinx + * @param fielddata */ + public TableDefinition( + Session s, + String tablename, + String[] fieldname, String[] fieldtran, Datas[] fielddata, Formats[] fieldformat, + int[] idinx) { + + m_s = s; + this.tablename = tablename; + + this.fieldname = fieldname; + this.fieldtran = fieldtran; + this.fielddata = fielddata; + this.fieldformat = fieldformat; + + this.idinx = idinx; + } + + /** + * + * @param s + * @param tablename + * @param fieldname + * @param fielddata + * @param fieldformat + * @param idinx + */ + public TableDefinition( + Session s, + String tablename, + String[] fieldname, Datas[] fielddata, Formats[] fieldformat, + int[] idinx) { + this(s, tablename, fieldname, fieldname, fielddata, fieldformat, idinx); + } + + /** + * + * @return + */ + public String getTableName() { + return tablename; + } + + /** + * + * @return + */ + public String[] getFields() { + return fieldname; + } + + /** + * + * @param aiFields + * @return + */ + public Vectorer getVectorerBasic(int[] aiFields) { + return new VectorerBasic(fieldtran, fieldformat, aiFields); + } + + /** + * + * @param aiFields + * @return + */ + public IRenderString getRenderStringBasic(int[] aiFields) { + return new RenderStringBasic(fieldformat, aiFields); + } + + /** + * + * @param aiOrders + * @return + */ + public ComparatorCreator getComparatorCreator(int [] aiOrders) { + return new ComparatorCreatorBasic(fieldtran, fielddata, aiOrders); + } + + /** + * + * @return + */ + public IKeyGetter getKeyGetterBasic() { + if (idinx.length == 1) { + return new KeyGetterFirst(idinx); + } else { + return new KeyGetterBasic(idinx); + } + } + + /** + * + * @return + */ + public SerializerRead getSerializerReadBasic() { + return new SerializerReadBasic(fielddata); + } + + /** + * + * @param fieldindx + * @return + */ + public SerializerWrite getSerializerInsertBasic(int[] fieldindx) { + return new SerializerWriteBasicExt(fielddata, fieldindx); + } + + /** + * + * @return + */ + public SerializerWrite getSerializerDeleteBasic() { + return new SerializerWriteBasicExt(fielddata, idinx); + } + + /** + * + * @param fieldindx + * @return + */ + public SerializerWrite getSerializerUpdateBasic(int[] fieldindx) { + + int[] aindex = new int[fieldindx.length + idinx.length]; + + for (int i = 0; i < fieldindx.length; i++) { + aindex[i] = fieldindx[i]; + } + for (int i = 0; i < idinx.length; i++) { + aindex[i + fieldindx.length] = idinx[i]; + } + + return new SerializerWriteBasicExt(fielddata, aindex); + } + + /** + * + * @return + */ + public SentenceList getListSentence() { + return getListSentence(getSerializerReadBasic()); + } + + /** + * + * @param sr + * @return + */ + public SentenceList getListSentence(SerializerRead sr) { + return new PreparedSentence(m_s, getListSQL(), null, sr); + } + + /** + * + * @return + */ + public String getListSQL() { + + StringBuilder sent = new StringBuilder(); + sent.append("select "); + + for (int i = 0; i < fieldname.length; i ++) { + if (i > 0) { + sent.append(", "); + } + sent.append(fieldname[i]); + } + + sent.append(" from "); + sent.append(tablename); + + return sent.toString(); + } + + /** + * + * @return + */ + public SentenceExec getDeleteSentence() { + return getDeleteSentence(getSerializerDeleteBasic()); + } + + /** + * + * @param sw + * @return + */ + public SentenceExec getDeleteSentence(SerializerWrite sw) { + return new PreparedSentence(m_s, getDeleteSQL(), sw, null); + } + + /** + * + * @return + */ + public String getDeleteSQL() { + + StringBuilder sent = new StringBuilder(); + sent.append("delete from "); + sent.append(tablename); + + for (int i = 0; i < idinx.length; i ++) { + sent.append((i == 0) ? " where " : " and "); + sent.append(fieldname[idinx[i]]); + sent.append(" = ?"); + } + + return sent.toString(); + } + + /** + * + * @return + */ + public SentenceExec getInsertSentence() { + return getInsertSentence(getAllFields()); + } + + /** + * + * @param fieldindx + * @return + */ + public SentenceExec getInsertSentence(int[] fieldindx) { + return new PreparedSentence(m_s, getInsertSQL(fieldindx), getSerializerInsertBasic(fieldindx), null); + } + + private String getInsertSQL(int[] fieldindx) { + + StringBuilder sent = new StringBuilder(); + StringBuilder values = new StringBuilder(); + + sent.append("insert into "); + sent.append(tablename); + sent.append(" ("); + + for (int i = 0; i < fieldindx.length; i ++) { + if (i > 0) { + sent.append(", "); + values.append(", "); + } + sent.append(fieldname[fieldindx[i]]); + values.append("?"); + } + + sent.append(") values ("); + sent.append(values.toString()); + sent.append(")"); + + return sent.toString(); + } + + private int[] getAllFields() { + + int[] fieldindx = new int[fieldname.length]; + for (int i = 0; i < fieldname.length; i++) { + fieldindx[i] = i; + } + return fieldindx; + } + + /** + * + * @return + */ + public SentenceExec getUpdateSentence() { + return getUpdateSentence(getAllFields()); + } + + /** + * + * @param fieldindx + * @return + */ + public SentenceExec getUpdateSentence(int[] fieldindx) { + return new PreparedSentence(m_s, getUpdateSQL(fieldindx), getSerializerUpdateBasic(fieldindx), null); + } + + private String getUpdateSQL(int[] fieldindx) { + + StringBuilder sent = new StringBuilder(); + + sent.append("update "); + sent.append(tablename); + sent.append(" set "); + + for (int i = 0; i < fieldindx.length; i ++) { + if (i > 0) { + sent.append(", "); + } + sent.append(fieldname[fieldindx[i]]); + sent.append(" = ?"); + } + + for (int i = 0; i < idinx.length; i ++) { + sent.append((i == 0) ? " where " : " and "); + sent.append(fieldname[idinx[i]]); + sent.append(" = ?"); + } + + return sent.toString(); + } +} diff --git a/src/main/java/com/unicenta/data/loader/TicketFooter.java b/src/main/java/com/unicenta/data/loader/TicketFooter.java new file mode 100644 index 0000000..a3f33ad --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/TicketFooter.java @@ -0,0 +1,83 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2013 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; +import com.unicenta.pos.forms.AppViewConnection; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.data.loader.Session; +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import java.io.*; + +public class TicketFooter { + private String footer_line1; + private String footer_line2; + private String footer_line3; + private String footer_line4; + private String footer_line5; + private String footer_line6; + private File m_config; + private Session session; + + public TicketFooter() { + AppConfig config = new AppConfig(m_config); + // AppViewConnection Session = new AppViewConnection(); + + } + + public void loadProperties(AppConfig config) { + footer_line1=(config.getProperty("till.footer1")); + footer_line2=(config.getProperty("till.footer2")); + footer_line3=(config.getProperty("till.footer3")); + footer_line4=(config.getProperty("till.footer4")); + footer_line5=(config.getProperty("till.footer5")); + footer_line6=(config.getProperty("till.footer6")); + } + + public String getTicketFooterLine1() { + return footer_line1; + } + + public String getTicketFooterLine2() { + return footer_line2; + } + + public String getTicketFooterLine3() { + return footer_line3; + } + + public String getTicketFooterLine4() { + return footer_line4; + } + + public String getTicketFooterLine5() { + return footer_line5; + } + + public String getTicketFooterLine6() { + return footer_line6; + } +} + + + + + diff --git a/src/main/java/com/unicenta/data/loader/TicketHeader.java b/src/main/java/com/unicenta/data/loader/TicketHeader.java new file mode 100644 index 0000000..ed64301 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/TicketHeader.java @@ -0,0 +1,83 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2013 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; +import com.unicenta.pos.forms.AppViewConnection; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.data.loader.Session; +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import java.io.*; + +public class TicketHeader { + private String header_line1; + private String header_line2; + private String header_line3; + private String header_line4; + private String header_line5; + private String header_line6; + private File m_config; + private Session session; + + public TicketHeader() { + AppConfig config = new AppConfig(m_config); + // AppViewConnection Session = new AppViewConnection(); + + } + + public void loadProperties(AppConfig config) { + header_line1=(config.getProperty("till.header1")); + header_line2=(config.getProperty("till.header2")); + header_line3=(config.getProperty("till.header3")); + header_line4=(config.getProperty("till.header4")); + header_line5=(config.getProperty("till.header5")); + header_line6=(config.getProperty("till.header6")); + } + + public String getTicketHeaderLine1() { + return header_line1; + } + + public String getTicketHeaderLine2() { + return header_line2; + } + + public String getTicketHeaderLine3() { + return header_line3; + } + + public String getTicketHeaderLine4() { + return header_line4; + } + + public String getTicketHeaderLine5() { + return header_line5; + } + + public String getTicketHeaderLine6() { + return header_line6; + } +} + + + + + diff --git a/src/main/java/com/unicenta/data/loader/Transaction.java b/src/main/java/com/unicenta/data/loader/Transaction.java new file mode 100644 index 0000000..6db4506 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/Transaction.java @@ -0,0 +1,74 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; +import java.sql.SQLException; + +/** + * + * @author adrianromero + * Created on 26 de febrero de 2007, 21:50 + * @param + * + */ +public abstract class Transaction { + + private Session s; + + /** Creates a new instance of Transaction + * @param s */ + public Transaction(Session s) { + this.s = s; + } + + /** + * + * @return + * @throws BasicException + */ + public final T execute() throws BasicException { + + if (s.isTransaction()) { + return transact(); + } else { + try { + try { + s.begin(); + T result = transact(); + s.commit(); + return result; + } catch (BasicException e) { + s.rollback(); + throw e; + } + } catch (SQLException eSQL) { + throw new BasicException("Transaction error", eSQL); + } + } + } + + /** + * + * @return + * @throws BasicException + */ + protected abstract T transact() throws BasicException; +} diff --git a/src/main/java/com/unicenta/data/loader/Vectorer.java b/src/main/java/com/unicenta/data/loader/Vectorer.java new file mode 100644 index 0000000..09ec818 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/Vectorer.java @@ -0,0 +1,46 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public interface Vectorer { + + // public int size(); + + /** + * + * @return + * @throws BasicException + */ + public String[] getHeaders() throws BasicException; + + /** + * + * @param obj + * @return + * @throws BasicException + */ + public String[] getValues(Object obj) throws BasicException; +} diff --git a/src/main/java/com/unicenta/data/loader/VectorerBasic.java b/src/main/java/com/unicenta/data/loader/VectorerBasic.java new file mode 100644 index 0000000..95d7beb --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/VectorerBasic.java @@ -0,0 +1,77 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import com.unicenta.format.Formats; +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public class VectorerBasic implements Vectorer { + + private int[] m_aiIndex; + private String[] m_asHeaders; + private Formats[] m_aFormats; + + /** + * + * @param asHeaders + * @param aFormats + * @param aiIndex + */ + public VectorerBasic(String[] asHeaders, Formats[] aFormats, int[] aiIndex) { + m_asHeaders = asHeaders; + m_aFormats = aFormats; + m_aiIndex = aiIndex; + } + + /** + * + * @return + * @throws BasicException + */ + public String[] getHeaders() throws BasicException { + + String[] asvalues = new String[m_aiIndex.length]; + for (int i = 0; i < m_aiIndex.length; i++) { + asvalues[i] = m_asHeaders[m_aiIndex[i]]; + } + + return asvalues; + } + + /** + * + * @param obj + * @return + * @throws BasicException + */ + public String[] getValues(Object obj) throws BasicException { + Object[] avalues = (Object[]) obj; + String[] asvalues = new String[m_aiIndex.length]; + for (int i = 0; i < m_aiIndex.length; i++) { + asvalues[i] = m_aFormats[m_aiIndex[i]].formatValue(avalues[m_aiIndex[i]]); + } + + return asvalues; + } +} diff --git a/src/main/java/com/unicenta/data/loader/VectorerBuilder.java b/src/main/java/com/unicenta/data/loader/VectorerBuilder.java new file mode 100644 index 0000000..ee6f8d3 --- /dev/null +++ b/src/main/java/com/unicenta/data/loader/VectorerBuilder.java @@ -0,0 +1,108 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.loader; + +import java.util.*; +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public abstract class VectorerBuilder implements Vectorer { + + /** Creates a new instance of VectorerBuilder */ + public VectorerBuilder() { + } + + /** + * + * @return + * @throws BasicException + */ + public abstract String[] getHeaders() throws BasicException; + + /** + * + * @param obj + * @return + * @throws BasicException + */ + public String[] getValues(Object obj) throws BasicException { + + SerializableToArray s2a = new SerializableToArray(); + ((SerializableWrite) obj).writeValues(s2a); + return s2a.getValues(); + } + + private static class SerializableToArray implements DataWrite { + + private ArrayList m_aParams; + + /** Creates a new instance of MetaParameter */ + public SerializableToArray() { + m_aParams = new ArrayList(); + } + + public void setDouble(int paramIndex, Double dValue) throws BasicException { + ensurePlace(paramIndex - 1); + m_aParams.set(paramIndex - 1, dValue.toString()); + } + public void setBoolean(int paramIndex, Boolean bValue) throws BasicException { + ensurePlace(paramIndex - 1); + m_aParams.set(paramIndex - 1, bValue.toString()); + } + public void setInt(int paramIndex, Integer iValue) throws BasicException { + ensurePlace(paramIndex - 1); + m_aParams.set(paramIndex - 1, iValue.toString()); + } + public void setString(int paramIndex, String sValue) throws BasicException { + ensurePlace(paramIndex - 1); + m_aParams.set(paramIndex - 1, sValue); + } + public void setTimestamp(int paramIndex, java.util.Date dValue) throws BasicException { + ensurePlace(paramIndex - 1); + m_aParams.set(paramIndex - 1, dValue.toString()); + } +// public void setBinaryStream(int paramIndex, java.io.InputStream in, int length) throws DataException { +// ensurePlace(paramIndex -1); +// // m_aParams.set(paramIndex - 1, value.toString()); // quiza un uuencode o algo asi +// } + public void setBytes(int paramIndex, byte[] value) throws BasicException { + ensurePlace(paramIndex -1); + m_aParams.set(paramIndex - 1, value.toString()); // quiza un uuencode o algo asi + } + public void setObject(int paramIndex, Object value) throws BasicException { + ensurePlace(paramIndex - 1); + m_aParams.set(paramIndex - 1, value.toString()); + } + + private void ensurePlace(int i) { + m_aParams.ensureCapacity(i); + while (i >= m_aParams.size()){ + m_aParams.add(null); + } + } + + public String[] getValues() { + return (String[]) m_aParams.toArray(new String[m_aParams.size()]); + } + } +} diff --git a/src/main/java/com/unicenta/data/model/Column.java b/src/main/java/com/unicenta/data/model/Column.java new file mode 100644 index 0000000..095c8d7 --- /dev/null +++ b/src/main/java/com/unicenta/data/model/Column.java @@ -0,0 +1,53 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.model; + +/** + * + * @author adrian + */ +public class Column { + + private String name; + + /** + * + * @param name + */ + public Column(String name) { + this.name = name; + } + + /** + * + * @return + */ + public String getName() { + return name; + } + + /** + * + * @return + */ + public boolean isPK() { + return false; + } +} diff --git a/src/main/java/com/unicenta/data/model/Field.java b/src/main/java/com/unicenta/data/model/Field.java new file mode 100644 index 0000000..2034375 --- /dev/null +++ b/src/main/java/com/unicenta/data/model/Field.java @@ -0,0 +1,114 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.model; + +import com.unicenta.data.loader.Datas; +import com.unicenta.format.Formats; + +/** + * + * @author adrian + */ +public class Field { + + private String label; + private Datas data; + private Formats format; + + private boolean searchable; + private boolean comparable; + private boolean title; + + /** + * + * @param label + * @param data + * @param format + * @param title + * @param searchable + * @param comparable + */ + public Field(String label, Datas data, Formats format, boolean title, boolean searchable, boolean comparable) { + this.label = label; + this.data = data; + this.format = format; + this.title = title; + this.searchable = searchable; + this.comparable = comparable; + } + + /** + * + * @param label + * @param data + * @param format + */ + public Field(String label, Datas data, Formats format) { + this(label, data, format, false, false, false); + } + + /** + * + * @return + */ + public String getLabel() { + return label; + } + + /** + * + * @return + */ + public Formats getFormat() { + return format; + } + + /** + * + * @return + */ + public Datas getData() { + return data; + } + + /** + * + * @return + */ + public boolean isSearchable() { + return searchable; + } + + /** + * + * @return + */ + public boolean isComparable() { + return comparable; + } + + /** + * + * @return + */ + public boolean isTitle() { + return title; + } +} diff --git a/src/main/java/com/unicenta/data/model/PrimaryKey.java b/src/main/java/com/unicenta/data/model/PrimaryKey.java new file mode 100644 index 0000000..a9ede17 --- /dev/null +++ b/src/main/java/com/unicenta/data/model/PrimaryKey.java @@ -0,0 +1,44 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.model; + +/** + * + * @author adrian + */ +public class PrimaryKey extends Column { + + /** + * + * @param name + */ + public PrimaryKey(String name) { + super(name); + } + + /** + * + * @return + */ + @Override + public boolean isPK() { + return true; + } +} diff --git a/src/main/java/com/unicenta/data/model/Row.java b/src/main/java/com/unicenta/data/model/Row.java new file mode 100644 index 0000000..418774a --- /dev/null +++ b/src/main/java/com/unicenta/data/model/Row.java @@ -0,0 +1,358 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.model; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ListCellRendererBasic; +import com.unicenta.data.loader.ComparatorCreator; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.DataWrite; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.loader.IRenderString; +import com.unicenta.data.loader.PreparedSentence; +import com.unicenta.data.loader.SentenceExec; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.loader.SerializerRead; +import com.unicenta.data.loader.SerializerWrite; +import com.unicenta.data.loader.Session; +import com.unicenta.data.loader.Vectorer; +import com.unicenta.data.user.FilterEditorCreator; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.data.user.SaveProvider; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import javax.swing.ListCellRenderer; + +/** + * + * @author adrian + */ +public class Row { + + private Field[] fields; + + /** + * + * @param fields + */ + public Row(Field... fields) { + this.fields = fields; + } + + /** + * + * @return + */ + public Vectorer getVectorer() { + return new RowVectorer(); + } + + /** + * + * @return + */ + public IRenderString getRenderString() { + return new RowRenderString(); + } + + /** + * + * @return + */ + public ListCellRenderer getListCellRenderer() { + return new ListCellRendererBasic(new RowRenderString()); + } + + /** + * + * @return + */ + public ComparatorCreator getComparatorCreator() { + return new RowComparatorCreator(); + } + + /** + * + * @param s + * @param sql + * @param indexes + * @return + */ + public SentenceExec getExecSentence(Session s, String sql, final int... indexes) { + return new PreparedSentence(s, sql, + new SerializerWrite() { + @Override + public void writeValues(DataWrite dp, Object[] obj) throws BasicException { + for (int i = 0; i < indexes.length; i++) { + fields[indexes[i]].getData().setValue(dp, i + 1, obj[indexes[i]]); + } + } + } + ); + } + + /** + * + * @param s + * @param t + * @return + */ + public ListProvider getListProvider(Session s, Table t) { + return new ListProviderCreator(getListSentence(s, t)); + } + + /** + * + * @param s + * @param t + * @return + */ + public SaveProvider getSaveProvider(Session s, Table t) { + return new SaveProvider(getUpdateSentence(s, t), getInsertSentence(s, t), getDeleteSentence(s, t)); + } + + /** + * + * @param s + * @param sql + * @param sw + * @return + */ + public SentenceList getListSentence(Session s, String sql, SerializerWrite sw) { + return new PreparedSentence(s, sql, sw, new RowSerializerRead()); + } + + /** + * + * @param s + * @param sql + * @param filter + * @return + */ + public ListProvider getListProvider(Session s, String sql, FilterEditorCreator filter) { + return new ListProviderCreator(getListSentence(s, sql, filter.getSerializerWrite()), filter); + } + + /** + * + * @param s + * @param t + * @return + */ + public SentenceList getListSentence(Session s, Table t) { + return getListSentence(s, t.getListSQL(), null); + } + + /** + * + * @param s + * @param t + * @return + */ + public SentenceExec getInsertSentence(Session s, final Table t) { + return new PreparedSentence(s, t.getInsertSQL(), + new SerializerWrite() { + @Override + public void writeValues(DataWrite dp, Object[] obj) throws BasicException { + for (int i = 0; i < t.getColumns().length; i++) { + fields[i].getData().setValue(dp, i + 1, obj[i]); + } + } + } + ); + } + + /** + * + * @param s + * @param t + * @return + */ + public SentenceExec getDeleteSentence(Session s, final Table t) { + return new PreparedSentence(s, t.getDeleteSQL(), + new SerializerWrite() { + @Override + public void writeValues(DataWrite dp, Object[] obj) throws BasicException { + int index = 1; + for (int i = 0; i < t.getColumns().length; i++) { + if (t.getColumns()[i].isPK()) { + fields[i].getData().setValue(dp, index++, obj[i]); + } + } + } + } + ); + } + + /** + * + * @param s + * @param t + * @return + */ + public SentenceExec getUpdateSentence(Session s, final Table t) { + return new PreparedSentence(s, t.getUpdateSQL(), + new SerializerWrite() { + @Override + public void writeValues(DataWrite dp, Object[] obj) throws BasicException { + int index = 1; + for (int i = 0; i < t.getColumns().length; i++) { + if (!t.getColumns()[i].isPK()) { + fields[i].getData().setValue(dp, index++, obj[i]); + } + } + for (int i = 0; i < t.getColumns().length; i++) { + if (t.getColumns()[i].isPK()) { + fields[i].getData().setValue(dp, index++, obj[i]); + } + } + } + } + ); + } + + /** + * + * @return + */ + public Datas[] getDatas() { + Datas[] d = new Datas[fields.length]; + for (int i = 0; i < fields.length; i++) { + d[i] = fields[i].getData(); + } + return d; + } + + /** + * + * @return + */ + public SerializerRead getSerializerRead() { + return new RowSerializerRead(); + } + + private class RowSerializerRead implements SerializerRead { + @Override + public Object readValues(DataRead dr) throws BasicException { + Object[] m_values = new Object[fields.length]; + for (int i = 0; i < fields.length; i++) { + m_values[i] = fields[i].getData().getValue(dr, i + 1); + } + return m_values; + } + } + + private class RowVectorer implements Vectorer { + @Override + public String[] getHeaders() throws BasicException { +// JG Aug 2013 use Diamon Inference + List l = new ArrayList<>(); + for (Field f : fields) { + if (f.isSearchable()) { + l.add(f.getLabel()); + } + } + return l.toArray(new String[l.size()]); + } + @Override + public String[] getValues(Object obj) throws BasicException { + Object[] values = (Object[]) obj; +// JG Aug 2013 use Diamon Inference + List l = new ArrayList<>(); + for (int i = 0; i < fields.length; i++) { + if (fields[i].isSearchable()) { + l.add(fields[i].getFormat().formatValue(values[i])); + } + } + return l.toArray(new String[l.size()]); + } + } + + private class RowRenderString implements IRenderString { + @Override + public String getRenderString(Object value) { + Object[] values = (Object[]) value; + StringBuilder s = new StringBuilder(); + for (int i = 0; i < fields.length; i++) { + if (fields[i].isTitle()) { + if (s.length() > 0) { + s.append(" - "); + } + s.append(fields[i].getFormat().formatValue(values[i])); + } + } + return s.toString(); + } + } + + private class RowComparatorCreator implements ComparatorCreator { + + private List comparablefields = new ArrayList<>(); + + public RowComparatorCreator() { + for (int i = 0; i < fields.length; i++) { + if (fields[i].isComparable()) { + comparablefields.add(i); + } + } + } + + @Override + public String[] getHeaders() { + String [] headers = new String [comparablefields.size()]; + for (int i = 0; i < comparablefields.size(); i++) { + headers[i] = fields[comparablefields.get(i)].getLabel(); + } + return headers; + } + + @Override + public Comparator createComparator(final int[] orderby) { + return new Comparator() { + @Override + public int compare(Object o1, Object o2) { + if (o1 == null) { + if (o2 == null) { + return 0; + } else { + return -1; + } + } else if (o2 == null) { + return +1; + } else { + Object[] ao1 = (Object[]) o1; + Object[] ao2 = (Object[]) o2; + for (int i = 0; i < orderby.length; i++) { + int result = fields[comparablefields.get(orderby[i])].getData().compare( + ao1[comparablefields.get(orderby[i])], + ao2[comparablefields.get(orderby[i])]); + if (result != 0) { + return result; + } + } + return 0; + } + } + }; + } + } +} diff --git a/src/main/java/com/unicenta/data/model/Table.java b/src/main/java/com/unicenta/data/model/Table.java new file mode 100644 index 0000000..818b55a --- /dev/null +++ b/src/main/java/com/unicenta/data/model/Table.java @@ -0,0 +1,159 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.model; + +/** + * + * @author adrian + */ +public class Table { + + private String name; + private Column[] columns; + + /** + * + * @param name + * @param columns + */ + public Table(String name, Column... columns) { + this.name = name; + this.columns = columns; + } + + /** + * + * @return + */ + public String getName() { + return name; + } + + /** + * + * @return + */ + public Column[] getColumns() { + return columns; + } + + /** + * + * @return + */ + public String getListSQL() { + StringBuilder sent = new StringBuilder(); + sent.append("select "); + + for (int i = 0; i < columns.length; i ++) { + if (i > 0) { + sent.append(", "); + } + sent.append(columns[i].getName()); + } + + sent.append(" from "); + sent.append(name); + + return sent.toString(); + } + + /** + * + * @return + */ + public String getInsertSQL() { + + StringBuilder sent = new StringBuilder(); + StringBuilder values = new StringBuilder(); + + sent.append("insert into "); + sent.append(name); + sent.append(" ("); + + for (int i = 0; i < columns.length; i ++) { + if (i > 0) { + sent.append(", "); + values.append(", "); + } + sent.append(columns[i].getName()); + values.append("?"); + } + + sent.append(") values ("); + sent.append(values.toString()); + sent.append(")"); + + return sent.toString(); + } + + /** + * + * @return + */ + public String getUpdateSQL() { + + StringBuilder values = new StringBuilder(); + StringBuilder filter = new StringBuilder(); + + for (int i = 0; i < columns.length; i ++) { + if (columns[i].isPK()) { + if (filter.length() == 0) { + filter.append(" where "); + } else { + filter.append(" and "); + } + filter.append(columns[i].getName()); + filter.append(" = ?"); + } else { + if (values.length() > 0) { + values.append(", "); + } + values.append(columns[i].getName()); + values.append(" = ?"); + } + } + + return "update " + name + " set " + values + filter; + } + + /** + * + * @return + */ + public String getDeleteSQL() { + + StringBuilder filter = new StringBuilder(); + + for (int i = 0; i < columns.length; i ++) { + if (columns[i].isPK()) { + if (filter.length() == 0) { + filter.append(" where "); + } else { + filter.append(" and "); + } + filter.append(columns[i].getName()); + filter.append(" = ?"); + } + } + + return "delete from " + name + filter; + } +} diff --git a/src/main/java/com/unicenta/data/user/BrowsableData.java b/src/main/java/com/unicenta/data/user/BrowsableData.java new file mode 100644 index 0000000..6200c4d --- /dev/null +++ b/src/main/java/com/unicenta/data/user/BrowsableData.java @@ -0,0 +1,410 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.user; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.LocalRes; +import java.util.*; +import javax.swing.ListModel; +import javax.swing.event.EventListenerList; +import javax.swing.event.ListDataEvent; +import javax.swing.event.ListDataListener; + +/** + * + * @author JG uniCenta + */ +public class BrowsableData implements ListModel { + + /** + * + */ + protected EventListenerList listeners = new EventListenerList(); + private boolean m_bIsAdjusting; + + private ListProvider m_dataprov; + private SaveProvider m_saveprov; + + private List m_aData; // List + + private Comparator m_comparer; + + /** Creates a new instance of BrowsableData + * @param dataprov + * @param saveprov + * @param c */ + public BrowsableData(ListProvider dataprov, SaveProvider saveprov, Comparator c) { + m_dataprov = dataprov; + m_saveprov = saveprov; + m_comparer = c; + m_bIsAdjusting = false; + + m_aData = new ArrayList(); + } + + /** + * + * @param dataprov + * @param saveprov + */ + public BrowsableData(ListProvider dataprov, SaveProvider saveprov) { + this(dataprov, saveprov, null); + } + + /** + * + * @param dataprov + */ + public BrowsableData(ListProvider dataprov) { + this(dataprov, null, null); + } + + public final void addListDataListener(ListDataListener l) { + listeners.add(ListDataListener.class, l); + } + public final void removeListDataListener(ListDataListener l) { + listeners.remove(ListDataListener.class, l); + } + + // Metodos de acceso + public final Object getElementAt(int index) { + return m_aData.get(index); + } + + public final int getSize() { + return m_aData.size(); + } + + /** + * + * @return + */ + public final boolean isAdjusting() { + return m_bIsAdjusting; + } + + /** + * + * @param index0 + * @param index1 + */ + protected void fireDataIntervalAdded(int index0, int index1) { + m_bIsAdjusting = true; + EventListener[] l = listeners.getListeners(ListDataListener.class); + ListDataEvent e = null; + for (int i = 0; i < l.length; i++) { + if (e == null) { + e = new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, index0, index1); + } + ((ListDataListener) l[i]).intervalAdded(e); + } + m_bIsAdjusting = false; + } + + /** + * + * @param index0 + * @param index1 + */ + protected void fireDataContentsChanged(int index0, int index1) { + m_bIsAdjusting = true; + EventListener[] l = listeners.getListeners(ListDataListener.class); + ListDataEvent e = null; + for (int i = 0; i < l.length; i++) { + if (e == null) { + e = new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index0, index1); + } + ((ListDataListener) l[i]).contentsChanged(e); + } + m_bIsAdjusting = false; + } + + /** + * + * @param index0 + * @param index1 + */ + protected void fireDataIntervalRemoved(int index0, int index1) { + m_bIsAdjusting = true; + EventListener[] l = listeners.getListeners(ListDataListener.class); + ListDataEvent e = null; + for (int i = 0; i < l.length; i++) { + if (e == null) { + e = new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, index0, index1); + } + ((ListDataListener) l[i]).intervalRemoved(e); + } + m_bIsAdjusting = false; + } + + /** + * + * @throws BasicException + */ + public void refreshData() throws BasicException { + + putNewData(m_dataprov == null + ? null + : m_dataprov.refreshData()); + } + + /** + * + * @throws BasicException + */ + public void loadData() throws BasicException { + + putNewData(m_dataprov == null + ? null + : m_dataprov.loadData()); + } + + /** + * + * @throws BasicException + */ + public void unloadData() throws BasicException { + putNewData(null); + } + + /** + * + * @param l + */ + public void loadList(List l) { + putNewData(l); + } + + /** + * + * @param c + * @throws BasicException + */ + public void sort(Comparator c) throws BasicException { + + Collections.sort(m_aData, c); + putNewData(m_aData); + } + + /** + * + * @return + */ + public final boolean canLoadData() { + return m_dataprov != null; + } + + /** + * + * @return + */ + public boolean canInsertData() { + return m_saveprov != null && m_saveprov.canInsert(); + } + + /** + * + * @return + */ + public boolean canDeleteData() { + return m_saveprov != null && m_saveprov.canDelete(); + } + + /** + * + * @return + */ + public boolean canUpdateData() { + return m_saveprov != null && m_saveprov.canUpdate(); + } + + /** + * + * @param index + * @param f + * @return + * @throws BasicException + */ + public final int findNext(int index, Finder f) throws BasicException { + int i = index + 1; + + // search up to the end of the recordset + while (i < m_aData.size()) { + if (f.match(this.getElementAt(i))) { + return i; + } + i++; + } + // search from the begining + i = 0; + while (i < index) { + if (f.match(this.getElementAt(i))) { + return i; + } + i++; + } + + // No se ha encontrado + return -1; + } + + /** + * + * @param index + * @return + * @throws BasicException + */ + public final int removeRecord(int index) throws BasicException { + if (canDeleteData() && index >= 0 && index < m_aData.size()) { + if (m_saveprov.deleteData(getElementAt(index)) > 0) { + // borramos el elemento indicado + m_aData.remove(index); + // disparamos los eventos + fireDataIntervalRemoved(index, index); + + int newindex; + if (index < m_aData.size()) { + newindex = index; + } else { + newindex = m_aData.size() - 1; + } + return newindex; + } else { + throw new BasicException(LocalRes.getIntString("exception.nodelete")); + } + } else { + // indice no valido + throw new BasicException(LocalRes.getIntString("exception.nodelete")); + } + } + + /** + * + * @param index + * @param value + * @return + * @throws BasicException + */ + public final int updateRecord(int index, Object value) throws BasicException { + + if (canUpdateData() && index >= 0 && index < m_aData.size()) { + if (m_saveprov.updateData(value) > 0) { + // Modificamos el elemento indicado + int newindex; + if (m_comparer == null) { + newindex = index; + m_aData.set(newindex, value); + } else { + // lo movemos + newindex = insertionPoint(value); + if (newindex == index + 1) { + newindex = index; + m_aData.set(newindex, value); + } else if (newindex > index + 1) { + m_aData.remove(index); + newindex --; + m_aData.add(newindex, value); + } else { + m_aData.remove(index); + m_aData.add(newindex, value); + } + } + + if (newindex >= index) { + fireDataContentsChanged(index, newindex); + } else { + fireDataContentsChanged(newindex, index); + } + return newindex; + } else { + // fallo la actualizacion + throw new BasicException(LocalRes.getIntString("exception.noupdate")); + } + } else { + // registro invalido + throw new BasicException(LocalRes.getIntString("exception.noupdate")); + } + } + + /** + * + * @param value + * @return + * @throws BasicException + */ + public final int insertRecord(Object value) throws BasicException { + + if (canInsertData() && m_saveprov.insertData(value) > 0) { + int newindex; + if (m_comparer == null) { + // Anadimos el elemento indicado al final... + newindex = m_aData.size(); + } else { + // lo insertamos en el lugar adecuado + newindex = insertionPoint(value); + } + m_aData.add(newindex, value); + + // Disparamos la inserccion + fireDataIntervalAdded(newindex, newindex); + return newindex; + } else { + throw new BasicException(LocalRes.getIntString("exception.noinsert")); + } + } + + private final void putNewData(List aData) { + + int oldSize = m_aData.size(); + m_aData = (aData == null) ? new ArrayList() : aData; + int newSize = m_aData.size(); + + // Ordeno si es un Browsabledata ordenado + if (m_comparer != null) { + Collections.sort(m_aData, m_comparer); + } + + fireDataContentsChanged(0, newSize - 1); + if (oldSize > newSize) { + fireDataIntervalRemoved(newSize, oldSize - 1); + } else if (oldSize < newSize) { + fireDataIntervalAdded(oldSize, newSize - 1); + } + } + + private final int insertionPoint(Object value) { + + int low = 0; + int high = m_aData.size() - 1; + + while (low <= high) { + int mid = (low + high) >> 1; + Object midVal = m_aData.get(mid); + int cmp = m_comparer.compare(midVal, value); + + if (cmp <= 0) { + low = mid + 1; + } else { + high = mid - 1; + } + } + return low; + } +} diff --git a/src/main/java/com/unicenta/data/user/BrowsableEditableData.java b/src/main/java/com/unicenta/data/user/BrowsableEditableData.java new file mode 100644 index 0000000..00dc1ad --- /dev/null +++ b/src/main/java/com/unicenta/data/user/BrowsableEditableData.java @@ -0,0 +1,595 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2015 uniCenta & previous Openbravo POS works +// http://www.unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.user; + +import java.util.*; +import javax.swing.*; +import java.awt.Component; +import javax.swing.event.EventListenerList; +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.LocalRes; +import com.unicenta.pos.customers.CustomerInfoExt; +import com.unicenta.pos.customers.CustomerInfoGlobal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSystem; +import com.unicenta.pos.scripting.ScriptEngine; +import com.unicenta.pos.scripting.ScriptFactory; + +/** + * + * @author JG uniCenta + */ +public class BrowsableEditableData { + + /** + * Ticket Type = Debit + */ + public static final int ST_NORECORD = 0; + + /** + * Ticket Type = Credit (Refund) + */ + public static final int ST_UPDATE = 1; + + /** + * Payment Type = Debit (On Account) + */ + public static final int ST_DELETE = 2; + + /** + * Payment Type = Credit (On Account) + */ + public static final int ST_INSERT = 3; + + private final static int INX_EOF = -1; + + private BrowsableData m_bd; + + protected EventListenerList listeners = new EventListenerList(); + + private EditorRecord m_editorrecord; + private DirtyManager m_Dirty; + private int m_iState; // vinculado siempre al m_editorrecord +// private DocumentLoader m_keyvalue; + private int m_iIndex; + private boolean m_bIsAdjusting; + + private boolean iseditable = true; + + /** + * Creates a new instance of BrowsableEditableData + * @param bd + * @param ed + * @param dirty + */ + public BrowsableEditableData(BrowsableData bd, EditorRecord ed, DirtyManager dirty) { + m_bd = bd; + + m_editorrecord = ed; + m_Dirty = dirty; + m_iState = ST_NORECORD; + m_iIndex = INX_EOF; // En EOF + m_bIsAdjusting = false; +// m_keyvalue = DocumentLoaderBasic.INSTANCE; + + // Inicializo ? + m_editorrecord.writeValueEOF(); + m_Dirty.setDirty(false); + } + + /** + * Check Ticket Dirty state + * @param dataprov + * @param saveprov + * @param c + * @param ed + * @param dirty + */ + public BrowsableEditableData(ListProvider dataprov, SaveProvider saveprov, Comparator c, EditorRecord ed, DirtyManager dirty) { + this(new BrowsableData(dataprov, saveprov, c), ed, dirty); + } + + /** + * Ticket Dirty state + * @param dataprov + * @param saveprov + * @param ed + * @param dirty + */ + public BrowsableEditableData(ListProvider dataprov, SaveProvider saveprov, EditorRecord ed, DirtyManager dirty) { + this(new BrowsableData(dataprov, saveprov, null), ed, dirty); + } + + /** + * Ticket data for list + * @return + */ + public final ListModel getListModel() { + return m_bd; + } + + /** + * Value Changes + * @return + */ + public final boolean isAdjusting() { + return m_bIsAdjusting || m_bd.isAdjusting(); + } + + private Object getCurrentElement() { + return (m_iIndex >= 0 && m_iIndex < m_bd.getSize()) ? m_bd.getElementAt(m_iIndex) : null; + } + + /** + * Return index + * @return + */ + public final int getIndex() { + return m_iIndex; + } + + /** + * Add to State listener + * @param l + */ + public final void addStateListener(StateListener l) { + listeners.add(StateListener.class, l); + } + + /** + * Delete from State listener + * @param l + */ + public final void removeStateListener(StateListener l) { + listeners.remove(StateListener.class, l); + } + + /** + * Edit State listener + * @param l + */ + public final void addEditorListener(EditorListener l) { + listeners.add(EditorListener.class, l); + } + + /** + * Delete from State listener + * @param l + */ + public final void removeEditorListener(EditorListener l) { + listeners.remove(EditorListener.class, l); + } + + /** + * Add to browse listener + * @param l + */ + public final void addBrowseListener(BrowseListener l) { + listeners.add(BrowseListener.class, l); + } + + /** + * Delete from browse listener + * @param l + */ + public final void removeBrowseListener(BrowseListener l) { + listeners.remove(BrowseListener.class, l); + } + + /** + * Return State + * @return + */ + public int getState() { + return m_iState; + } + + private void fireStateUpdate() { + EventListener[] l = listeners.getListeners(StateListener.class); + int iState = getState(); + for (int i = 0; i < l.length; i++) { + ((StateListener) l[i]).updateState(iState); + } + } + + /** + * Execute listener event fire + */ + protected void fireDataBrowse() { + + m_bIsAdjusting = true; + // Lanzamos los eventos... + Object obj = getCurrentElement(); + int iIndex = getIndex(); + int iCount = m_bd.getSize(); + + // actualizo el registro + if (obj == null) { + m_iState = ST_NORECORD; + m_editorrecord.writeValueEOF(); + } else { + m_iState = ST_UPDATE; + m_editorrecord.writeValueEdit(obj); + } + m_Dirty.setDirty(false); + fireStateUpdate(); + + // Invoco a los Editor Listener + EventListener[] l = listeners.getListeners(EditorListener.class); + for (int i = 0; i < l.length; i++) { + ((EditorListener) l[i]).updateValue(obj); + } + // Y luego a los Browse Listener + l = listeners.getListeners(BrowseListener.class); + for (int i = 0; i < l.length; i++) { + ((BrowseListener) l[i]).updateIndex(iIndex, iCount); + } + m_bIsAdjusting = false; + } + + /** + * Data available + * @return + */ + public boolean canLoadData() { + return m_bd.canLoadData(); + } + + /** + * Flag data editable + * @param value + */ + public void setEditable(boolean value) { + iseditable = value; + } + + /** + * Flag data can insert + * @return + */ + public boolean canInsertData() { + return iseditable && m_bd.canInsertData(); + } + + /** + * Flag data can delete + * @return + */ + public boolean canDeleteData() { + return iseditable && m_bd.canDeleteData(); + } + + /** + * Flag can update + * @return + */ + public boolean canUpdateData() { + return iseditable && m_bd.canUpdateData(); + } + + /** + * Refresh current state + */ + public void refreshCurrent() { + baseMoveTo(m_iIndex); + } + + /** + * Refresh object data + * @throws BasicException + */ + public void refreshData() throws BasicException { + saveData(); + m_bd.refreshData(); + m_editorrecord.refresh(); + baseMoveTo(0); + } + + /** + * Load object data + * @throws BasicException + */ + public void loadData() throws BasicException { + saveData(); + m_bd.loadData(); + m_editorrecord.refresh(); + baseMoveTo(0); + } + + /** + * Unload object data + * @throws BasicException + */ + public void unloadData() throws BasicException { + saveData(); + m_bd.unloadData(); + m_editorrecord.refresh(); + baseMoveTo(0); + } + + /** + * Sort object data + * @param c + * @throws BasicException + */ + public void sort(Comparator c) throws BasicException { + saveData(); + m_bd.sort(c); + baseMoveTo(0); + } + + /** + * Move data to object + * @param i + * @throws BasicException + */ + public void moveTo(int i) throws BasicException { + saveData(); + if (m_iIndex != i) { + baseMoveTo(i); + } + } + + /** + * Step into data -1 (Back) + * @throws BasicException + */ + public final void movePrev() throws BasicException { + saveData(); + if (m_iIndex > 0) { + baseMoveTo(m_iIndex - 1); + } + } + + /** + * Step into data +1 (Forward) + * @throws BasicException + */ + public final void moveNext() throws BasicException { + saveData(); + if (m_iIndex < m_bd.getSize() - 1) { + baseMoveTo(m_iIndex + 1); + } + } + + /** + * Step into data BOF (First) + * @throws BasicException + */ + public final void moveFirst() throws BasicException { + saveData(); + if (m_bd.getSize() > 0) { + baseMoveTo(0); + } + } + + /** + * Step into data EOF (End) + * @throws BasicException + */ + public final void moveLast() throws BasicException { + saveData(); + if (m_bd.getSize() > 0) { + baseMoveTo(m_bd.getSize() - 1); + } + } + + /** + * Step into data =value (Next) + * @param f + * @return + * @throws BasicException + */ + public final int findNext(Finder f) throws BasicException { + return m_bd.findNext(m_iIndex, f); + } + + /** + * Save data + * @throws BasicException + */ + public void saveData() throws BasicException { + + //Get the customer being referenced for firing action events + boolean isCustomerChangeEvent = false; + Object[] customer = new Object[27]; + if (m_editorrecord.getClass().getName().equals("com.unicenta.pos.customers.CustomersView")) { + isCustomerChangeEvent = true; + customer = (Object[]) m_editorrecord.createValue(); + } + + if (m_Dirty.isDirty()) { + if (m_iState == ST_UPDATE) { + int i = m_bd.updateRecord(m_iIndex, m_editorrecord.createValue()); + m_editorrecord.refresh(); + baseMoveTo(i); + + if (isCustomerChangeEvent) { + triggerCustomerEvent("customer.updated", customer, customer[27]); + } + + + } else if (m_iState == ST_INSERT) { + + if (isCustomerChangeEvent) { + m_editorrecord.refresh(); + + AppView appView = (AppView) customer[27]; + int i = m_bd.insertRecord(customer); + m_editorrecord.refresh(); + baseMoveTo(i); + + triggerCustomerEvent("customer.created", customer, customer[27]); + + int n = JOptionPane.showConfirmDialog( + null, + AppLocal.getIntString("message.customerassign"), + AppLocal.getIntString("title.editor"), + JOptionPane.YES_NO_OPTION); + + if (n == 0) { + CustomerInfoGlobal customerInfoGlobal = CustomerInfoGlobal.getInstance(); + CustomerInfoExt customerInfoExt = new CustomerInfoExt(customer[0].toString()); + customerInfoGlobal.setCustomerInfoExt(customerInfoExt); + customerInfoExt.setName(customer[3].toString()); + + appView.getAppUserView().showTask("com.unicenta.pos.sales.JPanelTicketSales"); + } + + } else { + int i = m_bd.insertRecord(m_editorrecord.createValue()); + m_editorrecord.refresh(); + baseMoveTo(i); + } + + } else if (m_iState == ST_DELETE) { + int i = m_bd.removeRecord(m_iIndex); + m_editorrecord.refresh(); + baseMoveTo(i); + + if (isCustomerChangeEvent) { + triggerCustomerEvent("customer.deleted", customer, customer[27]); + } + } + } + } + + private void triggerCustomerEvent(String event, Object[] customer, Object appContext) { + try { + AppView appView = (AppView) appContext; + ScriptEngine scriptEngine = ScriptFactory.getScriptEngine(ScriptFactory.BEANSHELL); + + DataLogicSystem dlSystem = (DataLogicSystem) appView.getBean("com.unicenta.pos.forms.DataLogicSystem"); + String script = dlSystem.getResourceAsXML(event); + scriptEngine.put("customer", customer); + scriptEngine.put("device", appView.getProperties().getProperty("machine.hostname")); + scriptEngine.eval(script); + + } + catch (Exception e) { + System.err.println("Script Exception: "+e); + } + } + + /** + * Reinstantiate data + * @param c + */ + public void actionReloadCurrent(Component c) { + if (!m_Dirty.isDirty() || + JOptionPane.showConfirmDialog(c, + LocalRes.getIntString("message.changeslost"), + LocalRes.getIntString("title.editor"), + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { + refreshCurrent(); + } + } + + /** + * Evaluate data before before commit + * @param c + * @return + * @throws BasicException + */ + public boolean actionClosingForm(Component c) throws BasicException { + if (m_Dirty.isDirty()) { + int res = JOptionPane.showConfirmDialog(c, LocalRes.getIntString("message.wannasave"), LocalRes.getIntString("title.editor"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); + if (res == JOptionPane.YES_OPTION) { + saveData(); + return true; + } else if (res == JOptionPane.NO_OPTION) { + refreshCurrent(); + return true; + } else { + return false; + } + } else { + return true; + } + } + + /* + * Metodos publicos finales (algunos protegidos que podrian ser finales + */ + + /** + * Instantiate data + * @throws BasicException + */ + + public final void actionLoad() throws BasicException { + loadData(); + if (m_bd.getSize() == 0) { + actionInsert(); + } + } + + /** + * Insert data - conditional + * @throws BasicException + */ + public final void actionInsert() throws BasicException { + // primero persistimos + saveData(); + + if (canInsertData()) { + // Y nos ponemos en estado de insert + m_iState = ST_INSERT; + m_editorrecord.writeValueInsert(); + m_Dirty.setDirty(false); + fireStateUpdate(); // ? + } + } + + /** + * Delete data + * @throws BasicException + */ + public final void actionDelete() throws BasicException { + // primero persistimos + saveData(); + + if (canDeleteData()) { + + // Y nos ponemos en estado de delete + Object obj = getCurrentElement(); + int iIndex = getIndex(); + int iCount = m_bd.getSize(); + if (iIndex >= 0 && iIndex < iCount) { + m_iState = ST_DELETE; + m_editorrecord.writeValueDelete(obj); + m_Dirty.setDirty(true); + fireStateUpdate(); // ? + } + } + } + + private final void baseMoveTo(int i) { + // Este senor y el constructor a INX_EOF, son los unicos que tienen potestad de modificar m_iIndex. + if (i >= 0 && i < m_bd.getSize()) { + m_iIndex = i; + } else { + m_iIndex = INX_EOF; + } + fireDataBrowse(); + } +} diff --git a/src/main/java/com/unicenta/data/user/BrowseListener.java b/src/main/java/com/unicenta/data/user/BrowseListener.java new file mode 100644 index 0000000..877f8d1 --- /dev/null +++ b/src/main/java/com/unicenta/data/user/BrowseListener.java @@ -0,0 +1,34 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.user; + +/** + * + * @author JG uniCenta + */ +public interface BrowseListener extends java.util.EventListener { + + /** + * + * @param iIndex + * @param iCounter + */ + public void updateIndex(int iIndex, int iCounter); +} diff --git a/src/main/java/com/unicenta/data/user/DirtyListener.java b/src/main/java/com/unicenta/data/user/DirtyListener.java new file mode 100644 index 0000000..dd5ab4a --- /dev/null +++ b/src/main/java/com/unicenta/data/user/DirtyListener.java @@ -0,0 +1,33 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.user; + +/** + * + * @author adrian + */ +public interface DirtyListener { + + /** + * + * @param bDirty + */ + public void changedDirty(boolean bDirty); +} diff --git a/src/main/java/com/unicenta/data/user/DirtyManager.java b/src/main/java/com/unicenta/data/user/DirtyManager.java new file mode 100644 index 0000000..1f0cb8a --- /dev/null +++ b/src/main/java/com/unicenta/data/user/DirtyManager.java @@ -0,0 +1,123 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.user; + +import java.awt.event.*; +import javax.swing.event.*; +import java.util.*; +import java.beans.*; + +/** + * + * @author adrian + */ +public class DirtyManager implements DocumentListener, ChangeListener, ActionListener, PropertyChangeListener { + + private boolean m_bDirty; + + /** + * + */ + protected Vector listeners = new Vector(); + + /** Creates a new instance of DirtyManager */ + public DirtyManager() { + m_bDirty = false; + } + + /** + * + * @param l + */ + public void addDirtyListener(DirtyListener l) { + listeners.add(l); + } + + /** + * + * @param l + */ + public void removeDirtyListener(DirtyListener l) { + listeners.remove(l); + } + + /** + * + */ + protected void fireChangedDirty() { + + Enumeration e = listeners.elements(); + while (e.hasMoreElements()) { + DirtyListener l = (DirtyListener) e.nextElement(); + l.changedDirty(m_bDirty); + } + } + + /** + * + * @param bValue + */ + public void setDirty(boolean bValue) { + + if (m_bDirty != bValue) { + m_bDirty = bValue; + fireChangedDirty(); + } + } + + /** + * + * @return + */ + public boolean isDirty() { + return m_bDirty; + } + + @Override + public void changedUpdate(DocumentEvent e) { + setDirty(true); + } + @Override + public void insertUpdate(DocumentEvent e) { + setDirty(true); + } + @Override + public void removeUpdate(DocumentEvent e) { + setDirty(true); + } + + @Override + public void stateChanged(ChangeEvent e) { + setDirty(true); + } + + @Override + public void actionPerformed(ActionEvent e) { + setDirty(true); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + //if ("image".equals(evt.getPropertyName())) { + setDirty(true); + //} + } + +} diff --git a/src/main/java/com/unicenta/data/user/DocumentLoader.java b/src/main/java/com/unicenta/data/user/DocumentLoader.java new file mode 100644 index 0000000..d1d8969 --- /dev/null +++ b/src/main/java/com/unicenta/data/user/DocumentLoader.java @@ -0,0 +1,43 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.user; + +/** + * + * @author adrianromero + * Created on 22 de marzo de 2007, 0:00 + * + */ +public interface DocumentLoader { + + /** + * + * @param key + * @return + */ + public Object getValue(Object key); + + /** + * + * @param value + * @return + */ + public Object getKey(Object value); +} diff --git a/src/main/java/com/unicenta/data/user/DocumentLoaderBasic.java b/src/main/java/com/unicenta/data/user/DocumentLoaderBasic.java new file mode 100644 index 0000000..b0371b3 --- /dev/null +++ b/src/main/java/com/unicenta/data/user/DocumentLoaderBasic.java @@ -0,0 +1,56 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.user; + +/** + * + * @author adrianromero + * Created on 22 de marzo de 2007, 0:01 + * + */ +public class DocumentLoaderBasic implements DocumentLoader { + + /** + * + */ + public static final DocumentLoader INSTANCE = new DocumentLoaderBasic(); + + /** Creates a new instance of DocumentLoaderBasic */ + private DocumentLoaderBasic() { + } + + /** + * + * @param key + * @return + */ + public Object getValue(Object key) { + return key; + } + + /** + * + * @param value + * @return + */ + public Object getKey(Object value) { + return value; + } +} diff --git a/src/main/java/com/unicenta/data/user/EditorCreator.java b/src/main/java/com/unicenta/data/user/EditorCreator.java new file mode 100644 index 0000000..f88f5d2 --- /dev/null +++ b/src/main/java/com/unicenta/data/user/EditorCreator.java @@ -0,0 +1,36 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.user; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public interface EditorCreator { + + /** + * + * @return + * @throws BasicException + */ + public Object createValue() throws BasicException; +} diff --git a/src/main/java/com/unicenta/data/user/EditorCreatorComposed.java b/src/main/java/com/unicenta/data/user/EditorCreatorComposed.java new file mode 100644 index 0000000..6288fbc --- /dev/null +++ b/src/main/java/com/unicenta/data/user/EditorCreatorComposed.java @@ -0,0 +1,52 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.user; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public class EditorCreatorComposed implements EditorCreator{ + + private EditorCreator[] m_editors; + + /** Creates a new instance of EditorCreatorComposed + * @param editors */ + public EditorCreatorComposed(EditorCreator... editors) { + m_editors = editors; + } + + /** + * + * @return + * @throws BasicException + */ + public Object createValue() throws BasicException { + + Object[] value = new Object[m_editors.length]; + for (int i = 0; i < m_editors.length; i++) { + value[i] = m_editors[i].createValue(); + } + + return value; + } +} diff --git a/src/main/java/com/unicenta/data/user/EditorListener.java b/src/main/java/com/unicenta/data/user/EditorListener.java new file mode 100644 index 0000000..476bfda --- /dev/null +++ b/src/main/java/com/unicenta/data/user/EditorListener.java @@ -0,0 +1,33 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.user; + +/** + * + * @author JG uniCenta + */ +public interface EditorListener extends java.util.EventListener { + + /** + * + * @param value + */ + public void updateValue(Object value); +} diff --git a/src/main/java/com/unicenta/data/user/EditorRecord.java b/src/main/java/com/unicenta/data/user/EditorRecord.java new file mode 100644 index 0000000..357455a --- /dev/null +++ b/src/main/java/com/unicenta/data/user/EditorRecord.java @@ -0,0 +1,62 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.user; + +import java.awt.Component; + +/** + * + * @author JG uniCenta + */ +public interface EditorRecord extends EditorCreator { + + /** + * + */ + public void writeValueEOF(); + + /** + * + */ + public void writeValueInsert(); + + /** + * + * @param value + */ + public void writeValueEdit(Object value); // not null por definicion. + + /** + * + * @param value + */ + public void writeValueDelete(Object value); // not null por definicion. + + /** + * + */ + public void refresh(); + + /** + * + * @return + */ + public Component getComponent(); +} diff --git a/src/main/java/com/unicenta/data/user/FilterEditorCreator.java b/src/main/java/com/unicenta/data/user/FilterEditorCreator.java new file mode 100644 index 0000000..297576a --- /dev/null +++ b/src/main/java/com/unicenta/data/user/FilterEditorCreator.java @@ -0,0 +1,35 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.user; + +import com.unicenta.data.loader.SerializerWrite; + +/** + * + * @author adrian + */ +public interface FilterEditorCreator extends EditorCreator { + + /** + * + * @return + */ + public SerializerWrite getSerializerWrite(); +} diff --git a/src/main/java/com/unicenta/data/user/Finder.java b/src/main/java/com/unicenta/data/user/Finder.java new file mode 100644 index 0000000..db62ae4 --- /dev/null +++ b/src/main/java/com/unicenta/data/user/Finder.java @@ -0,0 +1,37 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.user; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public interface Finder { + + /** + * + * @param obj + * @return + * @throws BasicException + */ + public boolean match(Object obj) throws BasicException; +} diff --git a/src/main/java/com/unicenta/data/user/ListProvider.java b/src/main/java/com/unicenta/data/user/ListProvider.java new file mode 100644 index 0000000..5176a72 --- /dev/null +++ b/src/main/java/com/unicenta/data/user/ListProvider.java @@ -0,0 +1,44 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.user; + +import com.unicenta.basic.BasicException; +import java.util.List; + +/** + * + * @author JG uniCenta + */ +public interface ListProvider { + + /** + * + * @return + * @throws BasicException + */ + public List loadData() throws BasicException; + + /** + * + * @return + * @throws BasicException + */ + public List refreshData() throws BasicException; +} diff --git a/src/main/java/com/unicenta/data/user/ListProviderCreator.java b/src/main/java/com/unicenta/data/user/ListProviderCreator.java new file mode 100644 index 0000000..f2f6e5d --- /dev/null +++ b/src/main/java/com/unicenta/data/user/ListProviderCreator.java @@ -0,0 +1,82 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.user; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.loader.TableDefinition; +import java.util.*; + +/** + * + * @author JG uniCenta + */ +public class ListProviderCreator implements ListProvider { + + private SentenceList sent; + private EditorCreator prov; + private Object params; + + /** Creates a new instance of ListProviderEditor + * @param sent + * @param prov */ + public ListProviderCreator(SentenceList sent, EditorCreator prov) { + this.sent = sent; + this.prov = prov; + params = null; + } + + /** + * + * @param sent + */ + public ListProviderCreator(SentenceList sent) { + this(sent, null); + } + + /** + * + * @param table + */ + public ListProviderCreator(TableDefinition table) { + this(table.getListSentence(), null); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public List loadData() throws BasicException { + params = (prov == null) ? null : prov.createValue(); + return refreshData(); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public List refreshData() throws BasicException { + return sent.list(params); + } +} diff --git a/src/main/java/com/unicenta/data/user/SaveProvider.java b/src/main/java/com/unicenta/data/user/SaveProvider.java new file mode 100644 index 0000000..d40b3ed --- /dev/null +++ b/src/main/java/com/unicenta/data/user/SaveProvider.java @@ -0,0 +1,130 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.data.user; +import com.unicenta.data.loader.TableDefinition; +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.SentenceExec; + +/** + * + * @author JG uniCenta + */ +public class SaveProvider { + + /** + * + */ + protected SentenceExec m_sentupdate; + + /** + * + */ + protected SentenceExec m_sentinsert; + + /** + * + */ + protected SentenceExec m_sentdelete; + + /** Creates a new instance of SavePrSentence + * @param sentupdate + * @param sentdelete + * @param sentinsert */ + public SaveProvider(SentenceExec sentupdate, SentenceExec sentinsert, SentenceExec sentdelete) { + m_sentupdate = sentupdate; + m_sentinsert = sentinsert; + m_sentdelete = sentdelete; + } + + /** + * + * @param table + */ + public SaveProvider(TableDefinition table) { + m_sentupdate = table.getUpdateSentence(); + m_sentdelete = table.getDeleteSentence(); + m_sentinsert = table.getInsertSentence(); + } + + /** + * + * @param table + * @param fields + */ + public SaveProvider(TableDefinition table, int[] fields) { + m_sentupdate = table.getUpdateSentence(fields); + m_sentdelete = table.getDeleteSentence(); + m_sentinsert = table.getInsertSentence(fields); + } + + /** + * + * @return + */ + public boolean canDelete() { + return m_sentdelete != null; + } + + /** + * + * @param value + * @return + * @throws BasicException + */ + public int deleteData(Object value) throws BasicException { + return m_sentdelete.exec(value); + } + + /** + * + * @return + */ + public boolean canInsert() { + return m_sentinsert != null; + } + + /** + * + * @param value + * @return + * @throws BasicException + */ + public int insertData(Object value) throws BasicException { + return m_sentinsert.exec(value); + } + + /** + * + * @return + */ + public boolean canUpdate() { + return m_sentupdate != null; + } + + /** + * + * @param value + * @return + * @throws BasicException + */ + public int updateData(Object value) throws BasicException { + return m_sentupdate.exec(value); + } +} diff --git a/src/main/java/com/unicenta/data/user/StateListener.java b/src/main/java/com/unicenta/data/user/StateListener.java new file mode 100644 index 0000000..23177a3 --- /dev/null +++ b/src/main/java/com/unicenta/data/user/StateListener.java @@ -0,0 +1,34 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + + +package com.unicenta.data.user; + +/** + * + * @author adrian + */ +public interface StateListener extends java.util.EventListener { + + /** + * + * @param iState + */ + public void updateState(int iState); +} diff --git a/src/main/java/com/unicenta/editor/EditorComponent.java b/src/main/java/com/unicenta/editor/EditorComponent.java new file mode 100644 index 0000000..063b48d --- /dev/null +++ b/src/main/java/com/unicenta/editor/EditorComponent.java @@ -0,0 +1,58 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.editor; + +import java.awt.Component; + +/** + * + * @author JG uniCenta + */ +public interface EditorComponent { + + /** + * + * @param ed + */ + public void addEditorKeys(EditorKeys ed); + + /** + * + * @return + */ + public Component getComponent(); + + /** + * + */ + public void deactivate(); + + /** + * + * @param c + */ + public void typeChar(char c); + + /** + * + * @param c + */ + public void transChar(char c); +} diff --git a/src/main/java/com/unicenta/editor/EditorKeys.java b/src/main/java/com/unicenta/editor/EditorKeys.java new file mode 100644 index 0000000..ce616d2 --- /dev/null +++ b/src/main/java/com/unicenta/editor/EditorKeys.java @@ -0,0 +1,65 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.editor; + +/** + * + * @author JG uniCenta + */ +public interface EditorKeys { + + /** + * + */ + public final static int MODE_STRING = 0; + + /** + * + */ + public final static int MODE_DOUBLE = 1; + + /** + * + */ + public final static int MODE_DOUBLE_POSITIVE = 2; + + /** + * + */ + public final static int MODE_INTEGER = 3; + + /** + * + */ + public final static int MODE_INTEGER_POSITIVE = 4; + + /** + * + * @param e + * @param imode + */ + public void setActive(EditorComponent e, int imode); + + /** + * + * @param e + */ + public void setInactive(EditorComponent e); +} diff --git a/src/main/java/com/unicenta/editor/JEditorAbstract.form b/src/main/java/com/unicenta/editor/JEditorAbstract.form new file mode 100644 index 0000000..77c0558 --- /dev/null +++ b/src/main/java/com/unicenta/editor/JEditorAbstract.form @@ -0,0 +1,81 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/editor/JEditorAbstract.java b/src/main/java/com/unicenta/editor/JEditorAbstract.java new file mode 100644 index 0000000..584b4ef --- /dev/null +++ b/src/main/java/com/unicenta/editor/JEditorAbstract.java @@ -0,0 +1,245 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.editor; + +import com.unicenta.basic.BasicException; +import java.awt.Color; +import java.awt.Component; +import javax.swing.border.Border; + +/** + * + * @author JG uniCenta + */ +public abstract class JEditorAbstract extends javax.swing.JPanel implements EditorComponent { + + private EditorKeys editorkeys; + + private boolean m_bActive; + private final Border m_borderactive = new javax.swing.border.CompoundBorder(new javax.swing.border.LineBorder(javax.swing.UIManager.getDefaults().getColor("TextField.selectionBackground")), new javax.swing.border.EmptyBorder(new java.awt.Insets(1, 4, 1, 4))); + private final Border m_borderinactive = new javax.swing.border.CompoundBorder(new javax.swing.border.LineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), new javax.swing.border.EmptyBorder(new java.awt.Insets(1, 4, 1, 4))); + + /** Creates new form JPanelNumber */ + public JEditorAbstract() { + + initComponents(); + + editorkeys = null; + m_bActive = false; + m_jText.setBorder(m_borderinactive); + } + + /** + * + * @return + */ + protected abstract int getMode(); + + /** + * + * @return + */ + protected abstract int getAlignment(); + + /** + * + * @return + */ + protected abstract String getEditMode(); + + /** + * + * @return + */ + protected abstract String getTextEdit(); + + /** + * + * @return + * @throws BasicException + */ + protected abstract String getTextFormat() throws BasicException; + + /** + * + * @param c + */ + protected abstract void typeCharInternal(char c); + + /** + * + * @param c + */ + protected abstract void transCharInternal(char c); + + /** + * + * @param c + */ + @Override + public void typeChar(char c) { + typeCharInternal(c); + reprintText(); + firePropertyChange("Edition", null, null); + } + + /** + * + * @param c + */ + @Override + public void transChar(char c) { + transCharInternal(c); + reprintText(); + firePropertyChange("Edition", null, null); + } + + /** + * + * @param ed + */ + @Override + public void addEditorKeys(EditorKeys ed) { + editorkeys = ed; + } + + /** + * + */ + @Override + public void deactivate() { + setActive(false); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + */ + public void activate() { + if (isEnabled()) { + editorkeys.setActive(this, getMode()); + setActive(true); + } + } + + private void setActive(boolean bValue) { + m_bActive = bValue; + m_jText.setBorder(m_bActive ? m_borderactive : m_borderinactive); + reprintText(); + } + + /** + * + */ + protected void reprintText() { + + m_jText.setHorizontalAlignment(getAlignment()); + if (m_bActive) { + m_jMode.setText(getEditMode()); + m_jText.setText(getTextEdit()); + m_jText.setForeground(javax.swing.UIManager.getDefaults().getColor("label.foreground")); + } else { + m_jMode.setText(null); + try { + m_jText.setText(getTextFormat()); + m_jText.setForeground(javax.swing.UIManager.getDefaults().getColor("label.foreground")); + } catch (BasicException e) { + m_jText.setText(getTextEdit()); + m_jText.setForeground(Color.RED); + } + } + } + + @Override + public void setEnabled(boolean b) { + + if (editorkeys != null) { + editorkeys.setInactive(this); + } + panBackground.setBackground(b + ? javax.swing.UIManager.getDefaults().getColor("TextField.background") + : javax.swing.UIManager.getDefaults().getColor("TextField.disabledBackground")); + super.setEnabled(b); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + panBackground = new javax.swing.JPanel(); + m_jText = new javax.swing.JButton(); + m_jMode = new javax.swing.JLabel(); + + setLayout(new java.awt.BorderLayout()); + + panBackground.setBackground(javax.swing.UIManager.getDefaults().getColor("TextField.background")); + panBackground.setLayout(new java.awt.BorderLayout()); + + m_jText.setBackground(javax.swing.UIManager.getDefaults().getColor("TextField.background")); + m_jText.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jText.setContentAreaFilled(false); + m_jText.setFocusPainted(false); + m_jText.setFocusable(false); + m_jText.setMinimumSize(new java.awt.Dimension(100, 25)); + m_jText.setPreferredSize(new java.awt.Dimension(100, 25)); + m_jText.setRequestFocusEnabled(false); + m_jText.setVerticalAlignment(javax.swing.SwingConstants.TOP); + m_jText.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jTextActionPerformed(evt); + } + }); + panBackground.add(m_jText, java.awt.BorderLayout.CENTER); + + add(panBackground, java.awt.BorderLayout.CENTER); + + m_jMode.setFont(new java.awt.Font("Dialog", 0, 9)); // NOI18N + m_jMode.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + m_jMode.setVerticalAlignment(javax.swing.SwingConstants.TOP); + m_jMode.setPreferredSize(new java.awt.Dimension(32, 0)); + add(m_jMode, java.awt.BorderLayout.LINE_END); + }// //GEN-END:initComponents + + private void m_jTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jTextActionPerformed + + activate(); + + }//GEN-LAST:event_m_jTextActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel m_jMode; + private javax.swing.JButton m_jText; + private javax.swing.JPanel panBackground; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/editor/JEditorCurrency.java b/src/main/java/com/unicenta/editor/JEditorCurrency.java new file mode 100644 index 0000000..f6d30aa --- /dev/null +++ b/src/main/java/com/unicenta/editor/JEditorCurrency.java @@ -0,0 +1,51 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.editor; + +import com.unicenta.format.Formats; + +/** + * + * @author JG uniCenta + */ +public class JEditorCurrency extends JEditorNumber { + + private static final long serialVersionUID = 5096754100573262803L; + + /** Creates a new instance of JEditorCurrency */ + public JEditorCurrency() { + } + + /** + * + * @return + */ + protected Formats getFormat() { + return Formats.CURRENCY; + } + + /** + * + * @return + */ + protected int getMode() { + return EditorKeys.MODE_DOUBLE; + } +} diff --git a/src/main/java/com/unicenta/editor/JEditorCurrencyPositive.java b/src/main/java/com/unicenta/editor/JEditorCurrencyPositive.java new file mode 100644 index 0000000..7374490 --- /dev/null +++ b/src/main/java/com/unicenta/editor/JEditorCurrencyPositive.java @@ -0,0 +1,52 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.editor; + +import com.unicenta.format.Formats; + +/** + * + * @author JG uniCenta + */ +public class JEditorCurrencyPositive extends JEditorNumber { + + /** Creates a new instance of JEditorCurrencyPositive */ + public JEditorCurrencyPositive() { + } + + /** + * + * @return + */ + @Override + protected Formats getFormat() { + return Formats.CURRENCY; + + } + + /** + * + * @return + */ + @Override + protected int getMode() { + return EditorKeys.MODE_DOUBLE_POSITIVE; + } +} diff --git a/src/main/java/com/unicenta/editor/JEditorDouble.java b/src/main/java/com/unicenta/editor/JEditorDouble.java new file mode 100644 index 0000000..2322072 --- /dev/null +++ b/src/main/java/com/unicenta/editor/JEditorDouble.java @@ -0,0 +1,49 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.editor; + +import com.unicenta.format.Formats; + +/** + * + * @author JG uniCenta + */ +public class JEditorDouble extends JEditorNumber { + + /** Creates a new instance of JEditorDouble */ + public JEditorDouble() { + } + + /** + * + * @return + */ + protected Formats getFormat() { + return Formats.DOUBLE; + } + + /** + * + * @return + */ + protected int getMode() { + return EditorKeys.MODE_DOUBLE; + } +} diff --git a/src/main/java/com/unicenta/editor/JEditorDoublePositive.java b/src/main/java/com/unicenta/editor/JEditorDoublePositive.java new file mode 100644 index 0000000..48ad4b9 --- /dev/null +++ b/src/main/java/com/unicenta/editor/JEditorDoublePositive.java @@ -0,0 +1,49 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.editor; + +import com.unicenta.format.Formats; + +/** + * + * @author JG uniCenta + */ +public class JEditorDoublePositive extends JEditorNumber { + + /** Creates a new instance of JEditorDoublePositive */ + public JEditorDoublePositive() { + } + + /** + * + * @return + */ + protected Formats getFormat() { + return Formats.DOUBLE; + } + + /** + * + * @return + */ + protected int getMode() { + return EditorKeys.MODE_DOUBLE_POSITIVE; + } +} diff --git a/src/main/java/com/unicenta/editor/JEditorIntegerPositive.java b/src/main/java/com/unicenta/editor/JEditorIntegerPositive.java new file mode 100644 index 0000000..f67358d --- /dev/null +++ b/src/main/java/com/unicenta/editor/JEditorIntegerPositive.java @@ -0,0 +1,49 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.editor; + +import com.unicenta.format.Formats; + +/** + * + * @author JG uniCenta + */ +public class JEditorIntegerPositive extends JEditorNumber { + + /** Creates a new instance of JEditorIntegerPositive */ + public JEditorIntegerPositive() { + } + + /** + * + * @return + */ + protected Formats getFormat() { + return Formats.INT; + } + + /** + * + * @return + */ + protected int getMode() { + return EditorKeys.MODE_INTEGER_POSITIVE; + } +} diff --git a/src/main/java/com/unicenta/editor/JEditorKeys.form b/src/main/java/com/unicenta/editor/JEditorKeys.form new file mode 100644 index 0000000..758cdb5 --- /dev/null +++ b/src/main/java/com/unicenta/editor/JEditorKeys.form @@ -0,0 +1,279 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/editor/JEditorKeys.java b/src/main/java/com/unicenta/editor/JEditorKeys.java new file mode 100644 index 0000000..1710839 --- /dev/null +++ b/src/main/java/com/unicenta/editor/JEditorKeys.java @@ -0,0 +1,516 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.editor; + +import com.unicenta.pos.customers.JCustomerFinder; +import java.awt.ComponentOrientation; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.util.EventListener; +import javax.swing.event.EventListenerList; + +/** + * + * @author JG uniCenta + */ +public class JEditorKeys extends javax.swing.JPanel implements EditorKeys { + + private final static char[] SET_DOUBLE = {'\u007f', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '-'}; + private final static char[] SET_DOUBLE_POSITIVE = {'\u007f', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.'}; + private final static char[] SET_INTEGER = {'\u007f', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-'}; + private final static char[] SET_INTEGER_POSITIVE = {'\u007f', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; + + /** + * + */ + protected EventListenerList listeners = new EventListenerList(); + + private EditorComponent editorcurrent ; + + private char[] keysavailable; + private boolean m_bMinus; + private boolean m_bKeyDot; + private JCustomerFinder customerFinder; + + /* + HS KeyShortcuts + */ + + /** + * + * @return + */ + + public JCustomerFinder getCustomerFinder() { + return customerFinder; + } + + /** + * + * @param customerFinder + */ + public void setCustomerFinder(JCustomerFinder customerFinder) { + this.customerFinder = customerFinder; + } + + + /** Creates new form JEditorKeys */ + public JEditorKeys() { + initComponents(); + + m_jKey0.addActionListener(new MyKeyNumberListener('0')); + m_jKey1.addActionListener(new MyKeyNumberListener('1')); + m_jKey2.addActionListener(new MyKeyNumberListener('2')); + m_jKey3.addActionListener(new MyKeyNumberListener('3')); + m_jKey4.addActionListener(new MyKeyNumberListener('4')); + m_jKey5.addActionListener(new MyKeyNumberListener('5')); + m_jKey6.addActionListener(new MyKeyNumberListener('6')); + m_jKey7.addActionListener(new MyKeyNumberListener('7')); + m_jKey8.addActionListener(new MyKeyNumberListener('8')); + m_jKey9.addActionListener(new MyKeyNumberListener('9')); + m_jKeyDot.addActionListener(new MyKeyNumberListener('.')); + m_jCE.addActionListener(new MyKeyNumberListener('\u007f')); + m_jMinus.addActionListener(new MyKeyNumberListener('-')); + + editorcurrent = null; + setMode(MODE_STRING); + doEnabled(false); + } + + @Override + public void setComponentOrientation(ComponentOrientation o) { + // Nothing to change + } + + /** + * + * @param l + */ + public void addActionListener(ActionListener l) { + listeners.add(ActionListener.class, l); + } + + /** + * + * @param l + */ + public void removeActionListener(ActionListener l) { + listeners.remove(ActionListener.class, l); + } + + /** + * + */ + protected void fireActionPerformed() { + EventListener[] l = listeners.getListeners(ActionListener.class); + ActionEvent e = null; + for (int i = 0; i < l.length; i++) { + if (e == null) { + e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, null); + } + ((ActionListener) l[i]).actionPerformed(e); + } + } + + private void doEnabled(boolean b) { + m_jKey0.setEnabled(b); + m_jKey1.setEnabled(b); + m_jKey2.setEnabled(b); + m_jKey3.setEnabled(b); + m_jKey4.setEnabled(b); + m_jKey5.setEnabled(b); + m_jKey6.setEnabled(b); + m_jKey7.setEnabled(b); + m_jKey8.setEnabled(b); + m_jKey9.setEnabled(b); + m_jKeyDot.setEnabled(b && m_bKeyDot); + m_jCE.setEnabled(b); + m_jMinus.setEnabled(b && m_bMinus); + } + + /** + * + * @param iMode + */ + public void setMode(int iMode) { + switch (iMode) { + case MODE_DOUBLE: + m_bMinus = true; + m_bKeyDot = true; + keysavailable = SET_DOUBLE; + break; + case MODE_DOUBLE_POSITIVE: + m_bMinus = false; + m_bKeyDot = true; + keysavailable = SET_DOUBLE_POSITIVE; + break; + case MODE_INTEGER: + m_bMinus = true; + m_bKeyDot = false; + keysavailable = SET_INTEGER; + break; + case MODE_INTEGER_POSITIVE: + m_bMinus = false; + m_bKeyDot = false; + keysavailable = SET_INTEGER_POSITIVE; + break; + case MODE_STRING: + default: + m_bMinus = true; + m_bKeyDot = true; + keysavailable = null; + break; + } + } + + private class MyKeyNumberListener implements java.awt.event.ActionListener { + + private char m_cCad; + + public MyKeyNumberListener(char cCad){ + m_cCad = cCad; + } + public void actionPerformed(java.awt.event.ActionEvent evt) { + + // como contenedor de editores + if (editorcurrent != null) { + editorcurrent.transChar(m_cCad); + } + } + } + + /** + * + * @param e + * @param iMode + */ + public void setActive(EditorComponent e, int iMode) { + + if (editorcurrent != null) { + editorcurrent.deactivate(); + } + editorcurrent = e; // e != null + setMode(iMode); + doEnabled(true); + + // keyboard listener activation + m_txtKeys.setText(null); + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + m_txtKeys.requestFocus(); + } + }); + } + + /** + * + * @param e + */ + public void setInactive(EditorComponent e) { + + if (e == editorcurrent && editorcurrent != null) { // e != null + editorcurrent.deactivate(); + editorcurrent = null; + setMode(MODE_STRING); + doEnabled(false); + } + } + + /** + * + * @param enabled + */ + public void dotIs00(boolean enabled) { + if (enabled) { + m_jKeyDot.setIcon(new javax.swing.ImageIcon(getClass() + .getResource("/com/unicenta/images/btn00.png"))); + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + m_jCE = new javax.swing.JButton(); + m_jMinus = new javax.swing.JButton(); + m_jKey1 = new javax.swing.JButton(); + m_jKey2 = new javax.swing.JButton(); + m_jKey3 = new javax.swing.JButton(); + m_jKey4 = new javax.swing.JButton(); + m_jKey5 = new javax.swing.JButton(); + m_jKey6 = new javax.swing.JButton(); + m_jKey7 = new javax.swing.JButton(); + m_jKey8 = new javax.swing.JButton(); + m_jKey9 = new javax.swing.JButton(); + m_jKey0 = new javax.swing.JButton(); + m_jKeyDot = new javax.swing.JButton(); + m_txtKeys = new javax.swing.JTextField(); + + setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + setPreferredSize(new java.awt.Dimension(300, 300)); + setLayout(new java.awt.GridBagLayout()); + + m_jCE.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btnce.png"))); // NOI18N + m_jCE.setFocusPainted(false); + m_jCE.setFocusable(false); + m_jCE.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jCE.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0); + add(m_jCE, gridBagConstraints); + + m_jMinus.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btnminus.png"))); // NOI18N + m_jMinus.setFocusPainted(false); + m_jMinus.setFocusable(false); + m_jMinus.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jMinus.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0); + add(m_jMinus, gridBagConstraints); + + m_jKey1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn1.png"))); // NOI18N + m_jKey1.setFocusPainted(false); + m_jKey1.setFocusable(false); + m_jKey1.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKey1.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(m_jKey1, gridBagConstraints); + + m_jKey2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn2a.png"))); // NOI18N + m_jKey2.setFocusPainted(false); + m_jKey2.setFocusable(false); + m_jKey2.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKey2.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(m_jKey2, gridBagConstraints); + + m_jKey3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn3a.png"))); // NOI18N + m_jKey3.setFocusPainted(false); + m_jKey3.setFocusable(false); + m_jKey3.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKey3.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(m_jKey3, gridBagConstraints); + + m_jKey4.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn4a.png"))); // NOI18N + m_jKey4.setFocusPainted(false); + m_jKey4.setFocusable(false); + m_jKey4.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKey4.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(m_jKey4, gridBagConstraints); + + m_jKey5.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn5a.png"))); // NOI18N + m_jKey5.setFocusPainted(false); + m_jKey5.setFocusable(false); + m_jKey5.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKey5.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(m_jKey5, gridBagConstraints); + + m_jKey6.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn6a.png"))); // NOI18N + m_jKey6.setFocusPainted(false); + m_jKey6.setFocusable(false); + m_jKey6.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKey6.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(m_jKey6, gridBagConstraints); + + m_jKey7.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn7a.png"))); // NOI18N + m_jKey7.setFocusPainted(false); + m_jKey7.setFocusable(false); + m_jKey7.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKey7.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(m_jKey7, gridBagConstraints); + + m_jKey8.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn8a.png"))); // NOI18N + m_jKey8.setFocusPainted(false); + m_jKey8.setFocusable(false); + m_jKey8.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKey8.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(m_jKey8, gridBagConstraints); + + m_jKey9.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn9a.png"))); // NOI18N + m_jKey9.setFocusPainted(false); + m_jKey9.setFocusable(false); + m_jKey9.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKey9.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(m_jKey9, gridBagConstraints); + + m_jKey0.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn0.png"))); // NOI18N + m_jKey0.setFocusPainted(false); + m_jKey0.setFocusable(false); + m_jKey0.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKey0.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 4; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(5, 0, 0, 0); + add(m_jKey0, gridBagConstraints); + + m_jKeyDot.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btndot.png"))); // NOI18N + m_jKeyDot.setFocusPainted(false); + m_jKeyDot.setFocusable(false); + m_jKeyDot.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jKeyDot.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(5, 0, 0, 0); + add(m_jKeyDot, gridBagConstraints); + + m_txtKeys.setPreferredSize(new java.awt.Dimension(0, 0)); + m_txtKeys.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusLost(java.awt.event.FocusEvent evt) { + m_txtKeysFocusLost(evt); + } + }); + m_txtKeys.addKeyListener(new java.awt.event.KeyAdapter() { + public void keyTyped(java.awt.event.KeyEvent evt) { + m_txtKeysKeyTyped(evt); + } + }); + add(m_txtKeys, new java.awt.GridBagConstraints()); + }// //GEN-END:initComponents + + private void m_txtKeysKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_m_txtKeysKeyTyped + + // como contenedor de editores solo + if (editorcurrent != null) { + m_txtKeys.setText("0"); + + // solo lo lanzamos si esta dentro del set de teclas + char c = evt.getKeyChar(); + if (c == '\n') { + fireActionPerformed(); + } else { + if (keysavailable == null) { + // todo disponible + editorcurrent.typeChar(c); + } else { + for (int i = 0; i < keysavailable.length; i++) { + if (c == keysavailable[i]) { + // todo disponible + editorcurrent.typeChar(c); + } + } + } + } + } + + }//GEN-LAST:event_m_txtKeysKeyTyped + + private void m_txtKeysFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_m_txtKeysFocusLost + + setInactive(editorcurrent); + + }//GEN-LAST:event_m_txtKeysFocusLost + + + // Variables declaration - do not modify//GEN-BEGIN:variables + javax.swing.JButton m_jCE; + javax.swing.JButton m_jKey0; + javax.swing.JButton m_jKey1; + javax.swing.JButton m_jKey2; + javax.swing.JButton m_jKey3; + javax.swing.JButton m_jKey4; + javax.swing.JButton m_jKey5; + javax.swing.JButton m_jKey6; + javax.swing.JButton m_jKey7; + javax.swing.JButton m_jKey8; + javax.swing.JButton m_jKey9; + javax.swing.JButton m_jKeyDot; + javax.swing.JButton m_jMinus; + javax.swing.JTextField m_txtKeys; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/editor/JEditorNumber.java b/src/main/java/com/unicenta/editor/JEditorNumber.java new file mode 100644 index 0000000..41743ab --- /dev/null +++ b/src/main/java/com/unicenta/editor/JEditorNumber.java @@ -0,0 +1,286 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.editor; + +import com.unicenta.basic.BasicException; +import com.unicenta.format.DoubleUtils; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import java.awt.Toolkit; +import java.io.File; + +/** + * + * @author JG uniCenta + */ +public abstract class JEditorNumber extends JEditorAbstract { + + // Variable numerica + private final static int NUMBER_ZERONULL = 0; + private final static int NUMBER_INT = 1; + private final static int NUMBER_DEC = 2; + + private char DEC_SEP = '.'; + private int m_iNumberStatus; + private String m_sNumber; + private boolean m_bNegative; + + private Formats m_fmt; + + private Boolean priceWith00; + + /** Creates a new instance of JEditorNumber */ + public JEditorNumber() { + m_fmt = getFormat(); + +// added JDL 11.05.13 + AppConfig m_config = new AppConfig(new File((System.getProperty("user.home")), AppLocal.APP_ID + ".properties")); + m_config.load(); + priceWith00 =("true".equals(m_config.getProperty("till.pricewith00"))); + m_config=null; + reset(); + } + + /** + * + * @return + */ + protected abstract Formats getFormat(); + + /** + * + */ + public void reset() { + + String sOldText = getText(); + + m_sNumber = ""; + m_bNegative = false; + m_iNumberStatus = NUMBER_ZERONULL; + + reprintText(); + + firePropertyChange("Text", sOldText, getText()); + } + + /** + * + * @param dvalue + */ + public void setDoubleValue(Double dvalue) { + + String sOldText = getText(); + + if (dvalue == null) { + m_sNumber = ""; + m_bNegative = false; + m_iNumberStatus = NUMBER_ZERONULL; + } else if (dvalue >= 0.0) { + m_sNumber = formatDouble(dvalue); + m_bNegative = false; + m_iNumberStatus = NUMBER_ZERONULL; + } else { + m_sNumber = formatDouble(-dvalue); + m_bNegative = true; + m_iNumberStatus = NUMBER_ZERONULL; + } + reprintText(); + + firePropertyChange("Text", sOldText, getText()); + } + + /** + * + * @return + */ + public Double getDoubleValue() { + String text = getText(); + if (text == null || text.equals("")) { + return null; + } else { + try { + //return priceWith00? Double.parseDouble(text)/100 : Double.parseDouble(text); + return Double.parseDouble(text); + // return Double.parseDouble(text); + } catch (NumberFormatException e) { + return null; + } + } + } + + /** + * + * @param ivalue + */ + public void setValueInteger(int ivalue) { + + String sOldText = getText(); + + if (ivalue >= 0) { + m_sNumber = Integer.toString(ivalue); + m_bNegative = false; + m_iNumberStatus = NUMBER_ZERONULL; + } else { + m_sNumber = Integer.toString(-ivalue); + m_bNegative = true; + m_iNumberStatus = NUMBER_ZERONULL; + } + reprintText(); + + firePropertyChange("Text", sOldText, getText()); + } + + /** + * + * @return + * @throws BasicException + */ + public int getValueInteger() throws BasicException { + try { + return Integer.parseInt(getText()); + } catch (NumberFormatException e) { + throw new BasicException(e); + } + } + + private String formatDouble(Double value) { + String sNumber = Double.toString(DoubleUtils.fixDecimals(value)); + if (sNumber.endsWith(".0")) { + sNumber = sNumber.substring(0, sNumber.length() - 2); + } + return sNumber; + } + + /** + * + * @return + */ + @Override + protected String getEditMode() { + return "-1.23"; + } + + /** + * + * @return + */ + public String getText() { + return (m_bNegative ? "-" : "") + m_sNumber; + } + + /** + * + * @return + */ + @Override + protected int getAlignment() { + return javax.swing.SwingConstants.RIGHT; + } + + /** + * + * @return + */ + @Override + protected String getTextEdit() { + return getText(); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + protected String getTextFormat() throws BasicException { + return m_fmt.formatValue(getDoubleValue()); + } + + /** + * + * @param cTrans + */ + @Override + protected void typeCharInternal(char cTrans) { + transChar(cTrans); + } + + /** + * + * @param cTrans + */ + @Override + protected void transCharInternal(char cTrans) { + + String sOldText = getText(); + + if (cTrans == '\u007f') { + reset(); + } else if (cTrans == '-') { + m_bNegative = !m_bNegative; + } else if ((cTrans == '0') + && (m_iNumberStatus == NUMBER_ZERONULL)) { + // m_iNumberStatus = NUMBER_ZERO; + m_sNumber = "0"; + } else if ((cTrans == '1' || cTrans == '2' || cTrans == '3' || cTrans == '4' || cTrans == '5' || cTrans == '6' || cTrans == '7' || cTrans == '8' || cTrans == '9') + && (m_iNumberStatus == NUMBER_ZERONULL)) { + m_iNumberStatus = NUMBER_INT; + m_sNumber = Character.toString(cTrans); +// } else if (cTrans == DEC_SEP && m_iNumberStatus == NUMBER_ZERONULL && !priceWith00) { + } else if (cTrans == DEC_SEP && m_iNumberStatus == NUMBER_ZERONULL) { + m_iNumberStatus = NUMBER_DEC; + m_sNumber = "0"+DEC_SEP; + } else if (cTrans == DEC_SEP && m_iNumberStatus == NUMBER_ZERONULL) { + m_iNumberStatus = NUMBER_INT; + m_sNumber = "0"; + + } else if ((cTrans == '0' || cTrans == '1' || cTrans == '2' || cTrans == '3' || cTrans == '4' || cTrans == '5' || cTrans == '6' || cTrans == '7' || cTrans == '8' || cTrans == '9') + && (m_iNumberStatus == NUMBER_INT)) { + //m_iNumberStatus = NUMBER_INT; + m_sNumber += cTrans; +// } else if (cTrans == DEC_SEP && m_iNumberStatus == NUMBER_INT && !priceWith00) { + } else if (cTrans == DEC_SEP && m_iNumberStatus == NUMBER_INT) { + m_iNumberStatus = NUMBER_DEC; + m_sNumber += DEC_SEP; + } else if (cTrans == DEC_SEP && m_iNumberStatus == NUMBER_INT) { +// m_iNumberStatus = NUMBER_DEC; + m_sNumber += "00"; + + } else if ((cTrans == '0' || cTrans == '1' || cTrans == '2' || cTrans == '3' || cTrans == '4' || cTrans == '5' || cTrans == '6' || cTrans == '7' || cTrans == '8' || cTrans == '9') + && (m_iNumberStatus == NUMBER_DEC)) { + m_sNumber += cTrans; + + } else { + Toolkit.getDefaultToolkit().beep(); + } + + firePropertyChange("Text", sOldText, getText()); + } + + + /* Added JDL 13.04.13 routine + * routine to set the amount appearance to show '.' + */ + private String setTempjPrice(String jPrice){ + jPrice = jPrice.replace(".",""); + return (jPrice.length()<= 2)? jPrice : (new StringBuffer(jPrice).insert(jPrice.length()-2,".").toString()); + } +} diff --git a/src/main/java/com/unicenta/editor/JEditorPassword.java b/src/main/java/com/unicenta/editor/JEditorPassword.java new file mode 100644 index 0000000..cc335eb --- /dev/null +++ b/src/main/java/com/unicenta/editor/JEditorPassword.java @@ -0,0 +1,104 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.editor; + +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public class JEditorPassword extends JEditorText { + + private static final char ECHO_CHAR = '*'; + + /** Creates a new instance of JEditorPassword */ + public JEditorPassword() { + super(); + } + + /** + * + * @return + */ + protected final int getMode() { + return EditorKeys.MODE_STRING; + } + + /** + * + * @return + */ + protected int getStartMode() { + return MODE_Abc1; + } + + /** + * + * @return + */ + protected String getTextEdit() { + + StringBuilder s = new StringBuilder(); + s.append(""); + s.append(getEcho(m_svalue)); + if (m_cLastChar != '\u0000') { + s.append(""); + s.append(ECHO_CHAR); + s.append(""); + } + s.append("_"); + + return s.toString(); + } + + /** + * + * @return + */ + public final String getPassword() { + + // como clave nunca devolvemos null + String sPassword = getText(); + return sPassword == null ? "" : sPassword; + } + + /** + * + * @return + * @throws BasicException + */ + protected String getTextFormat() throws BasicException { + return "" + getEcho(m_svalue); + } + + private String getEcho(String sValue) { + + if (sValue == null) { + return ""; + } else { + char[] c = new char[sValue.length()]; + for(int i = 0; i < sValue.length(); i++) { + c[i] = ECHO_CHAR; + } + return new String(c); + } + } +} diff --git a/src/main/java/com/unicenta/editor/JEditorString.java b/src/main/java/com/unicenta/editor/JEditorString.java new file mode 100644 index 0000000..a6f1351 --- /dev/null +++ b/src/main/java/com/unicenta/editor/JEditorString.java @@ -0,0 +1,52 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.editor; + +/** + * + * @author JG uniCenta + */ +public class JEditorString extends JEditorText { + + /** Creates a new instance of JEditorString */ + public JEditorString() { + super(); + } + + /** + * + * @return + */ + @Override + protected final int getMode() { + return EditorKeys.MODE_STRING; + } + + /** + * + * @return + */ + @Override + protected int getStartMode() { + return MODE_Abc1; + } + +} + diff --git a/src/main/java/com/unicenta/editor/JEditorStringNumber.java b/src/main/java/com/unicenta/editor/JEditorStringNumber.java new file mode 100644 index 0000000..2c36ce1 --- /dev/null +++ b/src/main/java/com/unicenta/editor/JEditorStringNumber.java @@ -0,0 +1,48 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.editor; + +/** + * + * @author adrian + */ +public class JEditorStringNumber extends JEditorText { + + /** Creates a new instance of JEditorStringNumber */ + public JEditorStringNumber() { + super(); + } + + /** + * + * @return + */ + protected int getMode() { + return EditorKeys.MODE_INTEGER_POSITIVE; + } + + /** + * + * @return + */ + protected int getStartMode() { + return MODE_123; + } +} diff --git a/src/main/java/com/unicenta/editor/JEditorText.java b/src/main/java/com/unicenta/editor/JEditorText.java new file mode 100644 index 0000000..bd811bd --- /dev/null +++ b/src/main/java/com/unicenta/editor/JEditorText.java @@ -0,0 +1,407 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.editor; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.Timer; +import com.unicenta.basic.BasicException; + +/** + * + * @author JG uniCenta + */ +public abstract class JEditorText extends JEditorAbstract { + + /** + * + */ + protected String m_svalue; + + /** + * + */ + public static final int MODE_Abc1 = 0; + + /** + * + */ + public static final int MODE_abc1 = 1; + + /** + * + */ + public static final int MODE_ABC1 = 2; + + /** + * + */ + public static final int MODE_123 = 3; + + /** + * + */ + public int m_iMode; + + /** + * + */ + protected int m_iTicks; + + /** + * + */ + protected char m_cLastChar; + + /** + * + */ + protected long m_lcount; + + private Timer m_jtimer; + + private static final char[] CHAR_abc1_1 = {'.', '?', '!', ',', '1', ';', ':'}; + private static final char[] CHAR_abc1_2 = {'a', 'b', 'c', '2', '\u00a0'}; + private static final char[] CHAR_abc1_3 = {'d', 'e', 'f', '3', '\u201a'}; + private static final char[] CHAR_abc1_4 = {'g', 'h', 'i', '4', '\u00a1'}; + private static final char[] CHAR_abc1_5 = {'j', 'k', 'l', '5'}; + private static final char[] CHAR_abc1_6 = {'m', 'n', 'o', '6', '\u00a4', '\u00a2'}; + private static final char[] CHAR_abc1_7 = {'p', 'q', 'r', 's', '7'}; + private static final char[] CHAR_abc1_8 = {'t', 'u', 'v', '8', '\u00a3', '\ufffd'}; + private static final char[] CHAR_abc1_9 = {'w', 'x', 'y', 'z', '9'}; + private static final char[] CHAR_abc1_0 = {' ', '0'}; + + private static final char[] CHAR_ABC1_1 = {'.', '?', '!', ',', '1', ';', ':'}; + private static final char[] CHAR_ABC1_2 = {'A', 'B', 'C', '2', '\u00b5'}; + private static final char[] CHAR_ABC1_3 = {'D', 'E', 'F', '3', '\u00c9'}; + private static final char[] CHAR_ABC1_4 = {'G', 'H', 'I', '4', '\u00cd'}; + private static final char[] CHAR_ABC1_5 = {'J', 'K', 'L', '5'}; + private static final char[] CHAR_ABC1_6 = {'M', 'N', 'O', '6', '\u00d1', '\u00d3'}; + private static final char[] CHAR_ABC1_7 = {'P', 'Q', 'R', 'S', '7'}; + private static final char[] CHAR_ABC1_8 = {'T', 'U', 'V', '8', '\u00da', '\u00dc'}; + private static final char[] CHAR_ABC1_9 = {'W', 'X', 'Y', 'Z', '9'}; + private static final char[] CHAR_ABC1_0 = {' ', '0'}; + + /** Creates a new instance of JEditorString */ + public JEditorText() { + m_svalue = null; + + m_iTicks = 0; + m_cLastChar = '\u0000'; + m_jtimer = new javax.swing.Timer(1000, new TimerAction()); + m_lcount = 0L; + m_iMode = getStartMode(); //MODE_Abc1; + m_jtimer.start(); + } + + /** + * + * @return + */ + protected abstract int getStartMode(); + + /** + * + */ + public final void reset() { + + String sOldText = getText(); + + // Los hemos borrado todos. + m_iMode = getStartMode(); //MODE_Abc1; + m_svalue = null; + m_iTicks = 0; + m_cLastChar = '\u0000'; + + reprintText(); + + firePropertyChange("Text", sOldText, getText()); + } + + /** + * + * @param sText + */ + public final void setText(String sText) { + + String sOldText = getText(); + + m_svalue = sText; + m_iTicks = 0; + m_cLastChar = '\u0000'; + + reprintText(); + + firePropertyChange("Text", sOldText, getText()); + } + + /** + * + * @param iMode + */ + public final void setEditModeEnum(int iMode) { + + m_iMode = iMode; + m_iTicks = 0; + m_cLastChar = '\u0000'; + + reprintText(); + } + + /** + * + * @return + */ + public final String getText() { + if (m_cLastChar == '\u0000') { + return m_svalue; + } else { + return appendChar2Value(getKeyChar()); + } + } + + /** + * + * @return + */ + protected final int getAlignment() { + return javax.swing.SwingConstants.LEFT; + } + + /** + * + * @return + */ + protected final String getEditMode() { + switch (m_iMode) { + case MODE_Abc1: return "Abc1"; + case MODE_abc1: return "abc1"; + case MODE_ABC1: return "ABC1"; + case MODE_123: return "123"; + default: return null; + } + } + + /** + * + * @return + */ + protected String getTextEdit() { + + StringBuilder s = new StringBuilder(); + s.append(""); + if (m_svalue != null) { + s.append(m_svalue); + } + if (m_cLastChar != '\u0000') { +// s.append(""); + s.append(""); + s.append(getKeyChar()); + s.append(""); + } +// s.append("_"); + s.append("_"); + + return s.toString(); + } + + /** + * + * @return + * @throws BasicException + */ + protected String getTextFormat() throws BasicException { + return (m_svalue == null) + ? "" + : "" + m_svalue; + } + + /** + * + * @param c + */ + protected void typeCharInternal(char c) { + + String sOldText = getText(); + + if (c == '\u0008') { + if (m_cLastChar == '\u0000') { + // borramos el \u00c3\u00baltimo caracter el si existe + if (m_svalue != null && m_svalue.length() > 0) { + m_svalue = m_svalue.substring(0, m_svalue.length() - 1); + } + } else { + // borramos el caracter pendiente + m_iTicks = 0; + m_cLastChar = '\u0000'; + } + } else if (c == '\u007f') { + // Los hemos borrado todos. + m_iMode = getStartMode(); //MODE_Abc1; + m_svalue = null; + m_iTicks = 0; + m_cLastChar = '\u0000'; + } else if (c >= ' ') { // es un caracter en condiciones + if (m_cLastChar != '\u0000') { + char ckey = getKeyChar(); + m_svalue = appendChar2Value(ckey); + acceptKeyChar(ckey); + } + m_iTicks = 0; + m_cLastChar = '\u0000'; + m_svalue = appendChar2Value(c); + } + + m_jtimer.restart(); + + firePropertyChange("Text", sOldText, getText()); + } + + /** + * + * @param c + */ + protected void transCharInternal(char c) { + + String sOldText = getText(); + + if (c == '-') { + if (m_cLastChar == '\u0000') { + // borramos el \u00c3\u00baltimo caracter el si existe + if (m_svalue != null && m_svalue.length() > 0) { + m_svalue = m_svalue.substring(0, m_svalue.length() - 1); + } + } else { + // borramos el caracter pendiente + m_iTicks = 0; + m_cLastChar = '\u0000'; + } + } else if (c == '\u007f') { + // Los hemos borrado todos. + m_iMode = getStartMode(); //MODE_Abc1; + m_svalue = null; + m_iTicks = 0; + m_cLastChar = '\u0000'; + } else if (c == '.') { + if (m_cLastChar != '\u0000') { + m_svalue = appendChar2Value(getKeyChar()); + } + m_iTicks = 0; + m_cLastChar = '\u0000'; + m_iMode = (m_iMode + 1) % 4; + } else if (c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9' || c == '0') { + if (m_iMode == MODE_123) { + m_svalue = appendChar2Value(c); + } else if (c == m_cLastChar) { + m_iTicks ++; + } else { + if (m_cLastChar != '\u0000') { + char ckey = getKeyChar(); + m_svalue = appendChar2Value(ckey); + acceptKeyChar(ckey); + } + m_iTicks = 0; + m_cLastChar = c; + } + } + + m_jtimer.restart(); + + firePropertyChange("Text", sOldText, getText()); + } + + private void acceptKeyChar(char c) { + if (m_iMode == MODE_Abc1 && c != ' ') { + m_iMode = MODE_abc1; + } else if (m_iMode == MODE_abc1 && c == '.') { + m_iMode = MODE_Abc1; + } + } + + /** + * + * @return + */ + protected char getKeyChar() { + + char[] clist = null; + switch (m_iMode) { + case MODE_abc1: + switch (m_cLastChar) { + case '1': clist = CHAR_abc1_1; break; + case '2': clist = CHAR_abc1_2; break; + case '3': clist = CHAR_abc1_3; break; + case '4': clist = CHAR_abc1_4; break; + case '5': clist = CHAR_abc1_5; break; + case '6': clist = CHAR_abc1_6; break; + case '7': clist = CHAR_abc1_7; break; + case '8': clist = CHAR_abc1_8; break; + case '9': clist = CHAR_abc1_9; break; + case '0': clist = CHAR_abc1_0; break; + } + break; + case MODE_Abc1: + case MODE_ABC1: + switch (m_cLastChar) { + case '1': clist = CHAR_ABC1_1; break; + case '2': clist = CHAR_ABC1_2; break; + case '3': clist = CHAR_ABC1_3; break; + case '4': clist = CHAR_ABC1_4; break; + case '5': clist = CHAR_ABC1_5; break; + case '6': clist = CHAR_ABC1_6; break; + case '7': clist = CHAR_ABC1_7; break; + case '8': clist = CHAR_ABC1_8; break; + case '9': clist = CHAR_ABC1_9; break; + case '0': clist = CHAR_ABC1_0; break; + } + break; + } + + if (clist == null) { + return m_cLastChar; + } else { + return clist[m_iTicks % clist.length]; + } + } + + private class TimerAction implements ActionListener { + public void actionPerformed(ActionEvent evt) { + if (m_cLastChar != '\u0000') { + // This method does not modify the "Text" property. + char ckey = getKeyChar(); + m_svalue = appendChar2Value(ckey); + acceptKeyChar(ckey); + m_iTicks = 0; + m_cLastChar = '\u0000'; + m_jtimer.restart(); + reprintText(); + } + } + } + + private String appendChar2Value(char c) { + StringBuilder s = new StringBuilder(); + if (m_svalue != null) { + s.append(m_svalue); + } + s.append(c); + return s.toString(); + } +} diff --git a/src/main/java/com/unicenta/format/DoubleUtils.java b/src/main/java/com/unicenta/format/DoubleUtils.java new file mode 100644 index 0000000..d268403 --- /dev/null +++ b/src/main/java/com/unicenta/format/DoubleUtils.java @@ -0,0 +1,22 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.unicenta.format; + +/** + * + * @author adrian + */ +public class DoubleUtils { + + /** + * + * @param value + * @return + */ + public static double fixDecimals(Number value) { + return Math.rint((value).doubleValue() * 1000000.0) / 1000000.0; + } +} diff --git a/src/main/java/com/unicenta/format/Formats.java b/src/main/java/com/unicenta/format/Formats.java new file mode 100644 index 0000000..edd39f5 --- /dev/null +++ b/src/main/java/com/unicenta/format/Formats.java @@ -0,0 +1,438 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.format; + +import java.text.*; +import com.unicenta.basic.BasicException; +import java.util.Date; + +/** + * + * @author JG uniCenta + */ +public abstract class Formats { + + public final static Formats NULL = new FormatsNULL(); + public final static Formats INT = new FormatsINT(); + public final static Formats STRING = new FormatsSTRING(); + public final static Formats DOUBLE = new FormatsDOUBLE(); + public final static Formats CURRENCY = new FormatsCURRENCY(); + public final static Formats PERCENT = new FormatsPERCENT(); + public final static Formats BOOLEAN = new FormatsBOOLEAN(); + public final static Formats TIMESTAMP = new FormatsTIMESTAMP(); + public final static Formats DATE = new FormatsDATE(); + public final static Formats TIME = new FormatsTIME(); + public final static Formats BYTEA = new FormatsBYTEA(); + public final static Formats HOURMIN = new FormatsHOURMIN(); + public final static Formats SIMPLEDATE = new FormatsSIMPLEDATE(); + + private static NumberFormat m_integerformat = NumberFormat.getIntegerInstance(); + private static NumberFormat m_doubleformat = NumberFormat.getNumberInstance(); + private static NumberFormat m_currencyformat = NumberFormat.getCurrencyInstance(); + private static NumberFormat m_percentformat = new DecimalFormat("#,##0.##%"); + private static DateFormat m_dateformat = DateFormat.getDateInstance(); + private static DateFormat m_timeformat = DateFormat.getTimeInstance(); + private static DateFormat m_datetimeformat = DateFormat.getDateTimeInstance(); + + private static final DateFormat m_hourminformat = new SimpleDateFormat("H:mm:ss"); + private static final DateFormat m_simpledate = new SimpleDateFormat("dd-MM-yyyy"); + /** Creates a new instance of Formats */ + + + protected Formats() { + } + + /** + * + * @return + */ + public static int getCurrencyDecimals() { + + return m_currencyformat.getMaximumFractionDigits(); + } + + /** + * + * @param value + * @return + */ + public String formatValue(Object value) { + if (value == null) { + return ""; + } else { + return formatValueInt(value); + } + } + + /** + * + * @param value + * @param defvalue + * @return + * @throws BasicException + */ + public Object parseValue(String value, Object defvalue) throws BasicException { + if (value == null || "".equals(value)) { + return defvalue; + } else { + try { + return parseValueInt(value); + } catch (ParseException e) { + throw new BasicException(e.getMessage(), e); + } + } + } + + /** + * + * @param value + * @return + * @throws BasicException + */ + public Object parseValue(String value) throws BasicException { + return parseValue(value, null); + } + + /** + * + * @param pattern + */ + public static void setIntegerPattern(String pattern) { + if (pattern == null || pattern.equals("")) { + m_integerformat = NumberFormat.getIntegerInstance(); + } else { + m_integerformat = new DecimalFormat(pattern); + } + } + + /** + * + * @param pattern + */ + public static void setDoublePattern(String pattern) { + if (pattern == null || pattern.equals("")) { + m_doubleformat = NumberFormat.getNumberInstance(); + } else { + m_doubleformat = new DecimalFormat(pattern); + } + } + + /** + * + * @param pattern + */ + public static void setCurrencyPattern(String pattern) { + if (pattern == null || pattern.equals("")) { + m_currencyformat = NumberFormat.getCurrencyInstance(); + } else { + m_currencyformat = new DecimalFormat(pattern); + } + } + + /** + * + * @param pattern + */ + public static void setPercentPattern(String pattern) { + if (pattern == null || pattern.equals("")) { + m_percentformat = new DecimalFormat("#,##0.##%"); + } else { + m_percentformat = new DecimalFormat(pattern); + } + } + + /** + * + * @param pattern + */ + public static void setDatePattern(String pattern) { + if (pattern == null || pattern.equals("")) { + m_dateformat = DateFormat.getDateInstance(); + } else { + m_dateformat = new SimpleDateFormat(pattern); + } + } + + /** + * + * @param pattern + */ + public static void setTimePattern(String pattern) { + if (pattern == null || pattern.equals("")) { + m_timeformat = DateFormat.getTimeInstance(); + } else { + m_timeformat = new SimpleDateFormat(pattern); + } + } + + /** + * + * @param pattern + */ + public static void setDateTimePattern(String pattern) { + if (pattern == null || pattern.equals("")) { + m_datetimeformat = DateFormat.getDateTimeInstance(); + } else { + m_datetimeformat = new SimpleDateFormat(pattern); + } + } + + /** + * + * @param value + * @return + */ + protected abstract String formatValueInt(Object value); + + /** + * + * @param value + * @return + * @throws ParseException + */ + protected abstract Object parseValueInt(String value) throws ParseException; + + /** + * + * @return + */ + public abstract int getAlignment(); + + private static final class FormatsNULL extends Formats { + @Override + protected String formatValueInt(Object value) { + return null; + } + @Override + protected Object parseValueInt(String value) throws ParseException { + return null; + } + @Override + public int getAlignment() { + return javax.swing.SwingConstants.LEFT; + } + } + private static final class FormatsINT extends Formats { + @Override + protected String formatValueInt(Object value) { + return m_integerformat.format(((Number) value).longValue()); + } + @Override + protected Object parseValueInt(String value) throws ParseException { + return m_integerformat.parse(value).intValue(); + } + @Override + public int getAlignment() { + return javax.swing.SwingConstants.RIGHT; + } + } + private static final class FormatsSTRING extends Formats { + @Override + protected String formatValueInt(Object value) { + return (String) value; + } + @Override + protected Object parseValueInt(String value) throws ParseException { + return value; + } + @Override + public int getAlignment() { + return javax.swing.SwingConstants.LEFT; + } + } + private static final class FormatsDOUBLE extends Formats { + @Override + protected String formatValueInt(Object value) { + return m_doubleformat.format(DoubleUtils.fixDecimals((Number) value)); // quickfix for 3838 + } + @Override + protected Object parseValueInt(String value) throws ParseException { + return m_doubleformat.parse(value).doubleValue(); + } + @Override + public int getAlignment() { + return javax.swing.SwingConstants.RIGHT; + } + } + private static final class FormatsPERCENT extends Formats { + @Override + protected String formatValueInt(Object value) { + return m_percentformat.format(DoubleUtils.fixDecimals((Number) value)); // quickfix for 3838 + } + @Override + protected Object parseValueInt(String value) throws ParseException { + try { + return m_percentformat.parse(value).doubleValue(); + } catch (ParseException e) { + // Segunda oportunidad como numero normalito + return m_doubleformat.parse(value).doubleValue() / 100; + } + } + @Override + public int getAlignment() { + return javax.swing.SwingConstants.RIGHT; + } + } + private static final class FormatsCURRENCY extends Formats { + @Override + protected String formatValueInt(Object value) { + return m_currencyformat.format(DoubleUtils.fixDecimals((Number) value)); // quickfix for 3838 + } + @Override + protected Object parseValueInt(String value) throws ParseException { + try { + return m_currencyformat.parse(value).doubleValue(); + } catch (ParseException e) { + // Segunda oportunidad como numero normalito + return m_doubleformat.parse(value).doubleValue(); + } + } + @Override + public int getAlignment() { + return javax.swing.SwingConstants.RIGHT; + } + } + private static final class FormatsBOOLEAN extends Formats { + @Override + protected String formatValueInt(Object value) { + return ((Boolean) value).toString(); + } + @Override + protected Object parseValueInt(String value) throws ParseException { + return Boolean.valueOf(value); + } + @Override + public int getAlignment() { + return javax.swing.SwingConstants.CENTER; + } + } + private static final class FormatsTIMESTAMP extends Formats { + @Override + protected String formatValueInt(Object value) { + return m_datetimeformat.format((Date) value); + } + @Override + protected Object parseValueInt(String value) throws ParseException { + try { + return m_datetimeformat.parse(value); + } catch (ParseException e) { + // segunda oportunidad como fecha normalita + return m_dateformat.parse(value); + } + } + @Override + public int getAlignment() { + return javax.swing.SwingConstants.CENTER; + } + } + private static final class FormatsDATE extends Formats { + @Override + protected String formatValueInt(Object value) { + return m_dateformat.format((Date) value); + } + @Override + protected Object parseValueInt(String value) throws ParseException { + return m_dateformat.parse(value); + } + @Override + public int getAlignment() { + return javax.swing.SwingConstants.CENTER; + } + } + private static final class FormatsTIME extends Formats { + @Override + protected String formatValueInt(Object value) { + return m_timeformat.format((Date) value); + } + @Override + protected Object parseValueInt(String value) throws ParseException { + return m_timeformat.parse(value); + } + @Override + public int getAlignment() { + return javax.swing.SwingConstants.CENTER; + } + } + private static final class FormatsBYTEA extends Formats { + @Override + protected String formatValueInt(Object value) { + try { + return new String((byte[]) value, "UTF-8"); + } catch (java.io.UnsupportedEncodingException eu) { + return ""; + } + } + @Override + protected Object parseValueInt(String value) throws ParseException { + try { + return value.getBytes("UTF-8"); + } catch (java.io.UnsupportedEncodingException eu) { + return new byte[0]; + } + } + @Override + public int getAlignment() { + return javax.swing.SwingConstants.LEADING; + } + } + private static final class FormatsHOURMIN extends Formats { + @Override + protected String formatValueInt(Object value) { + return m_hourminformat.format(value); +} + @Override + protected Date parseValueInt(String value) throws ParseException { + return m_hourminformat.parse(value); + } + @Override + public int getAlignment() { + + return javax.swing.SwingConstants.CENTER; + + } + + } + +/** Added; Thanks TSirwani 3 Mar 11 */ + private static final class FormatsSIMPLEDATE extends Formats { + + @Override + protected String formatValueInt(Object value) { + + return m_simpledate.format(value); + + } + + @Override + protected Date parseValueInt(String value) throws ParseException { + + return m_simpledate.parse(value); + + } + + @Override + public int getAlignment() { + + return javax.swing.SwingConstants.CENTER; + + } + + } +} diff --git a/src/main/java/com/unicenta/format/FormatsConstrain.java b/src/main/java/com/unicenta/format/FormatsConstrain.java new file mode 100644 index 0000000..dae1ca8 --- /dev/null +++ b/src/main/java/com/unicenta/format/FormatsConstrain.java @@ -0,0 +1,56 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.format; + +import java.text.ParseException; + +/** + * + * @author JG uniCenta + */ +public abstract class FormatsConstrain { + +// public final static FormatsConstrain NOTNULL = new FormatsConstrainNOTNULL(); + + /** + * + * @param value + * @return + * @throws ParseException + */ + + public abstract Object check(Object value) throws ParseException; + + /** + * + */ + public FormatsConstrain() { + } + +// private static class FormatsConstrainNOTNULL extends FormatsConstrain { +// public Object check(Object value) throws ParseException{ +// if (value == null) { +// throw new ParseException(LocalRes.getIntString("exception.notnull"), 0); +// } else { +// return value; +// } +// } +// } +} diff --git a/src/main/java/com/unicenta/format/FormatsException.java b/src/main/java/com/unicenta/format/FormatsException.java new file mode 100644 index 0000000..2bdf488 --- /dev/null +++ b/src/main/java/com/unicenta/format/FormatsException.java @@ -0,0 +1,41 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.format; + +/** + * + * @author JG uniCenta + */ +public class FormatsException extends java.lang.Exception { + + /** + * Creates a new instance of FormatsException without detail message. + */ + public FormatsException() { + } + + /** + * Constructs an instance of FormatsException with the specified detail message. + * @param msg the detail message. + */ + public FormatsException(String msg) { + super(msg); + } +} diff --git a/src/main/java/com/unicenta/format/FormatsRESOURCE.java b/src/main/java/com/unicenta/format/FormatsRESOURCE.java new file mode 100644 index 0000000..320971e --- /dev/null +++ b/src/main/java/com/unicenta/format/FormatsRESOURCE.java @@ -0,0 +1,76 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.format; + +import java.text.ParseException; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +/** + * + * @author JG uniCenta + */ +public class FormatsRESOURCE extends Formats { + + private ResourceBundle m_rb; + private String m_sPrefix; + + /** Creates a new instance of FormatsRESOURCE + * @param rb + * @param sPrefix */ + public FormatsRESOURCE(ResourceBundle rb, String sPrefix) { + m_rb = rb; + m_sPrefix = sPrefix; + } + + /** + * + * @param value + * @return + */ + @Override + protected String formatValueInt(Object value) { + try { + return m_rb.getString(m_sPrefix + (String) value); + } catch (MissingResourceException e) { + return (String) value; + } + } + + /** + * + * @param value + * @return + * @throws ParseException + */ + @Override + protected Object parseValueInt(String value) throws ParseException { + return value; + } + + /** + * + * @return + */ + @Override + public int getAlignment() { + return javax.swing.SwingConstants.LEFT; + } +} diff --git a/src/main/java/com/unicenta/format/FormatsValidate.java b/src/main/java/com/unicenta/format/FormatsValidate.java new file mode 100644 index 0000000..82e52f6 --- /dev/null +++ b/src/main/java/com/unicenta/format/FormatsValidate.java @@ -0,0 +1,87 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.format; + +import java.text.ParseException; + +/** + * + * @author JG uniCenta + */ +public class FormatsValidate extends Formats { + + private Formats m_fmt; + private FormatsConstrain[] m_aConstrains; + + /** Creates a new instance of FormatsValidate + * @param fmt + * @param constrains */ + public FormatsValidate(Formats fmt, FormatsConstrain[] constrains) { + m_fmt = fmt; + m_aConstrains = constrains; + } + /** Creates a new instance of FormatsValidate + * @param fmt */ + public FormatsValidate(Formats fmt) { + this(fmt, new FormatsConstrain[0]); + } + /** Creates a new instance of FormatsValidate + * @param fmt + * @param constrain */ + public FormatsValidate(Formats fmt, FormatsConstrain constrain) { + this(fmt, new FormatsConstrain[]{constrain}); + } + + /** + * + * @param value + * @return + */ + @Override + protected String formatValueInt(Object value) { + return m_fmt.formatValueInt(value); + } + + /** + * + * @param value + * @return + * @throws ParseException + */ + @Override + protected Object parseValueInt(String value) throws ParseException { + // Primero obtenemos el valor + Object val = m_fmt.parseValueInt(value); + for (int i = 0; i < m_aConstrains.length; i++) { + val = m_aConstrains[i].check(val); + } + + return val; + } + + /** + * + * @return + */ + @Override + public int getAlignment() { + return m_fmt.getAlignment(); + } +} diff --git a/src/main/java/com/unicenta/orderpop/OrderPop.java b/src/main/java/com/unicenta/orderpop/OrderPop.java new file mode 100644 index 0000000..48ad7e3 --- /dev/null +++ b/src/main/java/com/unicenta/orderpop/OrderPop.java @@ -0,0 +1,308 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2017 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta Remote Display +// +// uniCenta Remote Display is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta Remote Display is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +/* uniCenta's OrderPop is a simple utilty to list tickets sent to remote printer + * It connects to and list uniCenta oPOS orders table rows and requires a + * manual refresh using the button. + * It runs independently of uniCenta oPOS and uses the provided orderpop.bat + + */ + +package com.unicenta.orderpop; + +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.util.AltEncrypter; +import javafx.application.Application; +import javafx.application.Platform; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.concurrent.Task; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.ListView; +import javafx.scene.control.ProgressIndicator; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; +import javafx.stage.Stage; +import javafx.stage.WindowEvent; +import lombok.extern.slf4j.Slf4j; + +import java.sql.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicInteger; + +@Slf4j +public class OrderPop extends Application { + + public static void main(String[] args) { + launch(args); + } + + private ExecutorService databaseExecutor; + private Future databaseSetupFuture; + + @Override + public void init() throws Exception { + databaseExecutor = Executors.newFixedThreadPool( + 1, + new DatabaseThreadFactory() + ); + DBSetupTask setup = new DBSetupTask(); + databaseSetupFuture = databaseExecutor.submit(setup); + } + + // Pop the UI will use fxml rather than in code css to set styling later for release + @Override + public void start(Stage stage) throws InterruptedException, ExecutionException { + + databaseSetupFuture.get(); + final ListView orderView = new ListView<>(); + final ProgressIndicator databaseActivityIndicator = new ProgressIndicator(); + + Image fetchO = new Image(getClass().getResourceAsStream("/com/unicenta/images/resources.png")); + final Button fetchOrders = new Button("Fetch", new ImageView(fetchO)); + // fetch Orders table data and fill the list + databaseActivityIndicator.setVisible(false); + fetchOrders.setOnAction(event -> + fetchDBOrdersListView( + fetchOrders, + databaseActivityIndicator, + orderView + )); + + Image closeO = new Image(getClass().getResourceAsStream("/com/unicenta/images/fileclose.png")); + final Button closeOrderList = new Button("Close", new ImageView(closeO)); + closeOrderList.setOnAction(e -> { + try { + e.consume(); + stop(); + Platform.exit(); + } catch (Exception ex) { + log.error(ex.getMessage()); + } + }); + + stage.setOnCloseRequest((WindowEvent e) -> { + try { + Platform.exit(); + stop(); + Platform.exit(); + } catch (Exception ex) { + log.error(ex.getMessage()); + } + }); + + VBox layout = new VBox(10); + layout.setStyle("-fx-background-color: aliceblue; -fx-padding: 5;"); + //layout.getChildren().setAll( + // new HBox(10, + // fetchOrders, + // closeOrderList, + // databaseActivityIndicator + // ), + // orderView + //); + + layout.setPrefHeight(300); + layout.setPrefWidth(500); + + stage.getIcons().add(new Image("/com/unicenta/images/unicentaopos.png")); + stage.setTitle("Orders Waiting..."); + stage.setScene(new Scene(layout)); + //stage.setAlwaysOnTop(true); + stage.show(); + + } + + // shutdown the app + //@Override + public void istop() throws Exception { + + databaseExecutor.shutdown(); + if (!databaseExecutor.awaitTermination(3, TimeUnit.SECONDS)) { + log.info("DB thread time-out + 3 sec's not shut down clean"); + } + + Platform.exit(); + } + + private void fetchDBOrdersListView( + final Button triggerButton, + final ProgressIndicator databaseActivityIndicator, + final ListView listView) { + final FetchOrdersTask fetchOrdersTask = new FetchOrdersTask(); + + triggerButton.disableProperty().bind( + fetchOrdersTask.runningProperty() + ); + + databaseActivityIndicator.visibleProperty().bind( + fetchOrdersTask.runningProperty() + ); + + databaseActivityIndicator.progressProperty().bind( + fetchOrdersTask.progressProperty() + ); + + fetchOrdersTask.setOnSucceeded(t -> + listView.setItems(fetchOrdersTask.getValue()) + ); + + listView.setStyle("-fx-font-size: 14px;"); + +// prep for css +// listView.getStylesheets().add( +// this.getClass().getResource("listStyle.css").toExternalForm()); + + databaseExecutor.submit(fetchOrdersTask); + } + + abstract class DBTask extends Task { + DBTask() { + setOnFailed(t -> log.error(getException().getMessage())); + } + } + + class FetchOrdersTask extends DBTask> { + @Override + protected ObservableList call() throws Exception { + Thread.sleep(1000); + try (Connection con = getConnection()) { + return fetchOrders(con); + } + } + + // Using an ObservableList here but could use a table as well to give more + // flexibility to highlight specific row/column/cells + private ObservableList fetchOrders(Connection con) throws SQLException { + log.info("Fetch Orders from DB"); + ObservableList orders = FXCollections.observableArrayList(); + Statement st = con.createStatement(); + ResultSet rs = st.executeQuery("SELECT ticketid, orderid, " +// + "DATE_FORMAT(ordertime,'%b %d %Y %h:%i %p') AS ordertime, " + + "qty, " + + "ordertime, " + + "details " + + "FROM orders " + + "ORDER BY ordertime, orderid"); + + while (rs.next()) { + orders.add(rs.getString("ticketid") + " - " + + rs.getString("orderid") + " - " + + rs.getString("ordertime") + + " - " + rs.getString("qty") + + " * " + rs.getString("details")); + } + + log.info("Found {} orders", orders.size()); + return orders; + } + } + + /* + * Check to see if we have a connection to database and + * and pop some data in Orders table to prime if needed + */ + class DBSetupTask extends DBTask { + @Override + protected Void call() throws Exception { + try (Connection con = getConnection()) { + if (!schemaExists(con)) { + // un-comment if we need to create a new Orders table + // createSchema(con); + // populateDatabase(con); + } + } + + return null; + } + + private boolean schemaExists(Connection con) { + log.info("Check for Orders table"); + try { + Statement st = con.createStatement(); + st.executeQuery("select count(*) from orders"); + log.info("Orders table exists"); + } catch (SQLException ex) { + log.info("Create Orders table"); + return false; + } + return true; + } + +/* + * We don't need to create Orders table as should already exist + * as created by uniCenta oPOS or unicenta_remote_display apps + private void createSchema(Connection con) throws SQLException { + logger.info("Add Orders table to schema if not exist"); + Statement st = con.createStatement(); + String table = "create table orders(id integer, orderid varchar(50))"; + st.executeUpdate(table); + logger.info("Created schema"); + } +*/ + +/* + * Useful if we want to fill the Orders table with some sample data + * MySQL-createSampleData.sql - INSERT x12 rows + private void populateDatabase(Connection con) throws SQLException { + logger.info("Populating database"); + Statement st = con.createStatement(); + for (String order: SAMPLE_ORDER_DATA) { + st.executeUpdate("insert into orders values(1,'" + order + "')"); + } + logger.info("Populated database"); + } +*/ + } + + private Connection getConnection() throws ClassNotFoundException, SQLException { + // use explicit connection rather than uniCenta oPOS instance session + // better for this to be independent but use current instance's credentials + + log.info("Get DB connection"); + + String url = AppConfig.getInstance().getProperty("db.URL") + + AppConfig.getInstance().getProperty("db.schema") + + AppConfig.getInstance().getProperty("db.options"); + String sDBUser = AppConfig.getInstance().getProperty("db.user"); + String sDBPassword = AppConfig.getInstance().getProperty("db.password"); + + if (sDBUser != null && sDBPassword != null && sDBPassword.startsWith("crypt:")) { + AltEncrypter cypher = new AltEncrypter("cypherkey" + sDBUser); + sDBPassword = cypher.decrypt(sDBPassword.substring(6)); + } + + return DriverManager.getConnection(url, sDBUser, sDBPassword); + } + + static class DatabaseThreadFactory implements ThreadFactory { + static final AtomicInteger poolNumber = new AtomicInteger(1); + + @Override + public Thread newThread(Runnable runnable) { + Thread thread = new Thread(runnable, "Database-Connection-" + + poolNumber.getAndIncrement() + "-thread"); + thread.setDaemon(true); + return thread; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/orderpop/listStyle.css b/src/main/java/com/unicenta/orderpop/listStyle.css new file mode 100644 index 0000000..466e1aa --- /dev/null +++ b/src/main/java/com/unicenta/orderpop/listStyle.css @@ -0,0 +1,22 @@ +.root { + -fx-text-base-color: rgb(252.0, 240.0, 237.0); + -fx-text-fill: -fx-text-base-color; + -dark: rgb(47.0, 52.0, 57.0); + -fx-background-color: -dark; + + /*default font */ + -fx-font-family: 'Helvetica Neue'; + + -fx-font-size: 25.0px; + -fx-font-weight: 600; + -fx-disabled-opacity: 0.6; + + -flatter-red: rgb(237.0, 68.0, 37.0); + -flatter-blue: rgb(0.0, 184.0, 222.0); + + -fx-base: #383838; + -fx-background: -fx-base; + -fx-control-inner-background: -fx-base; + -fx-control-inner-background-alt: -fx-base; + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/admin/DataLogicAdmin.java b/src/main/java/com/unicenta/pos/admin/DataLogicAdmin.java new file mode 100644 index 0000000..9c0596b --- /dev/null +++ b/src/main/java/com/unicenta/pos/admin/DataLogicAdmin.java @@ -0,0 +1,131 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.admin; + +import com.unicenta.data.loader.*; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.BeanFactoryDataSingle; + +/** + * + * @author adrianromero + */ +public class DataLogicAdmin extends BeanFactoryDataSingle { + + private Session s; + private TableDefinition m_tpeople; + private TableDefinition m_troles; + private TableDefinition m_tresources; + + + /** Creates a new instance of DataLogicAdmin */ + public DataLogicAdmin() { + } + + /** + * + * @param s + */ + @Override + public void init(Session s){ + this.s = s; + + m_tpeople = new TableDefinition(s, + "people" + , new String[] {"ID", "NAME", "APPPASSWORD", "ROLE", "VISIBLE", "CARD", "IMAGE"} + , new String[] {"ID", AppLocal.getIntString("label.peoplename"), AppLocal.getIntString("label.Password"), AppLocal.getIntString("label.role"), AppLocal.getIntString("label.peoplevisible"), AppLocal.getIntString("label.card"), AppLocal.getIntString("label.peopleimage")} + , new Datas[] {Datas.STRING, Datas.STRING, Datas.STRING, Datas.STRING, Datas.BOOLEAN, Datas.STRING, Datas.IMAGE} + , new Formats[] {Formats.STRING, Formats.STRING, Formats.STRING, Formats.STRING, Formats.BOOLEAN, Formats.STRING, Formats.NULL} + , new int[] {0} + ); + + m_troles = new TableDefinition(s, + "roles" + , new String[] {"ID", "NAME", "PERMISSIONS"} + , new String[] {"ID", AppLocal.getIntString("label.name"), "PERMISSIONS"} + , new Datas[] {Datas.STRING, Datas.STRING, Datas.BYTES} + , new Formats[] {Formats.STRING, Formats.STRING, Formats.NULL} + , new int[] {0} + ); + + m_tresources = new TableDefinition(s, + "resources" + , new String[] { + "ID", "NAME", "RESTYPE", "CONTENT"} + , new String[] { + "ID", + AppLocal.getIntString("label.name"), + AppLocal.getIntString("label.type"), + "CONTENT"} + , new Datas[] { + Datas.STRING, Datas.STRING, Datas.INT, Datas.BYTES} + , new Formats[] { + Formats.STRING, Formats.STRING, Formats.INT, Formats.NULL} + , new int[] {0} + ); + } + + /** + * + * @return + */ + public final SentenceList getRolesList() { + return new StaticSentence(s + , "SELECT ID, NAME FROM roles ORDER BY NAME" + , null + , new SerializerReadClass(RoleInfo.class)); + } + + /** + * + * @return + */ + public final TableDefinition getTablePeople() { + return m_tpeople; + } + + /** + * + * @return + */ + public final TableDefinition getTableRoles() { + return m_troles; + } + + /** + * + * @return + */ + public final TableDefinition getTableResources() { + return m_tresources; + } + + /** + * + * @return + */ + public final SentenceList getPeopleList() { + return new StaticSentence(s + , "SELECT ID, NAME FROM people ORDER BY NAME" + , null + , new SerializerReadClass(PeopleInfo.class)); + } +} diff --git a/src/main/java/com/unicenta/pos/admin/JPeopleFinder.form b/src/main/java/com/unicenta/pos/admin/JPeopleFinder.form new file mode 100644 index 0000000..50e374f --- /dev/null +++ b/src/main/java/com/unicenta/pos/admin/JPeopleFinder.form @@ -0,0 +1,339 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/pos/admin/JPeopleFinder.java b/src/main/java/com/unicenta/pos/admin/JPeopleFinder.java new file mode 100644 index 0000000..284db41 --- /dev/null +++ b/src/main/java/com/unicenta/pos/admin/JPeopleFinder.java @@ -0,0 +1,417 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.admin; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.QBFCompareEnum; +import com.unicenta.data.user.EditorCreator; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.pos.forms.AppLocal; +import java.awt.*; +import java.util.ArrayList; +import javax.swing.JFrame; + +/** + * + * @author adrianromero + */ +public class JPeopleFinder extends javax.swing.JDialog implements EditorCreator { + + private PeopleInfo selectedPeople; + private ListProvider lpr; + + /** Creates new form JPeopleFinder */ + private JPeopleFinder(java.awt.Frame parent, boolean modal) { + super(parent, modal); + } + + /** + * Creates new form JPeopleFinder + */ + private JPeopleFinder(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + } + + /** + * + * @param parent + * @param dlPeople + * @return + */ + public static JPeopleFinder getPeopleFinder(Component parent, DataLogicAdmin dlPeople) { + Window window = getWindow(parent); + + JPeopleFinder myMsg; + if (window instanceof Frame) { + myMsg = new JPeopleFinder((Frame) window, true); + } else { + myMsg = new JPeopleFinder((Dialog) window, true); + } + myMsg.init(dlPeople); + myMsg.applyComponentOrientation(parent.getComponentOrientation()); + return myMsg; + } + + /** + * + * @return + */ + public PeopleInfo getSelectedPeople() { + return selectedPeople; + } + + private void init(DataLogicAdmin dlPeople) { + + initComponents(); + + jScrollPane1.getVerticalScrollBar().setPreferredSize(new Dimension(35, 35)); + m_jtxtName.addEditorKeys(m_jKeys); + m_jtxtName.reset(); + lpr = new ListProviderCreator(dlPeople.getPeopleList(), this); + jListPeople.setCellRenderer(new PeopleRenderer()); + + getRootPane().setDefaultButton(jcmdOK); + + selectedPeople = null; + } + + /** + * + * @param people + */ + public void search(PeopleInfo people) { + + if (people == null + || people.getName() == null + || people.getName().equals("")) { + m_jtxtName.reset(); + cleanSearch(); + } else { + m_jtxtName.setText(people.getName()); + executeSearch(); + } + } + + private void cleanSearch() { + jListPeople.setModel(new MyListData(new ArrayList())); + } + + /** + * This method actions the User data search + */ + public void executeSearch() { + try { + jListPeople.setModel(new MyListData(lpr.loadData())); + if (jListPeople.getModel().getSize() > 0) { + jListPeople.setSelectedIndex(0); + } + } catch (BasicException e) { + } + } + + /** + * + * @return creates object for search method + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + Object[] afilter = new Object[12]; + + if (m_jtxtName.getText() == null + || m_jtxtName.getText().equals("")) { + afilter[0] = QBFCompareEnum.COMP_NONE; + afilter[1] = null; + } else { + afilter[0] = QBFCompareEnum.COMP_RE; + afilter[1] = "%" + m_jtxtName.getText() + "%"; + } + + return afilter; + } + + private static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window) parent; + } else { + return getWindow(parent.getParent()); + } + } + + private static class MyListData extends javax.swing.AbstractListModel { + + private final java.util.List m_data; + + public MyListData(java.util.List data) { + m_data = data; + } + + @Override + public Object getElementAt(int index) { + return m_data.get(index); + } + + @Override + public int getSize() { + return m_data.size(); + } + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel3 = new javax.swing.JPanel(); + jPanel5 = new javax.swing.JPanel(); + jPanel7 = new javax.swing.JPanel(); + jLblName = new javax.swing.JLabel(); + m_jtxtName = new com.unicenta.editor.JEditorString(); + jPanel4 = new javax.swing.JPanel(); + jScrollPane1 = new javax.swing.JScrollPane(); + jListPeople = new javax.swing.JList(); + jPanel6 = new javax.swing.JPanel(); + jButton1 = new javax.swing.JButton(); + jButton3 = new javax.swing.JButton(); + jPanel2 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel8 = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + jcmdCancel = new javax.swing.JButton(); + jcmdOK = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(AppLocal.getIntString("form.usertitle")); // NOI18N + setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + setPreferredSize(new java.awt.Dimension(650, 300)); + + jPanel3.setPreferredSize(new java.awt.Dimension(450, 231)); + jPanel3.setLayout(new java.awt.BorderLayout()); + + jPanel5.setLayout(new java.awt.BorderLayout()); + + jPanel7.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + + jLblName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblName.setText(AppLocal.getIntString("label.prodname")); // NOI18N + jLblName.setMaximumSize(new java.awt.Dimension(60, 15)); + jLblName.setMinimumSize(new java.awt.Dimension(60, 15)); + jLblName.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jtxtName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jtxtName.setPreferredSize(new java.awt.Dimension(250, 30)); + + javax.swing.GroupLayout jPanel7Layout = new javax.swing.GroupLayout(jPanel7); + jPanel7.setLayout(jPanel7Layout); + jPanel7Layout.setHorizontalGroup( + jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel7Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLblName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jtxtName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + jPanel7Layout.setVerticalGroup( + jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel7Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(m_jtxtName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + ); + + m_jtxtName.getAccessibleContext().setAccessibleName(""); + + jPanel5.add(jPanel7, java.awt.BorderLayout.CENTER); + + jPanel3.add(jPanel5, java.awt.BorderLayout.PAGE_START); + + jPanel4.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel4.setLayout(new java.awt.BorderLayout()); + + jListPeople.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jListPeople.setFocusable(false); + jListPeople.setRequestFocusEnabled(false); + jListPeople.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + jListPeopleMouseClicked(evt); + } + }); + jListPeople.addListSelectionListener(new javax.swing.event.ListSelectionListener() { + public void valueChanged(javax.swing.event.ListSelectionEvent evt) { + jListPeopleValueChanged(evt); + } + }); + jScrollPane1.setViewportView(jListPeople); + + jPanel4.add(jScrollPane1, java.awt.BorderLayout.CENTER); + + jButton1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jButton1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reload.png"))); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jButton1.setText(bundle.getString("button.reset")); // NOI18N + jButton1.setToolTipText("Clear Filter"); + jButton1.setActionCommand("Reset "); + jButton1.setFocusable(false); + jButton1.setPreferredSize(new java.awt.Dimension(110, 45)); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + jPanel6.add(jButton1); + jButton1.getAccessibleContext().setAccessibleDescription(""); + + jButton3.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jButton3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jButton3.setText(AppLocal.getIntString("button.executefilter")); // NOI18N + jButton3.setToolTipText("Execute Filter"); + jButton3.setFocusPainted(false); + jButton3.setPreferredSize(new java.awt.Dimension(110, 45)); + jButton3.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton3ActionPerformed(evt); + } + }); + jPanel6.add(jButton3); + jButton3.getAccessibleContext().setAccessibleDescription(""); + + jPanel4.add(jPanel6, java.awt.BorderLayout.PAGE_START); + + jPanel3.add(jPanel4, java.awt.BorderLayout.CENTER); + + getContentPane().add(jPanel3, java.awt.BorderLayout.CENTER); + + jPanel2.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + jPanel2.setLayout(new java.awt.BorderLayout()); + jPanel2.add(m_jKeys, java.awt.BorderLayout.NORTH); + + jPanel8.setLayout(new java.awt.BorderLayout()); + + jcmdCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + jcmdCancel.setText(AppLocal.getIntString("button.Cancel")); // NOI18N + jcmdCancel.setFocusPainted(false); + jcmdCancel.setFocusable(false); + jcmdCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdCancel.setPreferredSize(new java.awt.Dimension(110, 45)); + jcmdCancel.setRequestFocusEnabled(false); + jcmdCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdCancelActionPerformed(evt); + } + }); + jPanel1.add(jcmdCancel); + + jcmdOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jcmdOK.setText(AppLocal.getIntString("button.OK")); // NOI18N + jcmdOK.setEnabled(false); + jcmdOK.setFocusPainted(false); + jcmdOK.setFocusable(false); + jcmdOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdOK.setMaximumSize(new java.awt.Dimension(103, 44)); + jcmdOK.setMinimumSize(new java.awt.Dimension(103, 44)); + jcmdOK.setPreferredSize(new java.awt.Dimension(110, 45)); + jcmdOK.setRequestFocusEnabled(false); + jcmdOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdOKActionPerformed(evt); + } + }); + jPanel1.add(jcmdOK); + + jPanel8.add(jPanel1, java.awt.BorderLayout.LINE_END); + + jPanel2.add(jPanel8, java.awt.BorderLayout.SOUTH); + + getContentPane().add(jPanel2, java.awt.BorderLayout.LINE_END); + + setSize(new java.awt.Dimension(758, 497)); + setLocationRelativeTo(null); + }// //GEN-END:initComponents + private void jcmdOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdOKActionPerformed + + selectedPeople = (PeopleInfo) jListPeople.getSelectedValue(); + dispose(); + + }//GEN-LAST:event_jcmdOKActionPerformed + + private void jcmdCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdCancelActionPerformed + + dispose(); + + }//GEN-LAST:event_jcmdCancelActionPerformed + + private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed + + executeSearch(); + + }//GEN-LAST:event_jButton3ActionPerformed + + private void jListPeopleValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_jListPeopleValueChanged + + jcmdOK.setEnabled(jListPeople.getSelectedValue() != null); + + }//GEN-LAST:event_jListPeopleValueChanged + + private void jListPeopleMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jListPeopleMouseClicked + + if (evt.getClickCount() == 2) { + selectedPeople = (PeopleInfo) jListPeople.getSelectedValue(); + dispose(); + } + + }//GEN-LAST:event_jListPeopleMouseClicked + +private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + + m_jtxtName.reset(); + + cleanSearch(); +}//GEN-LAST:event_jButton1ActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + private javax.swing.JButton jButton3; + private javax.swing.JLabel jLblName; + private javax.swing.JList jListPeople; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JPanel jPanel6; + private javax.swing.JPanel jPanel7; + private javax.swing.JPanel jPanel8; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JButton jcmdCancel; + private javax.swing.JButton jcmdOK; + private com.unicenta.editor.JEditorKeys m_jKeys; + private com.unicenta.editor.JEditorString m_jtxtName; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/admin/OWWatch.java b/src/main/java/com/unicenta/pos/admin/OWWatch.java new file mode 100644 index 0000000..5b7eaf0 --- /dev/null +++ b/src/main/java/com/unicenta/pos/admin/OWWatch.java @@ -0,0 +1,174 @@ + +/*--------------------------------------------------------------------------- + * Copyright (c) 1999,2000 Dallas Semiconductor Corporation, All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Dallas Semiconductor + * shall not be used except as stated in the Dallas Semiconductor + * Branding Policy. + *--------------------------------------------------------------------------- + */ + +import com.dalsemi.onewire.OneWireAccessProvider; +import com.dalsemi.onewire.adapter.DSPortAdapter; +import com.dalsemi.onewire.adapter.OneWireIOException; +import com.dalsemi.onewire.container.OneWireContainer; +import com.dalsemi.onewire.utils.*; +import com.dalsemi.onewire.application.monitor.*; + + +/** + * Minimal demo to monitor a simple network. + * + * @version 0.00, 25 September 2000 + * @author DS,BA,SH + */ +public class OWWatch + implements DeviceMonitorEventListener +{ + + /** + * Method main + * + * + * @param args + * + */ + public static void main (String args []) + { + OneWireContainer owd; + int delay; + + try + { + + // get the default adapter + DSPortAdapter adapter = OneWireAccessProvider.getDefaultAdapter(); + + System.out.println(); + System.out.println("Adapter: " + adapter.getAdapterName() + + " Port: " + adapter.getPortName()); + System.out.println(); + + // clear any previous search restrictions + adapter.setSearchAllDevices(); + adapter.targetAllFamilies(); + adapter.setSpeed(adapter.SPEED_REGULAR); + + // create the watcher with this adapter + OWWatch nw = new OWWatch(adapter); + + // sleep for the specified time + if (args.length >= 1) + delay = Integer.decode(args [0]).intValue(); + else + delay = 20000; + + System.out.println("Monitor run for: " + delay + "ms"); + Thread.sleep(delay); + + // Kill any threads we have running. + nw.killWatch(); + + // free port used by adapter + adapter.freePort(); + } + catch (Exception e) + { + System.out.println(e); + } + + return; + } + + //-------- + //-------- Variables + //-------- + + /** Network Monitor instance */ + private DeviceMonitor dm; + + //-------- + //-------- Constructor + //-------- + + /** + * Create a 1-Wire Network Watcher + * + * @param adapter for 1-Wire Network to monitor + */ + public OWWatch (DSPortAdapter adapter) + { + // create a network monitor + dm = new DeviceMonitor(adapter); + + // add this to the event listers + try + { + dm.addDeviceMonitorEventListener(this); + } + catch (Exception e){} + + // start the monitor + Thread t = new Thread(dm); + t.start(); + } + + /** + * + */ + public void killWatch() + { + // Kill the OneWireMonitor thread. + dm.killMonitor(); + } + + /** + * Arrival event as a NetworkMonitorEventListener + * + * @param owme DeviceMonitorEvent add + */ + public void deviceArrival (DeviceMonitorEvent devt) + { + for(int i=0; i. + +package com.unicenta.pos.admin; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.IKeyed; +import com.unicenta.data.loader.SerializableRead; + +/** + * + * @author adrianromero + * Created on 27 de febrero de 2007, 23:27 + * + */ +public class PeopleInfo implements SerializableRead, IKeyed { + + private static final long serialVersionUID = 9110127845966L; + private String m_sID; + + /** + * + */ + protected String m_sName; + + /** Creates a new instance of PeopleInfo */ + public PeopleInfo() { + m_sID = null; + m_sName = null; + } + + /** + * + * @return + */ + @Override + public Object getKey() { + return m_sID; + } + + + /** + * + * @param dr + * @throws BasicException + */ + @Override + public void readValues(DataRead dr) throws BasicException { + m_sID = dr.getString(1); + m_sName = dr.getString(2); + } + + + /** + * + * @return + */ + public String getID() { + return m_sID; + } + public void setID(String sID) { + m_sID = sID; + } + + /** + * + * @return + */ + public String getName() { + return m_sName; + } + + /** + * + * @param sValue + */ + public void setName(String sValue) { + m_sName = sValue; + } + + @Override + public String toString() { + return m_sName; + } +} diff --git a/src/main/java/com/unicenta/pos/admin/PeoplePanel.java b/src/main/java/com/unicenta/pos/admin/PeoplePanel.java new file mode 100644 index 0000000..d1fbb85 --- /dev/null +++ b/src/main/java/com/unicenta/pos/admin/PeoplePanel.java @@ -0,0 +1,131 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.admin; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ListCellRendererBasic; +import com.unicenta.data.loader.ComparatorCreator; +import com.unicenta.data.loader.TableDefinition; +import com.unicenta.data.loader.Vectorer; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.panels.JPanelTable; +import javax.swing.ListCellRenderer; + +/** + * + * @author adrianromero + */ +public class PeoplePanel extends JPanelTable { + + private TableDefinition tpeople; + private PeopleView jeditor; + + /** Creates a new instance of JPanelPeople */ + public PeoplePanel() { + } + + /** + * + */ + @Override + protected void init() { + DataLogicAdmin dlAdmin = (DataLogicAdmin) app.getBean("com.unicenta.pos.admin.DataLogicAdmin"); + tpeople = dlAdmin.getTablePeople(); + jeditor = new PeopleView(dlAdmin, dirty); + } + + /** + * + * @return + */ + @Override + public ListProvider getListProvider() { + return new ListProviderCreator(tpeople); + } + + /** + * + * @return + */ + @Override + public SaveProvider getSaveProvider() { + return new SaveProvider(tpeople); + } + + /** + * + * @return + */ + @Override + public Vectorer getVectorer() { + return tpeople.getVectorerBasic(new int[]{1}); + } + + /** + * + * @return + */ + @Override + public ComparatorCreator getComparatorCreator() { + return tpeople.getComparatorCreator(new int[] {1, 3}); + } + + /** + * + * @return + */ + @Override + public ListCellRenderer getListCellRenderer() { + return new ListCellRendererBasic(tpeople.getRenderStringBasic(new int[]{1})); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return jeditor; + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + + jeditor.activate(); // primero el editor + super.activate(); // y luego cargamos los datos + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.Users"); + } +} diff --git a/src/main/java/com/unicenta/pos/admin/PeopleRenderer.java b/src/main/java/com/unicenta/pos/admin/PeopleRenderer.java new file mode 100644 index 0000000..a0115a9 --- /dev/null +++ b/src/main/java/com/unicenta/pos/admin/PeopleRenderer.java @@ -0,0 +1,49 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.admin; + +import java.awt.Component; +import javax.swing.DefaultListCellRenderer; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JList; + +/** + * + * @author JG uniCenta + */ +public class PeopleRenderer extends DefaultListCellRenderer { + + private final Icon icopeople; + + /** Creates a new instance of PeopleRenderer */ + public PeopleRenderer() { + + icopeople = new ImageIcon(getClass().getClassLoader().getResource("com/unicenta/images/user_sml.png")); + } + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, null, index, isSelected, cellHasFocus); + setText(value.toString()); + setIcon(icopeople); + return this; + } +} diff --git a/src/main/java/com/unicenta/pos/admin/PeopleView.form b/src/main/java/com/unicenta/pos/admin/PeopleView.form new file mode 100644 index 0000000..dbc2f17 --- /dev/null +++ b/src/main/java/com/unicenta/pos/admin/PeopleView.form @@ -0,0 +1,289 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/pos/admin/PeopleView.java b/src/main/java/com/unicenta/pos/admin/PeopleView.java new file mode 100644 index 0000000..3053bee --- /dev/null +++ b/src/main/java/com/unicenta/pos/admin/PeopleView.java @@ -0,0 +1,467 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.admin; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.user.*; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.util.Hashcypher; +import com.unicenta.pos.util.StringUtils; +import com.unicenta.pos.util.uOWWatch; +import java.awt.Component; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.awt.image.BufferedImage; +import java.util.UUID; +import javax.swing.*; + +/** + * + * @author adrianromero + */ +public class PeopleView extends JPanel implements EditorRecord { + + private Object m_oId; + private String m_sPassword; + + private final DirtyManager m_Dirty; + + private final SentenceList m_sentrole; + private ComboBoxValModel m_RoleModel; + + private final ComboBoxValModel m_ReasonModel; + + /** Creates new form PeopleEditor + * @param dlAdmin + * @param dirty */ + public PeopleView(DataLogicAdmin dlAdmin, DirtyManager dirty) { + + initComponents(); + + // El modelo de roles + m_sentrole = dlAdmin.getRolesList(); + m_RoleModel = new ComboBoxValModel(); + + m_Dirty = dirty; + m_jName.getDocument().addDocumentListener(dirty); + m_jRole.addActionListener(dirty); + m_jVisible.addActionListener(dirty); + m_jImage.addPropertyChangeListener("image", dirty); + m_jcard.getDocument().addDocumentListener(dirty); + + m_ReasonModel = new ComboBoxValModel(); + m_ReasonModel.add(AppLocal.getIntString("cboption.generate")); + m_ReasonModel.add(AppLocal.getIntString("cboption.clear")); + m_ReasonModel.add(AppLocal.getIntString("cboption.iButton")); + + webCBSecurity.setModel(m_ReasonModel); + + writeValueEOF(); + } + + /** + * + */ + @Override + public void writeValueEOF() { + m_oId = null; + m_jName.setText(null); + m_sPassword = null; + m_RoleModel.setSelectedKey(null); + m_jVisible.setSelected(false); + m_jcard.setText(null); + m_jImage.setImage(null); + m_jName.setEnabled(false); + m_jRole.setEnabled(false); + m_jVisible.setEnabled(false); + m_jcard.setEnabled(false); + m_jImage.setEnabled(false); + jButton1.setEnabled(false); + webCBSecurity.setEnabled(false); + } + + /** + * + */ + @Override + public void writeValueInsert() { + m_oId = null; + m_jName.setText(null); + m_sPassword = null; + m_RoleModel.setSelectedKey(null); + m_jVisible.setSelected(true); + m_jcard.setText(null); + m_jImage.setImage(null); + m_jName.setEnabled(true); + m_jRole.setEnabled(true); + m_jVisible.setEnabled(true); + m_jcard.setEnabled(true); + m_jImage.setEnabled(true); + jButton1.setEnabled(true); + webCBSecurity.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueDelete(Object value) { + Object[] people = (Object[]) value; + m_oId = people[0]; + m_jName.setText(Formats.STRING.formatValue(people[1])); + m_sPassword = Formats.STRING.formatValue(people[2]); + m_RoleModel.setSelectedKey(people[3]); + m_jVisible.setSelected(((Boolean) people[4]).booleanValue()); + m_jcard.setText(Formats.STRING.formatValue(people[5])); + m_jImage.setImage((BufferedImage) people[6]); + + m_jName.setEnabled(false); + m_jRole.setEnabled(false); + m_jVisible.setEnabled(false); + m_jcard.setEnabled(false); + m_jImage.setEnabled(false); + jButton1.setEnabled(false); + webCBSecurity.setEnabled(false); + } + + /** + * + * @param value + */ + @Override + public void writeValueEdit(Object value) { + Object[] people = (Object[]) value; + m_oId = people[0]; + m_jName.setText(Formats.STRING.formatValue(people[1])); + m_sPassword = Formats.STRING.formatValue(people[2]); + m_RoleModel.setSelectedKey(people[3]); + m_jVisible.setSelected(((Boolean) people[4]).booleanValue()); + m_jcard.setText(Formats.STRING.formatValue(people[5])); + m_jImage.setImage((BufferedImage) people[6]); + + if (m_jcard.getText().length() == 16) { + jLblCardID.setText(AppLocal.getIntString("label.ibutton")); + } else { + jLblCardID.setText(AppLocal.getIntString("label.card")); + } + System.out.println(m_jcard.getText().length()); + + m_jName.setEnabled(true); + m_jRole.setEnabled(true); + m_jVisible.setEnabled(true); + m_jcard.setEnabled(true); + m_jImage.setEnabled(true); + jButton1.setEnabled(true); + webCBSecurity.setEnabled(true); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + Object[] people = new Object[7]; + people[0] = m_oId == null ? UUID.randomUUID().toString() : m_oId; + people[1] = Formats.STRING.parseValue(m_jName.getText()); + people[2] = Formats.STRING.parseValue(m_sPassword); + people[3] = m_RoleModel.getSelectedKey(); + people[4] = m_jVisible.isSelected(); + people[5] = Formats.STRING.parseValue(m_jcard.getText()); + people[6] = m_jImage.getImage(); + return people; + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @throws BasicException + */ + public void activate() throws BasicException { + + m_RoleModel = new ComboBoxValModel(m_sentrole.list()); + m_jRole.setModel(m_RoleModel); + } + + + /** + * + */ + @Override + public void refresh() { + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jLabel1 = new javax.swing.JLabel(); + m_jName = new javax.swing.JTextField(); + m_jVisible = new javax.swing.JCheckBox(); + jLabel3 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + m_jImage = new com.unicenta.data.gui.JImageEditor(); + jButton1 = new javax.swing.JButton(); + m_jRole = new javax.swing.JComboBox(); + jLabel2 = new javax.swing.JLabel(); + m_jcard = new javax.swing.JTextField(); + jLblCardID = new javax.swing.JLabel(); + webCBSecurity = new com.alee.laf.combobox.WebComboBox(); + jLabel6 = new javax.swing.JLabel(); + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setPreferredSize(new java.awt.Dimension(500, 500)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/info.png"))); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.peoplenamem")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(110, 30)); + jLabel1.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + jLabel1MouseClicked(evt); + } + }); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(0, 30)); + + m_jVisible.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jVisible.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.peoplevisible")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.peopleimage")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jImage.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jImage.setPreferredSize(new java.awt.Dimension(300, 250)); + + jButton1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jButton1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/password.png"))); // NOI18N + jButton1.setText(AppLocal.getIntString("button.peoplepassword")); // NOI18N + jButton1.setToolTipText(""); + jButton1.setPreferredSize(new java.awt.Dimension(80, 45)); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + + m_jRole.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jRole.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.rolem")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jcard.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jcard.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLblCardID.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblCardID.setText(AppLocal.getIntString("label.card")); // NOI18N + jLblCardID.setPreferredSize(new java.awt.Dimension(110, 30)); + + webCBSecurity.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Generate new key", "Delete exisitng key", "Use iButton ID" })); + webCBSecurity.setSelectedIndex(0); + webCBSecurity.setToolTipText(AppLocal.getIntString("tooltip.peoplesecurity")); // NOI18N + webCBSecurity.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + webCBSecurity.setPreferredSize(new java.awt.Dimension(140, 45)); + webCBSecurity.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + webCBSecurityActionPerformed(evt); + } + }); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setText(AppLocal.getIntString("label.Password")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(110, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(m_jVisible, javax.swing.GroupLayout.PREFERRED_SIZE, 207, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jRole, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jImage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLblCardID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jcard, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(webCBSecurity, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(18, 18, 18) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLblCardID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jcard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(webCBSecurity, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jRole, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jVisible, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(15, 15, 15) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jImage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + + String sNewPassword = Hashcypher.changePassword(this); + if (sNewPassword != null) { + m_sPassword = sNewPassword; + m_Dirty.setDirty(true); + } + + }//GEN-LAST:event_jButton1ActionPerformed + + private void webCBSecurityActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_webCBSecurityActionPerformed + + + if(webCBSecurity.getSelectedIndex() == 0){ + if (JOptionPane.showConfirmDialog(this, + AppLocal.getIntString("message.cardnew"), + AppLocal.getIntString("title.editor"), + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) + { + m_jcard.setText("C" + StringUtils.getCardNumber()); + m_Dirty.setDirty(true); + } + } + + if(webCBSecurity.getSelectedIndex() == 1){ + if (JOptionPane.showConfirmDialog(this, + AppLocal.getIntString("message.cardremove"), + AppLocal.getIntString("title.editor"), + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) + { + m_jcard.setText(null); + m_Dirty.setDirty(true); + } + } + + if(webCBSecurity.getSelectedIndex() == 2){ + if (JOptionPane.showConfirmDialog(this, + AppLocal.getIntString("message.ibuttonassign"), + AppLocal.getIntString("title.editor"), + JOptionPane.OK_CANCEL_OPTION, + JOptionPane.INFORMATION_MESSAGE) == JOptionPane.OK_OPTION) + + { + m_jcard.setText( uOWWatch.getibuttonid() ); + jLblCardID.setText(AppLocal.getIntString("label.ibutton")); + m_Dirty.setDirty(true); + } + + } + + }//GEN-LAST:event_webCBSecurityActionPerformed + + private void jLabel1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabel1MouseClicked + if (evt.getClickCount() == 2) { + String uuidString = m_oId.toString(); + StringSelection stringSelection = new StringSelection(uuidString); + Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard(); + clpbrd.setContents(stringSelection, null); + + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.uuidcopy")); + } + }//GEN-LAST:event_jLabel1MouseClicked + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLblCardID; + private com.unicenta.data.gui.JImageEditor m_jImage; + private javax.swing.JTextField m_jName; + private javax.swing.JComboBox m_jRole; + private javax.swing.JCheckBox m_jVisible; + private javax.swing.JTextField m_jcard; + private com.alee.laf.combobox.WebComboBox webCBSecurity; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/admin/ResourceType.java b/src/main/java/com/unicenta/pos/admin/ResourceType.java new file mode 100644 index 0000000..2b7ad37 --- /dev/null +++ b/src/main/java/com/unicenta/pos/admin/ResourceType.java @@ -0,0 +1,39 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.admin; + +import com.unicenta.pos.panels.ComboItemLocal; + +/** + * + * @author adrianromero + * Created on February 12, 2007, 11:50 PM + * + */ +public class ResourceType extends ComboItemLocal { + + public static final ResourceType TEXT = new ResourceType(0, "resource.text"); + public static final ResourceType IMAGE = new ResourceType(1, "resource.image"); + public static final ResourceType BINARY = new ResourceType(2, "resource.binary"); + + private ResourceType(Integer iKey, String sKeyValue) { + super(iKey, sKeyValue); + } +} diff --git a/src/main/java/com/unicenta/pos/admin/ResourcesPanel.java b/src/main/java/com/unicenta/pos/admin/ResourcesPanel.java new file mode 100644 index 0000000..2ba4336 --- /dev/null +++ b/src/main/java/com/unicenta/pos/admin/ResourcesPanel.java @@ -0,0 +1,130 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.admin; + +import com.unicenta.data.gui.ListCellRendererBasic; +import com.unicenta.data.loader.ComparatorCreator; +import com.unicenta.data.loader.TableDefinition; +import com.unicenta.data.loader.Vectorer; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSystem; +import com.unicenta.pos.panels.JPanelTable; +import javax.swing.ListCellRenderer; + +/** + * + * @author adrianromero + */ +public class ResourcesPanel extends JPanelTable { + + private TableDefinition tresources; + private ResourcesView jeditor; + + /** Creates a new instance of JPanelResources */ + public ResourcesPanel() { + } + + /** + * + */ + protected void init() { + DataLogicAdmin dlAdmin = (DataLogicAdmin) app.getBean("com.unicenta.pos.admin.DataLogicAdmin"); + tresources = dlAdmin.getTableResources(); + jeditor = new ResourcesView(dirty); + } + + /** + * + * @return + */ + @Override + public boolean deactivate() { + if (super.deactivate()) { + DataLogicSystem dlSystem = (DataLogicSystem) app.getBean("com.unicenta.pos.forms.DataLogicSystem"); + dlSystem.resetResourcesCache(); + return true; + } else { + return false; + } + } + + /** + * + * @return + */ + public ListProvider getListProvider() { + return new ListProviderCreator(tresources); + } + + /** + * + * @return + */ + public SaveProvider getSaveProvider() { + return new SaveProvider(tresources); + } + + /** + * + * @return + */ + @Override + public Vectorer getVectorer() { + return tresources.getVectorerBasic(new int[] {1}); + } + + /** + * + * @return + */ + @Override + public ComparatorCreator getComparatorCreator() { + return tresources.getComparatorCreator(new int[] {1, 2}); + } + + /** + * + * @return + */ + @Override + public ListCellRenderer getListCellRenderer() { + return new ListCellRendererBasic(tresources.getRenderStringBasic(new int[] {1})); + } + + /** + * + * @return + */ + public EditorRecord getEditor() { + return jeditor; + } + + /** + * + * @return + */ + public String getTitle() { + return AppLocal.getIntString("Menu.Resources"); + } +} diff --git a/src/main/java/com/unicenta/pos/admin/ResourcesView.form b/src/main/java/com/unicenta/pos/admin/ResourcesView.form new file mode 100644 index 0000000..9ad8345 --- /dev/null +++ b/src/main/java/com/unicenta/pos/admin/ResourcesView.form @@ -0,0 +1,164 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/pos/admin/ResourcesView.java b/src/main/java/com/unicenta/pos/admin/ResourcesView.java new file mode 100644 index 0000000..827dbc8 --- /dev/null +++ b/src/main/java/com/unicenta/pos/admin/ResourcesView.java @@ -0,0 +1,377 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.admin; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.loader.ImageUtils; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.util.Base64Encoder; +import java.awt.CardLayout; +import java.awt.Component; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.UUID; +import javax.swing.JFileChooser; +import javax.swing.JPanel; + +/** + * + * @author adrianromero + */ +public final class ResourcesView extends JPanel implements EditorRecord { + + private Object m_oId; + private ComboBoxValModel m_ResourceModel; + + /** Creates new form ResourcesEditor + * @param dirty */ + public ResourcesView(DirtyManager dirty) { + initComponents(); + + m_ResourceModel = new ComboBoxValModel(); + m_ResourceModel.add(ResourceType.TEXT); + m_ResourceModel.add(ResourceType.IMAGE); + m_ResourceModel.add(ResourceType.BINARY); + m_jType.setModel(m_ResourceModel); + + m_jName.getDocument().addDocumentListener(dirty); + m_jType.addActionListener(dirty); + m_jText.getDocument().addDocumentListener(dirty); + m_jImage.addPropertyChangeListener("image", dirty); + + writeValueEOF(); + } + + /** + * + */ + @Override + public void writeValueEOF() { + m_oId = null; + m_jName.setText(null); + m_ResourceModel.setSelectedItem(null); + m_jText.setText(null); + m_jImage.setImage(null); + m_jName.setEnabled(false); + m_jType.setEnabled(false); + m_jText.setEnabled(false); + m_jImage.setEnabled(false); + m_jBtnReadScript.setEnabled(false); + } + + /** + * + */ + @Override + public void writeValueInsert() { + m_oId = null; + m_jName.setText(null); + m_ResourceModel.setSelectedItem(ResourceType.TEXT); + m_jText.setText(null); + m_jImage.setImage(null); + m_jName.setEnabled(true); + m_jType.setEnabled(true); + m_jText.setEnabled(true); + m_jImage.setEnabled(true); + m_jBtnReadScript.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueDelete(Object value) { + Object[] resource = (Object[]) value; + m_oId = resource[0]; + m_jName.setText((String) resource[1]); + m_ResourceModel.setSelectedKey(resource[2]); + + ResourceType restype = (ResourceType) m_ResourceModel.getSelectedItem(); + if (restype == ResourceType.TEXT) { + m_jText.setText(Formats.BYTEA.formatValue(resource[3])); + m_jText.setCaretPosition(0); + m_jImage.setImage(null); + } else if (restype == ResourceType.IMAGE) { + m_jText.setText(null); + m_jImage.setImage(ImageUtils.readImage((byte[]) resource[3])); + } else if (restype == ResourceType.BINARY) { + m_jText.setText(resource[3] == null + ? null + : Base64Encoder.encodeChunked((byte[]) resource[3])); + m_jText.setCaretPosition(0); + m_jImage.setImage(null); + } else { + m_jText.setText(null); + m_jImage.setImage(null); + } + m_jName.setEnabled(false); + m_jType.setEnabled(false); + m_jText.setEnabled(false); + m_jImage.setEnabled(false); + m_jBtnReadScript.setEnabled(false); + } + + /** + * + * @param value + */ + @Override + public void writeValueEdit(Object value) { + Object[] resource = (Object[]) value; + m_oId = resource[0]; + m_jName.setText((String) resource[1]); + m_ResourceModel.setSelectedKey(resource[2]); + + ResourceType restype = (ResourceType) m_ResourceModel.getSelectedItem(); + if (restype == ResourceType.TEXT) { + m_jText.setText(Formats.BYTEA.formatValue(resource[3])); + m_jText.setCaretPosition(0); + m_jImage.setImage(null); + m_jBtnReadScript.setVisible(true); + } else if (restype == ResourceType.IMAGE) { + m_jText.setText(null); + m_jImage.setImage(ImageUtils.readImage((byte[]) resource[3])); + m_jBtnReadScript.setVisible(false); + } else if (restype == ResourceType.BINARY) { + m_jText.setText(resource[2] == null + ? null + : Base64Encoder.encodeChunked((byte[]) resource[3])); + m_jText.setCaretPosition(0); + m_jImage.setImage(null); + m_jBtnReadScript.setVisible(true); + } else { + m_jText.setText(null); + m_jImage.setImage(null); + m_jBtnReadScript.setVisible(true); + } + m_jName.setEnabled(true); + m_jType.setEnabled(true); + m_jText.setEnabled(true); + m_jImage.setEnabled(true); + m_jBtnReadScript.setEnabled(true); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + Object[] resource = new Object[4]; + + resource[0] = m_oId == null ? UUID.randomUUID().toString() : m_oId; + resource[1] = m_jName.getText(); + + ResourceType restype = (ResourceType) m_ResourceModel.getSelectedItem(); + resource[2] = restype.getKey(); + if (restype == ResourceType.TEXT) { + resource[3] = Formats.BYTEA.parseValue(m_jText.getText()); + } else if (restype == ResourceType.IMAGE) { + resource[3] = ImageUtils.writeImage(m_jImage.getImage()); + } else if (restype == ResourceType.BINARY) { + resource[3] = Base64Encoder.decode(m_jText.getText()); + } else { + resource[3] = null; + } + + return resource; + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + */ + @Override + public void refresh() { + } + + private void showView(String view) { + CardLayout cl = (CardLayout)(m_jContainer.getLayout()); + cl.show(m_jContainer, view); + } + + public static String readFileAsString(String fileName) { + JFileChooser chooser = new JFileChooser(); + chooser.showOpenDialog(null); + File f = chooser.getSelectedFile(); + String filename = f.getAbsolutePath(); + + String data = ""; + try { + data = new String(Files.readAllBytes(Paths.get(filename))); + } catch (IOException e) { + e.printStackTrace(); + } + return data; + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + m_jGroupType = new javax.swing.ButtonGroup(); + jPanel3 = new javax.swing.JPanel(); + m_jContainer = new javax.swing.JPanel(); + jScrollPane1 = new javax.swing.JScrollPane(); + m_jText = new javax.swing.JTextArea(); + jPanel1 = new javax.swing.JPanel(); + m_jImage = new com.unicenta.data.gui.JImageEditor(); + jLabel2 = new javax.swing.JLabel(); + m_jName = new javax.swing.JTextField(); + m_jType = new javax.swing.JComboBox(); + m_jBtnReadScript = new javax.swing.JButton(); + + jPanel3.setLayout(new java.awt.BorderLayout()); + + m_jContainer.setLayout(new java.awt.CardLayout()); + + m_jText.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jScrollPane1.setViewportView(m_jText); + + m_jContainer.add(jScrollPane1, "text"); + m_jContainer.add(jPanel1, "null"); + m_jContainer.add(m_jImage, "image"); + + jPanel3.add(m_jContainer, java.awt.BorderLayout.CENTER); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.resname")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(0, 30)); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(0, 30)); + + m_jType.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jType.setPreferredSize(new java.awt.Dimension(150, 30)); + m_jType.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jTypeActionPerformed(evt); + } + }); + + m_jBtnReadScript.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + m_jBtnReadScript.setText(bundle.getString("button.readscript")); // NOI18N + m_jBtnReadScript.setPreferredSize(new java.awt.Dimension(80, 30)); + m_jBtnReadScript.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jBtnReadScriptActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, 549, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(m_jBtnReadScript, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jBtnReadScript, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, 328, Short.MAX_VALUE) + .addContainerGap()) + ); + }// //GEN-END:initComponents + + private void m_jTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jTypeActionPerformed + + ResourceType restype = (ResourceType) m_ResourceModel.getSelectedItem(); + if (restype == ResourceType.TEXT) { + showView("text"); + m_jBtnReadScript.setVisible(true); + } else if (restype == ResourceType.IMAGE) { + showView("image"); + m_jBtnReadScript.setVisible(false); + } else if (restype == ResourceType.BINARY) { + showView("text"); + m_jBtnReadScript.setVisible(true); + } else { + showView("null"); + m_jBtnReadScript.setVisible(true); + } + + }//GEN-LAST:event_m_jTypeActionPerformed + + private void m_jBtnReadScriptActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jBtnReadScriptActionPerformed + String filename=""; + String data = readFileAsString(filename); + if (data != null) { + m_jText.setText(data); + } + }//GEN-LAST:event_m_jBtnReadScriptActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel2; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel3; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JButton m_jBtnReadScript; + private javax.swing.JPanel m_jContainer; + private javax.swing.ButtonGroup m_jGroupType; + private com.unicenta.data.gui.JImageEditor m_jImage; + private javax.swing.JTextField m_jName; + private javax.swing.JTextArea m_jText; + private javax.swing.JComboBox m_jType; + // End of variables declaration//GEN-END:variables + + +} diff --git a/src/main/java/com/unicenta/pos/admin/RoleExtInfo.java b/src/main/java/com/unicenta/pos/admin/RoleExtInfo.java new file mode 100644 index 0000000..7d62d26 --- /dev/null +++ b/src/main/java/com/unicenta/pos/admin/RoleExtInfo.java @@ -0,0 +1,80 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.admin; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; + +/** + * + * @author adrianromero + * Created on 27 de febrero de 2007, 23:46 + * + */ +public class RoleExtInfo extends RoleInfo { + + /** + * + */ + protected byte[] m_aPermissions; + + /** Creates a new instance of RoleExtInfo */ + public RoleExtInfo() { + super(); + m_aPermissions = null; + } + + /** + * + * @param dr + * @throws BasicException + */ + @Override + public void readValues(DataRead dr) throws BasicException { + m_sName = dr.getString(1); + m_aPermissions = dr.getBytes(2); + } + + // implements Vectorer, ComparatorCreator + + /** + * + * @return + */ + public static String[] getHeaders() { + return new String[] {"Name"}; + } + + /** + * + * @return + */ + public String[] toStringArray() { + return new String[] {m_sName}; + } + + /** + * + * @return + */ + public Comparable[] toComparableArray() { + return new Comparable[] {m_sName}; + } +} diff --git a/src/main/java/com/unicenta/pos/admin/RoleInfo.java b/src/main/java/com/unicenta/pos/admin/RoleInfo.java new file mode 100644 index 0000000..d63d849 --- /dev/null +++ b/src/main/java/com/unicenta/pos/admin/RoleInfo.java @@ -0,0 +1,105 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.admin; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.IKeyed; +import com.unicenta.data.loader.SerializableRead; + +/** + * + * @author adrianromero + * Created on 27 de febrero de 2007, 23:27 + * + */ +public class RoleInfo implements SerializableRead, IKeyed { + + private static final long serialVersionUID = 9110127845966L; + private String m_sID; + + /** + * + */ + protected String m_sName; + + /** Creates a new instance of RoleInfo */ + public RoleInfo() { + m_sID = null; + m_sName = null; + } + + /** + * + * @return + */ + @Override + public Object getKey() { + return m_sID; + } + + /** + * + * @param dr + * @throws BasicException + */ + @Override + public void readValues(DataRead dr) throws BasicException { + m_sID = dr.getString(1); + m_sName = dr.getString(2); + } + + /** + * + * @param sID + */ + public void setID(String sID) { + m_sID = sID; + } + + /** + * + * @return + */ + public String getID() { + return m_sID; + } + + /** + * + * @return + */ + public String getName() { + return m_sName; + } + + /** + * + * @param sValue + */ + public void setName(String sValue) { + m_sName = sValue; + } + + @Override + public String toString() { + return m_sName; + } +} diff --git a/src/main/java/com/unicenta/pos/admin/RolesPanel.java b/src/main/java/com/unicenta/pos/admin/RolesPanel.java new file mode 100644 index 0000000..923a37f --- /dev/null +++ b/src/main/java/com/unicenta/pos/admin/RolesPanel.java @@ -0,0 +1,121 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.admin; + +import com.unicenta.data.gui.ListCellRendererBasic; +import com.unicenta.data.loader.ComparatorCreator; +import com.unicenta.data.loader.TableDefinition; +import com.unicenta.data.loader.Vectorer; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.panels.JPanelTable; +import javax.swing.ListCellRenderer; + +/** + * + * @author adrianromero + */ +public class RolesPanel extends JPanelTable { + + private TableDefinition troles; + private TableDefinition trolesmenu; + private RolesView jeditor; + + + /** Creates a new instance of RolesPanel */ + public RolesPanel() { + } + + /** + * + */ + @Override + protected void init() { + DataLogicAdmin dlAdmin = (DataLogicAdmin) app.getBean("com.unicenta.pos.admin.DataLogicAdmin"); + troles = dlAdmin.getTableRoles(); + jeditor = new RolesView(dirty); + } + + /** + * + * @return + */ + @Override + public ListProvider getListProvider() { + return new ListProviderCreator(troles); + } + + /** + * + * @return + */ + @Override + public SaveProvider getSaveProvider() { + return new SaveProvider(troles); + } + + /** + * + * @return + */ + @Override + public Vectorer getVectorer() { + return troles.getVectorerBasic(new int[] {1}); + } + + /** + * + * @return + */ + @Override + public ComparatorCreator getComparatorCreator() { + return troles.getComparatorCreator(new int[] {1}); + } + + /** + * + * @return + */ + @Override + public ListCellRenderer getListCellRenderer() { + return new ListCellRendererBasic(troles.getRenderStringBasic(new int[] {1})); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return jeditor; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.Roles"); + } +} diff --git a/src/main/java/com/unicenta/pos/admin/RolesView.java b/src/main/java/com/unicenta/pos/admin/RolesView.java new file mode 100644 index 0000000..783c875 --- /dev/null +++ b/src/main/java/com/unicenta/pos/admin/RolesView.java @@ -0,0 +1,192 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.admin; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import java.awt.Component; +import java.util.UUID; + +/** + * + * @author adrianromero + */ +public final class RolesView extends javax.swing.JPanel implements EditorRecord { + + private Object m_oId; + + /** Creates new form RolesEditor + * @param dirty */ + public RolesView(DirtyManager dirty) { + initComponents(); + + m_jName.getDocument().addDocumentListener(dirty); + m_jText.getDocument().addDocumentListener(dirty); + + writeValueEOF(); + } + + /** + * + */ + @Override + public void writeValueEOF() { + m_oId = null; + m_jName.setText(null); + m_jText.setText(null); + m_jName.setEnabled(false); + m_jText.setEnabled(false); + } + + /** + * + */ + @Override + public void writeValueInsert() { + m_oId = null; + m_jName.setText(null); + m_jText.setText(null); + m_jName.setEnabled(true); + m_jText.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueDelete(Object value) { + + Object[] role = (Object[]) value; + m_oId = role[0]; + m_jName.setText(Formats.STRING.formatValue(role[1])); + m_jText.setText(Formats.BYTEA.formatValue(role[2])); + m_jText.setCaretPosition(0); + m_jName.setEnabled(false); + m_jText.setEnabled(false); + } + + /** + * + * @param value + */ + @Override + public void writeValueEdit(Object value) { + + Object[] role = (Object[]) value; + m_oId = role[0]; + m_jName.setText(Formats.STRING.formatValue(role[1])); + m_jText.setText(Formats.BYTEA.formatValue(role[2])); + m_jText.setCaretPosition(0); + m_jName.setEnabled(true); + m_jText.setEnabled(true); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + Object[] role = new Object[3]; + role[0] = m_oId == null ? UUID.randomUUID().toString() : m_oId; + role[1] = m_jName.getText(); + role[2] = Formats.BYTEA.parseValue(m_jText.getText()); + return role; + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + */ + @Override + public void refresh() { + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jScrollPane1 = new javax.swing.JScrollPane(); + m_jText = new javax.swing.JTextArea(); + jLabel2 = new javax.swing.JLabel(); + m_jName = new javax.swing.JTextField(); + + m_jText.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jScrollPane1.setViewportView(m_jText); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.namem")); // NOI18N + + m_jName.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 477, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, 260, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 312, Short.MAX_VALUE) + .addContainerGap()) + ); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel2; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JTextField m_jName; + private javax.swing.JTextArea m_jText; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/catalog/CatalogSelector.java b/src/main/java/com/unicenta/pos/catalog/CatalogSelector.java new file mode 100644 index 0000000..757983f --- /dev/null +++ b/src/main/java/com/unicenta/pos/catalog/CatalogSelector.java @@ -0,0 +1,67 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.catalog; + +import com.unicenta.basic.BasicException; +import java.awt.Component; +import java.awt.event.ActionListener; + +/** + * + * @author adrianromero + */ +public interface CatalogSelector { + + /** + * + * @throws BasicException + */ + public void loadCatalog() throws BasicException; + + /** + * + * @param id + */ + public void showCatalogPanel(String id); + + /** + * + * @param value + */ + public void setComponentEnabled(boolean value); + + /** + * + * @return + */ + public Component getComponent(); + + /** + * + * @param l + */ + public void addActionListener(ActionListener l); + + /** + * + * @param l + */ + public void removeActionListener(ActionListener l); +} diff --git a/src/main/java/com/unicenta/pos/catalog/CategoryStock.java b/src/main/java/com/unicenta/pos/catalog/CategoryStock.java new file mode 100644 index 0000000..1b5e3cd --- /dev/null +++ b/src/main/java/com/unicenta/pos/catalog/CategoryStock.java @@ -0,0 +1,118 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.catalog; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.SerializerRead; + +/** + * + * @author JG uniCenta Dec 17 + * Used in Categories to display all this Categories Products + */ + +public class CategoryStock { + + String productId; + String productName; + String productCode; + String categoryId; + + /** + * Main method to return all customer's transactions + */ + public CategoryStock() { + } + + /** + * + * @param productId + * @param productName + * @param cId + */ + public CategoryStock(String productId, String productName, String productCode, String pId) { + this.productId = productId; + this.productName = productName; + this.productCode = productCode; + this.categoryId = pId; + } + + /** + * + * @return product string + */ + public String getProductId() { + return productId; + } + public void setProductId(String productId) { + this.productId = productId; + } + + /** + * + * @return product name string + */ + public String getProductName() { + return productName; + } + public void setProductName(String productName) { + this.productName = productName; + } + + /** + * + * @return product barcode string + */ + public String getProductCode() { + return productCode; + } + public void setProductCode(String productCode) { + this.productCode = productCode; + } + + /** + * + * @return category name string + */ + public String getCategoryId() { + return categoryId; + } + public void setCategoryId(String categoryId) { + this.categoryId = categoryId; + } + + /** + * + * @return products for this category + */ + public static SerializerRead getSerializerRead() { + return new SerializerRead() { + @Override + public Object readValues(DataRead dr) throws BasicException { + String productId = dr.getString(1); + String productName = dr.getString(2); + String productCode = dr.getString(3); + String categoryId = dr.getString(4); + return new CategoryStock(productId, productName, productCode, categoryId); + } + }; + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/catalog/JCatalog.form b/src/main/java/com/unicenta/pos/catalog/JCatalog.form new file mode 100644 index 0000000..d62c18e --- /dev/null +++ b/src/main/java/com/unicenta/pos/catalog/JCatalog.form @@ -0,0 +1,229 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/pos/catalog/JCatalog.java b/src/main/java/com/unicenta/pos/catalog/JCatalog.java new file mode 100644 index 0000000..caa2e75 --- /dev/null +++ b/src/main/java/com/unicenta/pos/catalog/JCatalog.java @@ -0,0 +1,622 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.catalog; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.JMessageDialog; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.sales.TaxesLogic; +import com.unicenta.pos.ticket.CategoryInfo; +import com.unicenta.pos.ticket.ProductInfoExt; +import com.unicenta.pos.ticket.TaxInfo; +import com.unicenta.pos.util.ThumbNailBuilder; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.*; +import javax.swing.*; +import javax.swing.event.EventListenerList; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +/** + * + * @author adrianromero + */ +public class JCatalog extends JPanel implements ListSelectionListener, CatalogSelector { + + /** + * + */ + protected EventListenerList listeners = new EventListenerList(); + private DataLogicSales m_dlSales; + private TaxesLogic taxeslogic; + + private boolean pricevisible; + private boolean taxesincluded; + + // Set of Products panels + private final Map m_productsset = new HashMap<>(); + + // Set of Categoriespanels + private final Set m_categoriesset = new HashSet<>(); + + private ThumbNailBuilder tnbbutton; + private ThumbNailBuilder tnbcat; + private ThumbNailBuilder tnbsubcat; + + private CategoryInfo showingcategory = null; + + /** Creates new form JCatalog + * @param dlSales */ + public JCatalog(DataLogicSales dlSales) { + this(dlSales, false, false, 90, 60); + } + + /** + * + * @param dlSales + * @param pricevisible + * @param taxesincluded + * @param width + * @param height + */ + public JCatalog(DataLogicSales dlSales, boolean pricevisible, + boolean taxesincluded, int width, int height) { + + m_dlSales = dlSales; + this.pricevisible = pricevisible; + this.taxesincluded = taxesincluded; + + initComponents(); + + m_jListCategories.addListSelectionListener(this); + + m_jscrollcat.getVerticalScrollBar().setPreferredSize(new Dimension(35, 35)); + + tnbcat = new ThumbNailBuilder(48, 48, "com/unicenta/images/category.png"); + tnbsubcat = new ThumbNailBuilder(width, height, "com/unicenta/images/subcategory.png"); + tnbbutton = new ThumbNailBuilder(width, height, "com/unicenta/images/null.png"); + + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @param id + */ + @Override + public void showCatalogPanel(String id) { + + if (id == null) { + showRootCategoriesPanel(); + } else { + showProductPanel(id); + } + } + + public Component getCatComponent() { + return m_jCategories; + } + + public Component getProductComponent() { + return m_jProducts; + } + + public boolean setControls(String position) { + if (position.equals("south")) { + m_jRootCategories.add(jPanel2, BorderLayout.SOUTH); + m_jSubCategories.add(jPanel1, BorderLayout.SOUTH); + ((GridLayout) jPanel3.getLayout()).setRows(1); + ((GridLayout) jPanel5.getLayout()).setRows(1); + return true; + } + return false; + } + + + /** + * + * @throws BasicException + */ + @Override + public void loadCatalog() throws BasicException { + + // delete all categories panel + m_jProducts.removeAll(); + + m_productsset.clear(); + m_categoriesset.clear(); + + showingcategory = null; + + // Load the taxes logic + taxeslogic = new TaxesLogic(m_dlSales.getTaxList().list()); + + // Load all categories. + java.util.List categories = m_dlSales.getRootCategories(); + + // Select the first category + m_jListCategories.setCellRenderer(new SmallCategoryRenderer()); + m_jListCategories.setModel(new CategoriesListModel(categories)); // aCatList + + if (m_jListCategories.getModel().getSize() == 0) { + m_jscrollcat.setVisible(false); + jPanel2.setVisible(false); + } else { + m_jscrollcat.setVisible(true); + jPanel2.setVisible(true); + m_jListCategories.setSelectedIndex(0); + } + + showRootCategoriesPanel(); + } + + /** + * + * @param value + */ + @Override + public void setComponentEnabled(boolean value) { + + m_jListCategories.setEnabled(value); + m_jscrollcat.setEnabled(value); + m_lblIndicator.setEnabled(value); + m_btnBack1.setEnabled(value); + m_jProducts.setEnabled(value); + + synchronized (m_jProducts.getTreeLock()) { + int compCount = m_jProducts.getComponentCount(); + for (int i = 0 ; i < compCount ; i++) { + m_jProducts.getComponent(i).setEnabled(value); + } + } + + this.setEnabled(value); + } + + /** + * + * @param l + */ + @Override + public void addActionListener(ActionListener l) { + listeners.add(ActionListener.class, l); + } + + /** + * + * @param l + */ + @Override + public void removeActionListener(ActionListener l) { + listeners.remove(ActionListener.class, l); + } + + @Override + public void valueChanged(ListSelectionEvent evt) { + + if (!evt.getValueIsAdjusting()) { + int i = m_jListCategories.getSelectedIndex(); + if (i >= 0) { + // Lo hago visible... + Rectangle oRect = m_jListCategories.getCellBounds(i, i); + m_jListCategories.scrollRectToVisible(oRect); + } + } + } + + /** + * + * @param prod + */ + protected void fireSelectedProduct(ProductInfoExt prod) { + EventListener[] l = listeners.getListeners(ActionListener.class); + ActionEvent e = null; + for (EventListener l1 : l) { + if (e == null) { + e = new ActionEvent(prod, ActionEvent.ACTION_PERFORMED, prod.getID()); + } + ((ActionListener) l1).actionPerformed(e); + } + } + + private void selectCategoryPanel(String catid) { + try { + if (!m_categoriesset.contains(catid)) { + + JCatalogTab jcurrTab = new JCatalogTab(); + jcurrTab.applyComponentOrientation(getComponentOrientation()); + m_jProducts.add(jcurrTab, catid); + m_categoriesset.add(catid); + + java.util.List categories = m_dlSales.getSubcategories(catid); + for (CategoryInfo cat : categories) { + + if (cat.getCatShowName()) { + jcurrTab.addButton(new ImageIcon(tnbsubcat.getThumbNailText + (cat.getImage(), cat.getName())), + new SelectedCategory(cat),cat.getTextTip()); + }else{ + jcurrTab.addButton(new ImageIcon( + tnbsubcat.getThumbNailText(cat.getImage(), "")), + new SelectedCategory(cat),cat.getTextTip()); + } + } + + java.util.List prods = m_dlSales.getProductConstant(); + for (ProductInfoExt prod : prods) { + jcurrTab.addButton( + new ImageIcon(tnbbutton.getThumbNailText(prod.getImage(), + getProductLabel(prod))), + new SelectedAction(prod), + prod.getTextTip()); + } + + java.util.List products = m_dlSales.getProductCatalog(catid); + + for (ProductInfoExt prod : products) { + jcurrTab.addButton( + new ImageIcon(tnbbutton.getThumbNailText(prod.getImage(), + getProductLabel(prod))), + new SelectedAction(prod),prod.getTextTip()); + } + } + + CardLayout cl = (CardLayout)(m_jProducts.getLayout()); + cl.show(m_jProducts, catid); + } catch (BasicException e) { + JMessageDialog.showMessage(this, new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.notactive"), e)); + } + } + + private String getProductLabel(ProductInfoExt product) { + + if (pricevisible) { + if (taxesincluded) { + TaxInfo tax = taxeslogic.getTaxInfo(product.getTaxCategoryID()); + if(!"".equals(product.getDisplay())){ + return "
" + product.getDisplay() + "
" + product.printPriceSellTax(tax); + } else { + return "
" + product.getName() + "
" + product.printPriceSellTax(tax); + } + } else { + if(!"".equals(product.getDisplay())){ + return "
" + product.getDisplay() + "
" + product.printPriceSell(); + } else { + return "
" + product.getName() + "
" + product.printPriceSell(); + } + } + } else { + + if (!"".equals(product.getDisplay())) { + return product.getDisplay(); + } else { + return product.getName(); + } + } + } + + private void selectIndicatorPanel(Icon icon, String label, String texttip) { + + m_lblIndicator.setText(label); + m_lblIndicator.setIcon(icon); + + // Show subcategories panel + CardLayout cl = (CardLayout)(m_jCategories.getLayout()); + cl.show(m_jCategories, "subcategories"); + } + + private void selectIndicatorCategories() { + // Show root categories panel + CardLayout cl = (CardLayout)(m_jCategories.getLayout()); + cl.show(m_jCategories, "rootcategories"); + } + + private void showRootCategoriesPanel() { + + selectIndicatorCategories(); + // Show selected root category + CategoryInfo cat = (CategoryInfo) m_jListCategories.getSelectedValue(); + + if (cat != null) { + selectCategoryPanel(cat.getID()); + } + showingcategory = null; + } + + private void showSubcategoryPanel(CategoryInfo category) { +// Modified JDL 13.04.13 +// this is the new panel that displays when a sub catergory is selected mouse does not work here + selectIndicatorPanel(new ImageIcon(tnbsubcat.getThumbNail( + category.getImage())),category.getName(), category.getTextTip()); + selectCategoryPanel(category.getID()); + showingcategory = category; + } + + private void showProductPanel(String id) { + + ProductInfoExt product = m_productsset.get(id); + + if (product == null) { + if (m_productsset.containsKey(id)) { + // It is an empty panel + if (showingcategory == null) { + showRootCategoriesPanel(); + } else { + showSubcategoryPanel(showingcategory); + } + } else { + try { + // Create products panel + java.util.List products = m_dlSales.getProductComments(id); + + if (products.isEmpty()) { + m_productsset.put(id, null); + + if (showingcategory == null) { + showRootCategoriesPanel(); + } else { + showSubcategoryPanel(showingcategory); + } + } else { + + product = m_dlSales.getProductInfo(id); + m_productsset.put(id, product); + + JCatalogTab jcurrTab = new JCatalogTab(); + jcurrTab.applyComponentOrientation(getComponentOrientation()); + m_jProducts.add(jcurrTab, "PRODUCT." + id); + + // Add products + for (ProductInfoExt prod : products) { + jcurrTab.addButton(new ImageIcon(tnbbutton.getThumbNailText(prod.getImage(), + getProductLabel(prod))), new SelectedAction(prod),prod.getTextTip()); + } + selectIndicatorPanel(new ImageIcon(tnbbutton.getThumbNail(product.getImage())), + product.getDisplay(), product.getTextTip()); + + CardLayout cl = (CardLayout)(m_jProducts.getLayout()); + cl.show(m_jProducts, "PRODUCT." + id); + } + } catch (BasicException eb) { + m_productsset.put(id, null); + if (showingcategory == null) { + showRootCategoriesPanel(); + } else { + showSubcategoryPanel(showingcategory); + } + } + } + } else { + selectIndicatorPanel(new ImageIcon(tnbbutton.getThumbNail( + product.getImage())), product.getName(), product.getTextTip()); + + CardLayout cl = (CardLayout)(m_jProducts.getLayout()); + cl.show(m_jProducts, "PRODUCT." + id); + } + } + + private class SelectedAction implements ActionListener { + private final ProductInfoExt prod; + public SelectedAction(ProductInfoExt prod) { + this.prod = prod; + } + @Override + public void actionPerformed(ActionEvent e) { + fireSelectedProduct(prod); + } + } + + private class SelectedCategory implements ActionListener { + private final CategoryInfo category; + public SelectedCategory(CategoryInfo category) { + this.category = category; + } + @Override + public void actionPerformed(ActionEvent e) { + showSubcategoryPanel(category); + } + } + + private class CategoriesListModel extends AbstractListModel { + private final java.util.List m_aCategories; + public CategoriesListModel(java.util.List aCategories) { + m_aCategories = aCategories; + } + @Override + public int getSize() { + return m_aCategories.size(); + } + @Override + public Object getElementAt(int i) { + return m_aCategories.get(i); + } + } + + private class SmallCategoryRenderer extends DefaultListCellRenderer { + + @Override + public Component getListCellRendererComponent(JList list, Object value, + int index, boolean isSelected, boolean cellHasFocus) { + + super.getListCellRendererComponent(list, null, index, isSelected, cellHasFocus); + CategoryInfo cat = (CategoryInfo) value; + setText(cat.getName()); + setIcon(new ImageIcon(tnbcat.getThumbNail(cat.getImage()))); + + return this; + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + m_jCategories = new javax.swing.JPanel(); + m_jRootCategories = new javax.swing.JPanel(); + m_jscrollcat = new javax.swing.JScrollPane(); + m_jListCategories = new javax.swing.JList(); + jPanel2 = new javax.swing.JPanel(); + jPanel3 = new javax.swing.JPanel(); + m_jSubCategories = new javax.swing.JPanel(); + jPanel4 = new javax.swing.JPanel(); + m_lblIndicator = new javax.swing.JLabel(); + jPanel1 = new javax.swing.JPanel(); + jPanel5 = new javax.swing.JPanel(); + m_btnBack1 = new javax.swing.JButton(); + m_jProducts = new javax.swing.JPanel(); + + setLayout(new java.awt.BorderLayout()); + + m_jCategories.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jCategories.setMaximumSize(new java.awt.Dimension(275, 600)); + m_jCategories.setPreferredSize(new java.awt.Dimension(265, 0)); + m_jCategories.setLayout(new java.awt.CardLayout()); + + m_jRootCategories.setFont(new java.awt.Font("Arial", 0, 11)); // NOI18N + m_jRootCategories.setMinimumSize(new java.awt.Dimension(200, 100)); + m_jRootCategories.setPreferredSize(new java.awt.Dimension(275, 130)); + m_jRootCategories.setLayout(new java.awt.BorderLayout()); + + m_jscrollcat.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + m_jscrollcat.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + m_jscrollcat.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jscrollcat.setPreferredSize(new java.awt.Dimension(265, 130)); + + m_jListCategories.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jListCategories.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); + m_jListCategories.setFocusable(false); + m_jListCategories.addListSelectionListener(new javax.swing.event.ListSelectionListener() { + public void valueChanged(javax.swing.event.ListSelectionEvent evt) { + m_jListCategoriesValueChanged(evt); + } + }); + m_jscrollcat.setViewportView(m_jListCategories); + + m_jRootCategories.add(m_jscrollcat, java.awt.BorderLayout.CENTER); + + jPanel2.setLayout(new java.awt.BorderLayout()); + + jPanel3.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 5, 0, 5)); + jPanel3.setLayout(new java.awt.GridLayout(0, 1, 0, 5)); + jPanel2.add(jPanel3, java.awt.BorderLayout.NORTH); + + m_jRootCategories.add(jPanel2, java.awt.BorderLayout.LINE_END); + + m_jCategories.add(m_jRootCategories, "rootcategories"); + + m_jSubCategories.setLayout(new java.awt.BorderLayout()); + + jPanel4.setLayout(new java.awt.BorderLayout()); + + m_lblIndicator.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_lblIndicator.setText("jLabel1"); + jPanel4.add(m_lblIndicator, java.awt.BorderLayout.NORTH); + + m_jSubCategories.add(jPanel4, java.awt.BorderLayout.WEST); + + jPanel1.setLayout(new java.awt.BorderLayout()); + + jPanel5.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 5, 0, 5)); + jPanel5.setLayout(new java.awt.GridLayout(0, 1, 0, 5)); + + m_btnBack1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/2uparrow.png"))); // NOI18N + m_btnBack1.setFocusPainted(false); + m_btnBack1.setFocusable(false); + m_btnBack1.setMargin(new java.awt.Insets(8, 14, 8, 14)); + m_btnBack1.setPreferredSize(new java.awt.Dimension(60, 45)); + m_btnBack1.setRequestFocusEnabled(false); + m_btnBack1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_btnBack1ActionPerformed(evt); + } + }); + jPanel5.add(m_btnBack1); + + jPanel1.add(jPanel5, java.awt.BorderLayout.NORTH); + + m_jSubCategories.add(jPanel1, java.awt.BorderLayout.LINE_END); + + m_jCategories.add(m_jSubCategories, "subcategories"); + + add(m_jCategories, java.awt.BorderLayout.LINE_START); + + m_jProducts.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jProducts.setLayout(new java.awt.CardLayout()); + add(m_jProducts, java.awt.BorderLayout.CENTER); + }// //GEN-END:initComponents + + private void m_jListCategoriesValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_m_jListCategoriesValueChanged + + if (!evt.getValueIsAdjusting()) { + CategoryInfo cat = (CategoryInfo) m_jListCategories.getSelectedValue(); + if (cat != null) { + selectCategoryPanel(cat.getID()); + } + } + + }//GEN-LAST:event_m_jListCategoriesValueChanged + + private void m_btnBack1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_btnBack1ActionPerformed + + showRootCategoriesPanel(); + + }//GEN-LAST:event_m_btnBack1ActionPerformed + + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JButton m_btnBack1; + private javax.swing.JPanel m_jCategories; + private javax.swing.JList m_jListCategories; + private javax.swing.JPanel m_jProducts; + private javax.swing.JPanel m_jRootCategories; + private javax.swing.JPanel m_jSubCategories; + private javax.swing.JScrollPane m_jscrollcat; + private javax.swing.JLabel m_lblIndicator; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/catalog/JCatalogTab.form b/src/main/java/com/unicenta/pos/catalog/JCatalogTab.form new file mode 100644 index 0000000..5f7b79d --- /dev/null +++ b/src/main/java/com/unicenta/pos/catalog/JCatalogTab.form @@ -0,0 +1,22 @@ + + +
+ + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/pos/catalog/JCatalogTab.java b/src/main/java/com/unicenta/pos/catalog/JCatalogTab.java new file mode 100644 index 0000000..5882ed6 --- /dev/null +++ b/src/main/java/com/unicenta/pos/catalog/JCatalogTab.java @@ -0,0 +1,98 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.catalog; + +import com.unicenta.beans.JFlowPanel; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Insets; +import java.awt.event.ActionListener; +import javax.swing.*; + +/** + * + * @author adrianromero + */ +public class JCatalogTab extends javax.swing.JPanel { + + private JFlowPanel flowpanel; + + /** Creates new form JCategoryProducts */ + public JCatalogTab() { + initComponents(); + + flowpanel = new JFlowPanel(); + JScrollPane scroll = new JScrollPane(flowpanel); + scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + scroll.getVerticalScrollBar().setPreferredSize(new Dimension(35, 35)); + + add(scroll, BorderLayout.CENTER); + } + + @Override + public void setEnabled(boolean value) { + flowpanel.setEnabled(value); + super.setEnabled(value); + } + + /** + * + * @param ico + * @param al + * @param textTip + */ + public void addButton(Icon ico, ActionListener al, String textTip) { + JButton btn = new JButton(); + btn.applyComponentOrientation(getComponentOrientation()); + btn.setIcon(ico); + btn.setFocusPainted(false); + btn.setFocusable(false); + + if (textTip != null){ + btn.setToolTipText(textTip); + } + + btn.setRequestFocusEnabled(false); + btn.setHorizontalTextPosition(SwingConstants.CENTER); + btn.setVerticalTextPosition(SwingConstants.BOTTOM); + btn.setMargin(new Insets(2, 2, 2, 2)); + btn.addActionListener(al); + + flowpanel.add(btn); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setLayout(new java.awt.BorderLayout()); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/catalog/JProductsSelector.form b/src/main/java/com/unicenta/pos/catalog/JProductsSelector.form new file mode 100644 index 0000000..28175e5 --- /dev/null +++ b/src/main/java/com/unicenta/pos/catalog/JProductsSelector.form @@ -0,0 +1,44 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/pos/catalog/JProductsSelector.java b/src/main/java/com/unicenta/pos/catalog/JProductsSelector.java new file mode 100644 index 0000000..1aae710 --- /dev/null +++ b/src/main/java/com/unicenta/pos/catalog/JProductsSelector.java @@ -0,0 +1,95 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.catalog; + +import com.unicenta.beans.JFlowPanel; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Image; +import java.awt.Insets; +import java.awt.event.ActionListener; +import javax.swing.JButton; +import javax.swing.SwingConstants; + +/** + * + * @author adrianromero + */ +public class JProductsSelector extends javax.swing.JPanel { + + private final JFlowPanel flowpanel; + + /** Creates new form JProductsSelector */ + public JProductsSelector() { + initComponents(); + + flowpanel = new JFlowPanel(); + + add(flowpanel, BorderLayout.CENTER); + } + + + /** + * + * @param img + * @param display + * @param al + * @param textTip + */ + public void addProduct(Image img, String display, ActionListener al,String textTip) { + JButton btn = new JButton(); + btn.applyComponentOrientation(getComponentOrientation()); + btn.setText(display); + btn.setFocusPainted(false); + + if (textTip != null){ + btn.setToolTipText(textTip); + } + + btn.setFocusable(false); + btn.setRequestFocusEnabled(false); + btn.setHorizontalTextPosition(SwingConstants.CENTER); + btn.setVerticalTextPosition(SwingConstants.TOP); + btn.setMargin(new Insets(0, 0, 0, 0)); + btn.setMaximumSize(new Dimension(80, 70)); +// btn.setPreferredSize(new Dimension(20, 20)); + btn.setMinimumSize(new Dimension(40, 30)); + btn.addActionListener(al); + + flowpanel.add(btn); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setLayout(new org.jdesktop.swingx.VerticalLayout()); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/comm/CommStream.java b/src/main/java/com/unicenta/pos/comm/CommStream.java new file mode 100644 index 0000000..75b6fc7 --- /dev/null +++ b/src/main/java/com/unicenta/pos/comm/CommStream.java @@ -0,0 +1,123 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.comm; + +import gnu.io.CommPort; +import gnu.io.CommPortIdentifier; +import gnu.io.ParallelPort; +import gnu.io.SerialPort; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * + * @author adrianromero + */ +public class CommStream { + + private String m_sPort; + + private CommPortIdentifier m_PortIdPrinter; + private CommPort m_CommPortPrinter; + + private OutputStream m_out; + private InputStream m_in; + + /** Creates a new instance of CommPort + * @param port */ + public CommStream(String port) { + m_sPort = port; + + m_PortIdPrinter = null; + m_CommPortPrinter = null; + m_out = null; + m_in = null; + } + + private void init() { + + try { + if (m_out == null) { + m_PortIdPrinter = CommPortIdentifier.getPortIdentifier(m_sPort); // Tomamos el puerto + m_CommPortPrinter = m_PortIdPrinter.open("PORTID", 2000); // Abrimos el puerto + + m_out = m_CommPortPrinter.getOutputStream(); // Tomamos el chorro de escritura + + if (m_PortIdPrinter.getPortType() == CommPortIdentifier.PORT_SERIAL) { + ((SerialPort)m_CommPortPrinter).setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); // Configuramos el puerto + } else if (m_PortIdPrinter.getPortType() == CommPortIdentifier.PORT_PARALLEL) { + ((ParallelPort)m_CommPortPrinter).setMode(1); + } + } + } catch (Exception e) { + m_PortIdPrinter = null; + m_CommPortPrinter = null; + m_out = null; + m_in = null; +// } catch (NoSuchPortException e) { +// } catch (PortInUseException e) { +// } catch (UnsupportedCommOperationException e) { +// } catch (IOException e) { + } + } + + /** + * + * @throws IOException + */ + public void closeAll() throws IOException { + + if (m_out != null) { + m_in = null; + m_out.flush(); + m_out.close(); + m_out = null; + m_CommPortPrinter = null; + m_PortIdPrinter = null; + } + } + + /** + * + * @return + */ + public String getPort() { + return m_sPort; + } + + /** + * + * @return + */ + public InputStream getIn() { + init(); + return m_in; + } + + /** + * + * @return + */ + public OutputStream getOut() { + init(); + return m_out; + } +} diff --git a/src/main/java/com/unicenta/pos/config/JFrmConfig.form b/src/main/java/com/unicenta/pos/config/JFrmConfig.form new file mode 100644 index 0000000..8f7b4a2 --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JFrmConfig.form @@ -0,0 +1,31 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/pos/config/JFrmConfig.java b/src/main/java/com/unicenta/pos/config/JFrmConfig.java new file mode 100644 index 0000000..8d4c28a --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JFrmConfig.java @@ -0,0 +1,128 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.config; + +import com.alee.laf.WebLookAndFeel; +import com.unicenta.basic.BasicException; +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppProperties; +import com.unicenta.pos.forms.JRootFrame; +import java.awt.BorderLayout; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.IOException; +import javax.imageio.ImageIO; +import javax.swing.*; +import javax.swing.plaf.metal.MetalLookAndFeel; + +/** + * + * @author adrianromero + */ +public class JFrmConfig extends javax.swing.JFrame { + + private final JPanelConfiguration config; + + /** Creates new form JFrmConfig + * @param props */ + public JFrmConfig(AppProperties props) { + + initComponents(); + + try { + this.setIconImage(ImageIO.read(JRootFrame.class.getResourceAsStream("/com/unicenta/images/favicon.png"))); + } catch (IOException e) { + } + setTitle(AppLocal.APP_NAME + " - " + AppLocal.APP_VERSION + " - " + AppLocal.getIntString("Menu.Configuration")); + + addWindowListener(new MyFrameListener()); + + config = new JPanelConfiguration(props); + + getContentPane().add(config, BorderLayout.CENTER); + + try { + config.activate(); + } catch (BasicException e) { // never thrown ;-) + } + } + + private class MyFrameListener extends WindowAdapter{ + + @Override + public void windowClosing(WindowEvent evt) { + if (config.deactivate()) { + dispose(); + } + } + @Override + public void windowClosed(WindowEvent evt) { + System.exit(0); + } + } + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE); + setMinimumSize(new java.awt.Dimension(950, 450)); + setPreferredSize(new java.awt.Dimension(950, 500)); + + setSize(new java.awt.Dimension(808, 794)); + setLocationRelativeTo(null); + }// //GEN-END:initComponents + + /** + * @param args the command line arguments + */ + public static void main(final String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + + AppConfig config = new AppConfig(args); + config.load(); + + // Set the look and feel + try { + Object laf = Class.forName(config.getProperty("swing.defaultlaf")).newInstance(); + if (!(laf instanceof MetalLookAndFeel) && laf instanceof LookAndFeel) { + UIManager.setLookAndFeel((LookAndFeel) laf); + } else { + UIManager.setLookAndFeel("com.formdev.flatlaf.intellijthemes.FlatGrayIJTheme"); + } + } catch (Exception e) { + System.out.println("Cannot set Look and Feel "+e.getMessage()); + } + + new JFrmConfig(config).setVisible(true); + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/config/JPanelConfigCompany.form b/src/main/java/com/unicenta/pos/config/JPanelConfigCompany.form new file mode 100644 index 0000000..f01b04b --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JPanelConfigCompany.form @@ -0,0 +1,492 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/pos/config/JPanelConfigCompany.java b/src/main/java/com/unicenta/pos/config/JPanelConfigCompany.java new file mode 100644 index 0000000..3b8fe75 --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JPanelConfigCompany.java @@ -0,0 +1,425 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.config; + +import com.unicenta.data.user.DirtyManager; +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import java.awt.Component; +import javax.swing.ImageIcon; + +/** + * + * @author JG uniCenta + */ +public class JPanelConfigCompany extends javax.swing.JPanel implements PanelConfig { + + private final DirtyManager dirty = new DirtyManager(); + + + /** + * + */ + public JPanelConfigCompany() { + + initComponents(); + + jtxtTktHeader1.getDocument().addDocumentListener(dirty); + jtxtTktHeader2.getDocument().addDocumentListener(dirty); + jtxtTktHeader3.getDocument().addDocumentListener(dirty); + jtxtTktHeader4.getDocument().addDocumentListener(dirty); + jtxtTktHeader5.getDocument().addDocumentListener(dirty); + jtxtTktHeader6.getDocument().addDocumentListener(dirty); + + jtxtTktFooter1.getDocument().addDocumentListener(dirty); + jtxtTktFooter2.getDocument().addDocumentListener(dirty); + jtxtTktFooter3.getDocument().addDocumentListener(dirty); + jtxtTktFooter4.getDocument().addDocumentListener(dirty); + jtxtTktFooter5.getDocument().addDocumentListener(dirty); + jtxtTktFooter6.getDocument().addDocumentListener(dirty); + +// JG - For future + lblLogo.setVisible(false); + jLbllogoPath.setVisible(false); + webSwtch_Logo.setVisible(false); + + } + + /** + * + * @return + */ + @Override + public boolean hasChanged() { + return dirty.isDirty(); + } + + /** + * + * @return + */ + @Override + public Component getConfigComponent() { + return this; + } + + /** + * + * @param config + */ + @Override + public void loadProperties(AppConfig config) { + + jtxtTktHeader1.setText(config.getProperty("tkt.header1")); + jtxtTktHeader2.setText(config.getProperty("tkt.header2")); + jtxtTktHeader3.setText(config.getProperty("tkt.header3")); + jtxtTktHeader4.setText(config.getProperty("tkt.header4")); + jtxtTktHeader5.setText(config.getProperty("tkt.header5")); + jtxtTktHeader6.setText(config.getProperty("tkt.header6")); + + jtxtTktFooter1.setText(config.getProperty("tkt.footer1")); + jtxtTktFooter2.setText(config.getProperty("tkt.footer2")); + jtxtTktFooter3.setText(config.getProperty("tkt.footer3")); + jtxtTktFooter4.setText(config.getProperty("tkt.footer4")); + jtxtTktFooter5.setText(config.getProperty("tkt.footer5")); + jtxtTktFooter6.setText(config.getProperty("tkt.footer6")); + +/** JG - here for future per terminal + jLbllogoPath.setText(config.getProperty("tkt.logopath")); + ImageIcon image = new ImageIcon(jLbllogoPath.getText()); + jLogo.setIcon(image); +*/ + dirty.setDirty(false); + } + + /** + * + * @param config + */ + @Override + public void saveProperties(AppConfig config) { + + config.setProperty("tkt.header1", jtxtTktHeader1.getText()); + config.setProperty("tkt.header2", jtxtTktHeader2.getText()); + config.setProperty("tkt.header3", jtxtTktHeader3.getText()); + config.setProperty("tkt.header4", jtxtTktHeader4.getText()); + config.setProperty("tkt.header5", jtxtTktHeader5.getText()); + config.setProperty("tkt.header6", jtxtTktHeader6.getText()); + + config.setProperty("tkt.footer1", jtxtTktFooter1.getText()); + config.setProperty("tkt.footer2", jtxtTktFooter2.getText()); + config.setProperty("tkt.footer3", jtxtTktFooter3.getText()); + config.setProperty("tkt.footer4", jtxtTktFooter4.getText()); + config.setProperty("tkt.footer5", jtxtTktFooter5.getText()); + config.setProperty("tkt.footer6", jtxtTktFooter6.getText()); + + config.setProperty("tkt.logopath", jLbllogoPath.getText()); + + dirty.setDirty(false); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + lblTktHeader1 = new javax.swing.JLabel(); + lblTktFooter1 = new javax.swing.JLabel(); + webSwtch_Logo = new com.alee.extended.button.WebSwitch(); + jPanel1 = new javax.swing.JPanel(); + jtxtTktHeader3 = new javax.swing.JTextField(); + jtxtTktFooter6 = new javax.swing.JTextField(); + jtxtTktHeader2 = new javax.swing.JTextField(); + jtxtTktHeader5 = new javax.swing.JTextField(); + jtxtTktHeader6 = new javax.swing.JTextField(); + jtxtTktFooter4 = new javax.swing.JTextField(); + jtxtTktHeader4 = new javax.swing.JTextField(); + jtxtTktFooter5 = new javax.swing.JTextField(); + jtxtTktHeader1 = new javax.swing.JTextField(); + jtxtTktFooter3 = new javax.swing.JTextField(); + jtxtTktFooter2 = new javax.swing.JTextField(); + jtxtTktFooter1 = new javax.swing.JTextField(); + jLogo = new javax.swing.JLabel(); + jLbllogoPath = new javax.swing.JLabel(); + lblLogo = new javax.swing.JLabel(); + + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + setOpaque(false); + setPreferredSize(new java.awt.Dimension(700, 500)); + + lblTktHeader1.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + lblTktHeader1.setText(AppLocal.getIntString("label.tktheader1")); // NOI18N + lblTktHeader1.setMaximumSize(new java.awt.Dimension(0, 25)); + lblTktHeader1.setMinimumSize(new java.awt.Dimension(0, 0)); + lblTktHeader1.setPreferredSize(new java.awt.Dimension(150, 30)); + + lblTktFooter1.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + lblTktFooter1.setText(AppLocal.getIntString("label.tktfooter1")); // NOI18N + lblTktFooter1.setMaximumSize(new java.awt.Dimension(0, 25)); + lblTktFooter1.setMinimumSize(new java.awt.Dimension(0, 0)); + lblTktFooter1.setPreferredSize(new java.awt.Dimension(150, 30)); + + webSwtch_Logo.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + webSwtch_Logo.setPreferredSize(new java.awt.Dimension(80, 30)); + webSwtch_Logo.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + webSwtch_LogoActionPerformed(evt); + } + }); + + jtxtTktHeader3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtTktHeader3.setHorizontalAlignment(javax.swing.JTextField.CENTER); + jtxtTktHeader3.setBorder(null); + jtxtTktHeader3.setMaximumSize(new java.awt.Dimension(0, 25)); + jtxtTktHeader3.setMinimumSize(new java.awt.Dimension(0, 0)); + jtxtTktHeader3.setPreferredSize(new java.awt.Dimension(300, 30)); + + jtxtTktFooter6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtTktFooter6.setHorizontalAlignment(javax.swing.JTextField.CENTER); + jtxtTktFooter6.setBorder(null); + jtxtTktFooter6.setMaximumSize(new java.awt.Dimension(0, 25)); + jtxtTktFooter6.setMinimumSize(new java.awt.Dimension(0, 0)); + jtxtTktFooter6.setPreferredSize(new java.awt.Dimension(300, 30)); + + jtxtTktHeader2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtTktHeader2.setHorizontalAlignment(javax.swing.JTextField.CENTER); + jtxtTktHeader2.setBorder(null); + jtxtTktHeader2.setMaximumSize(new java.awt.Dimension(0, 25)); + jtxtTktHeader2.setMinimumSize(new java.awt.Dimension(0, 0)); + jtxtTktHeader2.setPreferredSize(new java.awt.Dimension(300, 30)); + + jtxtTktHeader5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtTktHeader5.setHorizontalAlignment(javax.swing.JTextField.CENTER); + jtxtTktHeader5.setBorder(null); + jtxtTktHeader5.setMaximumSize(new java.awt.Dimension(0, 25)); + jtxtTktHeader5.setMinimumSize(new java.awt.Dimension(0, 0)); + jtxtTktHeader5.setPreferredSize(new java.awt.Dimension(300, 30)); + + jtxtTktHeader6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtTktHeader6.setHorizontalAlignment(javax.swing.JTextField.CENTER); + jtxtTktHeader6.setBorder(null); + jtxtTktHeader6.setMaximumSize(new java.awt.Dimension(0, 25)); + jtxtTktHeader6.setMinimumSize(new java.awt.Dimension(0, 0)); + jtxtTktHeader6.setPreferredSize(new java.awt.Dimension(300, 30)); + + jtxtTktFooter4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtTktFooter4.setHorizontalAlignment(javax.swing.JTextField.CENTER); + jtxtTktFooter4.setBorder(null); + jtxtTktFooter4.setMaximumSize(new java.awt.Dimension(0, 25)); + jtxtTktFooter4.setMinimumSize(new java.awt.Dimension(0, 0)); + jtxtTktFooter4.setPreferredSize(new java.awt.Dimension(300, 30)); + + jtxtTktHeader4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtTktHeader4.setHorizontalAlignment(javax.swing.JTextField.CENTER); + jtxtTktHeader4.setBorder(null); + jtxtTktHeader4.setMaximumSize(new java.awt.Dimension(0, 25)); + jtxtTktHeader4.setMinimumSize(new java.awt.Dimension(0, 0)); + jtxtTktHeader4.setPreferredSize(new java.awt.Dimension(300, 30)); + + jtxtTktFooter5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtTktFooter5.setHorizontalAlignment(javax.swing.JTextField.CENTER); + jtxtTktFooter5.setBorder(null); + jtxtTktFooter5.setMaximumSize(new java.awt.Dimension(0, 25)); + jtxtTktFooter5.setMinimumSize(new java.awt.Dimension(0, 0)); + jtxtTktFooter5.setPreferredSize(new java.awt.Dimension(300, 30)); + + jtxtTktHeader1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtTktHeader1.setHorizontalAlignment(javax.swing.JTextField.CENTER); + jtxtTktHeader1.setBorder(null); + jtxtTktHeader1.setMaximumSize(new java.awt.Dimension(0, 25)); + jtxtTktHeader1.setMinimumSize(new java.awt.Dimension(0, 0)); + jtxtTktHeader1.setPreferredSize(new java.awt.Dimension(300, 30)); + + jtxtTktFooter3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtTktFooter3.setHorizontalAlignment(javax.swing.JTextField.CENTER); + jtxtTktFooter3.setBorder(null); + jtxtTktFooter3.setMaximumSize(new java.awt.Dimension(0, 25)); + jtxtTktFooter3.setMinimumSize(new java.awt.Dimension(0, 0)); + jtxtTktFooter3.setPreferredSize(new java.awt.Dimension(300, 30)); + + jtxtTktFooter2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtTktFooter2.setHorizontalAlignment(javax.swing.JTextField.CENTER); + jtxtTktFooter2.setBorder(null); + jtxtTktFooter2.setMaximumSize(new java.awt.Dimension(0, 25)); + jtxtTktFooter2.setMinimumSize(new java.awt.Dimension(0, 0)); + jtxtTktFooter2.setPreferredSize(new java.awt.Dimension(300, 30)); + + jtxtTktFooter1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtTktFooter1.setHorizontalAlignment(javax.swing.JTextField.CENTER); + jtxtTktFooter1.setBorder(null); + jtxtTktFooter1.setMaximumSize(new java.awt.Dimension(0, 25)); + jtxtTktFooter1.setMinimumSize(new java.awt.Dimension(0, 0)); + jtxtTktFooter1.setPreferredSize(new java.awt.Dimension(300, 30)); + + jLogo.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLogo.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLogo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/printer.ticket.logo.jpg"))); // NOI18N + jLogo.setToolTipText(""); + jLogo.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + jLogo.setOpaque(true); + jLogo.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jtxtTktFooter5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jtxtTktFooter4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jtxtTktFooter3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jtxtTktFooter2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jtxtTktFooter1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jtxtTktHeader6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jtxtTktHeader5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jtxtTktHeader4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jtxtTktHeader3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jtxtTktHeader2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jtxtTktHeader1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jtxtTktFooter6, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jLogo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLogo, javax.swing.GroupLayout.PREFERRED_SIZE, 91, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jtxtTktHeader1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(1, 1, 1) + .addComponent(jtxtTktHeader2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(1, 1, 1) + .addComponent(jtxtTktHeader3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(1, 1, 1) + .addComponent(jtxtTktHeader4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(1, 1, 1) + .addComponent(jtxtTktHeader5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(1, 1, 1) + .addComponent(jtxtTktHeader6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jtxtTktFooter1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(1, 1, 1) + .addComponent(jtxtTktFooter2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(1, 1, 1) + .addComponent(jtxtTktFooter3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(1, 1, 1) + .addComponent(jtxtTktFooter4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(1, 1, 1) + .addComponent(jtxtTktFooter5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(1, 1, 1) + .addComponent(jtxtTktFooter6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + + jLbllogoPath.setBackground(new java.awt.Color(255, 255, 255)); + jLbllogoPath.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLbllogoPath.setForeground(new java.awt.Color(153, 153, 153)); + jLbllogoPath.setText(AppLocal.getIntString("label.tktheader1")); // NOI18N + jLbllogoPath.setMaximumSize(new java.awt.Dimension(0, 25)); + jLbllogoPath.setMinimumSize(new java.awt.Dimension(0, 0)); + jLbllogoPath.setPreferredSize(new java.awt.Dimension(150, 30)); + + lblLogo.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + lblLogo.setText(AppLocal.getIntString("label.tktheader1")); // NOI18N + lblLogo.setMaximumSize(new java.awt.Dimension(0, 25)); + lblLogo.setMinimumSize(new java.awt.Dimension(0, 0)); + lblLogo.setPreferredSize(new java.awt.Dimension(150, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(lblTktFooter1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(lblTktHeader1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(lblLogo, javax.swing.GroupLayout.PREFERRED_SIZE, 66, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(webSwtch_Logo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(jLbllogoPath, javax.swing.GroupLayout.PREFERRED_SIZE, 134, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(214, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(39, 39, 39) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(lblLogo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(webSwtch_Logo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(55, 55, 55) + .addComponent(lblTktHeader1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(163, 163, 163) + .addComponent(lblTktFooter1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(70, 70, 70) + .addComponent(jLbllogoPath, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + private void webSwtch_LogoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_webSwtch_LogoActionPerformed +// JG - For future + if (webSwtch_Logo.isSelected()) { + + } else { + + } + + }//GEN-LAST:event_webSwtch_LogoActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLbllogoPath; + private javax.swing.JLabel jLogo; + private javax.swing.JPanel jPanel1; + private javax.swing.JTextField jtxtTktFooter1; + private javax.swing.JTextField jtxtTktFooter2; + private javax.swing.JTextField jtxtTktFooter3; + private javax.swing.JTextField jtxtTktFooter4; + private javax.swing.JTextField jtxtTktFooter5; + private javax.swing.JTextField jtxtTktFooter6; + private javax.swing.JTextField jtxtTktHeader1; + private javax.swing.JTextField jtxtTktHeader2; + private javax.swing.JTextField jtxtTktHeader3; + private javax.swing.JTextField jtxtTktHeader4; + private javax.swing.JTextField jtxtTktHeader5; + private javax.swing.JTextField jtxtTktHeader6; + private javax.swing.JLabel lblLogo; + private javax.swing.JLabel lblTktFooter1; + private javax.swing.JLabel lblTktHeader1; + private com.alee.extended.button.WebSwitch webSwtch_Logo; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/config/JPanelConfigDatabase.form b/src/main/java/com/unicenta/pos/config/JPanelConfigDatabase.form new file mode 100644 index 0000000..ba778bb --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JPanelConfigDatabase.form @@ -0,0 +1,1150 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/pos/config/JPanelConfigDatabase.java b/src/main/java/com/unicenta/pos/config/JPanelConfigDatabase.java new file mode 100644 index 0000000..dc66f05 --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JPanelConfigDatabase.java @@ -0,0 +1,1298 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.config; + +import com.unicenta.data.gui.JMessageDialog; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.loader.Session; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DriverWrapper; +import com.unicenta.pos.util.AltEncrypter; +import com.unicenta.pos.util.DirectoryEvent; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.*; +import java.awt.*; +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.sql.*; + +/** + * @author Jack Gerrard + * @author adrianromero + */ +@Slf4j +public class JPanelConfigDatabase extends javax.swing.JPanel implements PanelConfig { + + private final DirtyManager dirty = new DirtyManager(); + + /** Creates new form JPanelConfigDatabase */ + public JPanelConfigDatabase() { + + initComponents(); + + dbDriverLibraryValue.getDocument().addDocumentListener(dirty); + dbDriverClassValue.getDocument().addDocumentListener(dirty); + dbDriverLibrarySelect.addActionListener(new DirectoryEvent(dbDriverLibraryValue)); + jcboDBDriver.addActionListener(dirty); + // still in development! + //jcboDBDriver.addItem("SQLite"); + jcboDBDriver.addItem("Apache Derby"); + jcboDBDriver.addItem("MariaDB"); + jcboDBDriver.addItem("MySQL"); + jcboDBDriver.setSelectedIndex(0); + multiDBButton.addActionListener(dirty); + +// primary DB + dbNameValue.getDocument().addDocumentListener(dirty); + dbURLValue.getDocument().addDocumentListener(dirty); + jtxtDbSchema.getDocument().addDocumentListener(dirty); + jtxtDbOptions.getDocument().addDocumentListener(dirty); + dbPasswordValue.getDocument().addDocumentListener(dirty); + dbUserValue.getDocument().addDocumentListener(dirty); + jCBSchema.addActionListener(dirty); + +// secondary DB + db2NameValue.getDocument().addDocumentListener(dirty); + db2URLValue.getDocument().addDocumentListener(dirty); + jtxtDbSchema1.getDocument().addDocumentListener(dirty); + db2OptionsValue.getDocument().addDocumentListener(dirty); + db2PasswordValue.getDocument().addDocumentListener(dirty); + db2UserValue.getDocument().addDocumentListener(dirty); + jCBSchema1.addActionListener(dirty); + + dbConfigPanel.setVisible(false); + validUserAlert.setVisible(true); + dbVersionLabel.setVisible(false); + } + + /** + * + * @return + */ + @Override + public boolean hasChanged() { + return dirty.isDirty(); + } + + /** + * + * @return + */ + @Override + public Component getConfigComponent() { + return this; + } + + /** + * + * @param config + */ + @Override + public void loadProperties(AppConfig config) { + + multiDBButton.setSelected(Boolean.parseBoolean(config.getProperty("db.multi"))); + + jcboDBDriver.setSelectedItem(config.getProperty("db.engine")); + dbDriverLibraryValue.setText(config.getProperty("db.driverlib")); + dbDriverClassValue.setText(config.getProperty("db.driver")); + +// primary DB + dbNameValue.setText(config.getProperty("db.name")); + dbURLValue.setText("jdbc:mysql://localhost:3306/"); + dbURLValue.setText(config.getProperty("db.URL")); + jtxtDbSchema.setText(config.getProperty("db.schema")); + jtxtDbOptions.setText(config.getProperty("db.options")); + String sDBUser = config.getProperty("db.user"); + String sDBPassword = config.getProperty("db.password"); + + if (sDBUser != null && sDBPassword != null && sDBPassword.startsWith("crypt:")) { + AltEncrypter cypher = new AltEncrypter("cypherkey" + sDBUser); + sDBPassword = cypher.decrypt(sDBPassword.substring(6)); + } + dbUserValue.setText(sDBUser); + dbPasswordValue.setText(sDBPassword); + +// secondary DB + db2NameValue.setText(config.getProperty("db1.name")); + db2URLValue.setText(config.getProperty("db1.URL")); + jtxtDbSchema1.setText(config.getProperty("db1.schema")); + jtxtDbSchema1.setEnabled(false); + db2OptionsValue.setText(config.getProperty("db1.options")); + String sDBUser1 = config.getProperty("db1.user"); + String sDBPassword1 = config.getProperty("db1.password"); + + if (sDBUser1 != null && sDBPassword1 != null && sDBPassword1.startsWith("crypt:")) { + AltEncrypter cypher = new AltEncrypter("cypherkey" + sDBUser1); + sDBPassword1 = cypher.decrypt(sDBPassword1.substring(6)); + } + db2UserValue.setText(sDBUser1); + db2PasswordValue.setText(sDBPassword1); + + dirty.setDirty(false); + } + + /** + * + * @param config + */ + @Override + public void saveProperties(AppConfig config) { + +// multi-db + config.setProperty("db.multi",Boolean.toString(multiDBButton.isSelected())); + + config.setProperty("db.engine", comboValue(jcboDBDriver.getSelectedItem())); + config.setProperty("db.driverlib", dbDriverLibraryValue.getText()); + config.setProperty("db.driver", dbDriverClassValue.getText()); + +// primary DB + config.setProperty("db.name", dbNameValue.getText()); + config.setProperty("db.URL", dbURLValue.getText()); + config.setProperty("db.schema", jtxtDbSchema.getText()); + config.setProperty("db.options", jtxtDbOptions.getText()); + config.setProperty("db.user", dbUserValue.getText()); + AltEncrypter cypher = new AltEncrypter("cypherkey" + dbUserValue.getText()); + config.setProperty("db.password", "crypt:" + + cypher.encrypt(new String(dbPasswordValue.getPassword()))); + +// secondary DB + config.setProperty("db1.name", db2NameValue.getText()); + config.setProperty("db1.URL", db2URLValue.getText()); + config.setProperty("db1.schema", jtxtDbSchema1.getText()); + config.setProperty("db1.options", db2OptionsValue.getText()); + config.setProperty("db1.user", db2UserValue.getText()); + cypher = new AltEncrypter("cypherkey" + db2UserValue.getText()); + config.setProperty("db1.password", "crypt:" + + cypher.encrypt(new String(db2PasswordValue.getPassword()))); + + dirty.setDirty(false); + } + + private String comboValue(Object value) { + return value == null ? "" : value.toString(); + } + + public void fillSchema() { + /* Use existing session credentials but declare new session and connection + * to keep separated from current session instance as database could + * be a different server + */ + + if (jCBSchema.getItemCount() >= 1 ) { + jCBSchema.removeAllItems(); + } + + try { + String driverlib = dbDriverLibraryValue.getText(); + String driver = dbDriverClassValue.getText(); + String url = dbURLValue.getText(); + String user = dbUserValue.getText(); + String password = new String(dbPasswordValue.getPassword()); + + ClassLoader cloader = new URLClassLoader(new URL[]{new File(driverlib).toURI().toURL()}); + DriverManager.registerDriver(new DriverWrapper((Driver) Class.forName(driver, true, cloader).newInstance())); + + Session session1 = new Session(url, user, password); + Connection connection1 = session1.getConnection(); + ResultSet rs = connection1.getMetaData().getCatalogs(); + + while (rs.next()) { + jCBSchema.addItem(rs.getString("TABLE_CAT")); + } + + jCBSchema.setEnabled(true); + jCBSchema.setSelectedIndex(0); + + } catch (MalformedURLException | ClassNotFoundException | SQLException + | InstantiationException | IllegalAccessException ex) { + log.error(ex.getMessage()); + } + } + public void fillSchema1() { + /* Use existing session credentials but declare new session and connection + * to keep separated from current session instance as database could + * be a different server + */ + + if (jCBSchema1.getItemCount() >= 1 ) { + jCBSchema1.removeAllItems(); + } + + try { + String driverlib = dbDriverLibraryValue.getText(); + String driver = dbDriverClassValue.getText(); + String url = db2URLValue.getText(); + String user = db2UserValue.getText(); + String password = new String(db2PasswordValue.getPassword()); + + ClassLoader cloader = new URLClassLoader(new URL[]{new File(driverlib).toURI().toURL()}); + DriverManager.registerDriver(new DriverWrapper((Driver) Class.forName(driver, true, cloader).newInstance())); + + Session session1 = new Session(url, user, password); + Connection connection1 = session1.getConnection(); + ResultSet rs1 = connection1.getMetaData().getCatalogs(); + + while (rs1.next()) { + jCBSchema1.addItem(rs1.getString("TABLE_CAT")); + } + + jCBSchema1.setEnabled(true); + jCBSchema1.setSelectedIndex(0); + + } catch (MalformedURLException | ClassNotFoundException | SQLException + | InstantiationException | IllegalAccessException ex) { + log.error(ex.getMessage()); + } + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + webPopOver1 = new com.alee.extended.window.WebPopOver(); + headerPanel = new javax.swing.JPanel(); + dbTypeLabel = new javax.swing.JLabel(); + jcboDBDriver = new javax.swing.JComboBox(); + dbMessageLabel = new javax.swing.JLabel(); + dbConfigPanel = new javax.swing.JPanel(); + jLabel7 = new javax.swing.JLabel(); + jCBSchema = new javax.swing.JComboBox<>(); + jLabel8 = new javax.swing.JLabel(); + jtxtDbOptions = new javax.swing.JTextField(); + jbtnCreateDB = new javax.swing.JButton(); + jtxtDbSchema = new javax.swing.JTextField(); + jbtnSetDB = new javax.swing.JButton(); + dbDriverLibrarySelect = new javax.swing.JButton(); + dbURLLabel = new javax.swing.JLabel(); + dbDriverClassLabel = new javax.swing.JLabel(); + dbPasswordLabel = new javax.swing.JLabel(); + dbNameLabel = new javax.swing.JLabel(); + dbPasswordValue = new javax.swing.JPasswordField(); + dbDriverLibraryLabel = new javax.swing.JLabel(); + dbDriverLibraryValue = new javax.swing.JTextField(); + dbUserValue = new javax.swing.JTextField(); + dbURLValue = new javax.swing.JTextField(); + dbDriverClassValue = new javax.swing.JTextField(); + dbUserLabel = new javax.swing.JLabel(); + jSeparator1 = new javax.swing.JSeparator(); + dbNameValue = new javax.swing.JTextField(); + dbVersionLabel = new javax.swing.JLabel(); + dbConnectButton = new javax.swing.JButton(); + dbResetButton = new javax.swing.JButton(); + validUserAlert = new javax.swing.JLabel(); + db2ConfigPanel = new javax.swing.JPanel(); + db2NameLabel = new javax.swing.JLabel(); + db2NameValue = new javax.swing.JTextField(); + db2URLLabel = new javax.swing.JLabel(); + db2URLValue = new javax.swing.JTextField(); + db2UserValue = new javax.swing.JTextField(); + db2UserLabel = new javax.swing.JLabel(); + db2PasswordLabel = new javax.swing.JLabel(); + db2PasswordValue = new javax.swing.JPasswordField(); + jbtnConnect1 = new javax.swing.JButton(); + jbtnReset1 = new javax.swing.JButton(); + jLblDBServerversion1 = new javax.swing.JLabel(); + db2DBLabel = new javax.swing.JLabel(); + jCBSchema1 = new javax.swing.JComboBox<>(); + db2OptionsLabel = new javax.swing.JLabel(); + db2OptionsValue = new javax.swing.JTextField(); + jbtnSetDB1 = new javax.swing.JButton(); + jtxtDbSchema1 = new javax.swing.JTextField(); + multiDBPanel = new javax.swing.JPanel(); + multiDBButton = new com.alee.extended.button.WebSwitch(); + LblMultiDB = new com.alee.laf.label.WebLabel(); + dbInfoLabel = new javax.swing.JLabel(); + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setOpaque(false); + setPreferredSize(new java.awt.Dimension(900, 500)); + + dbTypeLabel.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + dbTypeLabel.setText(bundle.getString("label.Database")); // NOI18N + dbTypeLabel.setPreferredSize(new java.awt.Dimension(125, 30)); + + jcboDBDriver.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboDBDriver.setToolTipText(bundle.getString("tooltip.config.db.dbtype")); // NOI18N + jcboDBDriver.setPreferredSize(new java.awt.Dimension(160, 30)); + jcboDBDriver.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcboDBDriverActionPerformed(evt); + } + }); + + dbMessageLabel.setForeground(new java.awt.Color(51, 204, 255)); + dbMessageLabel.setText("If you require a multiple terminal config please use MariaDB"); + + javax.swing.GroupLayout headerPanelLayout = new javax.swing.GroupLayout(headerPanel); + headerPanel.setLayout(headerPanelLayout); + headerPanelLayout.setHorizontalGroup( + headerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(headerPanelLayout.createSequentialGroup() + .addContainerGap() + .addComponent(dbTypeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboDBDriver, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(dbMessageLabel) + .addContainerGap(2327, Short.MAX_VALUE)) + ); + headerPanelLayout.setVerticalGroup( + headerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(headerPanelLayout.createSequentialGroup() + .addGroup(headerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jcboDBDriver, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(dbTypeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(dbMessageLabel)) + .addGap(0, 6, Short.MAX_VALUE)) + ); + + dbConfigPanel.setBackground(new java.awt.Color(255, 255, 255)); + + jLabel7.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel7.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jLabel7.setText(AppLocal.getIntString("label.DBName")); // NOI18N + jLabel7.setPreferredSize(new java.awt.Dimension(125, 30)); + + jCBSchema.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jCBSchema.setToolTipText(bundle.getString("tooltip.config.db.schema")); // NOI18N + jCBSchema.setPreferredSize(new java.awt.Dimension(160, 30)); + jCBSchema.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jCBSchemaActionPerformed(evt); + } + }); + + jLabel8.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel8.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jLabel8.setText(AppLocal.getIntString("label.DbOptions")); // NOI18N + jLabel8.setPreferredSize(new java.awt.Dimension(125, 30)); + + jtxtDbOptions.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtDbOptions.setToolTipText(bundle.getString("tooltip.config.db.options")); // NOI18N + jtxtDbOptions.setPreferredSize(new java.awt.Dimension(330, 30)); + + jbtnCreateDB.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnCreateDB.setText("CREATE DEFAULT"); + jbtnCreateDB.setToolTipText(bundle.getString("message.databasecreate")); // NOI18N + jbtnCreateDB.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jbtnCreateDB.setPreferredSize(new java.awt.Dimension(160, 45)); + jbtnCreateDB.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnCreateDBActionPerformed(evt); + } + }); + + jtxtDbSchema.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtDbSchema.setEnabled(false); + jtxtDbSchema.setPreferredSize(new java.awt.Dimension(250, 30)); + + jbtnSetDB.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jbtnSetDB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn2.png"))); // NOI18N + jbtnSetDB.setText("SET"); + jbtnSetDB.setToolTipText(bundle.getString("tooltip.config.db.databaseset")); // NOI18N + jbtnSetDB.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jbtnSetDB.setPreferredSize(new java.awt.Dimension(160, 45)); + jbtnSetDB.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnSetDBActionPerformed(evt); + } + }); + + dbDriverLibrarySelect.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/fileopen.png"))); // NOI18N + dbDriverLibrarySelect.setText(" "); + dbDriverLibrarySelect.setToolTipText(bundle.getString("tooltip.config.db.file")); // NOI18N + dbDriverLibrarySelect.setMaximumSize(new java.awt.Dimension(64, 32)); + dbDriverLibrarySelect.setMinimumSize(new java.awt.Dimension(64, 32)); + dbDriverLibrarySelect.setPreferredSize(new java.awt.Dimension(80, 30)); + + dbURLLabel.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + dbURLLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + dbURLLabel.setText(AppLocal.getIntString("label.DbURL")); // NOI18N + dbURLLabel.setPreferredSize(new java.awt.Dimension(125, 30)); + + dbDriverClassLabel.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + dbDriverClassLabel.setText(AppLocal.getIntString("label.DbDriver")); // NOI18N + dbDriverClassLabel.setPreferredSize(new java.awt.Dimension(125, 30)); + + dbPasswordLabel.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + dbPasswordLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + dbPasswordLabel.setText(AppLocal.getIntString("label.DbPassword")); // NOI18N + dbPasswordLabel.setPreferredSize(new java.awt.Dimension(125, 30)); + + dbNameLabel.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + dbNameLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + dbNameLabel.setText(AppLocal.getIntString("label.DbName")); // NOI18N + dbNameLabel.setPreferredSize(new java.awt.Dimension(125, 30)); + + dbPasswordValue.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + dbPasswordValue.setToolTipText(bundle.getString("tooltip.config.db.password")); // NOI18N + dbPasswordValue.setPreferredSize(new java.awt.Dimension(160, 30)); + + dbDriverLibraryLabel.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + dbDriverLibraryLabel.setText(AppLocal.getIntString("label.dbdriverlib")); // NOI18N + dbDriverLibraryLabel.setPreferredSize(new java.awt.Dimension(125, 30)); + + dbDriverLibraryValue.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + dbDriverLibraryValue.setToolTipText(bundle.getString("tooltip.config.db.driverlib")); // NOI18N + dbDriverLibraryValue.setPreferredSize(new java.awt.Dimension(500, 30)); + + dbUserValue.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + dbUserValue.setText(bundle.getString("tooltip.config.db.user")); // NOI18N + dbUserValue.setToolTipText(bundle.getString("tooltip.config.db.user")); // NOI18N + dbUserValue.setPreferredSize(new java.awt.Dimension(160, 30)); + + dbURLValue.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + dbURLValue.setToolTipText(bundle.getString("tooltip.config.db.url")); // NOI18N + dbURLValue.setPreferredSize(new java.awt.Dimension(320, 30)); + + dbDriverClassValue.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + dbDriverClassValue.setToolTipText(bundle.getString("tooltip.config.db.driverclass")); // NOI18N + dbDriverClassValue.setPreferredSize(new java.awt.Dimension(150, 30)); + dbDriverClassValue.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + dbDriverClassValueActionPerformed(evt); + } + }); + + dbUserLabel.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + dbUserLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + dbUserLabel.setText(AppLocal.getIntString("label.DbUser")); // NOI18N + dbUserLabel.setPreferredSize(new java.awt.Dimension(125, 30)); + + dbNameValue.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + dbNameValue.setToolTipText(bundle.getString("tooltip.config.db.name")); // NOI18N + dbNameValue.setPreferredSize(new java.awt.Dimension(160, 30)); + + dbVersionLabel.setBackground(new java.awt.Color(51, 204, 255)); + dbVersionLabel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + dbVersionLabel.setForeground(new java.awt.Color(255, 255, 255)); + dbVersionLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + dbVersionLabel.setOpaque(true); + dbVersionLabel.setPreferredSize(new java.awt.Dimension(170, 30)); + + dbConnectButton.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + dbConnectButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn1.png"))); // NOI18N + dbConnectButton.setText(bundle.getString("button.connect")); // NOI18N + dbConnectButton.setToolTipText(bundle.getString("tooltip.config.db.connect")); // NOI18N + dbConnectButton.setActionCommand(bundle.getString("Button.Test")); // NOI18N + dbConnectButton.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + dbConnectButton.setPreferredSize(new java.awt.Dimension(160, 45)); + dbConnectButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + dbConnectButtonActionPerformed(evt); + } + }); + + dbResetButton.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + dbResetButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reload.png"))); // NOI18N + dbResetButton.setToolTipText(AppLocal.getIntString("tooltip.config.db.reset")); // NOI18N + dbResetButton.setPreferredSize(new java.awt.Dimension(80, 45)); + dbResetButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + dbResetButtonActionPerformed(evt); + } + }); + + validUserAlert.setBackground(new java.awt.Color(255, 0, 51)); + validUserAlert.setFont(new java.awt.Font("Lucida Sans Unicode", 0, 14)); // NOI18N + validUserAlert.setForeground(new java.awt.Color(255, 255, 255)); + validUserAlert.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + validUserAlert.setText(bundle.getString("message.dbalert")); // NOI18N + validUserAlert.setOpaque(true); + validUserAlert.setPreferredSize(new java.awt.Dimension(570, 30)); + + javax.swing.GroupLayout dbConfigPanelLayout = new javax.swing.GroupLayout(dbConfigPanel); + dbConfigPanel.setLayout(dbConfigPanelLayout); + dbConfigPanelLayout.setHorizontalGroup( + dbConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(dbConfigPanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(dbConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(dbConfigPanelLayout.createSequentialGroup() + .addComponent(validUserAlert, javax.swing.GroupLayout.DEFAULT_SIZE, 992, Short.MAX_VALUE) + .addGap(786, 786, 786)) + .addGroup(dbConfigPanelLayout.createSequentialGroup() + .addGroup(dbConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(dbConfigPanelLayout.createSequentialGroup() + .addComponent(dbDriverLibraryLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dbDriverLibraryValue, javax.swing.GroupLayout.PREFERRED_SIZE, 326, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dbDriverLibrarySelect, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dbDriverClassLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dbDriverClassValue, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(dbConfigPanelLayout.createSequentialGroup() + .addComponent(dbNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dbNameValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dbURLLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dbURLValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dbVersionLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 125, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(dbConfigPanelLayout.createSequentialGroup() + .addComponent(dbUserLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dbUserValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dbPasswordLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dbPasswordValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dbConnectButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dbResetButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(dbConfigPanelLayout.createSequentialGroup() + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(dbConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(dbConfigPanelLayout.createSequentialGroup() + .addComponent(jCBSchema, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jbtnSetDB, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(dbConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(dbConfigPanelLayout.createSequentialGroup() + .addComponent(jtxtDbSchema, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(32, 32, 32) + .addComponent(jbtnCreateDB, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jtxtDbOptions, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addGap(0, 0, Short.MAX_VALUE)))) + .addGroup(dbConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(dbConfigPanelLayout.createSequentialGroup() + .addGap(898, 898, 898) + .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 880, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + ); + dbConfigPanelLayout.setVerticalGroup( + dbConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(dbConfigPanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(dbConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(dbConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(dbDriverLibraryValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(dbDriverLibrarySelect, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(dbDriverClassLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(dbDriverClassValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(dbDriverLibraryLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(dbConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(dbConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(dbNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(dbNameValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(dbURLLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(dbURLValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(dbVersionLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(dbConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(dbConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(dbUserLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(dbUserValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(dbPasswordLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(dbPasswordValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(dbConnectButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(dbResetButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(dbConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jCBSchema, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtDbOptions, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(dbConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jbtnSetDB, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jbtnCreateDB, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtDbSchema, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(validUserAlert, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(dbConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(dbConfigPanelLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(246, Short.MAX_VALUE))) + ); + + db2ConfigPanel.setBackground(new java.awt.Color(255, 255, 255)); + + db2NameLabel.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + db2NameLabel.setText(AppLocal.getIntString("label.DbName1")); // NOI18N + db2NameLabel.setPreferredSize(new java.awt.Dimension(125, 30)); + + db2NameValue.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + db2NameValue.setToolTipText(bundle.getString("tooltip.config.db.name1")); // NOI18N + db2NameValue.setPreferredSize(new java.awt.Dimension(160, 30)); + + db2URLLabel.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + db2URLLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + db2URLLabel.setText(AppLocal.getIntString("label.DbURL")); // NOI18N + db2URLLabel.setPreferredSize(new java.awt.Dimension(125, 30)); + + db2URLValue.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + db2URLValue.setToolTipText(bundle.getString("tooltip.config.db.url1")); // NOI18N + db2URLValue.setPreferredSize(new java.awt.Dimension(320, 30)); + db2URLValue.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + db2URLValueActionPerformed(evt); + } + }); + + db2UserValue.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + db2UserValue.setToolTipText(bundle.getString("tooltip.config.db.user1")); // NOI18N + db2UserValue.setPreferredSize(new java.awt.Dimension(160, 30)); + + db2UserLabel.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + db2UserLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + db2UserLabel.setText(AppLocal.getIntString("label.DbUser")); // NOI18N + db2UserLabel.setPreferredSize(new java.awt.Dimension(125, 30)); + + db2PasswordLabel.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + db2PasswordLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + db2PasswordLabel.setText(AppLocal.getIntString("label.DbPassword")); // NOI18N + db2PasswordLabel.setPreferredSize(new java.awt.Dimension(125, 30)); + + db2PasswordValue.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + db2PasswordValue.setToolTipText(bundle.getString("tooltip.config.db.password1")); // NOI18N + db2PasswordValue.setPreferredSize(new java.awt.Dimension(160, 30)); + + jbtnConnect1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnConnect1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn1.png"))); // NOI18N + jbtnConnect1.setText(bundle.getString("button.connect")); // NOI18N + jbtnConnect1.setToolTipText(bundle.getString("tooltip.config.db.connect")); // NOI18N + jbtnConnect1.setActionCommand(bundle.getString("Button.Test")); // NOI18N + jbtnConnect1.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jbtnConnect1.setPreferredSize(new java.awt.Dimension(160, 45)); + jbtnConnect1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnConnect1ActionPerformed(evt); + } + }); + + jbtnReset1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnReset1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reload.png"))); // NOI18N + jbtnReset1.setToolTipText(AppLocal.getIntString("tooltip.config.db.reset1")); // NOI18N + jbtnReset1.setPreferredSize(new java.awt.Dimension(80, 45)); + jbtnReset1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnReset1ActionPerformed(evt); + } + }); + + jLblDBServerversion1.setBackground(new java.awt.Color(51, 204, 255)); + jLblDBServerversion1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLblDBServerversion1.setForeground(new java.awt.Color(255, 255, 255)); + jLblDBServerversion1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLblDBServerversion1.setOpaque(true); + jLblDBServerversion1.setPreferredSize(new java.awt.Dimension(170, 30)); + + db2DBLabel.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + db2DBLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + db2DBLabel.setText(AppLocal.getIntString("label.DBName")); // NOI18N + db2DBLabel.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT); + db2DBLabel.setPreferredSize(new java.awt.Dimension(125, 30)); + + jCBSchema1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jCBSchema1.setToolTipText(bundle.getString("tooltip.config.db.schema1")); // NOI18N + jCBSchema1.setPreferredSize(new java.awt.Dimension(160, 30)); + jCBSchema1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jCBSchema1ActionPerformed(evt); + } + }); + + db2OptionsLabel.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + db2OptionsLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + db2OptionsLabel.setText(AppLocal.getIntString("label.DbOptions")); // NOI18N + db2OptionsLabel.setPreferredSize(new java.awt.Dimension(125, 30)); + + db2OptionsValue.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + db2OptionsValue.setToolTipText(bundle.getString("tooltip.config.db.options")); // NOI18N + db2OptionsValue.setPreferredSize(new java.awt.Dimension(330, 30)); + + jbtnSetDB1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jbtnSetDB1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn2.png"))); // NOI18N + jbtnSetDB1.setText("SET"); + jbtnSetDB1.setToolTipText(bundle.getString("tooltip.config.db.databaseset1")); // NOI18N + jbtnSetDB1.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jbtnSetDB1.setPreferredSize(new java.awt.Dimension(160, 45)); + jbtnSetDB1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnSetDB1ActionPerformed(evt); + } + }); + + jtxtDbSchema1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtDbSchema1.setPreferredSize(new java.awt.Dimension(250, 30)); + + javax.swing.GroupLayout db2ConfigPanelLayout = new javax.swing.GroupLayout(db2ConfigPanel); + db2ConfigPanel.setLayout(db2ConfigPanelLayout); + db2ConfigPanelLayout.setHorizontalGroup( + db2ConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(db2ConfigPanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(db2ConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(db2ConfigPanelLayout.createSequentialGroup() + .addComponent(db2NameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(db2NameValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(db2URLLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(db2URLValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLblDBServerversion1, javax.swing.GroupLayout.PREFERRED_SIZE, 125, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(db2ConfigPanelLayout.createSequentialGroup() + .addComponent(db2UserLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(db2UserValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(db2PasswordLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(db2PasswordValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jbtnConnect1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jbtnReset1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(db2ConfigPanelLayout.createSequentialGroup() + .addComponent(db2DBLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(db2ConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(db2ConfigPanelLayout.createSequentialGroup() + .addComponent(jbtnSetDB1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(137, 137, 137) + .addComponent(jtxtDbSchema1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(db2ConfigPanelLayout.createSequentialGroup() + .addComponent(jCBSchema1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(db2OptionsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(db2OptionsValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + db2ConfigPanelLayout.setVerticalGroup( + db2ConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(db2ConfigPanelLayout.createSequentialGroup() + .addGroup(db2ConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(db2NameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(db2NameValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(db2ConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(db2URLLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(db2URLValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jLblDBServerversion1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(db2ConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jbtnConnect1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(db2ConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(db2PasswordValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(db2PasswordLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jbtnReset1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(db2UserValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(db2UserLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(db2ConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(db2DBLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jCBSchema1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(db2OptionsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(db2OptionsValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(db2ConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(db2ConfigPanelLayout.createSequentialGroup() + .addComponent(jtxtDbSchema1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(12, Short.MAX_VALUE)) + .addGroup(db2ConfigPanelLayout.createSequentialGroup() + .addGap(1, 1, 1) + .addComponent(jbtnSetDB1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)))) + ); + + multiDBButton.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + multiDBButton.setPreferredSize(new java.awt.Dimension(80, 30)); + multiDBButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + multiDBButtonActionPerformed(evt); + } + }); + + LblMultiDB.setText(AppLocal.getIntString("label.multidb")); // NOI18N + LblMultiDB.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + LblMultiDB.setPreferredSize(new java.awt.Dimension(125, 30)); + + dbInfoLabel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + dbInfoLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + dbInfoLabel.setText(bundle.getString("message.DBDefault")); // NOI18N + dbInfoLabel.setToolTipText(""); + dbInfoLabel.setVerticalAlignment(javax.swing.SwingConstants.TOP); + dbInfoLabel.setPreferredSize(new java.awt.Dimension(889, 120)); + dbInfoLabel.setVerticalTextPosition(javax.swing.SwingConstants.TOP); + + javax.swing.GroupLayout multiDBPanelLayout = new javax.swing.GroupLayout(multiDBPanel); + multiDBPanel.setLayout(multiDBPanelLayout); + multiDBPanelLayout.setHorizontalGroup( + multiDBPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(multiDBPanelLayout.createSequentialGroup() + .addContainerGap() + .addComponent(LblMultiDB, javax.swing.GroupLayout.PREFERRED_SIZE, 77, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(multiDBButton, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dbInfoLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 740, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(72, Short.MAX_VALUE)) + ); + multiDBPanelLayout.setVerticalGroup( + multiDBPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(multiDBPanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(multiDBPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(LblMultiDB, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(multiDBButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(multiDBPanelLayout.createSequentialGroup() + .addComponent(dbInfoLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(headerPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(dbConfigPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(multiDBPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, Short.MAX_VALUE)) + .addComponent(db2ConfigPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(headerPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dbConfigPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(multiDBPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(db2ConfigPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + private void dbDriverClassValueActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dbDriverClassValueActionPerformed + + }//GEN-LAST:event_dbDriverClassValueActionPerformed + + private void jcboDBDriverActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcboDBDriverActionPerformed + + String dirname = System.getProperty("dirname.path"); + dirname = dirname == null ? "./" : dirname; + + if ("Apache Derby".equals(jcboDBDriver.getSelectedItem())) { + dbDriverLibraryValue.setText(new File(new File(dirname), "derby-10.14.2.0.jar").getAbsolutePath()); + dbDriverClassValue.setText("org.apache.derby.jdbc.EmbeddedDriver"); + dbURLValue.setText("jdbc:derby:" + System.getProperty("user.home")+"/.unicenta/"); + jtxtDbSchema.setText("unicentaopos-database;create=true"); + dbUserValue.setText(""); + dbPasswordValue.setText(""); + //jtxtDbSchema.setText("unicentaopos-derby"); + jtxtDbOptions.setText(""); + dbConfigPanel.setVisible(false); + db2ConfigPanel.setVisible(false); + multiDBPanel.setVisible(false); + dbMessageLabel.setText("Single terminal only. If you require a multiple terminal config please use MariaDB"); + dbMessageLabel.setForeground(new java.awt.Color(51, 204, 255)); + } + else if ("SQLite".equals(jcboDBDriver.getSelectedItem())) { + dbDriverLibraryValue.setText(new File(new File(dirname), "sqlite-jdbc-3.7.2.jar").getAbsolutePath()); + dbDriverClassValue.setText("org.sqlite.JDBC"); + dbURLValue.setText("jdbc:sqlite:" + System.getProperty("user.home")+"/.unicenta/"); + dbUserValue.setText(""); + dbPasswordValue.setText(""); + jtxtDbSchema.setText("unicentaopos"); + jtxtDbOptions.setText(""); + dbConfigPanel.setVisible(false); + db2ConfigPanel.setVisible(false); + multiDBPanel.setVisible(false); + } + else if ("MariaDB".equals(jcboDBDriver.getSelectedItem())) { + dbDriverLibraryValue.setText(new File(new File(dirname), "mariadb-java-client-2.7.0.jar").getAbsolutePath()); + dbDriverClassValue.setText("org.mariadb.jdbc.Driver"); + dbURLValue.setText("jdbc:mariadb://localhost:3306/"); + jtxtDbSchema.setText("unicentaopos"); + jtxtDbOptions.setText("?zeroDateTimeBehavior=convertToNull"); + dbConfigPanel.setVisible(true); + multiDBPanel.setVisible(true); + dbMessageLabel.setText("This is the best option for multiple terminal configuration"); + dbMessageLabel.setForeground(new java.awt.Color(51, 204, 255)); + + } else { + dbDriverLibraryValue.setText(new File(new File(dirname), "mysql-connector-java-5.1.39.jar").getAbsolutePath()); + dbDriverClassValue.setText("com.mysql.jdbc.Driver"); + dbURLValue.setText("jdbc:mysql://localhost:3306/"); + jtxtDbSchema.setText("unicentaopos"); + jtxtDbOptions.setText("?zeroDateTimeBehavior=convertToNull"); + dbConfigPanel.setVisible(true); + multiDBPanel.setVisible(true); + dbMessageLabel.setText("MySQL is deprecated and will be remove in a subsequent release. Please migrate to MariaDB"); + dbMessageLabel.setForeground(new Color(255,0,51)); + } + }//GEN-LAST:event_jcboDBDriverActionPerformed + + private void dbConnectButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dbConnectButtonActionPerformed + try { + String driverlib = dbDriverLibraryValue.getText(); + String driver = dbDriverClassValue.getText(); + String url = dbURLValue.getText(); + String user = dbUserValue.getText(); + String password = new String(dbPasswordValue.getPassword()); + + ClassLoader cloader = new URLClassLoader(new URL[]{new File(driverlib).toURI().toURL()}); + DriverManager.registerDriver(new DriverWrapper((Driver) Class.forName(driver, true, cloader).newInstance())); + + Session session = new Session(url, user, password); + Connection connection = session.getConnection(); + + boolean isValid; + if (connection != null && connection.getClass().getName().equals("org.sqlite.Conn") ) { + isValid = true; + } + else isValid = connection != null && connection.isValid(1000); + + if (isValid) { + JOptionPane.showMessageDialog(this, + AppLocal.getIntString("message.databasesuccess"), + "Connection Test", JOptionPane.INFORMATION_MESSAGE); + fillSchema(); + validUserAlert.setVisible(false); + dbConfigPanel.setVisible(true); + } else { + validUserAlert.setVisible(true); + dbConfigPanel.setVisible(false); + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, "Connection Error")); + } + + ResultSet rs = connection.getMetaData().getCatalogs(); + String SQL="SELECT LEFT(VERSION(),3) "; + Statement stmt = (Statement) connection.createStatement(); + rs = stmt.executeQuery(SQL); + rs.next(); + dbVersionLabel.setVisible(true); + dbVersionLabel.setText(" MySQL Server : " + rs.getString(1)); + + //if (!rs.getString(1).equals("5.7")) { + // jLblDBServerversion.setBackground(Color.RED); + // JOptionPane.showMessageDialog(this, + // AppLocal.getIntString("message.databasefail"), + // "Connection Test", JOptionPane.WARNING_MESSAGE); + //} + + } catch (InstantiationException | IllegalAccessException | MalformedURLException | ClassNotFoundException e) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.databasedrivererror"), e)); + } catch (SQLException e) { + validUserAlert.setVisible(true); + dbVersionLabel.setText(""); + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.databaseconnectionerror"), e)); + } catch (Exception e) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, "Unknown exception", e)); + } + }//GEN-LAST:event_dbConnectButtonActionPerformed + + private void jbtnConnect1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnConnect1ActionPerformed + /* Even though TEST & TEST1 could be consolidated into method am deliberately + * keeping this separate as plan is to also include alternative + */ + try { + String driverlib = dbDriverLibraryValue.getText(); + String driver = dbDriverClassValue.getText(); + String url = db2URLValue.getText(); + String user = db2UserValue.getText(); + String password = new String(db2PasswordValue.getPassword()); + + ClassLoader cloader = new URLClassLoader(new URL[]{new File(driverlib).toURI().toURL()}); + DriverManager.registerDriver(new DriverWrapper((Driver) Class.forName(driver, true, cloader).newInstance())); + + Session session = new Session(url, user, password); + Connection connection = session.getConnection(); + + boolean isValid; + isValid = (connection == null) ? false : connection.isValid(1000); + + if (isValid) { + JOptionPane.showMessageDialog(this, + AppLocal.getIntString("message.databasesuccess"), + "Connection Test", JOptionPane.INFORMATION_MESSAGE); + fillSchema1(); + validUserAlert.setVisible(false); + } else { + validUserAlert.setVisible(true); + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, "Connection Error")); + } + + ResultSet rs = connection.getMetaData().getCatalogs(); + String SQL="SELECT LEFT(VERSION(),3) "; + Statement stmt = (Statement) connection.createStatement(); + rs = stmt.executeQuery(SQL); + rs.next(); + jLblDBServerversion1.setText(" MySQL Server : " + rs.getString(1)); + + } catch (InstantiationException | IllegalAccessException | MalformedURLException | ClassNotFoundException e) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.databasedrivererror"), e)); + } catch (SQLException e) { + validUserAlert.setVisible(true); + jLblDBServerversion1.setText(""); + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.databaseconnectionerror"), e)); + } catch (Exception e) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, "Unknown exception", e)); + } + }//GEN-LAST:event_jbtnConnect1ActionPerformed + + private void multiDBButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_multiDBButtonActionPerformed + if (multiDBButton.isSelected()) { + dbConfigPanel.setVisible(true); + db2ConfigPanel.setVisible(true); + multiDBPanel.setVisible(true); + } else { + db2ConfigPanel.setVisible(false); + } + }//GEN-LAST:event_multiDBButtonActionPerformed + + private void dbResetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dbResetButtonActionPerformed + if (jCBSchema.getItemCount() >= 1 ) { + jCBSchema.removeAllItems(); + } + + String dirname = System.getProperty("dirname.path"); + dirname = dirname == null ? "./" : dirname; + + dbDriverLibraryValue.setText(new File(new File(dirname), "lib/mysql-connector-java-5.1.39.jar").getAbsolutePath()); + dbDriverClassValue.setText("com.mysql.jdbc.Driver"); + + dbNameValue.setText("Main DB"); + dbURLValue.setText("jdbc:mysql://localhost:3306/"); + jtxtDbSchema.setText("unicentaopos"); + jtxtDbOptions.setText("?zeroDateTimeBehavior=convertToNull"); + dbUserValue.setText(null); + dbPasswordValue.setText(null); + dbVersionLabel.setText(null); + dbVersionLabel.setVisible(false); + dbConfigPanel.setVisible(false); + }//GEN-LAST:event_dbResetButtonActionPerformed + + private void jbtnReset1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnReset1ActionPerformed + if (jCBSchema1.getItemCount() >= 1 ) { + jCBSchema1.removeAllItems(); + } + + db2NameValue.setText("Other DB"); + db2URLValue.setText("jdbc:mysql://localhost:3306/"); + jtxtDbSchema1.setText("unicentaopos1"); + db2OptionsValue.setText("?zeroDateTimeBehavior=convertToNull"); + db2UserValue.setText(null); + db2PasswordValue.setText(null); + jLblDBServerversion1.setText(null); + }//GEN-LAST:event_jbtnReset1ActionPerformed + + private void jCBSchemaActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCBSchemaActionPerformed +/* + if (jCBSchema.getItemCount() > 0 ) { + String selected = jCBSchema.getSelectedItem().toString(); + if(!selected.equals(null)) { + jtxtDbSchema.setText(selected); + } + } +*/ + }//GEN-LAST:event_jCBSchemaActionPerformed + + private void jCBSchema1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCBSchema1ActionPerformed +/* + if (jCBSchema1.getItemCount() > 0 ) { + String selected1 = jCBSchema1.getSelectedItem().toString(); + if(!selected1.equals(null)) { + jtxtDbSchema1.setText(selected1); + } + } +*/ + }//GEN-LAST:event_jCBSchema1ActionPerformed + + private void db2URLValueActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_db2URLValueActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_db2URLValueActionPerformed + + private void jbtnCreateDBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnCreateDBActionPerformed + try { + String driverlib = dbDriverLibraryValue.getText(); + String driver = dbDriverClassValue.getText(); + String url = dbURLValue.getText(); + String user = dbUserValue.getText(); + String password = new String(dbPasswordValue.getPassword()); + + ClassLoader cloader = new URLClassLoader(new URL[]{new File(driverlib).toURI().toURL()}); + DriverManager.registerDriver(new DriverWrapper((Driver) Class.forName(driver, true, cloader).newInstance())); + + Session session = new Session(url, user, password); + Connection connection = session.getConnection(); + + boolean isValid; + isValid = (connection == null) ? false : connection.isValid(1000); + + if (isValid) { + String SQL="CREATE DATABASE if not exists unicentaopos"; + Statement stmt = (Statement) connection.createStatement(); + stmt.executeUpdate(SQL); + + fillSchema(); + validUserAlert.setVisible(false); + jtxtDbSchema.setText("unicentaopos"); + + JOptionPane.showMessageDialog(this, + AppLocal.getIntString("message.createdefaultdb"), + "Create Default Database", JOptionPane.INFORMATION_MESSAGE); + } else { + validUserAlert.setVisible(true); + dbConfigPanel.setVisible(false); + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, "Connection Error")); + } + + } catch (MalformedURLException ex) { + log.error(ex.getMessage()); + } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.databasedrivererror"), e)); + } catch (SQLException e) { + validUserAlert.setVisible(true); + dbVersionLabel.setText(""); + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.databaseconnectionerror"), e)); + } catch (Exception e) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, "Unknown exception", e)); + } + }//GEN-LAST:event_jbtnCreateDBActionPerformed + + private void jbtnSetDBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnSetDBActionPerformed + + if (jCBSchema.getItemCount() > 0 ) { + String selected = jCBSchema.getSelectedItem().toString(); + if(selected != null) { + jtxtDbSchema.setText(selected); + } + } + }//GEN-LAST:event_jbtnSetDBActionPerformed + + private void jbtnSetDB1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnSetDB1ActionPerformed + + if (jCBSchema1.getItemCount() > 0 ) { + String selected1 = jCBSchema1.getSelectedItem().toString(); + if(selected1 != null) { + jtxtDbSchema1.setText(selected1); + } + } + }//GEN-LAST:event_jbtnSetDB1ActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private com.alee.laf.label.WebLabel LblMultiDB; + private javax.swing.JPanel db2ConfigPanel; + private javax.swing.JLabel db2DBLabel; + private javax.swing.JLabel db2NameLabel; + private javax.swing.JTextField db2NameValue; + private javax.swing.JLabel db2OptionsLabel; + private javax.swing.JTextField db2OptionsValue; + private javax.swing.JLabel db2PasswordLabel; + private javax.swing.JPasswordField db2PasswordValue; + private javax.swing.JLabel db2URLLabel; + private javax.swing.JTextField db2URLValue; + private javax.swing.JLabel db2UserLabel; + private javax.swing.JTextField db2UserValue; + private javax.swing.JPanel dbConfigPanel; + private javax.swing.JButton dbConnectButton; + private javax.swing.JLabel dbDriverClassLabel; + private javax.swing.JTextField dbDriverClassValue; + private javax.swing.JLabel dbDriverLibraryLabel; + private javax.swing.JButton dbDriverLibrarySelect; + private javax.swing.JTextField dbDriverLibraryValue; + private javax.swing.JLabel dbInfoLabel; + private javax.swing.JLabel dbMessageLabel; + private javax.swing.JLabel dbNameLabel; + private javax.swing.JTextField dbNameValue; + private javax.swing.JLabel dbPasswordLabel; + private javax.swing.JPasswordField dbPasswordValue; + private javax.swing.JButton dbResetButton; + private javax.swing.JLabel dbTypeLabel; + private javax.swing.JLabel dbURLLabel; + private javax.swing.JTextField dbURLValue; + private javax.swing.JLabel dbUserLabel; + private javax.swing.JTextField dbUserValue; + private javax.swing.JLabel dbVersionLabel; + private javax.swing.JPanel headerPanel; + private javax.swing.JComboBox jCBSchema; + private javax.swing.JComboBox jCBSchema1; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JLabel jLblDBServerversion1; + private javax.swing.JSeparator jSeparator1; + private javax.swing.JButton jbtnConnect1; + private javax.swing.JButton jbtnCreateDB; + private javax.swing.JButton jbtnReset1; + private javax.swing.JButton jbtnSetDB; + private javax.swing.JButton jbtnSetDB1; + private javax.swing.JComboBox jcboDBDriver; + private javax.swing.JTextField jtxtDbOptions; + private javax.swing.JTextField jtxtDbSchema; + private javax.swing.JTextField jtxtDbSchema1; + private com.alee.extended.button.WebSwitch multiDBButton; + private javax.swing.JPanel multiDBPanel; + private javax.swing.JLabel validUserAlert; + private com.alee.extended.window.WebPopOver webPopOver1; + // End of variables declaration//GEN-END:variables + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/config/JPanelConfigERP.form b/src/main/java/com/unicenta/pos/config/JPanelConfigERP.form new file mode 100644 index 0000000..14e1956 --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JPanelConfigERP.form @@ -0,0 +1,226 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/pos/config/JPanelConfigERP.java b/src/main/java/com/unicenta/pos/config/JPanelConfigERP.java new file mode 100644 index 0000000..acf0f97 --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JPanelConfigERP.java @@ -0,0 +1,247 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.config; + +import com.unicenta.data.user.DirtyManager; +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.util.AltEncrypter; +import java.awt.Component; + +/** + * + * @author adrianromero + */ +public class JPanelConfigERP extends javax.swing.JPanel implements PanelConfig { + + private DirtyManager dirty = new DirtyManager(); + + /** Creates new form JPanelConfigERP */ + public JPanelConfigERP() { + initComponents(); + + jTextField1.getDocument().addDocumentListener(dirty); + jTextField2.getDocument().addDocumentListener(dirty); + jtxtId.getDocument().addDocumentListener(dirty); + jtxtName.getDocument().addDocumentListener(dirty); + jtxtPassword.getDocument().addDocumentListener(dirty); + jtxtUrl.getDocument().addDocumentListener(dirty); + } + + /** + * + * @return + */ + @Override + public boolean hasChanged() { + return dirty.isDirty(); + } + + /** + * + * @return + */ + @Override + public Component getConfigComponent() { + return this; + } + + /** + * + * @param config + */ + @Override + public void loadProperties(AppConfig config) { + + jtxtUrl.setText(config.getProperty("erp.URL")); + jtxtId.setText(config.getProperty("erp.id")); + jTextField2.setText(config.getProperty("erp.pos")); + jTextField1.setText(config.getProperty("erp.org")); + + String sERPUser = config.getProperty("erp.user"); + String sERPPassword = config.getProperty("erp.password"); + if (sERPUser != null && sERPPassword != null && sERPPassword.startsWith("crypt:")) { + // La clave esta encriptada. + AltEncrypter cypher = new AltEncrypter("cypherkey" + sERPUser); + sERPPassword = cypher.decrypt(sERPPassword.substring(6)); + } + jtxtName.setText(sERPUser); + jtxtPassword.setText(sERPPassword); + + dirty.setDirty(false); + } + + /** + * + * @param config + */ + @Override + public void saveProperties(AppConfig config) { + + config.setProperty("erp.URL", jtxtUrl.getText()); + config.setProperty("erp.id", jtxtId.getText()); + config.setProperty("erp.pos", jTextField2.getText()); + config.setProperty("erp.org", jTextField1.getText()); + + config.setProperty("erp.user", jtxtName.getText()); + AltEncrypter cypher = new AltEncrypter("cypherkey" + jtxtName.getText()); + config.setProperty("erp.password", "crypt:" + cypher.encrypt(new String(jtxtPassword.getPassword()))); + + dirty.setDirty(false); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jtxtUrl = new javax.swing.JTextField(); + jtxtId = new javax.swing.JTextField(); + jTextField1 = new javax.swing.JTextField(); + jTextField2 = new javax.swing.JTextField(); + jtxtName = new javax.swing.JTextField(); + jtxtPassword = new javax.swing.JPasswordField(); + jlabelUrl = new javax.swing.JLabel(); + jLabelId = new javax.swing.JLabel(); + jLabel1 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + jLabelName = new javax.swing.JLabel(); + jLabelProperties = new javax.swing.JLabel(); + + setBackground(new java.awt.Color(255, 255, 255)); + setPreferredSize(new java.awt.Dimension(700, 500)); + + jtxtUrl.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtUrl.setPreferredSize(new java.awt.Dimension(350, 30)); + + jtxtId.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtId.setPreferredSize(new java.awt.Dimension(250, 30)); + + jTextField1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTextField1.setPreferredSize(new java.awt.Dimension(250, 30)); + + jTextField2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTextField2.setPreferredSize(new java.awt.Dimension(250, 30)); + + jtxtName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtName.setPreferredSize(new java.awt.Dimension(250, 30)); + + jtxtPassword.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtPassword.setPreferredSize(new java.awt.Dimension(250, 30)); + + jlabelUrl.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jlabelUrl.setText(AppLocal.getIntString("label.erpurl")); // NOI18N + jlabelUrl.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabelId.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabelId.setText(AppLocal.getIntString("label.erpid")); // NOI18N + jLabelId.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.erporg")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.erppos")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabelName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabelName.setText(AppLocal.getIntString("label.erpuser")); // NOI18N + jLabelName.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabelProperties.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabelProperties.setText(AppLocal.getIntString("label.erppassword")); // NOI18N + jLabelProperties.setPreferredSize(new java.awt.Dimension(150, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jlabelUrl, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabelId, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabelName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabelProperties, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jtxtUrl, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtId, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(jtxtUrl, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jtxtId, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jtxtName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jtxtPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(jlabelUrl, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabelId, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabelName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabelProperties, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + ); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabelId; + private javax.swing.JLabel jLabelName; + private javax.swing.JLabel jLabelProperties; + private javax.swing.JTextField jTextField1; + private javax.swing.JTextField jTextField2; + private javax.swing.JLabel jlabelUrl; + private javax.swing.JTextField jtxtId; + private javax.swing.JTextField jtxtName; + private javax.swing.JPasswordField jtxtPassword; + private javax.swing.JTextField jtxtUrl; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/config/JPanelConfigGeneral.form b/src/main/java/com/unicenta/pos/config/JPanelConfigGeneral.form new file mode 100644 index 0000000..19ef05d --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JPanelConfigGeneral.form @@ -0,0 +1,655 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/pos/config/JPanelConfigGeneral.java b/src/main/java/com/unicenta/pos/config/JPanelConfigGeneral.java new file mode 100644 index 0000000..d53e206 --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JPanelConfigGeneral.java @@ -0,0 +1,668 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . +package com.unicenta.pos.config; + +import com.formdev.flatlaf.FlatLaf; +import com.formdev.flatlaf.FlatLightLaf; +import com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatAtomOneLightContrastIJTheme; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.util.FileChooserEvent; +import com.unicenta.pos.util.FlatLookAndFeel; +import lombok.extern.slf4j.Slf4j; +import org.pushingpixels.substance.api.SubstanceLookAndFeel; +import org.pushingpixels.substance.api.SubstanceSkin; +import org.pushingpixels.substance.api.skin.SkinInfo; + +import javax.swing.*; +import javax.swing.UIManager.LookAndFeelInfo; +import java.awt.*; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Map; + +/** + * @author JG uniCenta + */ + +@Slf4j +public class JPanelConfigGeneral extends javax.swing.JPanel implements PanelConfig { + + private final DirtyManager dirty = new DirtyManager(); + + /** + * Creates new form JPanelConfigGeneral + */ + public JPanelConfigGeneral() { + + initComponents(); + + InetAddress IP = null; + try { + IP = InetAddress.getLocalHost(); + } catch (UnknownHostException ex) { + log.error(ex.getMessage()); + } + + jtxtMachineHostname.getDocument().addDocumentListener(dirty); + jtxtMachineDepartment.getDocument().addDocumentListener(dirty); + lblIP_Address.setText(IP.toString()); + jcboLAF.addActionListener(dirty); + jcboMachineScreenmode.addActionListener(dirty); + jcboTicketsBag.addActionListener(dirty); + jchkHideInfo.addActionListener(dirty); + jtxtStartupText.getDocument().addDocumentListener(dirty); + jbtnText.addActionListener(new FileChooserEvent(jtxtStartupText)); + jtxtStartupLogo.getDocument().addDocumentListener(dirty); + jbtnLogo.addActionListener(new FileChooserEvent(jtxtStartupLogo)); + jtxtStartupHTML.getDocument().addDocumentListener(dirty); + jbtnHTML.addActionListener(new FileChooserEvent(jtxtStartupHTML)); + + FlatLookAndFeel.getLafs().forEach((key, value) -> + jcboLAF.addItem(new LAFInfo(key, value)) + ); + + jcboLAF.addActionListener((java.awt.event.ActionEvent evt) -> { + changeLAF(); + }); + + jcboMachineScreenmode.addItem("window"); + jcboMachineScreenmode.addItem("fullscreen"); + + jcboTicketsBag.addItem("simple"); + jcboTicketsBag.addItem("standard"); + jcboTicketsBag.addItem("restaurant"); + + } + + /** + * @return + */ + @Override + public boolean hasChanged() { + return dirty.isDirty(); + } + + /** + * @return + */ + @Override + public Component getConfigComponent() { + return this; + } + + /** + * @param config + */ + @Override + public void loadProperties(AppConfig config) { + + jtxtMachineHostname.setText(config.getProperty("machine.hostname")); + jtxtMachineDepartment.setText(config.getProperty("machine.department")); + + String lafclass = config.getProperty("swing.defaultlaf"); + jcboLAF.setSelectedItem(null); + for (int i = 0; i < jcboLAF.getItemCount(); i++) { + LAFInfo lafinfo = (LAFInfo) jcboLAF.getItemAt(i); + if (lafinfo.getClassName().equals(lafclass)) { + jcboLAF.setSelectedIndex(i); + break; + } + } + + jcboMachineScreenmode.setSelectedItem(config.getProperty("machine.screenmode")); + jcboTicketsBag.setSelectedItem(config.getProperty("machine.ticketsbag")); + jchkHideInfo.setSelected(Boolean.parseBoolean(config.getProperty("till.hideinfo"))); + jtxtStartupLogo.setText(config.getProperty("start.logo")); + jtxtStartupText.setText(config.getProperty("start.text")); + jtxtStartupLogo.setText(config.getProperty("start.logo")); + jtxtStartupHTML.setText(config.getProperty("start.html")); + + String txtPIN = (config.getProperty("override.pin")); + if (txtPIN == null) { + config.setProperty("override.check", "true"); + config.setProperty("override.pin", "1234"); + } + +// jtxtStartupMedia.setText(config.getProperty("start.media")); // Coming later!! + + dirty.setDirty(false); + } + + /** + * @param config + */ + @Override + public void saveProperties(AppConfig config) { + + config.setProperty("machine.hostname", jtxtMachineHostname.getText()); + config.setProperty("machine.department", jtxtMachineDepartment.getText()); + + LAFInfo laf = (LAFInfo) jcboLAF.getSelectedItem(); + config.setProperty("swing.defaultlaf", laf == null + ? System.getProperty("swing.defaultlaf", "javax.swing.plaf.metal.MetalLookAndFeel") + : laf.getClassName()); + + config.setProperty("machine.screenmode", comboValue(jcboMachineScreenmode.getSelectedItem())); + config.setProperty("machine.ticketsbag", comboValue(jcboTicketsBag.getSelectedItem())); + config.setProperty("till.hideinfo", Boolean.toString(jchkHideInfo.isSelected())); + config.setProperty("start.logo", jtxtStartupLogo.getText()); + config.setProperty("start.text", jtxtStartupText.getText()); + config.setProperty("start.html", jtxtStartupHTML.getText()); + +// config.setProperty("start.media", jtxtStartupMedia.getText()); // Coming later! + + dirty.setDirty(false); + } + + private String comboValue(Object value) { + return value == null ? "" : value.toString(); + } + + private void changeLAF() { + + final LAFInfo laf = (LAFInfo) jcboLAF.getSelectedItem(); + if (laf != null && !laf.getClassName().equals(UIManager.getLookAndFeel().getClass().getName())) { + // The selected look and feel is different from the current look and feel. + SwingUtilities.invokeLater(() -> { + try { + String lafname = laf.getClassName(); + Object laf1 = Class.forName(lafname).newInstance(); + if (laf1 instanceof LookAndFeel) { + UIManager.setLookAndFeel((LookAndFeel) laf1); + } else if (laf1 instanceof SubstanceSkin) { + SubstanceLookAndFeel.setSkin((SubstanceSkin) laf1); + } + SwingUtilities.updateComponentTreeUI(JPanelConfigGeneral.this.getTopLevelAncestor()); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) { + } + }); + } + } + + private static class LAFInfo { + + private final String name; + private final String classname; + + public LAFInfo(String name, String classname) { + this.name = name; + this.classname = classname; + } + + public String getName() { + return name; + } + + public String getClassName() { + return classname; + } + + @Override + public String toString() { + return name; + } + } + + /** + * This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel11 = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + jtxtMachineHostname = new javax.swing.JTextField(); + jcboLAF = new javax.swing.JComboBox(); + jcboMachineScreenmode = new javax.swing.JComboBox(); + jcboTicketsBag = new javax.swing.JComboBox(); + jchkHideInfo = new javax.swing.JCheckBox(); + jLabel18 = new javax.swing.JLabel(); + jtxtStartupLogo = new javax.swing.JTextField(); + jLabel19 = new javax.swing.JLabel(); + jtxtStartupText = new javax.swing.JTextField(); + jbtnLogo = new javax.swing.JButton(); + jbtnText = new javax.swing.JButton(); + jbtnTextClear = new javax.swing.JButton(); + jLabel6 = new javax.swing.JLabel(); + jtxtMachineDepartment = new javax.swing.JTextField(); + lblIP_Address = new com.alee.laf.label.WebLabel(); + webLabel1 = new com.alee.laf.label.WebLabel(); + jLblURL = new javax.swing.JLabel(); + jtxtStartupHTML = new javax.swing.JTextField(); + jbtnHTML = new javax.swing.JButton(); + jbtnClearHTML = new javax.swing.JButton(); + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setOpaque(false); + setPreferredSize(new java.awt.Dimension(800, 450)); + + jPanel11.setBackground(new java.awt.Color(255, 255, 255)); + jPanel11.setOpaque(false); + jPanel11.setPreferredSize(new java.awt.Dimension(750, 450)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.MachineName")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.looknfeel")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.MachineScreen")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.Ticketsbag")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(150, 30)); + + jtxtMachineHostname.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtMachineHostname.setToolTipText(AppLocal.getIntString("tooltip.config.general.terminal")); // NOI18N + jtxtMachineHostname.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + jtxtMachineHostname.setMinimumSize(new java.awt.Dimension(130, 25)); + jtxtMachineHostname.setPreferredSize(new java.awt.Dimension(200, 30)); + + jcboLAF.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboLAF.setToolTipText(AppLocal.getIntString("tooltip.config.general.skin")); // NOI18N + jcboLAF.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + jcboLAF.setPreferredSize(new java.awt.Dimension(200, 30)); + jcboLAF.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcboLAFActionPerformed(evt); + } + }); + + jcboMachineScreenmode.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboMachineScreenmode.setToolTipText(AppLocal.getIntString("tooltip.config.general.screen")); // NOI18N + jcboMachineScreenmode.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + jcboMachineScreenmode.setPreferredSize(new java.awt.Dimension(200, 30)); + + jcboTicketsBag.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboTicketsBag.setToolTipText(AppLocal.getIntString("tooltip.config.general.tickets")); // NOI18N + jcboTicketsBag.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + jcboTicketsBag.setPreferredSize(new java.awt.Dimension(200, 30)); + + jchkHideInfo.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jchkHideInfo.setSelected(true); + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jchkHideInfo.setText(bundle.getString("label.Infopanel")); // NOI18N + jchkHideInfo.setToolTipText(AppLocal.getIntString("tooltip.config.general.footer")); // NOI18N + jchkHideInfo.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jchkHideInfo.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT); + jchkHideInfo.setMaximumSize(new java.awt.Dimension(0, 25)); + jchkHideInfo.setMinimumSize(new java.awt.Dimension(0, 0)); + jchkHideInfo.setOpaque(false); + jchkHideInfo.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel18.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel18.setText(bundle.getString("label.startuplogo")); // NOI18N + jLabel18.setMaximumSize(new java.awt.Dimension(0, 25)); + jLabel18.setMinimumSize(new java.awt.Dimension(0, 0)); + jLabel18.setPreferredSize(new java.awt.Dimension(150, 30)); + + jtxtStartupLogo.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtStartupLogo.setToolTipText(AppLocal.getIntString("tooltip.config.general.logo")); // NOI18N + jtxtStartupLogo.setMaximumSize(new java.awt.Dimension(0, 25)); + jtxtStartupLogo.setMinimumSize(new java.awt.Dimension(0, 0)); + jtxtStartupLogo.setPreferredSize(new java.awt.Dimension(400, 30)); + + jLabel19.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel19.setText(AppLocal.getIntString("label.startuptext")); // NOI18N + jLabel19.setMaximumSize(new java.awt.Dimension(0, 25)); + jLabel19.setMinimumSize(new java.awt.Dimension(0, 0)); + jLabel19.setPreferredSize(new java.awt.Dimension(150, 30)); + + jtxtStartupText.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtStartupText.setToolTipText(AppLocal.getIntString("tooltip.config.general.text")); // NOI18N + jtxtStartupText.setMaximumSize(new java.awt.Dimension(0, 25)); + jtxtStartupText.setMinimumSize(new java.awt.Dimension(0, 0)); + jtxtStartupText.setPreferredSize(new java.awt.Dimension(400, 30)); + jtxtStartupText.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jtxtStartupTextFocusGained(evt); + } + }); + jtxtStartupText.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jtxtStartupTextActionPerformed(evt); + } + }); + + jbtnLogo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/fileopen.png"))); // NOI18N + jbtnLogo.setText(" "); + jbtnLogo.setToolTipText(AppLocal.getIntString("tooltip.config.general.logo")); // NOI18N + jbtnLogo.setMaximumSize(new java.awt.Dimension(64, 32)); + jbtnLogo.setMinimumSize(new java.awt.Dimension(64, 32)); + jbtnLogo.setPreferredSize(new java.awt.Dimension(80, 45)); + jbtnLogo.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnLogoActionPerformed(evt); + } + }); + + jbtnText.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/fileopen.png"))); // NOI18N + jbtnText.setText(" "); + jbtnText.setToolTipText(AppLocal.getIntString("tooltip.config.general.text")); // NOI18N + jbtnText.setMaximumSize(new java.awt.Dimension(64, 32)); + jbtnText.setMinimumSize(new java.awt.Dimension(64, 32)); + jbtnText.setPreferredSize(new java.awt.Dimension(80, 45)); + jbtnText.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnTextActionPerformed(evt); + } + }); + + jbtnTextClear.setFont(new java.awt.Font("Arial", 1, 12)); // NOI18N + jbtnTextClear.setForeground(new java.awt.Color(255, 0, 153)); + jbtnTextClear.setText("X"); + jbtnTextClear.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnTextClearActionPerformed(evt); + } + }); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setText(AppLocal.getIntString("label.MachineDepartment")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(150, 30)); + + jtxtMachineDepartment.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtMachineDepartment.setToolTipText(AppLocal.getIntString("tooltip.config.general.dept")); // NOI18N + jtxtMachineDepartment.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + jtxtMachineDepartment.setMinimumSize(new java.awt.Dimension(130, 25)); + jtxtMachineDepartment.setPreferredSize(new java.awt.Dimension(200, 30)); + + lblIP_Address.setBackground(new java.awt.Color(240, 240, 240)); + lblIP_Address.setBorder(null); + lblIP_Address.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + lblIP_Address.setToolTipText(AppLocal.getIntString("tooltip.config.general.compip")); // NOI18N + lblIP_Address.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + lblIP_Address.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT); + lblIP_Address.setPreferredSize(new java.awt.Dimension(230, 30)); + + webLabel1.setBackground(new java.awt.Color(240, 240, 240)); + webLabel1.setBorder(null); + webLabel1.setText(bundle.getString("label.nameIP")); // NOI18N + webLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + webLabel1.setPreferredSize(new java.awt.Dimension(300, 30)); + + jLblURL.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblURL.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/pay.png"))); // NOI18N + jLblURL.setText(AppLocal.getIntString("label.URL")); // NOI18N + jLblURL.setToolTipText(bundle.getString("tooltip.config.general.URL")); // NOI18N + jLblURL.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT); + jLblURL.setMaximumSize(new java.awt.Dimension(0, 25)); + jLblURL.setMinimumSize(new java.awt.Dimension(0, 0)); + jLblURL.setPreferredSize(new java.awt.Dimension(150, 30)); + jLblURL.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + jLblURLMouseClicked(evt); + } + }); + + jtxtStartupHTML.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtStartupHTML.setToolTipText(AppLocal.getIntString("tooltip.config.general.text")); // NOI18N + jtxtStartupHTML.setMaximumSize(new java.awt.Dimension(0, 25)); + jtxtStartupHTML.setMinimumSize(new java.awt.Dimension(0, 0)); + jtxtStartupHTML.setPreferredSize(new java.awt.Dimension(400, 30)); + jtxtStartupHTML.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jtxtStartupHTMLFocusGained(evt); + } + }); + jtxtStartupHTML.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jtxtStartupHTMLActionPerformed(evt); + } + }); + + jbtnHTML.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/fileopen.png"))); // NOI18N + jbtnHTML.setText(" "); + jbtnHTML.setToolTipText(AppLocal.getIntString("tooltip.config.general.text")); // NOI18N + jbtnHTML.setMaximumSize(new java.awt.Dimension(64, 32)); + jbtnHTML.setMinimumSize(new java.awt.Dimension(64, 32)); + jbtnHTML.setPreferredSize(new java.awt.Dimension(80, 45)); + jbtnHTML.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnHTMLActionPerformed(evt); + } + }); + + jbtnClearHTML.setFont(new java.awt.Font("Arial", 1, 12)); // NOI18N + jbtnClearHTML.setForeground(new java.awt.Color(255, 0, 153)); + jbtnClearHTML.setText("X"); + jbtnClearHTML.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnClearHTMLActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel11Layout = new javax.swing.GroupLayout(jPanel11); + jPanel11.setLayout(jPanel11Layout); + jPanel11Layout.setHorizontalGroup( + jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel11Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel11Layout.createSequentialGroup() + .addGroup(jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel11Layout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jtxtMachineHostname, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel11Layout.createSequentialGroup() + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jtxtMachineDepartment, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(webLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 132, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblIP_Address, javax.swing.GroupLayout.PREFERRED_SIZE, 271, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel11Layout.createSequentialGroup() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jcboLAF, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel11Layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jcboMachineScreenmode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel11Layout.createSequentialGroup() + .addGroup(jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel11Layout.createSequentialGroup() + .addComponent(jLabel18, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jtxtStartupLogo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel11Layout.createSequentialGroup() + .addGroup(jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel19, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblURL, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jchkHideInfo, javax.swing.GroupLayout.PREFERRED_SIZE, 287, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtStartupText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtStartupHTML, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jbtnLogo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel11Layout.createSequentialGroup() + .addComponent(jbtnText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jbtnTextClear, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel11Layout.createSequentialGroup() + .addComponent(jbtnHTML, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jbtnClearHTML, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addGroup(jPanel11Layout.createSequentialGroup() + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jcboTicketsBag, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel11Layout.setVerticalGroup( + jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel11Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtMachineHostname, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(webLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(lblIP_Address, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtMachineDepartment, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboLAF, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboMachineScreenmode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboTicketsBag, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(48, 48, 48) + .addGroup(jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel18, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtStartupLogo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jbtnLogo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel19, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtStartupText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jbtnText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jbtnTextClear)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLblURL, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtStartupHTML, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jbtnHTML, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jbtnClearHTML)) + .addGap(18, 18, 18) + .addComponent(jchkHideInfo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jPanel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + ); + + getAccessibleContext().setAccessibleName(""); + }// //GEN-END:initComponents + + private void jcboLAFActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcboLAFActionPerformed + + }//GEN-LAST:event_jcboLAFActionPerformed + + private void jtxtStartupTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jtxtStartupTextActionPerformed + + }//GEN-LAST:event_jtxtStartupTextActionPerformed + + private void jtxtStartupTextFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jtxtStartupTextFocusGained + // JG 31 August 2103 GNU GPL License Warning + +// transferFocus(); + +// JOptionPane.showMessageDialog(jPanel1,"Changing default Startup Text content may violate the
" +// + " Free Software Foundation's GNU General Public License GPL","GNU GPL Warning",JOptionPane.WARNING_MESSAGE); + + }//GEN-LAST:event_jtxtStartupTextFocusGained + + private void jbtnTextClearActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnTextClearActionPerformed + jtxtStartupText.setText(""); + }//GEN-LAST:event_jbtnTextClearActionPerformed + + private void jtxtStartupHTMLFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jtxtStartupHTMLFocusGained + // TODO add your handling code here: + }//GEN-LAST:event_jtxtStartupHTMLFocusGained + + private void jtxtStartupHTMLActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jtxtStartupHTMLActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jtxtStartupHTMLActionPerformed + + private void jbtnClearHTMLActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnClearHTMLActionPerformed + jtxtStartupHTML.setText(""); + }//GEN-LAST:event_jbtnClearHTMLActionPerformed + + private void jbtnHTMLActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnHTMLActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jbtnHTMLActionPerformed + + private void jbtnLogoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnLogoActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jbtnLogoActionPerformed + + private void jLblURLMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLblURLMouseClicked + JOptionPane.showMessageDialog(this, + AppLocal.getIntString("message.URL"), + "URL", + JOptionPane.INFORMATION_MESSAGE); + }//GEN-LAST:event_jLblURLMouseClicked + + private void jbtnTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnTextActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jbtnTextActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel18; + private javax.swing.JLabel jLabel19; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLblURL; + private javax.swing.JPanel jPanel11; + private javax.swing.JButton jbtnClearHTML; + private javax.swing.JButton jbtnHTML; + private javax.swing.JButton jbtnLogo; + private javax.swing.JButton jbtnText; + private javax.swing.JButton jbtnTextClear; + private javax.swing.JComboBox jcboLAF; + private javax.swing.JComboBox jcboMachineScreenmode; + private javax.swing.JComboBox jcboTicketsBag; + private javax.swing.JCheckBox jchkHideInfo; + private javax.swing.JTextField jtxtMachineDepartment; + private javax.swing.JTextField jtxtMachineHostname; + private javax.swing.JTextField jtxtStartupHTML; + private javax.swing.JTextField jtxtStartupLogo; + private javax.swing.JTextField jtxtStartupText; + private com.alee.laf.label.WebLabel lblIP_Address; + private com.alee.laf.label.WebLabel webLabel1; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/config/JPanelConfigLocale.form b/src/main/java/com/unicenta/pos/config/JPanelConfigLocale.form new file mode 100644 index 0000000..dcc99f0 --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JPanelConfigLocale.form @@ -0,0 +1,347 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/pos/config/JPanelConfigLocale.java b/src/main/java/com/unicenta/pos/config/JPanelConfigLocale.java new file mode 100644 index 0000000..db38801 --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JPanelConfigLocale.java @@ -0,0 +1,425 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.config; + +import com.unicenta.data.user.DirtyManager; +import java.awt.Component; +import java.util.Locale; +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * + * @author adrianromero + */ +public class JPanelConfigLocale extends javax.swing.JPanel implements PanelConfig { + + private final DirtyManager dirty = new DirtyManager(); + + private final static String DEFAULT_VALUE = "(Default)"; + + /** Creates new form JPanelConfigLocale */ + public JPanelConfigLocale() { + + initComponents(); + + jcboLocale.addActionListener(dirty); + jcboInteger.addActionListener(dirty); + jcboDouble.addActionListener(dirty); + jcboCurrency.addActionListener(dirty); + jcboPercent.addActionListener(dirty); + jcboDate.addActionListener(dirty); + jcboTime.addActionListener(dirty); + jcboDatetime.addActionListener(dirty); + + List availablelocales = new ArrayList<>(); + availablelocales.addAll(Arrays.asList(Locale.getAvailableLocales())); // Available java locales +// addLocale(availablelocales, new Locale("en", "GB", "")); // English GB +// addLocale(availablelocales, new Locale("en", "US", "")); // English USA + + Collections.sort(availablelocales, new LocaleComparator()); + + jcboLocale.addItem(new LocaleInfo (null)); + for (Locale l : availablelocales) { + jcboLocale.addItem(new LocaleInfo(l)); + } + + jcboInteger.addItem(DEFAULT_VALUE); + jcboInteger.addItem("#0"); + jcboInteger.addItem("#,##0"); + + jcboDouble.addItem(DEFAULT_VALUE); + jcboDouble.addItem("#0.0"); + jcboDouble.addItem("#,##0.#"); + + jcboCurrency.addItem(DEFAULT_VALUE); + jcboCurrency.addItem("\u00A4 #0.00"); + jcboCurrency.addItem("'$' #,##0.00"); + + jcboPercent.addItem(DEFAULT_VALUE); + jcboPercent.addItem("#,##0.##%"); + + jcboDate.addItem(DEFAULT_VALUE); + + jcboTime.addItem(DEFAULT_VALUE); + + jcboDatetime.addItem(DEFAULT_VALUE); + + } + + private void addLocale(List ll, Locale l) { + if (!ll.contains(l)) { + ll.add(l); + } + } + + /** + * + * @return + */ + @Override + public boolean hasChanged() { + return dirty.isDirty(); + } + + /** + * + * @return + */ + @Override + public Component getConfigComponent() { + return this; + } + + /** + * + * @param config + */ + @Override + public void loadProperties(AppConfig config) { + + String slang = config.getProperty("user.language"); + String scountry = config.getProperty("user.country"); + String svariant = config.getProperty("user.variant"); + + if (slang != null && !slang.equals("") && scountry != null && svariant != null) { + Locale currentlocale = new Locale(slang, scountry, svariant); + for (int i = 0 ; i < jcboLocale.getItemCount(); i++) { + LocaleInfo l = (LocaleInfo) jcboLocale.getItemAt(i); + if (currentlocale.equals(l.getLocale())) { + jcboLocale.setSelectedIndex(i); + break; + } + } + } else { + jcboLocale.setSelectedIndex(0); + } + + jcboInteger.setSelectedItem(writeWithDefault(config.getProperty("format.integer"))); + jcboDouble.setSelectedItem(writeWithDefault(config.getProperty("format.double"))); + jcboCurrency.setSelectedItem(writeWithDefault(config.getProperty("format.currency"))); + jcboPercent.setSelectedItem(writeWithDefault(config.getProperty("format.percent"))); + jcboDate.setSelectedItem(writeWithDefault(config.getProperty("format.date"))); + jcboTime.setSelectedItem(writeWithDefault(config.getProperty("format.time"))); + jcboDatetime.setSelectedItem(writeWithDefault(config.getProperty("format.datetime"))); + + dirty.setDirty(false); + } + + /** + * + * @param config + */ + @Override + public void saveProperties(AppConfig config) { + + Locale l = ((LocaleInfo) jcboLocale.getSelectedItem()).getLocale(); + if (l == null) { + config.setProperty("user.language", ""); + config.setProperty("user.country", ""); + config.setProperty("user.variant", ""); + } else { + config.setProperty("user.language", l.getLanguage()); + config.setProperty("user.country", l.getCountry()); + config.setProperty("user.variant", l.getVariant()); + } + + config.setProperty("format.integer", readWithDefault(jcboInteger.getSelectedItem())); + config.setProperty("format.double", readWithDefault(jcboDouble.getSelectedItem())); + config.setProperty("format.currency", readWithDefault(jcboCurrency.getSelectedItem())); + config.setProperty("format.percent", readWithDefault(jcboPercent.getSelectedItem())); + config.setProperty("format.date", readWithDefault(jcboDate.getSelectedItem())); + config.setProperty("format.time", readWithDefault(jcboTime.getSelectedItem())); + config.setProperty("format.datetime", readWithDefault(jcboDatetime.getSelectedItem())); + + dirty.setDirty(false); + } + + private String readWithDefault(Object value) { + if (DEFAULT_VALUE.equals(value)) { + return ""; + } else { + return value.toString(); + } + } + + private Object writeWithDefault(String value) { + if (value == null || value.equals("") || value.equals(DEFAULT_VALUE)) { + return DEFAULT_VALUE; + } else { + return value; + } + } + + private static class LocaleInfo { + private final Locale locale; + + public LocaleInfo(Locale locale) { + this.locale = locale; + } + public Locale getLocale() { + return locale; + } + @Override + public String toString() { + return locale == null + ? "(System default)" + : locale.getDisplayName(); + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jLabel5 = new javax.swing.JLabel(); + jcboLocale = new javax.swing.JComboBox(); + jLabel1 = new javax.swing.JLabel(); + jcboInteger = new javax.swing.JComboBox(); + jLabel2 = new javax.swing.JLabel(); + jcboDouble = new javax.swing.JComboBox(); + jLabel3 = new javax.swing.JLabel(); + jcboCurrency = new javax.swing.JComboBox(); + jLabel4 = new javax.swing.JLabel(); + jcboPercent = new javax.swing.JComboBox(); + jLabel6 = new javax.swing.JLabel(); + jcboDate = new javax.swing.JComboBox(); + jLabel7 = new javax.swing.JLabel(); + jcboTime = new javax.swing.JComboBox(); + jLabel8 = new javax.swing.JLabel(); + jcboDatetime = new javax.swing.JComboBox(); + + setMinimumSize(new java.awt.Dimension(0, 0)); + setOpaque(false); + setPreferredSize(new java.awt.Dimension(650, 450)); + + jPanel1.setOpaque(false); + jPanel1.setPreferredSize(new java.awt.Dimension(600, 400)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.locale")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(150, 30)); + + jcboLocale.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboLocale.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.integer")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(150, 30)); + + jcboInteger.setEditable(true); + jcboInteger.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboInteger.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.double")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(150, 30)); + + jcboDouble.setEditable(true); + jcboDouble.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboDouble.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.currency")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(150, 30)); + + jcboCurrency.setEditable(true); + jcboCurrency.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboCurrency.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.percent")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(150, 30)); + + jcboPercent.setEditable(true); + jcboPercent.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboPercent.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setText(AppLocal.getIntString("label.date")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(150, 30)); + + jcboDate.setEditable(true); + jcboDate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboDate.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel7.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel7.setText(AppLocal.getIntString("label.time")); // NOI18N + jLabel7.setPreferredSize(new java.awt.Dimension(150, 30)); + + jcboTime.setEditable(true); + jcboTime.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboTime.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel8.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel8.setText(AppLocal.getIntString("label.datetime")); // NOI18N + jLabel8.setPreferredSize(new java.awt.Dimension(150, 30)); + + jcboDatetime.setEditable(true); + jcboDatetime.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboDatetime.setPreferredSize(new java.awt.Dimension(0, 30)); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jcboDatetime, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jcboTime, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jcboDate, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jcboPercent, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jcboCurrency, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jcboDouble, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jcboInteger, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jcboLocale, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(51, 51, 51)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jcboLocale, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboInteger, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboDouble, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboCurrency, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboPercent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboDatetime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(100, Short.MAX_VALUE)) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(200, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(2, 2, 2) + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(148, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JPanel jPanel1; + private javax.swing.JComboBox jcboCurrency; + private javax.swing.JComboBox jcboDate; + private javax.swing.JComboBox jcboDatetime; + private javax.swing.JComboBox jcboDouble; + private javax.swing.JComboBox jcboInteger; + private javax.swing.JComboBox jcboLocale; + private javax.swing.JComboBox jcboPercent; + private javax.swing.JComboBox jcboTime; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/config/JPanelConfigPayment.form b/src/main/java/com/unicenta/pos/config/JPanelConfigPayment.form new file mode 100644 index 0000000..01da136 --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JPanelConfigPayment.form @@ -0,0 +1,216 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/pos/config/JPanelConfigPayment.java b/src/main/java/com/unicenta/pos/config/JPanelConfigPayment.java new file mode 100644 index 0000000..0e7391c --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JPanelConfigPayment.java @@ -0,0 +1,303 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.config; + +import com.unicenta.data.user.DirtyManager; +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.payment.ConfigPaymentPanelEmpty; +import com.unicenta.pos.payment.PaymentConfiguration; +import java.awt.Component; +import java.util.HashMap; +import java.util.Map; + +/** + * + * @author adrianromero + * @author Mikel Irurita + */ +public class JPanelConfigPayment extends javax.swing.JPanel implements PanelConfig { + + private final DirtyManager dirty = new DirtyManager(); + private final Map paymentsName = new HashMap<>(); + private PaymentConfiguration paymentConfiguration; + + /** Creates new form JPanelConfigPayment */ + public JPanelConfigPayment() { + + initComponents(); + + // dirty manager + jcboCardReader.addActionListener(dirty); + jcboPaymentGateway.addActionListener(dirty); + + // Payment Provider + initPayments("Not defined", new ConfigPaymentPanelEmpty()); + initPayments("external", new ConfigPaymentPanelEmpty()); + initPayments("PaymentSense", new ConfigPaymentPanelEmpty()); + + // Lector de tarjetas. + jcboCardReader.addItem("Not defined"); + jcboCardReader.addItem("EMV"); + jcboCardReader.addItem("External"); + jcboCardReader.addItem("Generic"); + jcboCardReader.addItem("Intelligent"); + jcboCardReader.addItem("Keyboard"); + jcboCardReader.addItem("NFC/RFID"); + } + + /** + * + * @return + */ + @Override + public boolean hasChanged() { + return dirty.isDirty(); + } + + /** + * + * @return + */ + @Override + public Component getConfigComponent() { + return this; + } + + /** + * + * @param config + */ + @Override + public void loadProperties(AppConfig config) { + + jcboCardReader.setSelectedItem(config.getProperty("payment.magcardreader")); + jcboPaymentGateway.setSelectedItem(config.getProperty("payment.gateway")); + urlValue.setText(config.getProperty("payment.URL")); + deviceIdValue.setText(config.getProperty("payment.device-id")); + securityKeyValue.setText(config.getProperty("payment.security-key")); + paymentConfiguration.loadProperties(config); + dirty.setDirty(false); + } + + /** + * + * @param config + */ + @Override + public void saveProperties(AppConfig config) { + + config.setProperty("payment.magcardreader", comboValue(jcboCardReader.getSelectedItem())); + config.setProperty("payment.gateway", comboValue(jcboPaymentGateway.getSelectedItem())); + config.setProperty("payment.URL", urlValue.getText()); + config.setProperty("payment.device-id", deviceIdValue.getText()); + config.setProperty("payment.security-key", securityKeyValue.getText()); + paymentConfiguration.saveProperties(config); + dirty.setDirty(false); + } + + private void initPayments(String name, PaymentConfiguration pc) { + jcboPaymentGateway.addItem(name); + paymentsName.put(name, pc); + } + + private String comboValue(Object value) { + return value == null ? "" : value.toString(); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jLabel13 = new javax.swing.JLabel(); + jcboPaymentGateway = new javax.swing.JComboBox(); + jLabel11 = new javax.swing.JLabel(); + jcboCardReader = new javax.swing.JComboBox(); + emvConfigPanel = new javax.swing.JPanel(); + urlLabel = new javax.swing.JLabel(); + urlValue = new javax.swing.JTextField(); + deviceIdLabel = new javax.swing.JLabel(); + deviceIdValue = new javax.swing.JTextField(); + securityKeyLabel = new javax.swing.JLabel(); + securityKeyValue = new javax.swing.JTextField(); + jLabel1 = new javax.swing.JLabel(); + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setOpaque(false); + setPreferredSize(new java.awt.Dimension(590, 450)); + + jLabel13.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel13.setText(AppLocal.getIntString("label.paymentgateway")); // NOI18N + jLabel13.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT); + jLabel13.setPreferredSize(new java.awt.Dimension(150, 30)); + + jcboPaymentGateway.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboPaymentGateway.setPreferredSize(new java.awt.Dimension(200, 30)); + jcboPaymentGateway.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcboPaymentGatewayActionPerformed(evt); + } + }); + + jLabel11.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel11.setText(AppLocal.getIntString("label.cardreader")); // NOI18N + jLabel11.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT); + jLabel11.setPreferredSize(new java.awt.Dimension(150, 30)); + + jcboCardReader.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboCardReader.setPreferredSize(new java.awt.Dimension(200, 30)); + + emvConfigPanel.setBackground(new java.awt.Color(255, 255, 255)); + + urlLabel.setText("URL"); + urlLabel.setFont(new java.awt.Font("Arial", 0, 14)); + + urlValue.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + urlValueActionPerformed(evt); + } + }); + + deviceIdLabel.setText("Device ID"); + deviceIdLabel.setFont(new java.awt.Font("Arial", 0, 14)); + + securityKeyLabel.setText("Security Key"); + securityKeyLabel.setFont(new java.awt.Font("Arial", 0, 14)); + + jLabel1.setFont(new java.awt.Font("Liberation Sans", 1, 18)); // NOI18N + jLabel1.setText("Device Configuration"); + + javax.swing.GroupLayout emvConfigPanelLayout = new javax.swing.GroupLayout(emvConfigPanel); + emvConfigPanel.setLayout(emvConfigPanelLayout); + emvConfigPanelLayout.setHorizontalGroup( + emvConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(emvConfigPanelLayout.createSequentialGroup() + .addGap(18, 18, 18) + .addGroup(emvConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(securityKeyLabel) + .addComponent(deviceIdLabel) + .addComponent(urlLabel)) + .addGap(59, 59, 59) + .addGroup(emvConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(urlValue) + .addComponent(deviceIdValue) + .addComponent(securityKeyValue)) + .addContainerGap()) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, emvConfigPanelLayout.createSequentialGroup() + .addContainerGap(125, Short.MAX_VALUE) + .addComponent(jLabel1) + .addGap(114, 114, 114)) + ); + emvConfigPanelLayout.setVerticalGroup( + emvConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, emvConfigPanelLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 12, Short.MAX_VALUE) + .addGroup(emvConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(urlValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(urlLabel)) + .addGap(18, 18, 18) + .addGroup(emvConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(deviceIdValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(deviceIdLabel)) + .addGap(15, 15, 15) + .addGroup(emvConfigPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(securityKeyValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(securityKeyLabel)) + .addContainerGap()) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(149, 149, 149) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(jLabel11, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel13, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jcboCardReader, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboPaymentGateway, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(layout.createSequentialGroup() + .addGap(109, 109, 109) + .addComponent(emvConfigPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(127, 127, 127)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(11, 11, 11) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboPaymentGateway, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboCardReader, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(64, 64, 64) + .addComponent(emvConfigPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(152, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + private void urlValueActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_urlValueActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_urlValueActionPerformed + + private void jcboPaymentGatewayActionPerformed(java.awt.event.ActionEvent evt) { + paymentConfiguration = paymentsName.get(comboValue(jcboPaymentGateway.getSelectedItem())); + + if (comboValue(jcboPaymentGateway.getSelectedItem()).equals("PaymentSense")) { + emvConfigPanel.setVisible(Boolean.TRUE); + jcboCardReader.setSelectedItem("EMV"); + jcboCardReader.setEnabled(Boolean.FALSE); + } + else { + emvConfigPanel.setVisible(Boolean.FALSE); + jcboCardReader.setEnabled(Boolean.TRUE); + } + } + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel deviceIdLabel; + private javax.swing.JTextField deviceIdValue; + private javax.swing.JPanel emvConfigPanel; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel11; + private javax.swing.JLabel jLabel13; + private javax.swing.JComboBox jcboCardReader; + private javax.swing.JComboBox jcboPaymentGateway; + private javax.swing.JLabel securityKeyLabel; + private javax.swing.JTextField securityKeyValue; + private javax.swing.JLabel urlLabel; + private javax.swing.JTextField urlValue; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/config/JPanelConfigPeripheral.form b/src/main/java/com/unicenta/pos/config/JPanelConfigPeripheral.form new file mode 100644 index 0000000..af35e80 --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JPanelConfigPeripheral.form @@ -0,0 +1,2344 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/pos/config/JPanelConfigPeripheral.java b/src/main/java/com/unicenta/pos/config/JPanelConfigPeripheral.java new file mode 100644 index 0000000..4b3673e --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JPanelConfigPeripheral.java @@ -0,0 +1,2549 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . +package com.unicenta.pos.config; + +import com.unicenta.data.user.DirtyManager; +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.util.ReportUtils; +import com.unicenta.pos.util.StringParser; +import java.awt.CardLayout; +import java.awt.Component; +import javax.print.PrintService; +import javax.print.PrintServiceLookup; + + +/** + * + * @author JG uniCenta + */ + +public class JPanelConfigPeripheral extends javax.swing.JPanel implements PanelConfig { + + private final DirtyManager dirty = new DirtyManager(); + + private PrintService[] printServices; + + private final ParametersConfig printer1printerparams; + private final ParametersConfig printer2printerparams; + private final ParametersConfig printer3printerparams; + private final ParametersConfig printer4printerparams; + private final ParametersConfig printer5printerparams; + private final ParametersConfig printer6printerparams; + + /** Creates new form JPanelConfigGeneral */ + public JPanelConfigPeripheral() { + + initComponents(); + + printServices = PrintServiceLookup.lookupPrintServices(null, null); + String[] printernames = ReportUtils.getPrintNames(); + + jcboMachineDisplay.addActionListener(dirty); + jcboConnDisplay.addActionListener(dirty); + jcboSerialDisplay.addActionListener(dirty); + m_jtxtJPOSName.getDocument().addDocumentListener(dirty); + + jcboMachinePrinter.addActionListener(dirty); + jcboConnPrinter.addActionListener(dirty); + jcboSerialPrinter.addActionListener(dirty); + m_jtxtJPOSPrinter.getDocument().addDocumentListener(dirty); + m_jtxtJPOSDrawer.getDocument().addDocumentListener(dirty); + + printer1printerparams = new ParametersPrinter(printernames); + printer1printerparams.addDirtyManager(dirty); + m_jPrinterParams1.add(printer1printerparams.getComponent(), "printer"); + + jcboMachinePrinter2.addActionListener(dirty); + jcboConnPrinter2.addActionListener(dirty); + jcboSerialPrinter2.addActionListener(dirty); + m_jtxtJPOSPrinter2.getDocument().addDocumentListener(dirty); + m_jtxtJPOSDrawer2.getDocument().addDocumentListener(dirty); + + printer2printerparams = new ParametersPrinter(printernames); + printer2printerparams.addDirtyManager(dirty); + m_jPrinterParams2.add(printer2printerparams.getComponent(), "printer"); + + jcboMachinePrinter3.addActionListener(dirty); + jcboConnPrinter3.addActionListener(dirty); + jcboSerialPrinter3.addActionListener(dirty); + m_jtxtJPOSPrinter3.getDocument().addDocumentListener(dirty); + m_jtxtJPOSDrawer3.getDocument().addDocumentListener(dirty); + + printer3printerparams = new ParametersPrinter(printernames); + printer3printerparams.addDirtyManager(dirty); + m_jPrinterParams3.add(printer3printerparams.getComponent(), "printer"); + + jcboMachinePrinter4.addActionListener(dirty); + jcboConnPrinter4.addActionListener(dirty); + jcboSerialPrinter4.addActionListener(dirty); + m_jtxtJPOSPrinter4.getDocument().addDocumentListener(dirty); + m_jtxtJPOSDrawer4.getDocument().addDocumentListener(dirty); + + printer4printerparams = new ParametersPrinter(printernames); + printer4printerparams.addDirtyManager(dirty); + m_jPrinterParams4.add(printer4printerparams.getComponent(), "printer"); + + jcboMachinePrinter5.addActionListener(dirty); + jcboConnPrinter5.addActionListener(dirty); + jcboSerialPrinter5.addActionListener(dirty); + m_jtxtJPOSPrinter5.getDocument().addDocumentListener(dirty); + m_jtxtJPOSDrawer5.getDocument().addDocumentListener(dirty); + + printer5printerparams = new ParametersPrinter(printernames); + printer5printerparams.addDirtyManager(dirty); + m_jPrinterParams5.add(printer5printerparams.getComponent(), "printer"); + + jcboMachinePrinter6.addActionListener(dirty); + jcboConnPrinter6.addActionListener(dirty); + jcboSerialPrinter6.addActionListener(dirty); + m_jtxtJPOSPrinter6.getDocument().addDocumentListener(dirty); + m_jtxtJPOSDrawer6.getDocument().addDocumentListener(dirty); + + printer6printerparams = new ParametersPrinter(printernames); + printer6printerparams.addDirtyManager(dirty); + m_jPrinterParams6.add(printer6printerparams.getComponent(), "printer"); + + jcboMachineScale.addActionListener(dirty); + jcboSerialScale.addActionListener(dirty); + + jcboMachineScanner.addActionListener(dirty); + jcboSerialScanner.addActionListener(dirty); + + cboPrinters.addActionListener(dirty); + + webSwtch_iButton.addActionListener(dirty); + webSlider.addChangeListener(dirty); + +// printers + jcboMachinePrinter.addItem("Not defined"); + jcboMachinePrinter.addItem("screen"); + jcboMachinePrinter.addItem("printer"); + jcboMachinePrinter.addItem("epson"); + jcboMachinePrinter.addItem("tmu220"); + jcboMachinePrinter.addItem("star"); + jcboMachinePrinter.addItem("ODP1000"); + jcboMachinePrinter.addItem("ithaca"); + jcboMachinePrinter.addItem("surepos"); + jcboMachinePrinter.addItem("plain"); + jcboMachinePrinter.addItem("javapos"); + + jcboConnPrinter.addItem("file"); + jcboConnPrinter.addItem("serial"); + + jcboSerialPrinter.addItem("COM1"); + jcboSerialPrinter.addItem("COM2"); + jcboSerialPrinter.addItem("COM3"); + jcboSerialPrinter.addItem("COM4"); + jcboSerialPrinter.addItem("COM5"); + jcboSerialPrinter.addItem("COM6"); + jcboSerialPrinter.addItem("COM7"); + jcboSerialPrinter.addItem("COM8"); + jcboSerialPrinter.addItem("LPT1"); + jcboSerialPrinter.addItem("/dev/ttyS0"); + jcboSerialPrinter.addItem("/dev/ttyS1"); + jcboSerialPrinter.addItem("/dev/ttyS2"); + jcboSerialPrinter.addItem("/dev/ttyS3"); + jcboSerialPrinter.addItem("/dev/ttyS4"); + jcboSerialPrinter.addItem("/dev/ttyS5"); + + jcboMachinePrinter2.addItem("Not defined"); + jcboMachinePrinter2.addItem("screen"); + jcboMachinePrinter2.addItem("printer"); + jcboMachinePrinter2.addItem("epson"); + jcboMachinePrinter2.addItem("tmu220"); + jcboMachinePrinter2.addItem("star"); + jcboMachinePrinter2.addItem("ODP1000"); + jcboMachinePrinter2.addItem("ithaca"); + jcboMachinePrinter2.addItem("surepos"); + jcboMachinePrinter2.addItem("plain"); + jcboMachinePrinter2.addItem("javapos"); + + jcboConnPrinter2.addItem("file"); + jcboConnPrinter2.addItem("serial"); + + jcboSerialPrinter2.addItem("COM1"); + jcboSerialPrinter2.addItem("COM2"); + jcboSerialPrinter2.addItem("COM3"); + jcboSerialPrinter2.addItem("COM4"); + jcboSerialPrinter2.addItem("COM5"); + jcboSerialPrinter2.addItem("COM6"); + jcboSerialPrinter2.addItem("COM7"); + jcboSerialPrinter2.addItem("COM8"); + jcboSerialPrinter2.addItem("LPT1"); + jcboSerialPrinter2.addItem("/dev/ttyS0"); + jcboSerialPrinter2.addItem("/dev/ttyS1"); + jcboSerialPrinter2.addItem("/dev/ttyS2"); + jcboSerialPrinter2.addItem("/dev/ttyS3"); + jcboSerialPrinter2.addItem("/dev/ttyS4"); + jcboSerialPrinter2.addItem("/dev/ttyS5"); + + jcboMachinePrinter3.addItem("Not defined"); + jcboMachinePrinter3.addItem("screen"); + jcboMachinePrinter3.addItem("printer"); + jcboMachinePrinter3.addItem("epson"); + jcboMachinePrinter3.addItem("tmu220"); + jcboMachinePrinter3.addItem("star"); + jcboMachinePrinter3.addItem("ODP1000"); + jcboMachinePrinter3.addItem("ithaca"); + jcboMachinePrinter3.addItem("surepos"); + jcboMachinePrinter3.addItem("plain"); + jcboMachinePrinter3.addItem("javapos"); + + jcboConnPrinter3.addItem("file"); + jcboConnPrinter3.addItem("serial"); + + jcboSerialPrinter3.addItem("COM1"); + jcboSerialPrinter3.addItem("COM2"); + jcboSerialPrinter3.addItem("COM3"); + jcboSerialPrinter3.addItem("COM4"); + jcboSerialPrinter3.addItem("COM5"); + jcboSerialPrinter3.addItem("COM6"); + jcboSerialPrinter3.addItem("COM7"); + jcboSerialPrinter3.addItem("COM8"); + jcboSerialPrinter3.addItem("LPT1"); + jcboSerialPrinter3.addItem("/dev/ttyS0"); + jcboSerialPrinter3.addItem("/dev/ttyS1"); + jcboSerialPrinter3.addItem("/dev/ttyS2"); + jcboSerialPrinter3.addItem("/dev/ttyS3"); + jcboSerialPrinter3.addItem("/dev/ttyS4"); + jcboSerialPrinter3.addItem("/dev/ttyS5"); + + jcboMachinePrinter4.addItem("Not defined"); + jcboMachinePrinter4.addItem("screen"); + jcboMachinePrinter4.addItem("printer"); + jcboMachinePrinter4.addItem("epson"); + jcboMachinePrinter4.addItem("tmu220"); + jcboMachinePrinter4.addItem("star"); + jcboMachinePrinter4.addItem("ODP1000"); + jcboMachinePrinter4.addItem("ithaca"); + jcboMachinePrinter4.addItem("surepos"); + jcboMachinePrinter4.addItem("plain"); + jcboMachinePrinter4.addItem("javapos"); + + jcboConnPrinter4.addItem("file"); + jcboConnPrinter4.addItem("serial"); + + jcboSerialPrinter4.addItem("COM1"); + jcboSerialPrinter4.addItem("COM2"); + jcboSerialPrinter4.addItem("COM3"); + jcboSerialPrinter4.addItem("COM4"); + jcboSerialPrinter4.addItem("COM5"); + jcboSerialPrinter4.addItem("COM6"); + jcboSerialPrinter4.addItem("COM7"); + jcboSerialPrinter4.addItem("COM8"); + jcboSerialPrinter4.addItem("LPT1"); + jcboSerialPrinter4.addItem("/dev/ttyS0"); + jcboSerialPrinter4.addItem("/dev/ttyS1"); + jcboSerialPrinter4.addItem("/dev/ttyS2"); + jcboSerialPrinter4.addItem("/dev/ttyS3"); + jcboSerialPrinter4.addItem("/dev/ttyS4"); + jcboSerialPrinter4.addItem("/dev/ttyS5"); + + jcboMachinePrinter5.addItem("Not defined"); + jcboMachinePrinter5.addItem("screen"); + jcboMachinePrinter5.addItem("printer"); + jcboMachinePrinter5.addItem("epson"); + jcboMachinePrinter5.addItem("tmu220"); + jcboMachinePrinter5.addItem("star"); + jcboMachinePrinter5.addItem("ODP1000"); + jcboMachinePrinter5.addItem("ithaca"); + jcboMachinePrinter5.addItem("surepos"); + jcboMachinePrinter5.addItem("plain"); + jcboMachinePrinter5.addItem("javapos"); + + jcboConnPrinter5.addItem("file"); + jcboConnPrinter5.addItem("serial"); + + jcboSerialPrinter5.addItem("COM1"); + jcboSerialPrinter5.addItem("COM2"); + jcboSerialPrinter5.addItem("COM3"); + jcboSerialPrinter5.addItem("COM4"); + jcboSerialPrinter5.addItem("COM5"); + jcboSerialPrinter5.addItem("COM6"); + jcboSerialPrinter5.addItem("COM7"); + jcboSerialPrinter5.addItem("COM8"); + jcboSerialPrinter5.addItem("LPT1"); + jcboSerialPrinter5.addItem("/dev/ttyS0"); + jcboSerialPrinter5.addItem("/dev/ttyS1"); + jcboSerialPrinter5.addItem("/dev/ttyS2"); + jcboSerialPrinter5.addItem("/dev/ttyS3"); + jcboSerialPrinter5.addItem("/dev/ttyS4"); + jcboSerialPrinter5.addItem("/dev/ttyS5"); + + jcboMachinePrinter6.addItem("Not defined"); + jcboMachinePrinter6.addItem("screen"); + jcboMachinePrinter6.addItem("printer"); + jcboMachinePrinter6.addItem("epson"); + jcboMachinePrinter6.addItem("tmu220"); + jcboMachinePrinter6.addItem("star"); + jcboMachinePrinter6.addItem("ODP1000"); + jcboMachinePrinter6.addItem("ithaca"); + jcboMachinePrinter6.addItem("surepos"); + jcboMachinePrinter6.addItem("plain"); + jcboMachinePrinter6.addItem("javapos"); + + jcboConnPrinter6.addItem("file"); + jcboConnPrinter6.addItem("serial"); + + jcboSerialPrinter6.addItem("COM1"); + jcboSerialPrinter6.addItem("COM2"); + jcboSerialPrinter6.addItem("COM3"); + jcboSerialPrinter6.addItem("COM4"); + jcboSerialPrinter6.addItem("COM5"); + jcboSerialPrinter6.addItem("COM6"); + jcboSerialPrinter6.addItem("COM7"); + jcboSerialPrinter6.addItem("COM8"); + jcboSerialPrinter6.addItem("LPT1"); + jcboSerialPrinter6.addItem("/dev/ttyS0"); + jcboSerialPrinter6.addItem("/dev/ttyS1"); + jcboSerialPrinter6.addItem("/dev/ttyS2"); + jcboSerialPrinter6.addItem("/dev/ttyS3"); + jcboSerialPrinter6.addItem("/dev/ttyS4"); + jcboSerialPrinter6.addItem("/dev/ttyS5"); + + + // Display + jcboMachineDisplay.addItem("Not defined"); + jcboMachineDisplay.addItem("screen"); + jcboMachineDisplay.addItem("window"); + jcboMachineDisplay.addItem("javapos"); + jcboMachineDisplay.addItem("epson"); + jcboMachineDisplay.addItem("ld200"); + jcboMachineDisplay.addItem("surepos"); + + jcboConnDisplay.addItem("serial"); + jcboConnDisplay.addItem("file"); + + jcboSerialDisplay.addItem("COM1"); + jcboSerialDisplay.addItem("COM2"); + jcboSerialDisplay.addItem("COM3"); + jcboSerialDisplay.addItem("COM4"); + jcboSerialDisplay.addItem("COM5"); + jcboSerialDisplay.addItem("COM6"); + jcboSerialDisplay.addItem("COM7"); + jcboSerialDisplay.addItem("COM8"); + jcboSerialDisplay.addItem("LPT1"); + jcboSerialDisplay.addItem("/dev/ttyS0"); + jcboSerialDisplay.addItem("/dev/ttyS1"); + jcboSerialDisplay.addItem("/dev/ttyS2"); + jcboSerialDisplay.addItem("/dev/ttyS3"); + jcboSerialDisplay.addItem("/dev/ttyS4"); + jcboSerialDisplay.addItem("/dev/ttyS5"); + + + // Scale + jcboMachineScale.addItem("Not defined"); + jcboMachineScale.addItem("screen"); + jcboMachineScale.addItem("acompc100"); + jcboMachineScale.addItem("averyberkel6720"); + jcboMachineScale.addItem("casiopd1"); + jcboMachineScale.addItem("caspdii"); + jcboMachineScale.addItem("dialog1"); + jcboMachineScale.addItem("mtind221"); + jcboMachineScale.addItem("samsungesp"); + + jcboSerialScale.addItem("COM1"); + jcboSerialScale.addItem("COM2"); + jcboSerialScale.addItem("COM3"); + jcboSerialScale.addItem("COM4"); + jcboSerialScale.addItem("COM5"); + jcboSerialScale.addItem("COM6"); + jcboSerialScale.addItem("COM7"); + jcboSerialScale.addItem("COM8"); + jcboSerialScale.addItem("/dev/ttyS0"); + jcboSerialScale.addItem("/dev/ttyS1"); + jcboSerialScale.addItem("/dev/ttyS2"); + jcboSerialScale.addItem("/dev/ttyS3"); + jcboSerialScale.addItem("/dev/ttyS4"); + jcboSerialScale.addItem("/dev/ttyS5"); + + // Scanner + jcboMachineScanner.addItem("Not defined"); + jcboMachineScanner.addItem("scanpal2"); + + jcboSerialScanner.addItem("COM1"); + jcboSerialScanner.addItem("COM2"); + jcboSerialScanner.addItem("COM3"); + jcboSerialScanner.addItem("COM4"); + jcboSerialScanner.addItem("COM5"); + jcboSerialScanner.addItem("COM6"); + jcboSerialScanner.addItem("COM7"); + jcboSerialScanner.addItem("COM8"); + jcboSerialScanner.addItem("/dev/ttyS0"); + jcboSerialScanner.addItem("/dev/ttyS1"); + jcboSerialScanner.addItem("/dev/ttyS2"); + jcboSerialScanner.addItem("/dev/ttyS3"); + jcboSerialScanner.addItem("/dev/ttyS4"); + jcboSerialScanner.addItem("/dev/ttyS5"); + + // Printers + cboPrinters.addItem("(Default)"); + cboPrinters.addItem("(Show dialog)"); + for (String name : printernames) { + cboPrinters.addItem(name); + } + } + + /** + * + * @return + */ + @Override + public boolean hasChanged() { + return dirty.isDirty(); + } + + /** + * + * @return + */ + @Override + public Component getConfigComponent() { + return this; + } + + /** + * + * @param config + */ + @Override + public void loadProperties(AppConfig config) { + +// JG 6 May 2013 to switch + StringParser p = new StringParser(config.getProperty("machine.printer")); + String sparam = unifySerialInterface(p.nextToken(':')); + + switch (sparam) { + case "serial": + case "file": + jcboMachinePrinter.setSelectedItem("epson"); + jcboConnPrinter.setSelectedItem(sparam); + jcboSerialPrinter.setSelectedItem(p.nextToken(',')); + break; + case "javapos": + jcboMachinePrinter.setSelectedItem(sparam); + m_jtxtJPOSPrinter.setText(p.nextToken(',')); + m_jtxtJPOSDrawer.setText(p.nextToken(',')); + break; + case "printer": + jcboMachinePrinter.setSelectedItem(sparam); + printer1printerparams.setParameters(p); + break; + default: + jcboMachinePrinter.setSelectedItem(sparam); + jcboConnPrinter.setSelectedItem(unifySerialInterface(p.nextToken(','))); + jcboSerialPrinter.setSelectedItem(p.nextToken(',')); + break; + } + +// JG 6 May 2013 to switch + p = new StringParser(config.getProperty("machine.printer.2")); + sparam = unifySerialInterface(p.nextToken(':')); + switch (sparam) { + case "serial": + case "file": + jcboMachinePrinter2.setSelectedItem("epson"); + jcboConnPrinter2.setSelectedItem(sparam); + jcboSerialPrinter2.setSelectedItem(p.nextToken(',')); + break; + case "javapos": + jcboMachinePrinter2.setSelectedItem(sparam); + m_jtxtJPOSPrinter2.setText(p.nextToken(',')); + m_jtxtJPOSDrawer2.setText(p.nextToken(',')); + break; + case "printer": + jcboMachinePrinter2.setSelectedItem(sparam); + printer2printerparams.setParameters(p); + break; + default: + jcboMachinePrinter2.setSelectedItem(sparam); + jcboConnPrinter2.setSelectedItem(unifySerialInterface(p.nextToken(','))); + jcboSerialPrinter2.setSelectedItem(p.nextToken(',')); + break; + } + +// JG 6 May 2013 to switch + p = new StringParser(config.getProperty("machine.printer.3")); + sparam = unifySerialInterface(p.nextToken(':')); + switch (sparam) { + case "serial": + case "file": + jcboMachinePrinter3.setSelectedItem("epson"); + jcboConnPrinter3.setSelectedItem(sparam); + jcboSerialPrinter3.setSelectedItem(p.nextToken(',')); + break; + case "javapos": + jcboMachinePrinter3.setSelectedItem(sparam); + m_jtxtJPOSPrinter3.setText(p.nextToken(',')); + m_jtxtJPOSDrawer3.setText(p.nextToken(',')); + break; + case "printer": + jcboMachinePrinter3.setSelectedItem(sparam); + printer3printerparams.setParameters(p); + break; + default: + jcboMachinePrinter3.setSelectedItem(sparam); + jcboConnPrinter3.setSelectedItem(unifySerialInterface(p.nextToken(','))); + jcboSerialPrinter3.setSelectedItem(p.nextToken(',')); + break; + } + +// new printers add jdl 10.11.12 + + p = new StringParser(config.getProperty("machine.printer.4")); + sparam = unifySerialInterface(p.nextToken(':')); + switch (sparam) { + case "serial": + case "file": + jcboMachinePrinter4.setSelectedItem("epson"); + jcboConnPrinter4.setSelectedItem(sparam); + jcboSerialPrinter4.setSelectedItem(p.nextToken(',')); + break; + case "javapos": + jcboMachinePrinter4.setSelectedItem(sparam); + m_jtxtJPOSPrinter4.setText(p.nextToken(',')); + m_jtxtJPOSDrawer4.setText(p.nextToken(',')); + break; + case "printer": + jcboMachinePrinter4.setSelectedItem(sparam); + printer4printerparams.setParameters(p); + break; + default: + jcboMachinePrinter4.setSelectedItem(sparam); + jcboConnPrinter4.setSelectedItem(unifySerialInterface(p.nextToken(','))); + jcboSerialPrinter4.setSelectedItem(p.nextToken(',')); + break; + } + + + p = new StringParser(config.getProperty("machine.printer.5")); + sparam = unifySerialInterface(p.nextToken(':')); + switch (sparam) { + case "serial": + case "file": + jcboMachinePrinter5.setSelectedItem("epson"); + jcboConnPrinter5.setSelectedItem(sparam); + jcboSerialPrinter5.setSelectedItem(p.nextToken(',')); + break; + case "javapos": + jcboMachinePrinter5.setSelectedItem(sparam); + m_jtxtJPOSPrinter5.setText(p.nextToken(',')); + m_jtxtJPOSDrawer5.setText(p.nextToken(',')); + break; + case "printer": + jcboMachinePrinter5.setSelectedItem(sparam); + printer5printerparams.setParameters(p); + break; + default: + jcboMachinePrinter5.setSelectedItem(sparam); + jcboConnPrinter5.setSelectedItem(unifySerialInterface(p.nextToken(','))); + jcboSerialPrinter5.setSelectedItem(p.nextToken(',')); + break; + } + + + p = new StringParser(config.getProperty("machine.printer.6")); + sparam = unifySerialInterface(p.nextToken(':')); + switch (sparam) { + case "serial": + case "file": + jcboMachinePrinter6.setSelectedItem("epson"); + jcboConnPrinter6.setSelectedItem(sparam); + jcboSerialPrinter6.setSelectedItem(p.nextToken(',')); + break; + case "javapos": + jcboMachinePrinter6.setSelectedItem(sparam); + m_jtxtJPOSPrinter6.setText(p.nextToken(',')); + m_jtxtJPOSDrawer6.setText(p.nextToken(',')); + break; + case "printer": + jcboMachinePrinter6.setSelectedItem(sparam); + printer6printerparams.setParameters(p); + break; + default: + jcboMachinePrinter6.setSelectedItem(sparam); + jcboConnPrinter6.setSelectedItem(unifySerialInterface(p.nextToken(','))); + jcboSerialPrinter6.setSelectedItem(p.nextToken(',')); + break; + } + + + p = new StringParser(config.getProperty("machine.display")); + sparam = unifySerialInterface(p.nextToken(':')); + switch (sparam) { + case "serial": + case "file": + jcboMachineDisplay.setSelectedItem("epson"); + jcboConnDisplay.setSelectedItem(sparam); + jcboSerialDisplay.setSelectedItem(p.nextToken(',')); + break; + case "javapos": + jcboMachineDisplay.setSelectedItem(sparam); + m_jtxtJPOSName.setText(p.nextToken(',')); + break; + default: + jcboMachineDisplay.setSelectedItem(sparam); + jcboConnDisplay.setSelectedItem(unifySerialInterface(p.nextToken(','))); + jcboSerialDisplay.setSelectedItem(p.nextToken(',')); + break; + } + + + p = new StringParser(config.getProperty("machine.scale")); + sparam = p.nextToken(':'); + jcboMachineScale.setSelectedItem(sparam); + if ("casiopd1".equals(sparam) || + "dialog1".equals(sparam) || + "samsungesp".equals(sparam) || + "caspdii".equals(sparam) || + "acompc100".equals(sparam) || + "averyberkel6720".equals(sparam) || + "mtind221".equals(sparam)) { + jcboSerialScale.setSelectedItem(p.nextToken(',')); + } + + p = new StringParser(config.getProperty("machine.scanner")); + sparam = p.nextToken(':'); + jcboMachineScanner.setSelectedItem(sparam); + if ("scanpal2".equals(sparam)) { + jcboSerialScanner.setSelectedItem(p.nextToken(',')); + } + + cboPrinters.setSelectedItem(config.getProperty("machine.printername")); + + webSwtch_iButton.setSelected(Boolean.parseBoolean(config.getProperty("machine.iButton"))); + webSlider.setValue(Integer.valueOf(config.getProperty("machine.iButtonResponse"))); + + dirty.setDirty(false); + } + + /** + * + * @param config + */ + @Override + public void saveProperties(AppConfig config) { + +// JG 6 May 2013 to switch + String sMachinePrinter = comboValue(jcboMachinePrinter.getSelectedItem()); + switch (sMachinePrinter) { + case "epson": + case "tmu220": + case "star": + case "ODP1000": + case "ithaca": + case "surepos": + config.setProperty("machine.printer", sMachinePrinter + ":" + + comboValue(jcboConnPrinter.getSelectedItem()) + "," + + comboValue(jcboSerialPrinter.getSelectedItem())); + break; + case "javapos": + config.setProperty("machine.printer", sMachinePrinter + ":" + + m_jtxtJPOSPrinter.getText() + "," + + m_jtxtJPOSDrawer.getText()); + break; + case "printer": + config.setProperty("machine.printer", sMachinePrinter + ":" + + printer1printerparams.getParameters()); + break; + default: + config.setProperty("machine.printer", sMachinePrinter); + break; + } +// JG 6 May 2013 to switch + String sMachinePrinter2 = comboValue(jcboMachinePrinter2.getSelectedItem()); + switch (sMachinePrinter2) { + case "epson": + case "tmu220": + case "star": + case "ODP1000": + case "ithaca": + case "surepos": + config.setProperty("machine.printer.2", sMachinePrinter2 + ":" + + comboValue(jcboConnPrinter2.getSelectedItem()) + "," + + comboValue(jcboSerialPrinter2.getSelectedItem())); + break; + case "javapos": + config.setProperty("machine.printer.2", sMachinePrinter2 + ":" + + m_jtxtJPOSPrinter2.getText() + "," + + m_jtxtJPOSDrawer2.getText()); + break; + case "printer": + config.setProperty("machine.printer.2", sMachinePrinter2 + ":" + + printer2printerparams.getParameters()); + break; + default: + config.setProperty("machine.printer.2", sMachinePrinter2); + break; + } + +// JG 6 May 2013 to switch + String sMachinePrinter3 = comboValue(jcboMachinePrinter3.getSelectedItem()); + switch (sMachinePrinter3) { + case "epson": + case "tmu220": + case "star": + case "ODP1000": + case "ithaca": + case "surepos": + config.setProperty("machine.printer.3", sMachinePrinter3 + ":" + + comboValue(jcboConnPrinter3.getSelectedItem()) + "," + + comboValue(jcboSerialPrinter3.getSelectedItem())); + break; + case "javapos": + config.setProperty("machine.printer.3", sMachinePrinter3 + ":" + + m_jtxtJPOSPrinter3.getText() + "," + m_jtxtJPOSDrawer3.getText()); + break; + case "printer": + config.setProperty("machine.printer.3", sMachinePrinter3 + ":" + + printer3printerparams.getParameters()); + break; + default: + config.setProperty("machine.printer.3", sMachinePrinter3); + break; + } +// new printers added 10.11.12 + String sMachinePrinter4 = comboValue(jcboMachinePrinter4.getSelectedItem()); + switch (sMachinePrinter4) { + case "epson": + case "tmu220": + case "star": + case "ODP1000": + case "ithaca": + case "surepos": + config.setProperty("machine.printer.4", sMachinePrinter4 + ":" + + comboValue(jcboConnPrinter4.getSelectedItem()) + "," + + comboValue(jcboSerialPrinter4.getSelectedItem())); + break; + case "javapos": + config.setProperty("machine.printer.4", sMachinePrinter4 + ":" + + m_jtxtJPOSPrinter4.getText() + "," + m_jtxtJPOSDrawer4.getText()); + break; + case "printer": + config.setProperty("machine.printer.4", sMachinePrinter4 + ":" + + printer4printerparams.getParameters()); + break; + default: + config.setProperty("machine.printer.4", sMachinePrinter4); + break; + } + + String sMachinePrinter5 = comboValue(jcboMachinePrinter5.getSelectedItem()); + switch (sMachinePrinter5) { + case "epson": + case "tmu220": + case "star": + case "ODP1000": + case "ithaca": + case "surepos": + config.setProperty("machine.printer.5", sMachinePrinter5 + ":" + + comboValue(jcboConnPrinter5.getSelectedItem()) + "," + + comboValue(jcboSerialPrinter5.getSelectedItem())); + break; + case "javapos": + config.setProperty("machine.printer.5", sMachinePrinter5 + ":" + + m_jtxtJPOSPrinter5.getText() + "," + m_jtxtJPOSDrawer5.getText()); + break; + case "printer": + config.setProperty("machine.printer.5", sMachinePrinter5 + ":" + + printer5printerparams.getParameters()); + break; + default: + config.setProperty("machine.printer.5", sMachinePrinter5); + break; + } + + + String sMachinePrinter6 = comboValue(jcboMachinePrinter6.getSelectedItem()); + switch (sMachinePrinter6) { + case "epson": + case "tmu220": + case "star": + case "ODP1000": + case "ithaca": + case "surepos": + config.setProperty("machine.printer.6", sMachinePrinter6 + ":" + + comboValue(jcboConnPrinter6.getSelectedItem()) + "," + + comboValue(jcboSerialPrinter6.getSelectedItem())); + break; + case "javapos": + config.setProperty("machine.printer.6", sMachinePrinter6 + ":" + + m_jtxtJPOSPrinter6.getText() + "," + m_jtxtJPOSDrawer6.getText()); + break; + case "printer": + config.setProperty("machine.printer.6", sMachinePrinter6 + ":" + + printer6printerparams.getParameters()); + break; + default: + config.setProperty("machine.printer.6", sMachinePrinter6); + break; + } + + +// JG 6 May 2013 to switch + String sMachineDisplay = comboValue(jcboMachineDisplay.getSelectedItem()); + switch (sMachineDisplay) { + case "epson": + case "ld200": + case "surepos": + config.setProperty("machine.display", sMachineDisplay + ":" + + comboValue(jcboConnDisplay.getSelectedItem()) + "," + + comboValue(jcboSerialDisplay.getSelectedItem())); + break; + case "javapos": + config.setProperty("machine.display", sMachineDisplay + ":" + m_jtxtJPOSName.getText()); + break; + default: + config.setProperty("machine.display", sMachineDisplay); + break; + } + +// acompc100 + averyberkel6720 scales added Feb 2017 + String sMachineScale = comboValue(jcboMachineScale.getSelectedItem()); + if ("casiopd1".equals(sMachineScale) || + "dialog1".equals(sMachineScale) || + "samsungesp".equals(sMachineScale) || + "caspdii".equals(sMachineScale) || + "acompc100".equals(sMachineScale) || + "averyberkel6720".equals(sMachineScale) || + "mtind221".equals(sMachineScale)) { + config.setProperty("machine.scale", sMachineScale + ":" + + comboValue(jcboSerialScale.getSelectedItem())); + } else { + config.setProperty("machine.scale", sMachineScale); + } + + // El scanner + String sMachineScanner = comboValue(jcboMachineScanner.getSelectedItem()); + if ("scanpal2".equals(sMachineScanner)) { + config.setProperty("machine.scanner", sMachineScanner + ":" + + comboValue(jcboSerialScanner.getSelectedItem())); + } else { + config.setProperty("machine.scanner", sMachineScanner); + } + + config.setProperty("machine.printername", comboValue(cboPrinters.getSelectedItem())); + +// iButton + config.setProperty("machine.iButton",Boolean.toString(webSwtch_iButton.isSelected())); + config.setProperty("machine.iButtonResponse",Integer.toString(webSlider.getValue())); + + dirty.setDirty(false); + } + + private String unifySerialInterface(String sparam) { + + // for backward compatibility + return ("rxtx".equals(sparam)) + ? "serial" + : sparam; + } + + private String comboValue(Object value) { + return value == null ? "" : value.toString(); + } + + private void buildPrinterList(javax.swing.JComboBox comboBox) { + + comboBox.addItem("COM1"); + comboBox.addItem("COM2"); + comboBox.addItem("COM3"); + comboBox.addItem("COM4"); + comboBox.addItem("COM5"); + comboBox.addItem("COM6"); + comboBox.addItem("COM7"); + comboBox.addItem("COM8"); + comboBox.addItem("COM9"); + comboBox.addItem("COM10"); + comboBox.addItem("COM11"); + comboBox.addItem("COM12"); + + comboBox.addItem("LPT1"); + comboBox.addItem("/dev/ttyS0"); + comboBox.addItem("/dev/ttyS1"); + comboBox.addItem("/dev/ttyS2"); + comboBox.addItem("/dev/ttyS3"); + comboBox.addItem("/dev/ttyS4"); + comboBox.addItem("/dev/ttyS5"); + } + + private void addRegisteredPrinters(javax.swing.JComboBox comboBox) { + for (PrintService printer : printServices) { + comboBox.addItem(printer.getName()); + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel13 = new javax.swing.JPanel(); + jLabel5 = new javax.swing.JLabel(); + jLabel6 = new javax.swing.JLabel(); + jLabel7 = new javax.swing.JLabel(); + jLabel8 = new javax.swing.JLabel(); + jLabel9 = new javax.swing.JLabel(); + jLabel10 = new javax.swing.JLabel(); + jLabel11 = new javax.swing.JLabel(); + jLabel12 = new javax.swing.JLabel(); + jLabel13 = new javax.swing.JLabel(); + jLabel14 = new javax.swing.JLabel(); + jcboMachineDisplay = new javax.swing.JComboBox(); + jcboMachinePrinter = new javax.swing.JComboBox(); + jcboMachinePrinter2 = new javax.swing.JComboBox(); + jcboMachinePrinter3 = new javax.swing.JComboBox(); + jcboMachinePrinter4 = new javax.swing.JComboBox(); + jcboMachinePrinter5 = new javax.swing.JComboBox(); + jcboMachinePrinter6 = new javax.swing.JComboBox(); + jcboMachineScale = new javax.swing.JComboBox(); + jcboMachineScanner = new javax.swing.JComboBox(); + cboPrinters = new javax.swing.JComboBox(); + m_jDisplayParams = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + jlblConnDisplay = new javax.swing.JLabel(); + jcboConnDisplay = new javax.swing.JComboBox(); + jlblDisplayPort = new javax.swing.JLabel(); + jcboSerialDisplay = new javax.swing.JComboBox(); + jPanel3 = new javax.swing.JPanel(); + jLabel20 = new javax.swing.JLabel(); + m_jtxtJPOSName = new javax.swing.JTextField(); + m_jPrinterParams1 = new javax.swing.JPanel(); + jPanel5 = new javax.swing.JPanel(); + jPanel6 = new javax.swing.JPanel(); + jlblConnPrinter = new javax.swing.JLabel(); + jcboConnPrinter = new javax.swing.JComboBox(); + jlblPrinterPort = new javax.swing.JLabel(); + jcboSerialPrinter = new javax.swing.JComboBox(); + jPanel4 = new javax.swing.JPanel(); + jLabel21 = new javax.swing.JLabel(); + m_jtxtJPOSPrinter = new javax.swing.JTextField(); + m_jtxtJPOSDrawer = new javax.swing.JTextField(); + jLabel24 = new javax.swing.JLabel(); + m_jPrinterParams2 = new javax.swing.JPanel(); + jPanel7 = new javax.swing.JPanel(); + jPanel8 = new javax.swing.JPanel(); + jlblConnPrinter2 = new javax.swing.JLabel(); + jcboConnPrinter2 = new javax.swing.JComboBox(); + jlblPrinterPort2 = new javax.swing.JLabel(); + jcboSerialPrinter2 = new javax.swing.JComboBox(); + jPanel11 = new javax.swing.JPanel(); + m_jtxtJPOSPrinter2 = new javax.swing.JTextField(); + m_jtxtJPOSDrawer2 = new javax.swing.JTextField(); + jLabel27 = new javax.swing.JLabel(); + jLabel22 = new javax.swing.JLabel(); + m_jPrinterParams3 = new javax.swing.JPanel(); + jPanel9 = new javax.swing.JPanel(); + jPanel10 = new javax.swing.JPanel(); + jlblConnPrinter3 = new javax.swing.JLabel(); + jcboConnPrinter3 = new javax.swing.JComboBox(); + jlblPrinterPort3 = new javax.swing.JLabel(); + jcboSerialPrinter3 = new javax.swing.JComboBox(); + jPanel12 = new javax.swing.JPanel(); + m_jtxtJPOSPrinter3 = new javax.swing.JTextField(); + m_jtxtJPOSDrawer3 = new javax.swing.JTextField(); + jLabel28 = new javax.swing.JLabel(); + jLabel23 = new javax.swing.JLabel(); + m_jPrinterParams4 = new javax.swing.JPanel(); + jPanel14 = new javax.swing.JPanel(); + jPanel15 = new javax.swing.JPanel(); + jlblConnPrinter4 = new javax.swing.JLabel(); + jcboConnPrinter4 = new javax.swing.JComboBox(); + jlblPrinterPort6 = new javax.swing.JLabel(); + jcboSerialPrinter4 = new javax.swing.JComboBox(); + jPanel18 = new javax.swing.JPanel(); + m_jtxtJPOSPrinter4 = new javax.swing.JTextField(); + m_jtxtJPOSDrawer4 = new javax.swing.JTextField(); + jLabel30 = new javax.swing.JLabel(); + jLabel31 = new javax.swing.JLabel(); + m_jPrinterParams5 = new javax.swing.JPanel(); + jPanel20 = new javax.swing.JPanel(); + jPanel21 = new javax.swing.JPanel(); + jlblConnPrinter5 = new javax.swing.JLabel(); + jcboConnPrinter5 = new javax.swing.JComboBox(); + jlblPrinterPort7 = new javax.swing.JLabel(); + jcboSerialPrinter5 = new javax.swing.JComboBox(); + jPanel22 = new javax.swing.JPanel(); + m_jtxtJPOSPrinter5 = new javax.swing.JTextField(); + m_jtxtJPOSDrawer5 = new javax.swing.JTextField(); + jLabel33 = new javax.swing.JLabel(); + jLabel34 = new javax.swing.JLabel(); + m_jPrinterParams6 = new javax.swing.JPanel(); + jPanel23 = new javax.swing.JPanel(); + jPanel25 = new javax.swing.JPanel(); + jlblConnPrinter6 = new javax.swing.JLabel(); + jcboConnPrinter6 = new javax.swing.JComboBox(); + jlblPrinterPort8 = new javax.swing.JLabel(); + jcboSerialPrinter6 = new javax.swing.JComboBox(); + jPanel26 = new javax.swing.JPanel(); + m_jtxtJPOSPrinter6 = new javax.swing.JTextField(); + m_jtxtJPOSDrawer6 = new javax.swing.JTextField(); + jLabel36 = new javax.swing.JLabel(); + jLabel37 = new javax.swing.JLabel(); + m_jScaleParams = new javax.swing.JPanel(); + jPanel16 = new javax.swing.JPanel(); + jPanel17 = new javax.swing.JPanel(); + jlblPrinterPort4 = new javax.swing.JLabel(); + jcboSerialScale = new javax.swing.JComboBox(); + m_jScannerParams = new javax.swing.JPanel(); + jPanel24 = new javax.swing.JPanel(); + jPanel19 = new javax.swing.JPanel(); + jcboSerialScanner = new javax.swing.JComboBox(); + jlblPrinterPort5 = new javax.swing.JLabel(); + jPanel27 = new javax.swing.JPanel(); + webSwtch_iButton = new com.alee.extended.button.WebSwitch(); + webLbliButton = new com.alee.laf.label.WebLabel(); + webSlider = new com.alee.laf.slider.WebSlider(); + webLabel1 = new com.alee.laf.label.WebLabel(); + webLabel2 = new com.alee.laf.label.WebLabel(); + webLabel3 = new com.alee.laf.label.WebLabel(); + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setOpaque(false); + setPreferredSize(new java.awt.Dimension(800, 525)); + + jPanel13.setOpaque(false); + jPanel13.setPreferredSize(new java.awt.Dimension(800, 520)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.MachineDisplay")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setText(AppLocal.getIntString("label.MachinePrinter")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel7.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel7.setText(AppLocal.getIntString("label.MachinePrinter2")); // NOI18N + jLabel7.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel8.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel8.setText(AppLocal.getIntString("label.MachinePrinter3")); // NOI18N + jLabel8.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel9.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel9.setText(AppLocal.getIntString("label.MachinePrinter4")); // NOI18N + jLabel9.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel10.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel10.setText(AppLocal.getIntString("label.MachinePrinter5")); // NOI18N + jLabel10.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel11.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel11.setText(AppLocal.getIntString("label.MachinePrinter6")); // NOI18N + jLabel11.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel12.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel12.setText(AppLocal.getIntString("label.scale")); // NOI18N + jLabel12.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel13.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel13.setText(AppLocal.getIntString("label.scanner")); // NOI18N + jLabel13.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel14.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel14.setText(AppLocal.getIntString("label.reportsprinter")); // NOI18N + jLabel14.setPreferredSize(new java.awt.Dimension(150, 30)); + + jcboMachineDisplay.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboMachineDisplay.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + jcboMachineDisplay.setPreferredSize(new java.awt.Dimension(200, 30)); + jcboMachineDisplay.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcboMachineDisplayActionPerformed(evt); + } + }); + + jcboMachinePrinter.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboMachinePrinter.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + jcboMachinePrinter.setPreferredSize(new java.awt.Dimension(200, 30)); + jcboMachinePrinter.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcboMachinePrinterActionPerformed(evt); + } + }); + + jcboMachinePrinter2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboMachinePrinter2.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + jcboMachinePrinter2.setPreferredSize(new java.awt.Dimension(200, 30)); + jcboMachinePrinter2.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcboMachinePrinter2ActionPerformed(evt); + } + }); + + jcboMachinePrinter3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboMachinePrinter3.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + jcboMachinePrinter3.setPreferredSize(new java.awt.Dimension(200, 30)); + jcboMachinePrinter3.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcboMachinePrinter3ActionPerformed(evt); + } + }); + + jcboMachinePrinter4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboMachinePrinter4.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + jcboMachinePrinter4.setPreferredSize(new java.awt.Dimension(200, 30)); + jcboMachinePrinter4.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcboMachinePrinter4ActionPerformed(evt); + } + }); + + jcboMachinePrinter5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboMachinePrinter5.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + jcboMachinePrinter5.setPreferredSize(new java.awt.Dimension(200, 30)); + jcboMachinePrinter5.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcboMachinePrinter5ActionPerformed(evt); + } + }); + + jcboMachinePrinter6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboMachinePrinter6.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + jcboMachinePrinter6.setPreferredSize(new java.awt.Dimension(200, 30)); + jcboMachinePrinter6.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcboMachinePrinter6ActionPerformed(evt); + } + }); + + jcboMachineScale.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboMachineScale.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + jcboMachineScale.setPreferredSize(new java.awt.Dimension(200, 30)); + jcboMachineScale.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcboMachineScaleActionPerformed(evt); + } + }); + + jcboMachineScanner.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboMachineScanner.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + jcboMachineScanner.setPreferredSize(new java.awt.Dimension(200, 30)); + jcboMachineScanner.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcboMachineScannerActionPerformed(evt); + } + }); + + cboPrinters.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + cboPrinters.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + cboPrinters.setPreferredSize(new java.awt.Dimension(200, 30)); + + m_jDisplayParams.setPreferredSize(new java.awt.Dimension(400, 30)); + m_jDisplayParams.setLayout(new java.awt.CardLayout()); + + jPanel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanel2.setOpaque(false); + jPanel2.setPreferredSize(new java.awt.Dimension(400, 30)); + m_jDisplayParams.add(jPanel2, "empty"); + + jPanel1.setBackground(new java.awt.Color(255, 255, 255)); + jPanel1.setPreferredSize(new java.awt.Dimension(400, 30)); + + jlblConnDisplay.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jlblConnDisplay.setText(AppLocal.getIntString("label.machinedisplayconn")); // NOI18N + jlblConnDisplay.setPreferredSize(new java.awt.Dimension(50, 30)); + + jcboConnDisplay.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcboConnDisplay.setMinimumSize(new java.awt.Dimension(80, 28)); + jcboConnDisplay.setPreferredSize(new java.awt.Dimension(80, 30)); + + jlblDisplayPort.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jlblDisplayPort.setText(AppLocal.getIntString("label.machinedisplayport")); // NOI18N + jlblDisplayPort.setPreferredSize(new java.awt.Dimension(50, 30)); + + jcboSerialDisplay.setEditable(true); + jcboSerialDisplay.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcboSerialDisplay.setPreferredSize(new java.awt.Dimension(150, 28)); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jlblConnDisplay, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboConnDisplay, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jlblDisplayPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboSerialDisplay, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(62, Short.MAX_VALUE)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jcboConnDisplay, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblDisplayPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboSerialDisplay, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblConnDisplay, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0)) + ); + + m_jDisplayParams.add(jPanel1, "comm"); + + jLabel20.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel20.setText(AppLocal.getIntString("Label.Name")); // NOI18N + jLabel20.setPreferredSize(new java.awt.Dimension(50, 25)); + + m_jtxtJPOSName.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jtxtJPOSName.setPreferredSize(new java.awt.Dimension(120, 25)); + m_jtxtJPOSName.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jtxtJPOSNameActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); + jPanel3.setLayout(jPanel3Layout); + jPanel3Layout.setHorizontalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jtxtJPOSName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(224, Short.MAX_VALUE)) + ); + jPanel3Layout.setVerticalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jtxtJPOSName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0)) + ); + + m_jDisplayParams.add(jPanel3, "javapos"); + + m_jPrinterParams1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jPrinterParams1.setPreferredSize(new java.awt.Dimension(400, 30)); + m_jPrinterParams1.setLayout(new java.awt.CardLayout()); + + jPanel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanel5.setOpaque(false); + jPanel5.setPreferredSize(new java.awt.Dimension(450, 30)); + m_jPrinterParams1.add(jPanel5, "empty"); + + jPanel6.setBackground(new java.awt.Color(255, 255, 255)); + jPanel6.setPreferredSize(new java.awt.Dimension(450, 30)); + + jlblConnPrinter.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jlblConnPrinter.setText(AppLocal.getIntString("label.machinedisplayconn")); // NOI18N + jlblConnPrinter.setPreferredSize(new java.awt.Dimension(50, 30)); + + jcboConnPrinter.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcboConnPrinter.setMinimumSize(new java.awt.Dimension(80, 28)); + jcboConnPrinter.setPreferredSize(new java.awt.Dimension(80, 30)); + jcboConnPrinter.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcboConnPrinterActionPerformed(evt); + } + }); + + jlblPrinterPort.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jlblPrinterPort.setText(AppLocal.getIntString("label.machineprinterport")); // NOI18N + jlblPrinterPort.setPreferredSize(new java.awt.Dimension(50, 30)); + + jcboSerialPrinter.setEditable(true); + jcboSerialPrinter.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcboSerialPrinter.setPreferredSize(new java.awt.Dimension(150, 28)); + + javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6); + jPanel6.setLayout(jPanel6Layout); + jPanel6Layout.setHorizontalGroup( + jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel6Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jlblConnPrinter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboConnPrinter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jlblPrinterPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboSerialPrinter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + jPanel6Layout.setVerticalGroup( + jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel6Layout.createSequentialGroup() + .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jcboConnPrinter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblPrinterPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboSerialPrinter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblConnPrinter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0)) + ); + + m_jPrinterParams1.add(jPanel6, "comm"); + + jLabel21.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel21.setText(AppLocal.getIntString("label.javapos.drawer")); // NOI18N + jLabel21.setPreferredSize(new java.awt.Dimension(50, 25)); + + m_jtxtJPOSPrinter.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jtxtJPOSPrinter.setPreferredSize(new java.awt.Dimension(120, 25)); + + m_jtxtJPOSDrawer.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jtxtJPOSDrawer.setPreferredSize(new java.awt.Dimension(120, 25)); + + jLabel24.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel24.setText(AppLocal.getIntString("label.javapos.printer")); // NOI18N + jLabel24.setPreferredSize(new java.awt.Dimension(50, 25)); + + javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); + jPanel4.setLayout(jPanel4Layout); + jPanel4Layout.setHorizontalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel24, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jtxtJPOSPrinter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jtxtJPOSDrawer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel4Layout.setVerticalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jtxtJPOSPrinter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jtxtJPOSDrawer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel24, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0)) + ); + + m_jPrinterParams1.add(jPanel4, "javapos"); + + m_jPrinterParams2.setPreferredSize(new java.awt.Dimension(400, 30)); + m_jPrinterParams2.setLayout(new java.awt.CardLayout()); + + jPanel7.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanel7.setOpaque(false); + jPanel7.setPreferredSize(new java.awt.Dimension(200, 30)); + m_jPrinterParams2.add(jPanel7, "empty"); + + jPanel8.setBackground(new java.awt.Color(255, 255, 255)); + jPanel8.setPreferredSize(new java.awt.Dimension(450, 30)); + + jlblConnPrinter2.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jlblConnPrinter2.setText(AppLocal.getIntString("label.machinedisplayconn")); // NOI18N + jlblConnPrinter2.setPreferredSize(new java.awt.Dimension(50, 30)); + + jcboConnPrinter2.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcboConnPrinter2.setMinimumSize(new java.awt.Dimension(80, 28)); + jcboConnPrinter2.setPreferredSize(new java.awt.Dimension(80, 30)); + jcboConnPrinter2.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcboConnPrinter2ActionPerformed(evt); + } + }); + + jlblPrinterPort2.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jlblPrinterPort2.setText(AppLocal.getIntString("label.machineprinterport")); // NOI18N + jlblPrinterPort2.setPreferredSize(new java.awt.Dimension(50, 30)); + + jcboSerialPrinter2.setEditable(true); + jcboSerialPrinter2.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcboSerialPrinter2.setPreferredSize(new java.awt.Dimension(150, 28)); + + javax.swing.GroupLayout jPanel8Layout = new javax.swing.GroupLayout(jPanel8); + jPanel8.setLayout(jPanel8Layout); + jPanel8Layout.setHorizontalGroup( + jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel8Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jlblConnPrinter2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboConnPrinter2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jlblPrinterPort2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboSerialPrinter2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + jPanel8Layout.setVerticalGroup( + jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel8Layout.createSequentialGroup() + .addGroup(jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jcboConnPrinter2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblPrinterPort2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboSerialPrinter2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblConnPrinter2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0)) + ); + + m_jPrinterParams2.add(jPanel8, "comm"); + + m_jtxtJPOSPrinter2.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jtxtJPOSPrinter2.setPreferredSize(new java.awt.Dimension(120, 25)); + + m_jtxtJPOSDrawer2.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jtxtJPOSDrawer2.setPreferredSize(new java.awt.Dimension(120, 25)); + + jLabel27.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel27.setText(AppLocal.getIntString("label.javapos.printer")); // NOI18N + jLabel27.setPreferredSize(new java.awt.Dimension(50, 25)); + + jLabel22.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel22.setText(AppLocal.getIntString("label.javapos.drawer")); // NOI18N + jLabel22.setPreferredSize(new java.awt.Dimension(50, 25)); + + javax.swing.GroupLayout jPanel11Layout = new javax.swing.GroupLayout(jPanel11); + jPanel11.setLayout(jPanel11Layout); + jPanel11Layout.setHorizontalGroup( + jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel11Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel27, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jtxtJPOSPrinter2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel22, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jtxtJPOSDrawer2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel11Layout.setVerticalGroup( + jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel11Layout.createSequentialGroup() + .addGroup(jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jtxtJPOSPrinter2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel22, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jtxtJPOSDrawer2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel27, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0)) + ); + + m_jPrinterParams2.add(jPanel11, "javapos"); + + m_jPrinterParams3.setPreferredSize(new java.awt.Dimension(400, 30)); + m_jPrinterParams3.setLayout(new java.awt.CardLayout()); + + jPanel9.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanel9.setOpaque(false); + jPanel9.setPreferredSize(new java.awt.Dimension(200, 30)); + m_jPrinterParams3.add(jPanel9, "empty"); + + jPanel10.setBackground(new java.awt.Color(255, 255, 255)); + jPanel10.setPreferredSize(new java.awt.Dimension(450, 30)); + + jlblConnPrinter3.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jlblConnPrinter3.setText(AppLocal.getIntString("label.machinedisplayconn")); // NOI18N + jlblConnPrinter3.setPreferredSize(new java.awt.Dimension(50, 30)); + + jcboConnPrinter3.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcboConnPrinter3.setMinimumSize(new java.awt.Dimension(80, 28)); + jcboConnPrinter3.setPreferredSize(new java.awt.Dimension(80, 30)); + jcboConnPrinter3.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcboConnPrinter3ActionPerformed(evt); + } + }); + + jlblPrinterPort3.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jlblPrinterPort3.setText(AppLocal.getIntString("label.machineprinterport")); // NOI18N + jlblPrinterPort3.setPreferredSize(new java.awt.Dimension(50, 30)); + + jcboSerialPrinter3.setEditable(true); + jcboSerialPrinter3.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcboSerialPrinter3.setPreferredSize(new java.awt.Dimension(150, 28)); + + javax.swing.GroupLayout jPanel10Layout = new javax.swing.GroupLayout(jPanel10); + jPanel10.setLayout(jPanel10Layout); + jPanel10Layout.setHorizontalGroup( + jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel10Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jlblConnPrinter3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboConnPrinter3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jlblPrinterPort3, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboSerialPrinter3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + jPanel10Layout.setVerticalGroup( + jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel10Layout.createSequentialGroup() + .addGroup(jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jcboConnPrinter3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblPrinterPort3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboSerialPrinter3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblConnPrinter3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0)) + ); + + m_jPrinterParams3.add(jPanel10, "comm"); + + m_jtxtJPOSPrinter3.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jtxtJPOSPrinter3.setPreferredSize(new java.awt.Dimension(120, 25)); + + m_jtxtJPOSDrawer3.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jtxtJPOSDrawer3.setPreferredSize(new java.awt.Dimension(120, 25)); + + jLabel28.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel28.setText(AppLocal.getIntString("label.javapos.printer")); // NOI18N + jLabel28.setPreferredSize(new java.awt.Dimension(50, 25)); + + jLabel23.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel23.setText(AppLocal.getIntString("label.javapos.drawer")); // NOI18N + jLabel23.setPreferredSize(new java.awt.Dimension(50, 25)); + + javax.swing.GroupLayout jPanel12Layout = new javax.swing.GroupLayout(jPanel12); + jPanel12.setLayout(jPanel12Layout); + jPanel12Layout.setHorizontalGroup( + jPanel12Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel12Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel28, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jtxtJPOSPrinter3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel23, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jtxtJPOSDrawer3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel12Layout.setVerticalGroup( + jPanel12Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel12Layout.createSequentialGroup() + .addGroup(jPanel12Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jtxtJPOSPrinter3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel23, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jtxtJPOSDrawer3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel28, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0)) + ); + + m_jPrinterParams3.add(jPanel12, "javapos"); + + m_jPrinterParams4.setPreferredSize(new java.awt.Dimension(400, 30)); + m_jPrinterParams4.setLayout(new java.awt.CardLayout()); + + jPanel14.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanel14.setOpaque(false); + jPanel14.setPreferredSize(new java.awt.Dimension(200, 30)); + m_jPrinterParams4.add(jPanel14, "empty"); + + jPanel15.setBackground(new java.awt.Color(255, 255, 255)); + jPanel15.setPreferredSize(new java.awt.Dimension(450, 30)); + + jlblConnPrinter4.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jlblConnPrinter4.setText(AppLocal.getIntString("label.machinedisplayconn")); // NOI18N + jlblConnPrinter4.setPreferredSize(new java.awt.Dimension(50, 30)); + + jcboConnPrinter4.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcboConnPrinter4.setMinimumSize(new java.awt.Dimension(80, 28)); + jcboConnPrinter4.setPreferredSize(new java.awt.Dimension(80, 30)); + jcboConnPrinter4.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcboConnPrinter4ActionPerformed(evt); + } + }); + + jlblPrinterPort6.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jlblPrinterPort6.setText(AppLocal.getIntString("label.machineprinterport")); // NOI18N + jlblPrinterPort6.setPreferredSize(new java.awt.Dimension(50, 30)); + + jcboSerialPrinter4.setEditable(true); + jcboSerialPrinter4.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcboSerialPrinter4.setPreferredSize(new java.awt.Dimension(150, 28)); + + javax.swing.GroupLayout jPanel15Layout = new javax.swing.GroupLayout(jPanel15); + jPanel15.setLayout(jPanel15Layout); + jPanel15Layout.setHorizontalGroup( + jPanel15Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel15Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jlblConnPrinter4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboConnPrinter4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jlblPrinterPort6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboSerialPrinter4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + jPanel15Layout.setVerticalGroup( + jPanel15Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel15Layout.createSequentialGroup() + .addGroup(jPanel15Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jcboConnPrinter4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblPrinterPort6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboSerialPrinter4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblConnPrinter4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0)) + ); + + m_jPrinterParams4.add(jPanel15, "comm"); + + m_jtxtJPOSPrinter4.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jtxtJPOSPrinter4.setPreferredSize(new java.awt.Dimension(120, 25)); + + m_jtxtJPOSDrawer4.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jtxtJPOSDrawer4.setPreferredSize(new java.awt.Dimension(120, 25)); + + jLabel30.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel30.setText(AppLocal.getIntString("label.javapos.printer")); // NOI18N + jLabel30.setPreferredSize(new java.awt.Dimension(50, 25)); + + jLabel31.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel31.setText(AppLocal.getIntString("label.javapos.drawer")); // NOI18N + jLabel31.setPreferredSize(new java.awt.Dimension(50, 25)); + + javax.swing.GroupLayout jPanel18Layout = new javax.swing.GroupLayout(jPanel18); + jPanel18.setLayout(jPanel18Layout); + jPanel18Layout.setHorizontalGroup( + jPanel18Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel18Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel30, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jtxtJPOSPrinter4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel31, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jtxtJPOSDrawer4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel18Layout.setVerticalGroup( + jPanel18Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel18Layout.createSequentialGroup() + .addGroup(jPanel18Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jtxtJPOSPrinter4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel31, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jtxtJPOSDrawer4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel30, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0)) + ); + + m_jPrinterParams4.add(jPanel18, "javapos"); + + m_jPrinterParams5.setPreferredSize(new java.awt.Dimension(400, 30)); + m_jPrinterParams5.setLayout(new java.awt.CardLayout()); + + jPanel20.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanel20.setOpaque(false); + jPanel20.setPreferredSize(new java.awt.Dimension(200, 30)); + m_jPrinterParams5.add(jPanel20, "empty"); + + jPanel21.setBackground(new java.awt.Color(255, 255, 255)); + jPanel21.setPreferredSize(new java.awt.Dimension(450, 30)); + + jlblConnPrinter5.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jlblConnPrinter5.setText(AppLocal.getIntString("label.machinedisplayconn")); // NOI18N + jlblConnPrinter5.setPreferredSize(new java.awt.Dimension(50, 30)); + + jcboConnPrinter5.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcboConnPrinter5.setMinimumSize(new java.awt.Dimension(80, 28)); + jcboConnPrinter5.setPreferredSize(new java.awt.Dimension(80, 30)); + jcboConnPrinter5.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcboConnPrinter5ActionPerformed(evt); + } + }); + + jlblPrinterPort7.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jlblPrinterPort7.setText(AppLocal.getIntString("label.machineprinterport")); // NOI18N + jlblPrinterPort7.setPreferredSize(new java.awt.Dimension(50, 30)); + + jcboSerialPrinter5.setEditable(true); + jcboSerialPrinter5.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcboSerialPrinter5.setPreferredSize(new java.awt.Dimension(150, 28)); + + javax.swing.GroupLayout jPanel21Layout = new javax.swing.GroupLayout(jPanel21); + jPanel21.setLayout(jPanel21Layout); + jPanel21Layout.setHorizontalGroup( + jPanel21Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel21Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jlblConnPrinter5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboConnPrinter5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jlblPrinterPort7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboSerialPrinter5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + jPanel21Layout.setVerticalGroup( + jPanel21Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel21Layout.createSequentialGroup() + .addGroup(jPanel21Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jcboConnPrinter5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblPrinterPort7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboSerialPrinter5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblConnPrinter5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0)) + ); + + m_jPrinterParams5.add(jPanel21, "comm"); + + m_jtxtJPOSPrinter5.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jtxtJPOSPrinter5.setPreferredSize(new java.awt.Dimension(120, 25)); + + m_jtxtJPOSDrawer5.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jtxtJPOSDrawer5.setPreferredSize(new java.awt.Dimension(120, 25)); + + jLabel33.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel33.setText(AppLocal.getIntString("label.javapos.printer")); // NOI18N + jLabel33.setPreferredSize(new java.awt.Dimension(50, 25)); + + jLabel34.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel34.setText(AppLocal.getIntString("label.javapos.drawer")); // NOI18N + jLabel34.setPreferredSize(new java.awt.Dimension(50, 25)); + + javax.swing.GroupLayout jPanel22Layout = new javax.swing.GroupLayout(jPanel22); + jPanel22.setLayout(jPanel22Layout); + jPanel22Layout.setHorizontalGroup( + jPanel22Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel22Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel33, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jtxtJPOSPrinter5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel34, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jtxtJPOSDrawer5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel22Layout.setVerticalGroup( + jPanel22Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel22Layout.createSequentialGroup() + .addGroup(jPanel22Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jtxtJPOSPrinter5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel34, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jtxtJPOSDrawer5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel33, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0)) + ); + + m_jPrinterParams5.add(jPanel22, "javapos"); + + m_jPrinterParams6.setPreferredSize(new java.awt.Dimension(400, 30)); + m_jPrinterParams6.setLayout(new java.awt.CardLayout()); + + jPanel23.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanel23.setOpaque(false); + jPanel23.setPreferredSize(new java.awt.Dimension(200, 30)); + m_jPrinterParams6.add(jPanel23, "empty"); + + jPanel25.setBackground(new java.awt.Color(255, 255, 255)); + jPanel25.setPreferredSize(new java.awt.Dimension(450, 30)); + + jlblConnPrinter6.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jlblConnPrinter6.setText(AppLocal.getIntString("label.machinedisplayconn")); // NOI18N + jlblConnPrinter6.setPreferredSize(new java.awt.Dimension(50, 30)); + + jcboConnPrinter6.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcboConnPrinter6.setPreferredSize(new java.awt.Dimension(80, 30)); + jcboConnPrinter6.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcboConnPrinter6ActionPerformed(evt); + } + }); + + jlblPrinterPort8.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jlblPrinterPort8.setText(AppLocal.getIntString("label.machineprinterport")); // NOI18N + jlblPrinterPort8.setPreferredSize(new java.awt.Dimension(50, 25)); + + jcboSerialPrinter6.setEditable(true); + jcboSerialPrinter6.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcboSerialPrinter6.setPreferredSize(new java.awt.Dimension(150, 28)); + + javax.swing.GroupLayout jPanel25Layout = new javax.swing.GroupLayout(jPanel25); + jPanel25.setLayout(jPanel25Layout); + jPanel25Layout.setHorizontalGroup( + jPanel25Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel25Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jlblConnPrinter6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboConnPrinter6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jlblPrinterPort8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboSerialPrinter6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + jPanel25Layout.setVerticalGroup( + jPanel25Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel25Layout.createSequentialGroup() + .addGroup(jPanel25Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jcboConnPrinter6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblPrinterPort8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboSerialPrinter6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblConnPrinter6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0)) + ); + + m_jPrinterParams6.add(jPanel25, "comm"); + + m_jtxtJPOSPrinter6.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jtxtJPOSPrinter6.setPreferredSize(new java.awt.Dimension(120, 25)); + + m_jtxtJPOSDrawer6.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jtxtJPOSDrawer6.setPreferredSize(new java.awt.Dimension(120, 25)); + + jLabel36.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel36.setText(AppLocal.getIntString("label.javapos.printer")); // NOI18N + jLabel36.setPreferredSize(new java.awt.Dimension(50, 25)); + + jLabel37.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel37.setText(AppLocal.getIntString("label.javapos.drawer")); // NOI18N + jLabel37.setPreferredSize(new java.awt.Dimension(50, 25)); + + javax.swing.GroupLayout jPanel26Layout = new javax.swing.GroupLayout(jPanel26); + jPanel26.setLayout(jPanel26Layout); + jPanel26Layout.setHorizontalGroup( + jPanel26Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel26Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel36, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jtxtJPOSPrinter6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel37, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jtxtJPOSDrawer6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel26Layout.setVerticalGroup( + jPanel26Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel26Layout.createSequentialGroup() + .addGroup(jPanel26Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jtxtJPOSPrinter6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel37, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jtxtJPOSDrawer6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel36, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0)) + ); + + m_jPrinterParams6.add(jPanel26, "javapos"); + + m_jScaleParams.setPreferredSize(new java.awt.Dimension(400, 30)); + m_jScaleParams.setLayout(new java.awt.CardLayout()); + + jPanel16.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanel16.setOpaque(false); + jPanel16.setPreferredSize(new java.awt.Dimension(400, 30)); + m_jScaleParams.add(jPanel16, "empty"); + + jPanel17.setBackground(new java.awt.Color(255, 255, 255)); + jPanel17.setPreferredSize(new java.awt.Dimension(400, 30)); + + jlblPrinterPort4.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jlblPrinterPort4.setText(AppLocal.getIntString("label.machineprinterport")); // NOI18N + jlblPrinterPort4.setPreferredSize(new java.awt.Dimension(50, 30)); + + jcboSerialScale.setEditable(true); + jcboSerialScale.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcboSerialScale.setMinimumSize(new java.awt.Dimension(80, 28)); + jcboSerialScale.setPreferredSize(new java.awt.Dimension(80, 28)); + + javax.swing.GroupLayout jPanel17Layout = new javax.swing.GroupLayout(jPanel17); + jPanel17.setLayout(jPanel17Layout); + jPanel17Layout.setHorizontalGroup( + jPanel17Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel17Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jlblPrinterPort4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboSerialScale, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + jPanel17Layout.setVerticalGroup( + jPanel17Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel17Layout.createSequentialGroup() + .addGroup(jPanel17Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jcboSerialScale, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblPrinterPort4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0)) + ); + + m_jScaleParams.add(jPanel17, "comm"); + + m_jScannerParams.setPreferredSize(new java.awt.Dimension(400, 30)); + m_jScannerParams.setLayout(new java.awt.CardLayout()); + + jPanel24.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanel24.setOpaque(false); + jPanel24.setPreferredSize(new java.awt.Dimension(400, 30)); + m_jScannerParams.add(jPanel24, "empty"); + + jPanel19.setBackground(new java.awt.Color(255, 255, 255)); + jPanel19.setPreferredSize(new java.awt.Dimension(400, 30)); + + jcboSerialScanner.setEditable(true); + jcboSerialScanner.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcboSerialScanner.setMinimumSize(new java.awt.Dimension(80, 28)); + jcboSerialScanner.setPreferredSize(new java.awt.Dimension(80, 28)); + + jlblPrinterPort5.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jlblPrinterPort5.setText(AppLocal.getIntString("label.machineprinterport")); // NOI18N + jlblPrinterPort5.setPreferredSize(new java.awt.Dimension(50, 30)); + + javax.swing.GroupLayout jPanel19Layout = new javax.swing.GroupLayout(jPanel19); + jPanel19.setLayout(jPanel19Layout); + jPanel19Layout.setHorizontalGroup( + jPanel19Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel19Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jlblPrinterPort5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboSerialScanner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + jPanel19Layout.setVerticalGroup( + jPanel19Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel19Layout.createSequentialGroup() + .addGroup(jPanel19Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jcboSerialScanner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblPrinterPort5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(6, 6, 6)) + ); + + m_jScannerParams.add(jPanel19, "comm"); + + jPanel27.setOpaque(false); + + webSwtch_iButton.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + webSwtch_iButton.setPreferredSize(new java.awt.Dimension(80, 30)); + webSwtch_iButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + webSwtch_iButtonActionPerformed(evt); + } + }); + + webLbliButton.setBackground(new java.awt.Color(240, 240, 240)); + webLbliButton.setText(AppLocal.getIntString("label.ibutton")); // NOI18N + webLbliButton.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + webLbliButton.setPreferredSize(new java.awt.Dimension(150, 30)); + + webSlider.setMajorTickSpacing(10); + webSlider.setMinorTickSpacing(5); + webSlider.setPaintLabels(true); + webSlider.setPaintTicks(true); + webSlider.setSnapToTicks(true); + webSlider.setToolTipText(""); + webSlider.setValue(5); + webSlider.setAnimated(false); + webSlider.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + webSlider.setPreferredSize(new java.awt.Dimension(270, 47)); + webSlider.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + webSliderStateChanged(evt); + } + }); + + webLabel1.setBackground(new java.awt.Color(240, 240, 240)); + webLabel1.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + webLabel1.setText(bundle.getString("label.ibuttonresponsespeed")); // NOI18N + webLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + webLabel1.setPreferredSize(new java.awt.Dimension(150, 30)); + + webLabel2.setText(bundle.getString("label.fast")); // NOI18N + webLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + + webLabel3.setText(bundle.getString("label.slow")); // NOI18N + webLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + + javax.swing.GroupLayout jPanel27Layout = new javax.swing.GroupLayout(jPanel27); + jPanel27.setLayout(jPanel27Layout); + jPanel27Layout.setHorizontalGroup( + jPanel27Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel27Layout.createSequentialGroup() + .addComponent(webLbliButton, javax.swing.GroupLayout.PREFERRED_SIZE, 156, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(webSwtch_iButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(webLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(14, 14, 14) + .addGroup(jPanel27Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(jPanel27Layout.createSequentialGroup() + .addComponent(webLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(194, 194, 194) + .addComponent(webLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(webSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + jPanel27Layout.setVerticalGroup( + jPanel27Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel27Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel27Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(webLbliButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(webSwtch_iButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(webLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(webSlider, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 13, Short.MAX_VALUE) + .addGroup(jPanel27Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(webLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(webLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + + javax.swing.GroupLayout jPanel13Layout = new javax.swing.GroupLayout(jPanel13); + jPanel13.setLayout(jPanel13Layout); + jPanel13Layout.setHorizontalGroup( + jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel13Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel13Layout.createSequentialGroup() + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboMachinePrinter2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jPrinterParams2, javax.swing.GroupLayout.DEFAULT_SIZE, 414, Short.MAX_VALUE)) + .addGroup(jPanel13Layout.createSequentialGroup() + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboMachinePrinter3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jPrinterParams3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(jPanel13Layout.createSequentialGroup() + .addComponent(jLabel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboMachineScale, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jScaleParams, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(jPanel13Layout.createSequentialGroup() + .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboMachinePrinter4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jPrinterParams4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(jPanel13Layout.createSequentialGroup() + .addComponent(jLabel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboMachinePrinter5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jPrinterParams5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(jPanel13Layout.createSequentialGroup() + .addComponent(jLabel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboMachinePrinter6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jPrinterParams6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(jPanel13Layout.createSequentialGroup() + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel13Layout.createSequentialGroup() + .addComponent(jcboMachineDisplay, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jDisplayParams, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(jPanel13Layout.createSequentialGroup() + .addComponent(jcboMachinePrinter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jPrinterParams1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addGroup(jPanel13Layout.createSequentialGroup() + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel13Layout.createSequentialGroup() + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel13Layout.createSequentialGroup() + .addComponent(jLabel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jcboMachineScanner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel13Layout.createSequentialGroup() + .addComponent(jLabel14, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cboPrinters, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jScannerParams, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jPanel27, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, Short.MAX_VALUE))) + .addGap(16, 16, 16)) + ); + jPanel13Layout.setVerticalGroup( + jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel13Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboMachineDisplay, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(m_jDisplayParams, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboMachinePrinter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(m_jPrinterParams1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboMachinePrinter2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(m_jPrinterParams2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboMachinePrinter3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(m_jPrinterParams3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboMachinePrinter4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(m_jPrinterParams4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboMachinePrinter5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(m_jPrinterParams5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboMachinePrinter6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(m_jPrinterParams6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboMachineScale, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(m_jScaleParams, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel13Layout.createSequentialGroup() + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcboMachineScanner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel14, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(cboPrinters, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(m_jScannerParams, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jPanel27, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jPanel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jPanel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + private void jcboMachinePrinter3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcboMachinePrinter3ActionPerformed + CardLayout cl = (CardLayout) (m_jPrinterParams3.getLayout()); + + if ("epson".equals(jcboMachinePrinter3.getSelectedItem()) || + "ODP1000".equals(jcboMachinePrinter3.getSelectedItem()) || + "tmu220".equals(jcboMachinePrinter3.getSelectedItem()) || + "star".equals(jcboMachinePrinter3.getSelectedItem()) || + "ithaca".equals(jcboMachinePrinter3.getSelectedItem()) || + "surepos".equals(jcboMachinePrinter3.getSelectedItem())) { + cl.show(m_jPrinterParams3, "comm"); + } else if ("javapos".equals(jcboMachinePrinter3.getSelectedItem())) { + cl.show(m_jPrinterParams3, "javapos"); + } else if ("printer".equals(jcboMachinePrinter3.getSelectedItem())) { + cl.show(m_jPrinterParams3, "printer"); + } else { + cl.show(m_jPrinterParams3, "empty"); + } + }//GEN-LAST:event_jcboMachinePrinter3ActionPerformed + + private void jcboMachinePrinter2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcboMachinePrinter2ActionPerformed + CardLayout cl = (CardLayout) (m_jPrinterParams2.getLayout()); + + if ("epson".equals(jcboMachinePrinter2.getSelectedItem()) || + "ODP1000".equals(jcboMachinePrinter2.getSelectedItem()) || + "tmu220".equals(jcboMachinePrinter2.getSelectedItem()) || + "star".equals(jcboMachinePrinter2.getSelectedItem()) || + "ithaca".equals(jcboMachinePrinter2.getSelectedItem()) || + "surepos".equals(jcboMachinePrinter2.getSelectedItem())) { + cl.show(m_jPrinterParams2, "comm"); + } else if ("javapos".equals(jcboMachinePrinter2.getSelectedItem())) { + cl.show(m_jPrinterParams2, "javapos"); + } else if ("printer".equals(jcboMachinePrinter2.getSelectedItem())) { + cl.show(m_jPrinterParams2, "printer"); + } else { + cl.show(m_jPrinterParams2, "empty"); + } + }//GEN-LAST:event_jcboMachinePrinter2ActionPerformed + + private void jcboMachinePrinterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcboMachinePrinterActionPerformed + CardLayout cl = (CardLayout) (m_jPrinterParams1.getLayout()); + + if ("epson".equals(jcboMachinePrinter.getSelectedItem()) || + "ODP1000".equals(jcboMachinePrinter.getSelectedItem()) || + "tmu220".equals(jcboMachinePrinter.getSelectedItem()) || + "star".equals(jcboMachinePrinter.getSelectedItem()) || + "ithaca".equals(jcboMachinePrinter.getSelectedItem()) || + "surepos".equals(jcboMachinePrinter.getSelectedItem())) { + cl.show(m_jPrinterParams1, "comm"); + } else if ("javapos".equals(jcboMachinePrinter.getSelectedItem())) { + cl.show(m_jPrinterParams1, "javapos"); + } else if ("printer".equals(jcboMachinePrinter.getSelectedItem())) { + cl.show(m_jPrinterParams1, "printer"); + } else { + cl.show(m_jPrinterParams1, "empty"); + } + }//GEN-LAST:event_jcboMachinePrinterActionPerformed + + private void jcboMachinePrinter4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcboMachinePrinter4ActionPerformed + CardLayout cl = (CardLayout) (m_jPrinterParams4.getLayout()); + + if ("epson".equals(jcboMachinePrinter4.getSelectedItem()) || + "ODP1000".equals(jcboMachinePrinter4.getSelectedItem()) || + "tmu220".equals(jcboMachinePrinter4.getSelectedItem()) || + "star".equals(jcboMachinePrinter4.getSelectedItem()) || + "ithaca".equals(jcboMachinePrinter4.getSelectedItem()) || + "surepos".equals(jcboMachinePrinter4.getSelectedItem())) { + cl.show(m_jPrinterParams4, "comm"); + } else if ("javapos".equals(jcboMachinePrinter4.getSelectedItem())) { + cl.show(m_jPrinterParams4, "javapos"); + } else if ("printer".equals(jcboMachinePrinter4.getSelectedItem())) { + cl.show(m_jPrinterParams4, "printer"); + } else { + cl.show(m_jPrinterParams4, "empty"); + } + }//GEN-LAST:event_jcboMachinePrinter4ActionPerformed + + private void jcboMachinePrinter5ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcboMachinePrinter5ActionPerformed + CardLayout cl = (CardLayout) (m_jPrinterParams5.getLayout()); + + if ("epson".equals(jcboMachinePrinter5.getSelectedItem()) || + "ODP1000".equals(jcboMachinePrinter5.getSelectedItem()) || + "tmu220".equals(jcboMachinePrinter5.getSelectedItem()) || + "star".equals(jcboMachinePrinter5.getSelectedItem()) || + "ithaca".equals(jcboMachinePrinter5.getSelectedItem()) || + "surepos".equals(jcboMachinePrinter5.getSelectedItem())) { + cl.show(m_jPrinterParams5, "comm"); + } else if ("javapos".equals(jcboMachinePrinter5.getSelectedItem())) { + cl.show(m_jPrinterParams5, "javapos"); + } else if ("printer".equals(jcboMachinePrinter5.getSelectedItem())) { + cl.show(m_jPrinterParams5, "printer"); + } else { + cl.show(m_jPrinterParams5, "empty"); + } + }//GEN-LAST:event_jcboMachinePrinter5ActionPerformed + + private void jcboMachinePrinter6ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcboMachinePrinter6ActionPerformed + CardLayout cl = (CardLayout) (m_jPrinterParams6.getLayout()); + + if ("epson".equals(jcboMachinePrinter6.getSelectedItem()) || + "ODP1000".equals(jcboMachinePrinter6.getSelectedItem()) || + "tmu220".equals(jcboMachinePrinter6.getSelectedItem()) || + "star".equals(jcboMachinePrinter6.getSelectedItem()) || + "ithaca".equals(jcboMachinePrinter6.getSelectedItem()) || + "surepos".equals(jcboMachinePrinter6.getSelectedItem())) { + cl.show(m_jPrinterParams6, "comm"); + } else if ("javapos".equals(jcboMachinePrinter6.getSelectedItem())) { + cl.show(m_jPrinterParams6, "javapos"); + } else if ("printer".equals(jcboMachinePrinter6.getSelectedItem())) { + cl.show(m_jPrinterParams6, "printer"); + } else { + cl.show(m_jPrinterParams6, "empty"); + } + }//GEN-LAST:event_jcboMachinePrinter6ActionPerformed + + private void m_jtxtJPOSNameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jtxtJPOSNameActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_m_jtxtJPOSNameActionPerformed + + private void jcboMachineScannerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcboMachineScannerActionPerformed + CardLayout cl = (CardLayout) (m_jScannerParams.getLayout()); + + if ("scanpal2".equals(jcboMachineScanner.getSelectedItem())) { + cl.show(m_jScannerParams, "comm"); + } else { + cl.show(m_jScannerParams, "empty"); + } + }//GEN-LAST:event_jcboMachineScannerActionPerformed + + private void jcboMachineScaleActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcboMachineScaleActionPerformed + CardLayout cl = (CardLayout) (m_jScaleParams.getLayout()); + + // JG 29 Aug 13 - Add Casio PD1 Scale + if ("casiopd1".equals(jcboMachineScale.getSelectedItem()) || + "dialog1".equals(jcboMachineScale.getSelectedItem()) || + "samsungesp".equals(jcboMachineScale.getSelectedItem()) || + "caspdii".equals(jcboMachineScale.getSelectedItem())|| + "acompc100".equals(jcboMachineScale.getSelectedItem())|| + "averyberkel6720".equals(jcboMachineScale.getSelectedItem())|| + "mtind221".equals(jcboMachineScale.getSelectedItem())) { + cl.show(m_jScaleParams, "comm"); + } else { + cl.show(m_jScaleParams, "empty"); + } + }//GEN-LAST:event_jcboMachineScaleActionPerformed + + private void jcboMachineDisplayActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcboMachineDisplayActionPerformed + CardLayout cl = (CardLayout) (m_jDisplayParams.getLayout()); + + if ("epson".equals(jcboMachineDisplay.getSelectedItem()) || + "ld200".equals(jcboMachineDisplay.getSelectedItem()) || + "surepos".equals(jcboMachineDisplay.getSelectedItem())) { + cl.show(m_jDisplayParams, "comm"); + } else if ("javapos".equals(jcboMachineDisplay.getSelectedItem())) { + cl.show(m_jDisplayParams, "javapos"); + } else { + cl.show(m_jDisplayParams, "empty"); + } + }//GEN-LAST:event_jcboMachineDisplayActionPerformed + + private void webSwtch_iButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_webSwtch_iButtonActionPerformed + if (webSwtch_iButton.isSelected()) { + + } else { + + } + + }//GEN-LAST:event_webSwtch_iButtonActionPerformed + + private void webSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_webSliderStateChanged + webSlider.getValue(); + + }//GEN-LAST:event_webSliderStateChanged + + private void jcboConnPrinterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcboConnPrinterActionPerformed + jcboSerialPrinter.removeAllItems(); + if (("raw".equals(jcboConnPrinter.getSelectedItem())) + || ("usb".equals(jcboConnPrinter.getSelectedItem()))) { + jlblPrinterPort.setText("Printer"); + addRegisteredPrinters(jcboSerialPrinter); + } else { + jlblPrinterPort.setText("Port"); + buildPrinterList(jcboSerialPrinter); + } + jcboSerialPrinter.setSelectedItem(null); + }//GEN-LAST:event_jcboConnPrinterActionPerformed + + private void jcboConnPrinter2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcboConnPrinter2ActionPerformed + jcboSerialPrinter2.removeAllItems(); + if (("raw".equals(jcboConnPrinter2.getSelectedItem())) + || ("usb".equals(jcboConnPrinter2.getSelectedItem()))) { + jlblPrinterPort2.setText("Printer"); + addRegisteredPrinters(jcboSerialPrinter2); + } else { + jlblPrinterPort2.setText("Port"); + buildPrinterList(jcboSerialPrinter2); + } + jcboSerialPrinter2.setSelectedItem(null); + + }//GEN-LAST:event_jcboConnPrinter2ActionPerformed + + private void jcboConnPrinter3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcboConnPrinter3ActionPerformed + jcboSerialPrinter3.removeAllItems(); + if (("raw".equals(jcboConnPrinter3.getSelectedItem())) + || ("usb".equals(jcboConnPrinter3.getSelectedItem()))) { + jlblPrinterPort3.setText("Printer"); + addRegisteredPrinters(jcboSerialPrinter3); + } else { + jlblPrinterPort3.setText("Port"); + buildPrinterList(jcboSerialPrinter3); + } + jcboSerialPrinter2.setSelectedItem(null); + }//GEN-LAST:event_jcboConnPrinter3ActionPerformed + + private void jcboConnPrinter4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcboConnPrinter4ActionPerformed + jcboSerialPrinter4.removeAllItems(); + if (("raw".equals(jcboConnPrinter4.getSelectedItem())) + || ("usb".equals(jcboConnPrinter4.getSelectedItem()))) { + jlblPrinterPort4.setText("Printer"); + addRegisteredPrinters(jcboSerialPrinter4); + } else { + jlblPrinterPort4.setText("Port"); + buildPrinterList(jcboSerialPrinter4); + } + jcboSerialPrinter4.setSelectedItem(null); + }//GEN-LAST:event_jcboConnPrinter4ActionPerformed + + private void jcboConnPrinter5ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcboConnPrinter5ActionPerformed + jcboSerialPrinter5.removeAllItems(); + if (("raw".equals(jcboConnPrinter5.getSelectedItem())) + || ("usb".equals(jcboConnPrinter5.getSelectedItem()))) { + jlblPrinterPort5.setText("Printer"); + addRegisteredPrinters(jcboSerialPrinter5); + } else { + jlblPrinterPort5.setText("Port"); + buildPrinterList(jcboSerialPrinter5); + } + jcboSerialPrinter5.setSelectedItem(null); + }//GEN-LAST:event_jcboConnPrinter5ActionPerformed + + private void jcboConnPrinter6ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcboConnPrinter6ActionPerformed + jcboSerialPrinter6.removeAllItems(); + if (("raw".equals(jcboConnPrinter.getSelectedItem())) + || ("usb".equals(jcboConnPrinter6.getSelectedItem()))) { + jlblPrinterPort6.setText("Printer"); + addRegisteredPrinters(jcboSerialPrinter6); + } else { + jlblPrinterPort6.setText("Port"); + buildPrinterList(jcboSerialPrinter6); + } + jcboSerialPrinter6.setSelectedItem(null); + }//GEN-LAST:event_jcboConnPrinter6ActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JComboBox cboPrinters; + private javax.swing.JLabel jLabel10; + private javax.swing.JLabel jLabel11; + private javax.swing.JLabel jLabel12; + private javax.swing.JLabel jLabel13; + private javax.swing.JLabel jLabel14; + private javax.swing.JLabel jLabel20; + private javax.swing.JLabel jLabel21; + private javax.swing.JLabel jLabel22; + private javax.swing.JLabel jLabel23; + private javax.swing.JLabel jLabel24; + private javax.swing.JLabel jLabel27; + private javax.swing.JLabel jLabel28; + private javax.swing.JLabel jLabel30; + private javax.swing.JLabel jLabel31; + private javax.swing.JLabel jLabel33; + private javax.swing.JLabel jLabel34; + private javax.swing.JLabel jLabel36; + private javax.swing.JLabel jLabel37; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JLabel jLabel9; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel10; + private javax.swing.JPanel jPanel11; + private javax.swing.JPanel jPanel12; + private javax.swing.JPanel jPanel13; + private javax.swing.JPanel jPanel14; + private javax.swing.JPanel jPanel15; + private javax.swing.JPanel jPanel16; + private javax.swing.JPanel jPanel17; + private javax.swing.JPanel jPanel18; + private javax.swing.JPanel jPanel19; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel20; + private javax.swing.JPanel jPanel21; + private javax.swing.JPanel jPanel22; + private javax.swing.JPanel jPanel23; + private javax.swing.JPanel jPanel24; + private javax.swing.JPanel jPanel25; + private javax.swing.JPanel jPanel26; + private javax.swing.JPanel jPanel27; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JPanel jPanel6; + private javax.swing.JPanel jPanel7; + private javax.swing.JPanel jPanel8; + private javax.swing.JPanel jPanel9; + private javax.swing.JComboBox jcboConnDisplay; + private javax.swing.JComboBox jcboConnPrinter; + private javax.swing.JComboBox jcboConnPrinter2; + private javax.swing.JComboBox jcboConnPrinter3; + private javax.swing.JComboBox jcboConnPrinter4; + private javax.swing.JComboBox jcboConnPrinter5; + private javax.swing.JComboBox jcboConnPrinter6; + private javax.swing.JComboBox jcboMachineDisplay; + private javax.swing.JComboBox jcboMachinePrinter; + private javax.swing.JComboBox jcboMachinePrinter2; + private javax.swing.JComboBox jcboMachinePrinter3; + private javax.swing.JComboBox jcboMachinePrinter4; + private javax.swing.JComboBox jcboMachinePrinter5; + private javax.swing.JComboBox jcboMachinePrinter6; + private javax.swing.JComboBox jcboMachineScale; + private javax.swing.JComboBox jcboMachineScanner; + private javax.swing.JComboBox jcboSerialDisplay; + private javax.swing.JComboBox jcboSerialPrinter; + private javax.swing.JComboBox jcboSerialPrinter2; + private javax.swing.JComboBox jcboSerialPrinter3; + private javax.swing.JComboBox jcboSerialPrinter4; + private javax.swing.JComboBox jcboSerialPrinter5; + private javax.swing.JComboBox jcboSerialPrinter6; + private javax.swing.JComboBox jcboSerialScale; + private javax.swing.JComboBox jcboSerialScanner; + private javax.swing.JLabel jlblConnDisplay; + private javax.swing.JLabel jlblConnPrinter; + private javax.swing.JLabel jlblConnPrinter2; + private javax.swing.JLabel jlblConnPrinter3; + private javax.swing.JLabel jlblConnPrinter4; + private javax.swing.JLabel jlblConnPrinter5; + private javax.swing.JLabel jlblConnPrinter6; + private javax.swing.JLabel jlblDisplayPort; + private javax.swing.JLabel jlblPrinterPort; + private javax.swing.JLabel jlblPrinterPort2; + private javax.swing.JLabel jlblPrinterPort3; + private javax.swing.JLabel jlblPrinterPort4; + private javax.swing.JLabel jlblPrinterPort5; + private javax.swing.JLabel jlblPrinterPort6; + private javax.swing.JLabel jlblPrinterPort7; + private javax.swing.JLabel jlblPrinterPort8; + private javax.swing.JPanel m_jDisplayParams; + private javax.swing.JPanel m_jPrinterParams1; + private javax.swing.JPanel m_jPrinterParams2; + private javax.swing.JPanel m_jPrinterParams3; + private javax.swing.JPanel m_jPrinterParams4; + private javax.swing.JPanel m_jPrinterParams5; + private javax.swing.JPanel m_jPrinterParams6; + private javax.swing.JPanel m_jScaleParams; + private javax.swing.JPanel m_jScannerParams; + private javax.swing.JTextField m_jtxtJPOSDrawer; + private javax.swing.JTextField m_jtxtJPOSDrawer2; + private javax.swing.JTextField m_jtxtJPOSDrawer3; + private javax.swing.JTextField m_jtxtJPOSDrawer4; + private javax.swing.JTextField m_jtxtJPOSDrawer5; + private javax.swing.JTextField m_jtxtJPOSDrawer6; + private javax.swing.JTextField m_jtxtJPOSName; + private javax.swing.JTextField m_jtxtJPOSPrinter; + private javax.swing.JTextField m_jtxtJPOSPrinter2; + private javax.swing.JTextField m_jtxtJPOSPrinter3; + private javax.swing.JTextField m_jtxtJPOSPrinter4; + private javax.swing.JTextField m_jtxtJPOSPrinter5; + private javax.swing.JTextField m_jtxtJPOSPrinter6; + private com.alee.laf.label.WebLabel webLabel1; + private com.alee.laf.label.WebLabel webLabel2; + private com.alee.laf.label.WebLabel webLabel3; + private com.alee.laf.label.WebLabel webLbliButton; + private com.alee.laf.slider.WebSlider webSlider; + private com.alee.extended.button.WebSwitch webSwtch_iButton; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/config/JPanelConfigSystem.form b/src/main/java/com/unicenta/pos/config/JPanelConfigSystem.form new file mode 100644 index 0000000..37ada68 --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JPanelConfigSystem.form @@ -0,0 +1,922 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/pos/config/JPanelConfigSystem.java b/src/main/java/com/unicenta/pos/config/JPanelConfigSystem.java new file mode 100644 index 0000000..b238ccd --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JPanelConfigSystem.java @@ -0,0 +1,828 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.config; + +import com.unicenta.data.user.DirtyManager; +import com.unicenta.pos.forms.AppConfig; +import java.awt.*; +import com.alee.extended.colorchooser.*; +import com.alee.managers.language.*; +import com.alee.laf.*; +import com.alee.extended.colorchooser.ColorDisplayType; +import javax.swing.*; + + +/** + * + * @author JG uniCenta + */ +public class JPanelConfigSystem extends javax.swing.JPanel implements PanelConfig { + + private DirtyManager dirty = new DirtyManager(); + + /** Creates new form JPanelConfigDatabase */ + public JPanelConfigSystem() { + + WebLookAndFeel.initializeManagers (); + + initComponents(); + + + jTextAutoLogoffTime.getDocument().addDocumentListener(dirty); + jchkInstance.addActionListener(dirty); + jchkTextOverlay.addActionListener(dirty); + jchkAutoLogoff.addActionListener(dirty); + jchkAutoLogoffToTables.addActionListener(dirty); + jTaxIncluded.addActionListener(dirty); + jCheckPrice00.addActionListener(dirty); + jMoveAMountBoxToTop.addActionListener(dirty); + jCloseCashbtn.addActionListener(dirty); + jchkautoRefreshTableMap.addActionListener(dirty); + jTxtautoRefreshTimer.getDocument().addDocumentListener(dirty); + jchkSCOnOff.addActionListener(dirty); + jchkSCRestaurant.addActionListener(dirty); + jTextSCRate.getDocument().addDocumentListener(dirty); + jchkPriceUpdate.addActionListener(dirty); + jchkBarcodetype.addActionListener(dirty); + jchkShowCustomerDetails.addActionListener(dirty); + jchkShowWaiterDetails.addActionListener(dirty); + CustomerColour.addActionListener(dirty); + WaiterColour.addActionListener(dirty); + TableNameColour.addActionListener(dirty); + jchkTransBtn.addActionListener(dirty); + jchkOverride.addActionListener(dirty); + jtxtPIN.getDocument().addDocumentListener(dirty); + disableAnonymousStats.addActionListener(dirty); + + } + + /** + * + * @return + */ + @Override + public boolean hasChanged() { + return dirty.isDirty(); + } + + /** + * + * @return + */ + @Override + public Component getConfigComponent() { + return this; + } + + /** + * + * @param config + */ + @Override + public void loadProperties(AppConfig config) { + + String timerCheck =(config.getProperty("till.autotimer")); + if (timerCheck == null){ + config.setProperty("till.autotimer","100"); + } else { + jTextAutoLogoffTime.setText(config.getProperty("till.autotimer")); + } + + String autoRefreshtimerCheck =(config.getProperty("till.autoRefreshTimer")); + if (autoRefreshtimerCheck == null){ + config.setProperty("till.autoRefreshTableMap","false"); + config.setProperty("till.autoRefreshTimer","5"); + } + jTxtautoRefreshTimer.setText(config.getProperty("till.autoRefreshTimer")); + + jchkInstance.setSelected(Boolean.parseBoolean(config.getProperty("machine.uniqueinstance"))); + + jchkTextOverlay.setSelected(Boolean.parseBoolean(config.getProperty("payments.textoverlay"))); + jchkAutoLogoff.setSelected(Boolean.parseBoolean(config.getProperty("till.autoLogoff"))); + jchkAutoLogoffToTables.setSelected(Boolean.parseBoolean(config.getProperty("till.autoLogoffrestaurant"))); + jTaxIncluded.setSelected(Boolean.parseBoolean(config.getProperty("till.taxincluded"))); + jCheckPrice00.setSelected(Boolean.parseBoolean(config.getProperty("till.pricewith00"))); + jMoveAMountBoxToTop.setSelected(Boolean.parseBoolean(config.getProperty("till.amountattop"))); + jCloseCashbtn.setSelected(Boolean.parseBoolean(config.getProperty("screen.600800"))); + jchkautoRefreshTableMap.setSelected(Boolean.parseBoolean(config.getProperty("till.autoRefreshTableMap"))); + jchkPriceUpdate.setSelected(AppConfig.getInstance().getBoolean("db.prodpriceupdate")); + jchkBarcodetype.setSelected(Boolean.parseBoolean(config.getProperty("machine.barcodetype"))); + + String txtPIN =(config.getProperty("override.pin")); + if (txtPIN == null){ + config.setProperty("override.check","true"); + config.setProperty("override.pin","1234"); + } + jchkOverride.setSelected(Boolean.parseBoolean(config.getProperty("override.check"))); + jtxtPIN.setText(config.getProperty("override.pin")); + +/** Added: JG 23 July 13 */ + String SCCheck =(config.getProperty("till.SCRate")); + if (SCCheck == null){ + config.setProperty("till.SCRate","0"); + } + jTextSCRate.setText(config.getProperty("till.SCRate")); + jchkSCOnOff.setSelected(Boolean.parseBoolean(config.getProperty("till.SCOnOff"))); + jchkSCRestaurant.setSelected(Boolean.parseBoolean(config.getProperty("till.SCRestaurant"))); + + if (jchkSCOnOff.isSelected()){ + jchkSCRestaurant.setVisible(true); + jLabelSCRate.setVisible(true); + jTextSCRate.setVisible(true); + jLabelSCRatePerCent.setVisible(true); + }else{ + jchkSCRestaurant.setVisible(false); + jLabelSCRate.setVisible(false); + jTextSCRate.setVisible(false); + jLabelSCRatePerCent.setVisible(false); + } + + if (jchkAutoLogoff.isSelected()){ + jchkAutoLogoffToTables.setVisible(true); + jLabelInactiveTime.setVisible(true); + jLabelTimedMessage.setVisible(true); + jTextAutoLogoffTime.setVisible(true); + }else{ + jchkAutoLogoffToTables.setVisible(false); + jLabelInactiveTime.setVisible(false); + jLabelTimedMessage.setVisible(false); + jTextAutoLogoffTime.setVisible(false); + } + + if (jchkautoRefreshTableMap.isSelected()){ + jLblautoRefresh.setVisible(true); + jLabelInactiveTime1.setVisible(true); + jTxtautoRefreshTimer.setVisible(true); + }else{ + jLblautoRefresh.setVisible(false); + jLabelInactiveTime1.setVisible(false); + jTxtautoRefreshTimer.setVisible(false); + } + + String customerCheck =(config.getProperty("table.showcustomerdetails")); + if (customerCheck == null) { + config.setProperty("table.showcustomerdetails","true"); + } + jchkShowCustomerDetails.setSelected(Boolean.parseBoolean(config.getProperty("table.showcustomerdetails"))); + if (config.getProperty("table.customercolour")==null){ + CustomerColour.setText(""); + }else{ + CustomerColour.setText(config.getProperty("table.customercolour")); + } + + String waiterCheck =(config.getProperty("table.showwaiterdetails")); + if (waiterCheck == null) { + config.setProperty("table.showwaiterdetails","true"); + } + jchkShowWaiterDetails.setSelected(Boolean.parseBoolean(config.getProperty("table.showwaiterdetails"))); + if (config.getProperty("table.waitercolour")==null){ + WaiterColour.setText(""); + }else{ + WaiterColour.setText(config.getProperty("table.waitercolour")); + } + if (config.getProperty("table.tablecolour")==null){ + TableNameColour.setText(""); + }else{ + TableNameColour.setText(config.getProperty("table.tablecolour")); + } + + jchkTransBtn.setSelected(Boolean.parseBoolean(config.getProperty("table.transbtn"))); + + dirty.setDirty(false); + } + + /** + * + * @param config + */ + @Override + public void saveProperties(AppConfig config) { + + config.setProperty("till.autotimer",jTextAutoLogoffTime.getText()); + config.setProperty("machine.uniqueinstance", Boolean.toString(jchkInstance.isSelected())); + config.setProperty("table.showcustomerdetails", Boolean.toString(jchkShowCustomerDetails.isSelected())); + config.setProperty("table.showwaiterdetails", Boolean.toString(jchkShowWaiterDetails.isSelected())); + config.setProperty("payments.textoverlay", Boolean.toString(jchkTextOverlay.isSelected())); + config.setProperty("till.autoLogoff", Boolean.toString(jchkAutoLogoff.isSelected())); + config.setProperty("till.autoLogoffrestaurant", Boolean.toString(jchkAutoLogoffToTables.isSelected())); + config.setProperty("table.customercolour",CustomerColour.getText()); + config.setProperty("table.waitercolour",WaiterColour.getText()); + config.setProperty("table.tablecolour",TableNameColour.getText()); + config.setProperty("till.taxincluded",Boolean.toString(jTaxIncluded.isSelected())); + config.setProperty("till.pricewith00",Boolean.toString(jCheckPrice00.isSelected())); + config.setProperty("till.amountattop",Boolean.toString(jMoveAMountBoxToTop.isSelected())); + config.setProperty("screen.600800",Boolean.toString(jCloseCashbtn.isSelected())); + config.setProperty("till.autoRefreshTableMap", Boolean.toString(jchkautoRefreshTableMap.isSelected())); + config.setProperty("till.autoRefreshTimer", jTxtautoRefreshTimer.getText()); + + config.setProperty("till.SCOnOff",Boolean.toString(jchkSCOnOff.isSelected())); + config.setProperty("till.SCRate",jTextSCRate.getText()); + config.setProperty("till.SCRestaurant",Boolean.toString(jchkSCRestaurant.isSelected())); + + config.setProperty("db.prodpriceupdate", Boolean.toString(jchkPriceUpdate.isSelected())); + config.setProperty("machine.barcodetype", Boolean.toString(jchkBarcodetype.isSelected())); + + config.setProperty("table.transbtn", Boolean.toString(jchkTransBtn.isSelected())); + + config.setProperty("override.check", Boolean.toString(jchkOverride.isSelected())); + config.setProperty("override.pin",jtxtPIN.getText()); + config.setProperty("disable.stats", Boolean.toString(disableAnonymousStats.isSelected())); + + dirty.setDirty(false); + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jLabel1 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + jchkInstance = new javax.swing.JCheckBox(); + jLabelInactiveTime = new javax.swing.JLabel(); + jTextAutoLogoffTime = new javax.swing.JTextField(); + jLabelTimedMessage = new javax.swing.JLabel(); + jchkAutoLogoff = new javax.swing.JCheckBox(); + jchkAutoLogoffToTables = new javax.swing.JCheckBox(); + jchkShowCustomerDetails = new javax.swing.JCheckBox(); + jchkShowWaiterDetails = new javax.swing.JCheckBox(); + jLabelTableNameTextColour = new javax.swing.JLabel(); + jCheckPrice00 = new javax.swing.JCheckBox(); + jTaxIncluded = new javax.swing.JCheckBox(); + jCloseCashbtn = new javax.swing.JCheckBox(); + jMoveAMountBoxToTop = new javax.swing.JCheckBox(); + jchkTextOverlay = new javax.swing.JCheckBox(); + jchkautoRefreshTableMap = new javax.swing.JCheckBox(); + jLabelInactiveTime1 = new javax.swing.JLabel(); + jTxtautoRefreshTimer = new javax.swing.JTextField(); + jLblautoRefresh = new javax.swing.JLabel(); + jchkSCOnOff = new javax.swing.JCheckBox(); + jLabelSCRate = new javax.swing.JLabel(); + jTextSCRate = new javax.swing.JTextField(); + jLabelSCRatePerCent = new javax.swing.JLabel(); + jchkSCRestaurant = new javax.swing.JCheckBox(); + jchkPriceUpdate = new javax.swing.JCheckBox(); + jchkBarcodetype = new javax.swing.JCheckBox(); + jchkTransBtn = new javax.swing.JCheckBox(); + WaiterColour = new com.alee.extended.colorchooser.WebColorChooserField(); + TableNameColour = new com.alee.extended.colorchooser.WebColorChooserField(); + CustomerColour = new com.alee.extended.colorchooser.WebColorChooserField(); + jchkOverride = new javax.swing.JCheckBox(); + jtxtPIN = new javax.swing.JTextField(); + jLabel5 = new javax.swing.JLabel(); + disableAnonymousStats = new javax.swing.JCheckBox(); + + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + setOpaque(false); + setPreferredSize(new java.awt.Dimension(700, 500)); + + jLabel1.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jLabel1.setText(bundle.getString("label.configOptionStartup")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(250, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + jLabel2.setText(bundle.getString("label.configOptionKeypad")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(250, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + jLabel3.setText(bundle.getString("label.configOptionLogOff")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + jLabel4.setText(bundle.getString("label.configOptionRestaurant")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(250, 30)); + + jchkInstance.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jchkInstance.setSelected(true); + jchkInstance.setText(bundle.getString("label.instance")); // NOI18N + jchkInstance.setMaximumSize(new java.awt.Dimension(0, 25)); + jchkInstance.setMinimumSize(new java.awt.Dimension(0, 0)); + jchkInstance.setPreferredSize(new java.awt.Dimension(250, 25)); + + jLabelInactiveTime.setBackground(new java.awt.Color(255, 255, 255)); + jLabelInactiveTime.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabelInactiveTime.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + jLabelInactiveTime.setText(bundle.getString("label.autolofftime")); // NOI18N + jLabelInactiveTime.setMaximumSize(new java.awt.Dimension(0, 25)); + jLabelInactiveTime.setMinimumSize(new java.awt.Dimension(0, 0)); + jLabelInactiveTime.setPreferredSize(new java.awt.Dimension(100, 30)); + + jTextAutoLogoffTime.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTextAutoLogoffTime.setText("0"); + jTextAutoLogoffTime.setMaximumSize(new java.awt.Dimension(0, 25)); + jTextAutoLogoffTime.setMinimumSize(new java.awt.Dimension(0, 0)); + jTextAutoLogoffTime.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabelTimedMessage.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabelTimedMessage.setText(bundle.getString("label.autologoffzero")); // NOI18N + jLabelTimedMessage.setMaximumSize(new java.awt.Dimension(0, 25)); + jLabelTimedMessage.setMinimumSize(new java.awt.Dimension(0, 0)); + jLabelTimedMessage.setPreferredSize(new java.awt.Dimension(200, 30)); + + jchkAutoLogoff.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jchkAutoLogoff.setText(bundle.getString("label.autologonoff")); // NOI18N + jchkAutoLogoff.setMaximumSize(new java.awt.Dimension(0, 25)); + jchkAutoLogoff.setMinimumSize(new java.awt.Dimension(0, 0)); + jchkAutoLogoff.setPreferredSize(new java.awt.Dimension(200, 30)); + jchkAutoLogoff.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jchkAutoLogoffActionPerformed(evt); + } + }); + + jchkAutoLogoffToTables.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jchkAutoLogoffToTables.setText(bundle.getString("label.autoloffrestaurant")); // NOI18N + jchkAutoLogoffToTables.setMaximumSize(new java.awt.Dimension(0, 25)); + jchkAutoLogoffToTables.setMinimumSize(new java.awt.Dimension(0, 0)); + jchkAutoLogoffToTables.setPreferredSize(new java.awt.Dimension(0, 30)); + jchkAutoLogoffToTables.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jchkAutoLogoffToTablesActionPerformed(evt); + } + }); + + jchkShowCustomerDetails.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jchkShowCustomerDetails.setSelected(true); + jchkShowCustomerDetails.setText(bundle.getString("label.tableshowcustomerdetails")); // NOI18N + jchkShowCustomerDetails.setMaximumSize(new java.awt.Dimension(0, 25)); + jchkShowCustomerDetails.setMinimumSize(new java.awt.Dimension(0, 0)); + jchkShowCustomerDetails.setPreferredSize(new java.awt.Dimension(350, 30)); + jchkShowCustomerDetails.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jchkShowCustomerDetailsActionPerformed(evt); + } + }); + + jchkShowWaiterDetails.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jchkShowWaiterDetails.setSelected(true); + jchkShowWaiterDetails.setText(bundle.getString("label.tableshowwaiterdetails")); // NOI18N + jchkShowWaiterDetails.setMaximumSize(new java.awt.Dimension(0, 25)); + jchkShowWaiterDetails.setMinimumSize(new java.awt.Dimension(0, 0)); + jchkShowWaiterDetails.setPreferredSize(new java.awt.Dimension(350, 30)); + + jLabelTableNameTextColour.setBackground(new java.awt.Color(255, 255, 255)); + jLabelTableNameTextColour.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabelTableNameTextColour.setText(bundle.getString("label.textclourtablename")); // NOI18N + jLabelTableNameTextColour.setMaximumSize(new java.awt.Dimension(0, 25)); + jLabelTableNameTextColour.setMinimumSize(new java.awt.Dimension(0, 0)); + jLabelTableNameTextColour.setPreferredSize(new java.awt.Dimension(350, 30)); + + jCheckPrice00.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jCheckPrice00.setText(bundle.getString("label.pricewith00")); // NOI18N + jCheckPrice00.setToolTipText(""); + jCheckPrice00.setMaximumSize(new java.awt.Dimension(0, 25)); + jCheckPrice00.setMinimumSize(new java.awt.Dimension(0, 0)); + jCheckPrice00.setPreferredSize(new java.awt.Dimension(250, 25)); + jCheckPrice00.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jCheckPrice00ActionPerformed(evt); + } + }); + + jTaxIncluded.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTaxIncluded.setText(bundle.getString("label.taxincluded")); // NOI18N + jTaxIncluded.setMaximumSize(new java.awt.Dimension(0, 25)); + jTaxIncluded.setMinimumSize(new java.awt.Dimension(0, 0)); + jTaxIncluded.setPreferredSize(new java.awt.Dimension(250, 25)); + + jCloseCashbtn.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jCloseCashbtn.setText(bundle.getString("message.systemclosecash")); // NOI18N + jCloseCashbtn.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jCloseCashbtn.setMaximumSize(new java.awt.Dimension(0, 25)); + jCloseCashbtn.setMinimumSize(new java.awt.Dimension(0, 0)); + jCloseCashbtn.setPreferredSize(new java.awt.Dimension(250, 25)); + + jMoveAMountBoxToTop.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jMoveAMountBoxToTop.setSelected(true); + jMoveAMountBoxToTop.setText(bundle.getString("label.inputamount")); // NOI18N + jMoveAMountBoxToTop.setMaximumSize(new java.awt.Dimension(0, 25)); + jMoveAMountBoxToTop.setMinimumSize(new java.awt.Dimension(0, 0)); + jMoveAMountBoxToTop.setPreferredSize(new java.awt.Dimension(250, 25)); + + jchkTextOverlay.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jchkTextOverlay.setText(bundle.getString("label.currencybutton")); // NOI18N + jchkTextOverlay.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jchkTextOverlay.setMaximumSize(new java.awt.Dimension(0, 25)); + jchkTextOverlay.setMinimumSize(new java.awt.Dimension(0, 0)); + jchkTextOverlay.setPreferredSize(new java.awt.Dimension(250, 25)); + + jchkautoRefreshTableMap.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jchkautoRefreshTableMap.setText(bundle.getString("label.autoRefreshTableMap")); // NOI18N + jchkautoRefreshTableMap.setMaximumSize(new java.awt.Dimension(0, 25)); + jchkautoRefreshTableMap.setMinimumSize(new java.awt.Dimension(0, 0)); + jchkautoRefreshTableMap.setPreferredSize(new java.awt.Dimension(200, 30)); + jchkautoRefreshTableMap.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jchkautoRefreshTableMapActionPerformed(evt); + } + }); + + jLabelInactiveTime1.setBackground(new java.awt.Color(255, 255, 255)); + jLabelInactiveTime1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabelInactiveTime1.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + jLabelInactiveTime1.setText(bundle.getString("label.autolofftime")); // NOI18N + jLabelInactiveTime1.setMaximumSize(new java.awt.Dimension(0, 25)); + jLabelInactiveTime1.setMinimumSize(new java.awt.Dimension(0, 0)); + jLabelInactiveTime1.setPreferredSize(new java.awt.Dimension(100, 30)); + + jTxtautoRefreshTimer.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTxtautoRefreshTimer.setText("0"); + jTxtautoRefreshTimer.setMaximumSize(new java.awt.Dimension(0, 25)); + jTxtautoRefreshTimer.setMinimumSize(new java.awt.Dimension(0, 0)); + jTxtautoRefreshTimer.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLblautoRefresh.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblautoRefresh.setText(bundle.getString("label.autoRefreshTableMapTimer")); // NOI18N + jLblautoRefresh.setMaximumSize(new java.awt.Dimension(0, 25)); + jLblautoRefresh.setMinimumSize(new java.awt.Dimension(0, 0)); + jLblautoRefresh.setPreferredSize(new java.awt.Dimension(200, 30)); + + jchkSCOnOff.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jchkSCOnOff.setText(bundle.getString("label.SCOnOff")); // NOI18N + jchkSCOnOff.setMaximumSize(new java.awt.Dimension(0, 25)); + jchkSCOnOff.setMinimumSize(new java.awt.Dimension(0, 0)); + jchkSCOnOff.setPreferredSize(new java.awt.Dimension(0, 25)); + jchkSCOnOff.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jchkSCOnOffActionPerformed(evt); + } + }); + + jLabelSCRate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabelSCRate.setText(bundle.getString("label.SCRate")); // NOI18N + jLabelSCRate.setMaximumSize(new java.awt.Dimension(0, 25)); + jLabelSCRate.setMinimumSize(new java.awt.Dimension(0, 0)); + jLabelSCRate.setPreferredSize(new java.awt.Dimension(190, 30)); + + jTextSCRate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTextSCRate.setText("0"); + jTextSCRate.setMaximumSize(new java.awt.Dimension(0, 25)); + jTextSCRate.setMinimumSize(new java.awt.Dimension(0, 0)); + jTextSCRate.setPreferredSize(new java.awt.Dimension(0, 30)); + jTextSCRate.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jTextSCRateActionPerformed(evt); + } + }); + + jLabelSCRatePerCent.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabelSCRatePerCent.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabelSCRatePerCent.setText(bundle.getString("label.SCZero")); // NOI18N + jLabelSCRatePerCent.setMaximumSize(new java.awt.Dimension(0, 25)); + jLabelSCRatePerCent.setMinimumSize(new java.awt.Dimension(0, 0)); + jLabelSCRatePerCent.setPreferredSize(new java.awt.Dimension(0, 30)); + + jchkSCRestaurant.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jchkSCRestaurant.setText(bundle.getString("label.SCRestaurant")); // NOI18N + jchkSCRestaurant.setMaximumSize(new java.awt.Dimension(0, 25)); + jchkSCRestaurant.setMinimumSize(new java.awt.Dimension(0, 0)); + jchkSCRestaurant.setPreferredSize(new java.awt.Dimension(0, 25)); + + jchkPriceUpdate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jchkPriceUpdate.setText(bundle.getString("label.priceupdate")); // NOI18N + jchkPriceUpdate.setToolTipText(bundle.getString("tooltip.priceupdate")); // NOI18N + jchkPriceUpdate.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jchkPriceUpdate.setMaximumSize(new java.awt.Dimension(0, 25)); + jchkPriceUpdate.setMinimumSize(new java.awt.Dimension(0, 0)); + jchkPriceUpdate.setPreferredSize(new java.awt.Dimension(250, 25)); + + jchkBarcodetype.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jchkBarcodetype.setText(bundle.getString("label.barcodetype")); // NOI18N + jchkBarcodetype.setToolTipText(bundle.getString("tooltip.barcodetype")); // NOI18N + jchkBarcodetype.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jchkBarcodetype.setMaximumSize(new java.awt.Dimension(0, 25)); + jchkBarcodetype.setMinimumSize(new java.awt.Dimension(0, 0)); + jchkBarcodetype.setPreferredSize(new java.awt.Dimension(250, 25)); + + jchkTransBtn.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jchkTransBtn.setText(bundle.getString("label.tabletransbutton")); // NOI18N + jchkTransBtn.setMaximumSize(new java.awt.Dimension(0, 25)); + jchkTransBtn.setMinimumSize(new java.awt.Dimension(0, 0)); + jchkTransBtn.setPreferredSize(new java.awt.Dimension(350, 30)); + jchkTransBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jchkTransBtnActionPerformed(evt); + } + }); + + WaiterColour.setToolTipText(bundle.getString("tooltip.prodhtmldisplayColourChooser")); // NOI18N + WaiterColour.setColorDisplayType(com.alee.extended.colorchooser.ColorDisplayType.hex); + WaiterColour.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + WaiterColour.setMinimumSize(new java.awt.Dimension(51, 30)); + + TableNameColour.setToolTipText(bundle.getString("tooltip.prodhtmldisplayColourChooser")); // NOI18N + TableNameColour.setColorDisplayType(com.alee.extended.colorchooser.ColorDisplayType.hex); + TableNameColour.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + TableNameColour.setMinimumSize(new java.awt.Dimension(51, 30)); + + CustomerColour.setToolTipText(bundle.getString("tooltip.prodhtmldisplayColourChooser")); // NOI18N + CustomerColour.setColorDisplayType(com.alee.extended.colorchooser.ColorDisplayType.hex); + CustomerColour.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + CustomerColour.setMinimumSize(new java.awt.Dimension(51, 30)); + + jchkOverride.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jchkOverride.setText(bundle.getString("label.override")); // NOI18N + jchkOverride.setMaximumSize(new java.awt.Dimension(0, 25)); + jchkOverride.setMinimumSize(new java.awt.Dimension(0, 0)); + jchkOverride.setPreferredSize(new java.awt.Dimension(200, 30)); + + jtxtPIN.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtPIN.setText("1234"); + jtxtPIN.setToolTipText(""); + jtxtPIN.setMaximumSize(new java.awt.Dimension(0, 25)); + jtxtPIN.setMinimumSize(new java.awt.Dimension(0, 0)); + jtxtPIN.setPreferredSize(new java.awt.Dimension(60, 30)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText("PIN"); + + disableAnonymousStats.setText("Disable Anonymous Stats"); + disableAnonymousStats.setFont(new java.awt.Font("Arial", 0, 14)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(10, 10, 10) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(jchkSCOnOff, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jchkautoRefreshTableMap, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabelInactiveTime1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jchkShowWaiterDetails, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabelTableNameTextColour, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jchkShowCustomerDetails, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jchkTransBtn, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(50, 50, 50)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(jLabelSCRate, javax.swing.GroupLayout.PREFERRED_SIZE, 333, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(12, 12, 12) + .addComponent(jLabelSCRatePerCent, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED))) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jTextSCRate, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jchkSCRestaurant, javax.swing.GroupLayout.PREFERRED_SIZE, 240, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jTxtautoRefreshTimer, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLblautoRefresh, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(WaiterColour, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(TableNameColour, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(CustomerColour, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(15, 15, 15) + .addComponent(jchkAutoLogoffToTables, javax.swing.GroupLayout.PREFERRED_SIZE, 340, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jchkAutoLogoff, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabelInactiveTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(100, 100, 100) + .addComponent(jTextAutoLogoffTime, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabelTimedMessage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(0, 0, Short.MAX_VALUE)))) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 654, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 260, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createSequentialGroup() + .addGap(10, 10, 10) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jchkInstance, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTaxIncluded, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jchkTextOverlay, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jchkPriceUpdate, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createSequentialGroup() + .addComponent(jchkOverride, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jtxtPIN, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel5)) + .addComponent(disableAnonymousStats)))) + .addGap(107, 107, 107) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jCheckPrice00, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jMoveAMountBoxToTop, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jCloseCashbtn, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jchkBarcodetype, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addGap(0, 0, Short.MAX_VALUE)))) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTaxIncluded, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jCheckPrice00, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jchkInstance, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jMoveAMountBoxToTop, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jchkTextOverlay, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jCloseCashbtn, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jchkPriceUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jchkBarcodetype, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel5) + .addComponent(jtxtPIN, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jchkOverride, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(disableAnonymousStats) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jchkAutoLogoff, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabelInactiveTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextAutoLogoffTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabelTimedMessage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jchkAutoLogoffToTables, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jchkautoRefreshTableMap, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabelInactiveTime1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTxtautoRefreshTimer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblautoRefresh, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jchkSCOnOff, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabelSCRate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextSCRate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabelSCRatePerCent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jchkSCRestaurant, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jchkShowCustomerDetails, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(CustomerColour, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jchkShowWaiterDetails, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(WaiterColour, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(TableNameColour, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabelTableNameTextColour, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jchkTransBtn, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(32, 32, 32)) + ); + }// //GEN-END:initComponents + + private void jchkAutoLogoffActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jchkAutoLogoffActionPerformed + if (jchkAutoLogoff.isSelected()){ + jchkAutoLogoffToTables.setVisible(true); + jLabelInactiveTime.setVisible(true); + jLabelTimedMessage.setVisible(true); + jTextAutoLogoffTime.setVisible(true); + }else{ + jchkAutoLogoffToTables.setVisible(false); + jLabelInactiveTime.setVisible(false); + jLabelTimedMessage.setVisible(false); + jTextAutoLogoffTime.setVisible(false); + } + }//GEN-LAST:event_jchkAutoLogoffActionPerformed + + private void jCheckPrice00ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckPrice00ActionPerformed + + }//GEN-LAST:event_jCheckPrice00ActionPerformed + + private void jchkAutoLogoffToTablesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jchkAutoLogoffToTablesActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jchkAutoLogoffToTablesActionPerformed + + private void jchkShowCustomerDetailsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jchkShowCustomerDetailsActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jchkShowCustomerDetailsActionPerformed + + private void jchkautoRefreshTableMapActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jchkautoRefreshTableMapActionPerformed + if (jchkautoRefreshTableMap.isSelected()){ + jLblautoRefresh.setVisible(true); + jLabelInactiveTime1.setVisible(true); + jTxtautoRefreshTimer.setVisible(true); + }else{ + jLblautoRefresh.setVisible(false); + jLabelInactiveTime1.setVisible(false); + jTxtautoRefreshTimer.setVisible(false); + } + }//GEN-LAST:event_jchkautoRefreshTableMapActionPerformed + + private void jchkSCOnOffActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jchkSCOnOffActionPerformed + if (jchkSCOnOff.isSelected()){ + jchkSCRestaurant.setVisible(true); + jLabelSCRate.setVisible(true); + jTextSCRate.setVisible(true); + jLabelSCRatePerCent.setVisible(true); + }else{ + jchkSCRestaurant.setVisible(false); + jLabelSCRate.setVisible(false); + jTextSCRate.setVisible(false); + jLabelSCRatePerCent.setVisible(false); + } + }//GEN-LAST:event_jchkSCOnOffActionPerformed + + private void jTextSCRateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextSCRateActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jTextSCRateActionPerformed + + private void jchkTransBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jchkTransBtnActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jchkTransBtnActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private com.alee.extended.colorchooser.WebColorChooserField CustomerColour; + private com.alee.extended.colorchooser.WebColorChooserField TableNameColour; + private com.alee.extended.colorchooser.WebColorChooserField WaiterColour; + private javax.swing.JCheckBox disableAnonymousStats; + private javax.swing.JCheckBox jCheckPrice00; + private javax.swing.JCheckBox jCloseCashbtn; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabelInactiveTime; + private javax.swing.JLabel jLabelInactiveTime1; + private javax.swing.JLabel jLabelSCRate; + private javax.swing.JLabel jLabelSCRatePerCent; + private javax.swing.JLabel jLabelTableNameTextColour; + private javax.swing.JLabel jLabelTimedMessage; + private javax.swing.JLabel jLblautoRefresh; + private javax.swing.JCheckBox jMoveAMountBoxToTop; + private javax.swing.JCheckBox jTaxIncluded; + private javax.swing.JTextField jTextAutoLogoffTime; + private javax.swing.JTextField jTextSCRate; + private javax.swing.JTextField jTxtautoRefreshTimer; + private javax.swing.JCheckBox jchkAutoLogoff; + private javax.swing.JCheckBox jchkAutoLogoffToTables; + private javax.swing.JCheckBox jchkBarcodetype; + private javax.swing.JCheckBox jchkInstance; + private javax.swing.JCheckBox jchkOverride; + private javax.swing.JCheckBox jchkPriceUpdate; + private javax.swing.JCheckBox jchkSCOnOff; + private javax.swing.JCheckBox jchkSCRestaurant; + private javax.swing.JCheckBox jchkShowCustomerDetails; + private javax.swing.JCheckBox jchkShowWaiterDetails; + private javax.swing.JCheckBox jchkTextOverlay; + private javax.swing.JCheckBox jchkTransBtn; + private javax.swing.JCheckBox jchkautoRefreshTableMap; + private javax.swing.JTextField jtxtPIN; + // End of variables declaration//GEN-END:variables + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/config/JPanelConfiguration.form b/src/main/java/com/unicenta/pos/config/JPanelConfiguration.form new file mode 100644 index 0000000..4793651 --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JPanelConfiguration.form @@ -0,0 +1,312 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/pos/config/JPanelConfiguration.java b/src/main/java/com/unicenta/pos/config/JPanelConfiguration.java new file mode 100644 index 0000000..60332dd --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JPanelConfiguration.java @@ -0,0 +1,384 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.config; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.JMessageDialog; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.pos.forms.*; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import javax.swing.*; +/** + * + * @author adrianromero + */ +public class JPanelConfiguration extends JPanel implements JPanelView { + + private List m_panelconfig; + + private AppConfig config; + + /** Creates new form JPanelConfiguration + * @param oApp */ + public JPanelConfiguration(AppView oApp) { + this(oApp.getProperties()); + if (oApp!= null) { + jbtnExit.setVisible(false); + } + + + } + + /** + * + * @param props + */ + public JPanelConfiguration(AppProperties props) { + + initComponents(); + config = new AppConfig(props.getConfigFile()); + + m_panelconfig = new ArrayList<>(); + + PanelConfig panel; + + panel = new JPanelConfigDatabase(); + m_panelconfig.add(panel); + jPanelDatabase.add(panel.getConfigComponent()); + + panel = new JPanelConfigGeneral(); + m_panelconfig.add(panel); + jPanelGeneral.add(panel.getConfigComponent()); + + panel = new JPanelConfigLocale(); + m_panelconfig.add(panel); + jPanelLocale.add(panel.getConfigComponent()); + + panel = new JPanelConfigPayment(); + m_panelconfig.add(panel); + jPanelPayment.add(panel.getConfigComponent()); + + panel = new JPanelConfigPeripheral(); + m_panelconfig.add(panel); + jPanelPeripheral.add(panel.getConfigComponent()); + + panel = new JPanelConfigSystem(); + m_panelconfig.add(panel); + jPanelSystem.add(panel.getConfigComponent()); + + panel = new JPanelTicketSetup(); + m_panelconfig.add(panel); + jPanelTicketSetup.add(panel.getConfigComponent()); + + panel = new JPanelConfigCompany(); + m_panelconfig.add(panel); + jPanelCompany.add(panel.getConfigComponent()); + + } + + private void restoreProperties() { + + if (config.delete()) { + loadProperties(); + } else { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.cannotdeleteconfig"))); + } + } + + private void loadProperties() { + + config.load(); + + // paneles auxiliares + for (PanelConfig c: m_panelconfig) { + c.loadProperties(config); + } + } + + private void saveProperties() { + + // paneles auxiliares + for (PanelConfig c: m_panelconfig) { + c.saveProperties(config); + } + + try { + config.save(); + JOptionPane.showMessageDialog(this, + AppLocal.getIntString("message.restartchanges"), + AppLocal.getIntString("message.title"), + JOptionPane.INFORMATION_MESSAGE); + } catch (IOException e) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.cannotsaveconfig"), e)); + } + } + + /** + * + * @return + */ + @Override + public JComponent getComponent() { + return this; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.Configuration"); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + loadProperties(); + } + + /** + * + * @return + */ + @Override + public boolean deactivate() { + + boolean haschanged = false; + for (PanelConfig c: m_panelconfig) { + if (c.hasChanged()) { + haschanged = true; + } + } + + + if (haschanged) { + int res = JOptionPane.showConfirmDialog(this, + AppLocal.getIntString("message.wannasave"), + AppLocal.getIntString("title.editor"), + JOptionPane.YES_NO_CANCEL_OPTION, + JOptionPane.QUESTION_MESSAGE); + + if (res == JOptionPane.YES_OPTION) { + saveProperties(); + return true; + } else { + return res == JOptionPane.NO_OPTION; + } + } else { + return true; + } + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jTabbedPane1 = new javax.swing.JTabbedPane(); + jPanelGeneral = new javax.swing.JPanel(); + jPanelLocale = new javax.swing.JPanel(); + jPanelPayment = new javax.swing.JPanel(); + jPanelPeripheral = new javax.swing.JPanel(); + jPanelSystem = new javax.swing.JPanel(); + jPanelTicketSetup = new javax.swing.JPanel(); + jPanelCompany = new javax.swing.JPanel(); + jPanelDatabase = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + jbtnRestore = new javax.swing.JButton(); + jbtnExit = new javax.swing.JButton(); + jbtnSave = new javax.swing.JButton(); + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setMinimumSize(new java.awt.Dimension(0, 0)); + setPreferredSize(new java.awt.Dimension(950, 600)); + + jTabbedPane1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTabbedPane1.setOpaque(true); + jTabbedPane1.setPreferredSize(new java.awt.Dimension(930, 550)); + + jPanelGeneral.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanelGeneral.setPreferredSize(new java.awt.Dimension(0, 400)); + jPanelGeneral.setLayout(new javax.swing.BoxLayout(jPanelGeneral, javax.swing.BoxLayout.LINE_AXIS)); + jTabbedPane1.addTab("General", jPanelGeneral); + + jPanelLocale.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanelLocale.setPreferredSize(new java.awt.Dimension(0, 400)); + jPanelLocale.setLayout(new javax.swing.BoxLayout(jPanelLocale, javax.swing.BoxLayout.LINE_AXIS)); + jTabbedPane1.addTab("Locale", jPanelLocale); + + jPanelPayment.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanelPayment.setPreferredSize(new java.awt.Dimension(0, 400)); + jPanelPayment.setLayout(new javax.swing.BoxLayout(jPanelPayment, javax.swing.BoxLayout.LINE_AXIS)); + jTabbedPane1.addTab("Payment Method", jPanelPayment); + + jPanelPeripheral.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanelPeripheral.setPreferredSize(new java.awt.Dimension(0, 400)); + jPanelPeripheral.setLayout(new javax.swing.BoxLayout(jPanelPeripheral, javax.swing.BoxLayout.LINE_AXIS)); + jTabbedPane1.addTab("Peripherals", jPanelPeripheral); + + jPanelSystem.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanelSystem.setPreferredSize(new java.awt.Dimension(0, 400)); + jPanelSystem.setLayout(new javax.swing.BoxLayout(jPanelSystem, javax.swing.BoxLayout.LINE_AXIS)); + jTabbedPane1.addTab("System Options", jPanelSystem); + + jPanelTicketSetup.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanelTicketSetup.setPreferredSize(new java.awt.Dimension(0, 400)); + jPanelTicketSetup.setLayout(new javax.swing.BoxLayout(jPanelTicketSetup, javax.swing.BoxLayout.LINE_AXIS)); + jTabbedPane1.addTab("Ticket Setup", jPanelTicketSetup); + + jPanelCompany.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanelCompany.setLayout(new javax.swing.BoxLayout(jPanelCompany, javax.swing.BoxLayout.LINE_AXIS)); + jTabbedPane1.addTab("Company", jPanelCompany); + + jPanelDatabase.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanelDatabase.setPreferredSize(new java.awt.Dimension(0, 400)); + jPanelDatabase.setLayout(new javax.swing.BoxLayout(jPanelDatabase, javax.swing.BoxLayout.LINE_AXIS)); + jTabbedPane1.addTab("Database Setup", jPanelDatabase); + + jbtnRestore.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnRestore.setText(AppLocal.getIntString("button.factory")); // NOI18N + jbtnRestore.setMaximumSize(new java.awt.Dimension(103, 33)); + jbtnRestore.setMinimumSize(new java.awt.Dimension(103, 33)); + jbtnRestore.setPreferredSize(new java.awt.Dimension(110, 45)); + jbtnRestore.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnRestoreActionPerformed(evt); + } + }); + + jbtnExit.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnExit.setText(AppLocal.getIntString("Button.Exit")); // NOI18N + jbtnExit.setMaximumSize(new java.awt.Dimension(70, 33)); + jbtnExit.setMinimumSize(new java.awt.Dimension(70, 33)); + jbtnExit.setPreferredSize(new java.awt.Dimension(110, 45)); + jbtnExit.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnExitActionPerformed(evt); + } + }); + + jbtnSave.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnSave.setText(AppLocal.getIntString("button.save")); // NOI18N + jbtnSave.setMaximumSize(new java.awt.Dimension(70, 33)); + jbtnSave.setMinimumSize(new java.awt.Dimension(70, 33)); + jbtnSave.setPreferredSize(new java.awt.Dimension(110, 45)); + jbtnSave.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnSaveActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jbtnSave, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(jbtnRestore, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(jbtnExit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(31, Short.MAX_VALUE)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jbtnRestore, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jbtnExit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jbtnSave, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + }// //GEN-END:initComponents + + private void jbtnRestoreActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnRestoreActionPerformed + + if (JOptionPane.showConfirmDialog(this, + AppLocal.getIntString("message.configfactory"), + AppLocal.getIntString("message.title"), + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { + restoreProperties(); + } + + }//GEN-LAST:event_jbtnRestoreActionPerformed + + private void jbtnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnSaveActionPerformed + + saveProperties(); + + }//GEN-LAST:event_jbtnSaveActionPerformed + + private void jbtnExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnExitActionPerformed + deactivate(); + System.exit(0); + }//GEN-LAST:event_jbtnExitActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanelCompany; + private javax.swing.JPanel jPanelDatabase; + private javax.swing.JPanel jPanelGeneral; + private javax.swing.JPanel jPanelLocale; + private javax.swing.JPanel jPanelPayment; + private javax.swing.JPanel jPanelPeripheral; + private javax.swing.JPanel jPanelSystem; + private javax.swing.JPanel jPanelTicketSetup; + private javax.swing.JTabbedPane jTabbedPane1; + private javax.swing.JButton jbtnExit; + private javax.swing.JButton jbtnRestore; + private javax.swing.JButton jbtnSave; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/config/JPanelTicketSetup.form b/src/main/java/com/unicenta/pos/config/JPanelTicketSetup.form new file mode 100644 index 0000000..351aac3 --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JPanelTicketSetup.form @@ -0,0 +1,244 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/pos/config/JPanelTicketSetup.java b/src/main/java/com/unicenta/pos/config/JPanelTicketSetup.java new file mode 100644 index 0000000..54b1e0f --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/JPanelTicketSetup.java @@ -0,0 +1,400 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.config; + +import com.unicenta.data.user.DirtyManager; +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.util.AltEncrypter; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.*; +import java.awt.*; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; + +/** + * + * @author JG uniCenta + */ +@Slf4j +public class JPanelTicketSetup extends javax.swing.JPanel implements PanelConfig { + + private final DirtyManager dirty = new DirtyManager(); + private String receipt="1"; + private Integer x = 0; + private String receiptSize; + private String pickupSize; + private final Integer ps = 0; + + private Connection conn; + private String sdbmanager; + private String SQL; + private Statement stmt; + + /** + * + */ + public JPanelTicketSetup() { + + initComponents(); + + jReceiptSize.addChangeListener(dirty); + jPickupSize.addChangeListener(dirty); + jTextReceiptPrefix.getDocument().addDocumentListener(dirty); + m_jReceiptPrintOff.addActionListener(dirty); + + jbtnReset.setVisible(true); + } + + + /** + * + * @return + */ + @Override + public boolean hasChanged() { + return dirty.isDirty(); + } + + /** + * + * @return + */ + @Override + public Component getConfigComponent() { + return this; + } + + /** + * + * @param config + */ + @Override + public void loadProperties(AppConfig config) { + + receiptSize =(config.getProperty("till.receiptsize")); + if (receiptSize == null || "".equals(receiptSize)){ + jReceiptSize.setModel(new SpinnerNumberModel(1,1,20,1)); + } else { + jReceiptSize.setModel(new SpinnerNumberModel(Integer.parseInt(receiptSize),1,20,1)); + } + + pickupSize =(config.getProperty("till.pickupsize")); + if (pickupSize == null || "".equals(pickupSize)){ + jPickupSize.setModel(new SpinnerNumberModel(1,1,20,1)); + } else { + jPickupSize.setModel(new SpinnerNumberModel(Integer.parseInt(pickupSize),1,20,1)); + } + + jTextReceiptPrefix.setText(config.getProperty("till.receiptprefix")); +// build the example receipt using the loaded details + receipt=""; + x=1; + while (x < (Integer)jReceiptSize.getValue()){ + receipt += "0"; + x++; + } + + receipt += "1"; + jTicketExample.setText(jTextReceiptPrefix.getText()+receipt); + m_jReceiptPrintOff.setSelected(Boolean.parseBoolean(config.getProperty("till.receiptprintoff"))); + + digitalReceipt.setSelected(Boolean.parseBoolean(config.getProperty("till.digital-receipt"))); + + dirty.setDirty(false); + + + } + + /* + * JG Oct 2017 + * This block to be used for internal SETS/RESETS and external ORDERS sync's + */ + public void loadUp() throws ClassNotFoundException, SQLException { + +/* Add external received order reset block here - + * Get connex to secondary or external system's DB + [params] + * Pref' use is JSON/REST rather than PreparedStatement +*/ + } + + /** + * + * @param config + */ + @Override + public void saveProperties(AppConfig config) { + + config.setProperty("till.receiptprefix", jTextReceiptPrefix.getText()); + config.setProperty("till.receiptsize", jReceiptSize.getValue().toString()); + config.setProperty("till.pickupsize", jPickupSize.getValue().toString()); + config.setProperty("till.receiptprintoff",Boolean.toString(m_jReceiptPrintOff.isSelected())); + config.setProperty("till.digital-receipt", Boolean.toString(digitalReceipt.isSelected())); + + dirty.setDirty(false); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jLabel1 = new javax.swing.JLabel(); + jReceiptSize = new javax.swing.JSpinner(); + jLabel3 = new javax.swing.JLabel(); + jTextReceiptPrefix = new javax.swing.JTextField(); + jTicketExample = new javax.swing.JTextField(); + jLabel2 = new javax.swing.JLabel(); + jPickupSize = new javax.swing.JSpinner(); + m_jReceiptPrintOff = new javax.swing.JCheckBox(); + jbtnReset = new javax.swing.JButton(); + digitalReceipt = new javax.swing.JCheckBox(); + + setBackground(new java.awt.Color(0, 0, 0)); + setOpaque(false); + setPreferredSize(new java.awt.Dimension(700, 500)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jLabel1.setText(bundle.getString("label.ticketsetupnumber")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(190, 30)); + + jReceiptSize.setFont(new java.awt.Font("Arial", 0, 18)); // NOI18N + jReceiptSize.setModel(new javax.swing.SpinnerNumberModel(0, 0, null, 1)); + jReceiptSize.setPreferredSize(new java.awt.Dimension(50, 30)); + jReceiptSize.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + jReceiptSizeStateChanged(evt); + } + }); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(bundle.getString("label.ticketsetupprefix")); // NOI18N + + jTextReceiptPrefix.setFont(new java.awt.Font("Arial", 0, 18)); // NOI18N + jTextReceiptPrefix.setHorizontalAlignment(javax.swing.JTextField.CENTER); + jTextReceiptPrefix.setPreferredSize(new java.awt.Dimension(100, 30)); + jTextReceiptPrefix.addKeyListener(new java.awt.event.KeyAdapter() { + public void keyReleased(java.awt.event.KeyEvent evt) { + jTextReceiptPrefixKeyReleased(evt); + } + }); + + jTicketExample.setFont(new java.awt.Font("Arial", 0, 18)); // NOI18N + jTicketExample.setText("1"); + jTicketExample.setDisabledTextColor(new java.awt.Color(0, 0, 0)); + jTicketExample.setEnabled(false); + jTicketExample.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(bundle.getString("label.pickupcodesize")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(190, 30)); + + jPickupSize.setFont(new java.awt.Font("Arial", 0, 18)); // NOI18N + jPickupSize.setModel(new javax.swing.SpinnerNumberModel(0, 0, null, 1)); + jPickupSize.setToolTipText(""); + jPickupSize.setPreferredSize(new java.awt.Dimension(50, 30)); + jPickupSize.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + jPickupSizeStateChanged(evt); + } + }); + + m_jReceiptPrintOff.setBackground(new java.awt.Color(255, 255, 255)); + m_jReceiptPrintOff.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jReceiptPrintOff.setText(bundle.getString("label.receiptprint")); // NOI18N + m_jReceiptPrintOff.setPreferredSize(new java.awt.Dimension(180, 30)); + m_jReceiptPrintOff.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jReceiptPrintOffActionPerformed(evt); + } + }); + + jbtnReset.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnReset.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reload.png"))); // NOI18N + jbtnReset.setText(AppLocal.getIntString("label.resetpickup")); // NOI18N + jbtnReset.setMaximumSize(new java.awt.Dimension(70, 33)); + jbtnReset.setMinimumSize(new java.awt.Dimension(70, 33)); + jbtnReset.setPreferredSize(new java.awt.Dimension(100, 45)); + jbtnReset.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnResetActionPerformed(evt); + } + }); + + digitalReceipt.setText("Enable digital email Receipts"); + digitalReceipt.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + digitalReceiptActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jReceiptPrintOff, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(jPickupSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(jbtnReset, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 160, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jReceiptSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createSequentialGroup() + .addComponent(jTextReceiptPrefix, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jTicketExample, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))) + .addComponent(digitalReceipt)) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jReceiptSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextReceiptPrefix, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTicketExample, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addComponent(m_jReceiptPrintOff, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jPickupSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jbtnReset, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addComponent(digitalReceipt) + .addContainerGap(254, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + private void jTextReceiptPrefixKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTextReceiptPrefixKeyReleased + + jTicketExample.setText(jTextReceiptPrefix.getText()+ receipt); + }//GEN-LAST:event_jTextReceiptPrefixKeyReleased + + private void jReceiptSizeStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jReceiptSizeStateChanged + + receipt=""; + x=1; + while (x < (Integer)jReceiptSize.getValue()){ + receipt += "0"; + x++; + } + receipt += "1"; + jTicketExample.setText(jTextReceiptPrefix.getText()+receipt); + + }//GEN-LAST:event_jReceiptSizeStateChanged + + private void jPickupSizeStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jPickupSizeStateChanged + + }//GEN-LAST:event_jPickupSizeStateChanged + + private void m_jReceiptPrintOffActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jReceiptPrintOffActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_m_jReceiptPrintOffActionPerformed + + private void jbtnResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnResetActionPerformed + int response = JOptionPane.showOptionDialog(null, + AppLocal.getIntString("message.resetpickup"), + "Reset", + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE, + null, null, null); + if (response == JOptionPane.YES_OPTION) { + try { + + String db_url = (AppConfig.getInstance().getProperty("db.URL")); + String db_schema = (AppConfig.getInstance().getProperty("db.schema")); + String db_user =(AppConfig.getInstance().getProperty("db.user")); + String db_password = (AppConfig.getInstance().getProperty("db.password")); + + if (db_user != null && db_password != null && db_password.startsWith("crypt:")) { + AltEncrypter cypher = new AltEncrypter("cypherkey" + db_user); + db_password = cypher.decrypt(db_password.substring(6)); + } + + String url = db_url + db_schema; + + conn = DriverManager.getConnection(url,db_user,db_password); + sdbmanager = conn.getMetaData().getDatabaseProductName(); + stmt = (Statement) conn.createStatement(); + + if ("MySQL".equals(sdbmanager)) { + SQL = "UPDATE pickup_number SET id = 0"; + try { + stmt.executeUpdate(SQL); + } catch (SQLException e){ + System.out.println(e.getMessage()); + } + } else if ("PostgreSQL".equals(sdbmanager)) { + SQL = "ALTER SEQUENCE pickup_number RESTART WITH 1"; + try { + stmt.executeUpdate(SQL); + } catch (SQLException e) { + System.out.println(e.getMessage()); + } + } + } catch (SQLException ex) { log.error(ex.getMessage()); + } + } + }//GEN-LAST:event_jbtnResetActionPerformed + + private void digitalReceiptActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_digitalReceiptActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_digitalReceiptActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JCheckBox digitalReceipt; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JSpinner jPickupSize; + private javax.swing.JSpinner jReceiptSize; + private javax.swing.JTextField jTextReceiptPrefix; + private javax.swing.JTextField jTicketExample; + private javax.swing.JButton jbtnReset; + private javax.swing.JCheckBox m_jReceiptPrintOff; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/config/LocaleComparator.java b/src/main/java/com/unicenta/pos/config/LocaleComparator.java new file mode 100644 index 0000000..8989ae7 --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/LocaleComparator.java @@ -0,0 +1,39 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.config; + +import java.util.Comparator; +import java.util.Locale; + +/** + * + * @author adrianromero + */ +public class LocaleComparator implements Comparator { + + /** Creates a new instance of LocaleComparator */ + public LocaleComparator() { + } + + @Override + public int compare(Locale o1, Locale o2) { + return o1.getDisplayName().compareTo(o2.getDisplayName()); + } +} diff --git a/src/main/java/com/unicenta/pos/config/PanelConfig.java b/src/main/java/com/unicenta/pos/config/PanelConfig.java new file mode 100644 index 0000000..f5c5c5c --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/PanelConfig.java @@ -0,0 +1,54 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.config; + +import com.unicenta.pos.forms.AppConfig; +import java.awt.Component; + +/** + * + * @author adrianromero + */ +public interface PanelConfig { + + /** + * + * @param config + */ + public void loadProperties(AppConfig config); + + /** + * + * @param config + */ + public void saveProperties(AppConfig config); + + /** + * + * @return + */ + public boolean hasChanged(); + + /** + * + * @return + */ + public Component getConfigComponent(); +} diff --git a/src/main/java/com/unicenta/pos/config/ParametersConfig.java b/src/main/java/com/unicenta/pos/config/ParametersConfig.java new file mode 100644 index 0000000..5b53818 --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/ParametersConfig.java @@ -0,0 +1,56 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.config; + +import com.unicenta.data.user.DirtyManager; +import com.unicenta.pos.util.StringParser; +import java.awt.Component; + +/** + * + * @author adrian + */ +public interface ParametersConfig { + + /** + * + * @return + */ + public Component getComponent(); + + /** + * + * @param dirty + */ + public void addDirtyManager(DirtyManager dirty); + + /** + * + * @param p + */ + public void setParameters(StringParser p); + + /** + * + * @return + */ + public String getParameters(); + +} diff --git a/src/main/java/com/unicenta/pos/config/ParametersPrinter.form b/src/main/java/com/unicenta/pos/config/ParametersPrinter.form new file mode 100644 index 0000000..608a9ea --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/ParametersPrinter.form @@ -0,0 +1,70 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/pos/config/ParametersPrinter.java b/src/main/java/com/unicenta/pos/config/ParametersPrinter.java new file mode 100644 index 0000000..e8a357e --- /dev/null +++ b/src/main/java/com/unicenta/pos/config/ParametersPrinter.java @@ -0,0 +1,149 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.config; + +import com.unicenta.data.user.DirtyManager; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.util.StringParser; +import java.awt.Component; + +/** + * + * @author adrian + */ +public class ParametersPrinter extends javax.swing.JPanel implements ParametersConfig { + + private String othersizename = "standard"; + + /** Creates new form ParametersPrinter + * @param printernames */ + public ParametersPrinter(String [] printernames) { + initComponents(); + + jPrinters.addItem("(Default)"); + jPrinters.addItem("(Show dialog)"); + for (String name : printernames) { + jPrinters.addItem(name); + } + } + + /** + * + * @return + */ + public Component getComponent() { + return this; + } + + /** + * + * @param dirty + */ + public void addDirtyManager(DirtyManager dirty) { + jPrinters.addActionListener(dirty); + jReceiptPrinter.addActionListener(dirty); + } + + /** + * + * @param p + */ + public void setParameters(StringParser p) { + jPrinters.setSelectedItem(p.nextToken(',')); + String sizename = p.nextToken(','); + jReceiptPrinter.setSelected("receipt".equals(sizename)); + othersizename = "receipt".equals(sizename) ? "standard" : sizename; + } + + /** + * + * @return + */ + public String getParameters() { + return comboValue(jPrinters.getSelectedItem()) + "," + boolValue(jReceiptPrinter.isSelected()); + } + + private static String comboValue(Object value) { + return value == null ? "" : value.toString(); + } + + private String boolValue(boolean value) { + return value ? "receipt" : othersizename; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPrinters = new javax.swing.JComboBox(); + jReceiptPrinter = new javax.swing.JCheckBox(); + + setOpaque(false); + + jPrinters.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPrinters.setPreferredSize(new java.awt.Dimension(200, 30)); + jPrinters.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jPrintersActionPerformed(evt); + } + }); + + jReceiptPrinter.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jReceiptPrinter.setSelected(true); + jReceiptPrinter.setText(AppLocal.getIntString("label.receiptprinter")); // NOI18N + jReceiptPrinter.setOpaque(false); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jPrinters, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jReceiptPrinter) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jPrinters, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jReceiptPrinter, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + private void jPrintersActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jPrintersActionPerformed + + }//GEN-LAST:event_jPrintersActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JComboBox jPrinters; + private javax.swing.JCheckBox jReceiptPrinter; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/customers/CustomerInfo.java b/src/main/java/com/unicenta/pos/customers/CustomerInfo.java new file mode 100644 index 0000000..e5a41c6 --- /dev/null +++ b/src/main/java/com/unicenta/pos/customers/CustomerInfo.java @@ -0,0 +1,171 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.customers; + +import com.unicenta.pos.util.StringUtils; +import java.awt.image.BufferedImage; +import java.io.Serializable; + +/** @author jack gerrard, adrianromero */ + +// JG 20 Sep 12 Extended for Postal +// JG 2 Sep 13 Extended for Phone + Email +public class CustomerInfo implements Serializable { + + private static final long serialVersionUID = 9083257536541L; + + protected String id; + protected String searchkey; + protected String taxid; + protected String name; + protected String postal; + protected String phone; + protected String email; + protected BufferedImage image; + protected Double curdebt; + + + /** Creates a new instance of CustomerInfo + * @param id */ + public CustomerInfo(String id) { + this.id = id; + this.searchkey = null; + this.taxid = null; + this.name = null; + this.postal = null; + this.phone = null; + this.email = null; + this.image = null; + this.curdebt = null; + } + + /** + * + * @return id string + */ + public String getId() { + return id; + } + + /** + * + * @return searchkey string + */ + public String getSearchkey() { + return searchkey; + } + public void setSearchkey(String searchkey) { + this.searchkey = searchkey; + } + + /** + * + * @return taxid string + */ + public String getTaxid() { + return taxid; + } + public void setTaxid(String taxid) { + this.taxid = taxid; + } + + /** + * + * @return name string + */ + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + /** + * + * @return postal/zip code string + */ + public String getPcode() { + return postal; + } + public void setPcode(String postal) { + this.postal = postal; + } + + /** + * + * @return Primary Telephone string + */ + public String getPhone1() { + return phone; + } + public void setPhone1(String phone) { + this.phone = phone; + } + + /** + * + * @return email string + */ + public String getCemail() { + return email; + } + public void setCemail(String email) { + this.email = email; + } + + /** + * + * @return + */ + public String printName() { + return StringUtils.encodeXML(name); + } + + @Override + public String toString() { + return getName(); + } + + /** + * + * @return customer's photograph / image + */ + public BufferedImage getImage() { + return image; + } + /** + * + * @param img + */ + public void setImage(BufferedImage img) { + image = img; + } + + /** + * + * @return name double + */ + public Double getCurDebt() { + return curdebt; + } + public void setCurDebt(Double curdebt) { + this.curdebt = curdebt; + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/customers/CustomerInfoExt.java b/src/main/java/com/unicenta/pos/customers/CustomerInfoExt.java new file mode 100644 index 0000000..8ffc707 --- /dev/null +++ b/src/main/java/com/unicenta/pos/customers/CustomerInfoExt.java @@ -0,0 +1,467 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.customers; + +import com.unicenta.format.Formats; +import com.unicenta.pos.util.RoundUtils; +import java.awt.image.BufferedImage; +import java.util.Date; + +/** + * + * @author adrianromero + * @author JG uniCenta + */ +public class CustomerInfoExt extends CustomerInfo { + + protected String taxcustomerid; + protected String taxcustcategoryid; + protected String card; + protected Double maxdebt; + protected String address; + protected String address2; + protected String pcode; + protected String city; + protected String region; + protected String country; + protected String firstname; + protected String lastname; + protected String cemail; + protected String phone1; + protected String phone2; + protected String fax; + protected String notes; + protected boolean visible; + protected Date curdate; + protected Double accdebt; + protected BufferedImage m_Image; + protected boolean isvip; + protected Double discount; + protected String prepay; + protected String memodate; + + /** Creates a new instance of UserInfoBasic + * @param id */ + public CustomerInfoExt(String id) { + super(id); + } + + /** + * + * @return customer's tax category + */ + public String getTaxCustCategoryID() { +// return taxcustomerid; + return taxcustcategoryid; + } + public void setTaxCustCategoryID(String taxcustcategoryid) { + this.taxcustcategoryid = taxcustcategoryid; + } + + public String getTaxCustomerID() { + return taxcustomerid; + } + public void setTaxCustomerID(String taxcustomerid) { + this.taxcustomerid = taxcustomerid; + } + public String printTaxCustomerID() { + return Formats.STRING.formatValue(taxcustomerid); + } + + @Override + public String getTaxid() { + return taxid; + } + @Override + public void setTaxid(String taxid) { + this.taxid = taxid; + } + public String printTaxid() { + return Formats.STRING.formatValue(taxid); + } + + + /** + * + * @return notes string + */ + public String getNotes() { + return notes; + } + public void setNotes(String notes) { + this.notes = notes; + } + + + /** + * + * @return Is visible Y/N? boolean + */ + public boolean isVisible() { + return visible; + } + public void setVisible(boolean visible) { + this.visible = visible; + } + + + /** + * + * @return customer's hashed member/loyalty card string + */ + public String getCard() { + return card; + } + public void setCard(String card) { + this.card = card; + } + + /** + * + * @return customer's maximum allowed debt value + */ + public Double getMaxdebt() { + return maxdebt; + } + public void setMaxdebt(Double maxdebt) { + this.maxdebt = maxdebt; + } + public String printMaxDebt() { + return Formats.CURRENCY.formatValue(RoundUtils.getValue(getMaxdebt())); + } + + + /** + * + * @return customer's last ticket transaction date + */ + public Date getCurdate() { + return curdate; + } + public void setCurdate(Date curdate) { + this.curdate = curdate; + } + public String printCurDate() { + return Formats.DATE.formatValue(getCurdate()); + } + + /** + * + * @return customer's current value of account + */ + public Double getAccdebt() { + return accdebt; + } + public void setAccdebt(Double accdebt) { + this.accdebt = accdebt; + } + public String printCurDebt() { + return Formats.CURRENCY.formatValue(RoundUtils.getValue(getAccdebt())); + } + + public String printCurBal() { + String balance = null; + + if (getMaxdebt() != null && getAccdebt() != null) { + balance = Formats.CURRENCY.formatValue(RoundUtils.getValue(getMaxdebt() - getAccdebt())); + } + return balance; + } + + /** + * + * @return prepay string + */ + public String getPrePay() { + return prepay; + } + public void setPrePay(String prepay) { + this.prepay = prepay; + } + + + /** + * + * @param amount + * @param d + */ + public void updateCurDebt(Double amount, Date d) { + + accdebt = accdebt == null ? amount : accdebt + amount; + curdate = (new Date()); + + if (RoundUtils.compare(accdebt, 0.0) > 0) { + if (curdate == null) { + // new date + curdate = d; + } + } else if (RoundUtils.compare(accdebt, 0.0) == 0) { + accdebt = null; + curdate = null; + } else { // < 0 +// curdate = null; + } + } + + /** + * + * @return customer's firstname string + */ + public String getFirstname() { + return firstname; + } + + /** + * + * @param firstname + */ + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + /** + * + * @return customer's lastname string + */ + public String getLastname() { + return lastname; + } + + /** + * + * @param lastname + */ + public void setLastname(String lastname) { + this.lastname = lastname; + } + + /** + * + * @return customer's cemail string + */ + @Override + public String getCemail() { + return cemail; + } + + /** + * + * @param cemail + */ + @Override + public void setCemail(String cemail) { + this.cemail = cemail; + } + + /** + * + * @return customer's Primary telephone string + */ + @Override + public String getPhone1() { + return phone1; + } + @Override + public void setPhone1(String phone1) { + this.phone1 = phone1; + } + public String printPhone1() { + return Formats.STRING.formatValue(phone1); + } + + /** + * + * @return customer's Secondary telephone string + */ + public String getPhone2() { + return phone2; + } + + /** + * + * @param phone2 + */ + public void setPhone2(String phone2) { + this.phone2 = phone2; + } + + /** + * + * @return customer's fax number string + */ + public String getFax() { + return fax; + } + + /** + * + * @param fax + */ + public void setFax(String fax) { + this.fax = fax; + } + + /** + * + * @return customer's address line 1 string + */ + public String getAddress() { + return address; + } + public void setAddress(String address) { + this.address = address; + } + public String printAddress() { + return Formats.STRING.formatValue(address); + } + + /** + * + * @return customer's address line 2 string + */ + public String getAddress2() { + return address2; + } + public void setAddress2(String address2) { + this.address2 = address2; + } + public String printAddress2() { + return Formats.STRING.formatValue(address2); + } + + /** + * + * @return customer's pcode/zip code string + */ + @Override + public String getPcode() { + return pcode; + } + @Override + public void setPcode(String pcode) { + this.pcode = pcode; + } + public String printPostal() { + return Formats.STRING.formatValue(pcode); + } + + /** + * + * @return customer's address city string + */ + public String getCity() { + return city; + } + /** + * + * @param city + */ + public void setCity(String city) { + this.city = city; + } + + /** + * + * @return customer's address region/state/county string + */ + public String getRegion() { + return region; + } + /** + * + * @param region + */ + public void setRegion(String region) { + this.region = region; + } + + /** + * + * @return customer's address country string + */ + public String getCountry() { + return country; + } + /** + * + * @param country + */ + public void setCountry(String country) { + this.country = country; + } + + /** + * + * @return customer's photograph / image + */ + @Override + public BufferedImage getImage() { + return m_Image; + } + /** + * + * @param img + */ + @Override + public void setImage(BufferedImage img) { + this.m_Image = img; + } + + /** + * + * @return Is VIP Y/N? boolean + */ + public boolean isVIP() { + return isvip; + } + public void setisVIP(boolean isvip) { + this.isvip = isvip; + } + + + /** + * + * @return customer's discount allowed + */ + public Double getDiscount() { + return discount; + } + public void setDiscount(Double discount) { + this.discount = discount; + } + public String printDiscount() { + return Formats.CURRENCY.formatValue(RoundUtils.getValue(getDiscount())); + } + + /** + * + * @return memo date string + */ + public String getMemoDate() { + return memodate; + } + public void setMemoDate(String memodate) { + this.memodate = memodate; + } + public String printMemoDate() { + return Formats.STRING.formatValue(memodate); + } + +} diff --git a/src/main/java/com/unicenta/pos/customers/CustomerInfoGlobal.java b/src/main/java/com/unicenta/pos/customers/CustomerInfoGlobal.java new file mode 100644 index 0000000..931deda --- /dev/null +++ b/src/main/java/com/unicenta/pos/customers/CustomerInfoGlobal.java @@ -0,0 +1,88 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . +// + +// For BrowseEditableData + +package com.unicenta.pos.customers; + +import com.unicenta.data.user.BrowsableEditableData; + +/** + * + * @author HS uniCenta + */ +public class CustomerInfoGlobal { + + private static CustomerInfoGlobal INSTANCE; + private CustomerInfoExt customerInfoExt; + private BrowsableEditableData editableData; + + //Singleton class + private CustomerInfoGlobal() { + } + + //Singleton constructor + + /** + * + * @return + */ + public static CustomerInfoGlobal getInstance() { + if (INSTANCE == null) { + INSTANCE = new CustomerInfoGlobal(); + } + + return INSTANCE; + } + + /** + * + * @return + */ + public CustomerInfoExt getCustomerInfoExt() { + return customerInfoExt; + } + + /** + * + * @param customerInfoExt + */ + public void setCustomerInfoExt(CustomerInfoExt customerInfoExt) { + this.customerInfoExt = customerInfoExt; + } + + /** + * + * @return + */ + public BrowsableEditableData getEditableData() { + return editableData; +} + + /** + * + * @param editableData + */ + public void setEditableData(BrowsableEditableData editableData) { + this.editableData = editableData; + } + + +} diff --git a/src/main/java/com/unicenta/pos/customers/CustomerRenderer.java b/src/main/java/com/unicenta/pos/customers/CustomerRenderer.java new file mode 100644 index 0000000..a552b43 --- /dev/null +++ b/src/main/java/com/unicenta/pos/customers/CustomerRenderer.java @@ -0,0 +1,53 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.customers; + +import java.awt.Component; +import javax.swing.DefaultListCellRenderer; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JList; + +/** + * + * @author JG uniCenta + */ +public class CustomerRenderer extends DefaultListCellRenderer { + + private final Icon icocustomer; + + /** Creates a new instance of CustomerRenderer */ + public CustomerRenderer() { + + icocustomer = new ImageIcon(getClass().getClassLoader().getResource("com/unicenta/images/customer_sml.png")); + + } + + @Override + public Component getListCellRendererComponent(JList list, Object value, + int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, null, index, isSelected, cellHasFocus); + + setIcon(icocustomer); + setText(value.toString()); + + return this; + } +} diff --git a/src/main/java/com/unicenta/pos/customers/CustomerTransaction.java b/src/main/java/com/unicenta/pos/customers/CustomerTransaction.java new file mode 100644 index 0000000..7fd05b2 --- /dev/null +++ b/src/main/java/com/unicenta/pos/customers/CustomerTransaction.java @@ -0,0 +1,209 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.customers; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.SerializerRead; +import lombok.extern.slf4j.Slf4j; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * @author JG uniCenta Gerrard 1 Nov 12 + * Used in Customer's transactions tab to display all this Customer's + * ticketline values + */ +@Slf4j +public class CustomerTransaction { + + String ticketId; + String productName; + String unit; + Double amount; + Double total; + Date transactionDate; + String customerId; + + /** + * Main method to return all customer's transactions + */ + public CustomerTransaction() { + } + + /** + * @param ticketId + * @param productName + * @param unit + * @param amount + * @param total + * @param transactionDate + * @param cId + */ + public CustomerTransaction(String ticketId, String productName, String unit, Double amount, Double total, Date transactionDate, String cId) { + this.ticketId = ticketId; + this.productName = productName; + this.unit = unit; + this.amount = amount; + this.total = total; + this.transactionDate = transactionDate; +// this.customerName = name; + this.customerId = cId; + } + + /** + * @return ticket id string + */ + public String getTicketId() { + return ticketId; + } + + /** + * @param ticketId + */ + public void setTicketId(String ticketId) { + this.ticketId = ticketId; + } + + /** + * @return ticket amount value + */ + public Double getAmount() { + return amount; + } + + /** + * @param amount + */ + public void setAmount(Double amount) { + this.amount = amount; + } + + /** + * @param total + */ + public void setTotal(Double total) { + this.total = total; + } + + /** + * @return ticketline value + */ + public Double getTotal() { + return total; + } + + /** + * @return ticketline's product name string + */ + public String getProductName() { + return productName; + } + + /** + * @param productName + */ + public void setProductName(String productName) { + this.productName = productName; + } + + /** + * @return ticket's transaction date + */ + public Date getTransactionDate() { + return transactionDate; + } + + /** + * @param transactionDate + */ + public void setTransactionDate(Date transactionDate) { + this.transactionDate = transactionDate; + } + + /** + * @return ticketline's quantity string value + */ + public String getUnit() { + return unit; + } + + /** + * @param unit + */ + public void setUnit(String unit) { + this.unit = unit; + } + + /** + * + * @return customer's account name string + public String getCustomerName() { + return customerName; + } + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + */ + + /** + * @return customer's account name string + */ + public String getCustomerId() { + return customerId; + } + + public void setCustomerId(String customerId) { + this.customerId = customerId; + } + + + /** + * @return ticketlines for this customer + */ + public static SerializerRead getSerializerRead() { + return new SerializerRead() { + + @Override + public Object readValues(DataRead dr) throws BasicException { + + String ticketId = dr.getString(1); + String productName = dr.getString(2); + String unit = dr.getString(3); + Double amount = dr.getDouble(4); + Double total = dr.getDouble(5); + String dateValue = dr.getString(6); + String customerId = dr.getString(7); + + + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); + Date date = null; + try { + date = formatter.parse(dateValue); + } catch (ParseException ex) { + log.error(ex.getMessage()); + } + return new CustomerTransaction(ticketId, productName, unit, amount, total, date, customerId); + } + }; + } +} diff --git a/src/main/java/com/unicenta/pos/customers/CustomersPanel.java b/src/main/java/com/unicenta/pos/customers/CustomersPanel.java new file mode 100644 index 0000000..da69e54 --- /dev/null +++ b/src/main/java/com/unicenta/pos/customers/CustomersPanel.java @@ -0,0 +1,135 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.customers; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ListCellRendererBasic; +import com.unicenta.data.loader.ComparatorCreator; +import com.unicenta.data.loader.TableDefinition; +import com.unicenta.data.loader.Vectorer; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.panels.JPanelTable; +import javax.swing.ListCellRenderer; + +/** + * + * @author adrianromero + */ +public class CustomersPanel extends JPanelTable { + + private TableDefinition tcustomers; + private CustomersView jeditor; + + /** Creates a new instance of CustomersPanel */ + public CustomersPanel() { +// CustomerInfoGlobal.getInstance().setEditableData(bd); + } + + /** + * + */ + @Override + protected void init() { + DataLogicCustomers dlCustomers = (DataLogicCustomers) app.getBean("com.unicenta.pos.customers.DataLogicCustomers"); + tcustomers = dlCustomers.getTableCustomers(); + jeditor = new CustomersView(app, dirty); +// System.out.println(tcustomers.getListSQL()); + + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + jeditor.activate(); + super.activate(); + } + + /** + * + * @return + */ + @Override + public ListProvider getListProvider() { + return new ListProviderCreator(tcustomers); + } + + /** + * + * @return + */ + @Override + public SaveProvider getSaveProvider() { + return new SaveProvider(tcustomers, new int[] { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}); + } + + /** + * + * @return + */ + @Override + public Vectorer getVectorer() { + return tcustomers.getVectorerBasic(new int[]{1, 2, 3, 4}); + } + + /** + * + * @return + */ + @Override + public ComparatorCreator getComparatorCreator() { + return tcustomers.getComparatorCreator(new int[] {1, 2, 3, 4}); + } + + /** + * + * @return + */ + @Override + public ListCellRenderer getListCellRenderer() { + return new ListCellRendererBasic(tcustomers.getRenderStringBasic(new int[]{3})); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return jeditor; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.CustomersManagement"); + } +} diff --git a/src/main/java/com/unicenta/pos/customers/CustomersPayment.form b/src/main/java/com/unicenta/pos/customers/CustomersPayment.form new file mode 100644 index 0000000..d38b567 --- /dev/null +++ b/src/main/java/com/unicenta/pos/customers/CustomersPayment.form @@ -0,0 +1,572 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/unicenta/pos/customers/CustomersPayment.java b/src/main/java/com/unicenta/pos/customers/CustomersPayment.java new file mode 100644 index 0000000..4c100b5 --- /dev/null +++ b/src/main/java/com/unicenta/pos/customers/CustomersPayment.java @@ -0,0 +1,793 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +package com.unicenta.pos.customers; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.*; +import com.unicenta.pos.payment.JPaymentSelect; +import com.unicenta.pos.payment.JPaymentSelectCustomer; +import com.unicenta.pos.payment.PaymentInfo; +import com.unicenta.pos.payment.PaymentInfoTicket; +import com.unicenta.pos.printer.TicketParser; +import com.unicenta.pos.printer.TicketPrinterException; +import com.unicenta.pos.scripting.ScriptEngine; +import com.unicenta.pos.scripting.ScriptException; +import com.unicenta.pos.scripting.ScriptFactory; +import com.unicenta.pos.ticket.TicketInfo; +import com.unicenta.pos.util.RoundUtils; +import java.util.Date; +import java.util.List; +import javax.swing.JComponent; +import javax.swing.JOptionPane; + +/** + * + * @author adrianromero + */ +public class CustomersPayment extends javax.swing.JPanel implements JPanelView, BeanFactoryApp { + + private AppView app; + private DataLogicCustomers dlcustomers; + private DataLogicSales dlsales; + private DataLogicSystem dlsystem; + private TicketParser ttp; + private JPaymentSelect paymentdialog; + + private CustomerInfoExt customerext; + private DirtyManager dirty; + + /** Creates new form CustomersPayment */ + public CustomersPayment() { + + initComponents(); + + editorcard.addEditorKeys(m_jKeys); + txtNotes.addEditorKeys(m_jKeys); + txtPrePay.addEditorKeys(m_jKeys); + + dirty = new DirtyManager(); + txtNotes.addPropertyChangeListener("Text", dirty); + txtPrePay.addPropertyChangeListener("Number", dirty); + } + + /** + * + * @param app + * @throws BeanFactoryException + */ + @Override + public void init(AppView app) throws BeanFactoryException { + + this.app = app; + dlcustomers = (DataLogicCustomers) app.getBean("com.unicenta.pos.customers.DataLogicCustomers"); + dlsales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + dlsystem = (DataLogicSystem) app.getBean("com.unicenta.pos.forms.DataLogicSystem"); + ttp = new TicketParser(app.getDeviceTicket(), dlsystem); + } + + /** + * + * @return + */ + @Override + public Object getBean() { + return this; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.CustomersPayment"); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + + paymentdialog = JPaymentSelectCustomer.getDialog(this); + paymentdialog.init(app); + + resetCustomer(); + + editorcard.reset(); + editorcard.activate(); + } + + /** + * + * @return + */ + @Override + public boolean deactivate() { + if (dirty.isDirty()) { + int res = JOptionPane.showConfirmDialog(this, AppLocal.getIntString("message.wannasave"), + AppLocal.getIntString("title.editor"), + JOptionPane.YES_NO_CANCEL_OPTION, + JOptionPane.QUESTION_MESSAGE); + + if (res == JOptionPane.YES_OPTION) { + save(); + return true; + } else { + return res == JOptionPane.NO_OPTION; + } + } else { + return true; + } + } + + /** + * + * @return + */ + @Override + public JComponent getComponent() { + return this; + } + + private void editCustomer(CustomerInfoExt customer) { + + customerext = customer; + + txtTaxId.setText(customer.getTaxid()); + txtName.setText(customer.getName()); + txtCard.setText(customer.getCard()); + txtNotes.reset(); + txtNotes.setText(customer.getNotes()); + txtMaxdebt.setText(Formats.CURRENCY.formatValue(customer.getMaxdebt())); + txtCurdebt.setText(Formats.CURRENCY.formatValue(customer.getAccdebt())); + txtCurdate.setText(Formats.DATE.formatValue(customer.getCurdate())); + txtPrePay.setText(null); + + txtNotes.setEnabled(true); + txtPrePay.setEnabled(true); + + dirty.setDirty(false); + + btnSave.setEnabled(true); + btnPay.setEnabled(true); + btnPrePay.setEnabled(true); + +// btnPay.setEnabled(customer.getCurdebt() != null && customer.getCurdebt().doubleValue() > 0.0); + + } + + private void resetCustomer() { + + customerext = null; + + txtTaxId.setText(null); + txtName.setText(null); + txtCard.setText(null); + txtNotes.reset(); + txtMaxdebt.setText(null); + txtCurdebt.setText(null); + txtCurdate.setText(null); + txtPrePay.setText(null); + + txtNotes.setEnabled(false); + txtPrePay.setEnabled(false); + + dirty.setDirty(false); + + btnSave.setEnabled(false); + btnPay.setEnabled(false); + btnPrePay.setEnabled(false); + + } + + private void readCustomer() { + + try { + CustomerInfoExt customer = dlsales.findCustomerExt(editorcard.getText()); + if (customer == null) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotfindcustomer")); + msg.show(this); + } else { + editCustomer(customer); + } + + } catch (BasicException ex) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotfindcustomer"), ex); + msg.show(this); + } + + editorcard.reset(); + editorcard.activate(); + } + + private void save() { + + customerext.setNotes(txtNotes.getText()); + customerext.setPrePay(txtPrePay.getText()); + + try { + dlcustomers.updateCustomerExt(customerext); + editCustomer(customerext); + } catch (BasicException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, AppLocal.getIntString("message.nosave"), e); + msg.show(this); + } + + } + + private void printTicket(String resname, TicketInfo ticket, CustomerInfoExt customer) { + + String resource = dlsystem.getResourceAsXML(resname); + if (resource == null) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotprintticket")); + msg.show(this); + } else { + try { + ScriptEngine script = ScriptFactory.getScriptEngine(ScriptFactory.VELOCITY); + script.put("ticket", ticket); + script.put("customer", customer); + ttp.printTicket(script.eval(resource).toString()); +// JG 6 May use multicatch + } catch ( ScriptException | TicketPrinterException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotprintticket"), e); + msg.show(this); + } + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + jPanel2 = new javax.swing.JPanel(); + jPanel6 = new javax.swing.JPanel(); + btnCustomer = new javax.swing.JButton(); + btnSave = new javax.swing.JButton(); + jSeparator1 = new javax.swing.JSeparator(); + btnPay = new javax.swing.JButton(); + btnPrePay = new javax.swing.JButton(); + jPanel3 = new javax.swing.JPanel(); + jPanel4 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel5 = new javax.swing.JPanel(); + editorcard = new com.unicenta.editor.JEditorString(); + jButton1 = new javax.swing.JButton(); + jPanel1 = new javax.swing.JPanel(); + jLabel3 = new javax.swing.JLabel(); + jLabel12 = new javax.swing.JLabel(); + jLabel5 = new javax.swing.JLabel(); + txtCard = new javax.swing.JTextField(); + jLabel1 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + txtCurdebt = new javax.swing.JTextField(); + txtCurdate = new javax.swing.JTextField(); + jLabel6 = new javax.swing.JLabel(); + txtName = new javax.swing.JTextField(); + txtMaxdebt = new javax.swing.JTextField(); + txtPrePay = new com.unicenta.editor.JEditorString(); + txtTaxId = new javax.swing.JTextField(); + jLabel7 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + txtNotes = new com.unicenta.editor.JEditorString(); + + setLayout(new java.awt.BorderLayout()); + + jPanel2.setLayout(new java.awt.BorderLayout()); + + btnCustomer.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/customer_sml.png"))); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + btnCustomer.setToolTipText(bundle.getString("tooltip.customerpay.customer")); // NOI18N + btnCustomer.setFocusPainted(false); + btnCustomer.setFocusable(false); + btnCustomer.setMargin(new java.awt.Insets(8, 14, 8, 14)); + btnCustomer.setPreferredSize(new java.awt.Dimension(110, 45)); + btnCustomer.setRequestFocusEnabled(false); + btnCustomer.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnCustomerActionPerformed(evt); + } + }); + jPanel6.add(btnCustomer); + + btnSave.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/filesave.png"))); // NOI18N + btnSave.setToolTipText(bundle.getString("tootltip.save")); // NOI18N + btnSave.setFocusPainted(false); + btnSave.setFocusable(false); + btnSave.setMargin(new java.awt.Insets(8, 14, 8, 14)); + btnSave.setPreferredSize(new java.awt.Dimension(110, 45)); + btnSave.setRequestFocusEnabled(false); + btnSave.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnSaveActionPerformed(evt); + } + }); + jPanel6.add(btnSave); + jPanel6.add(jSeparator1); + + btnPay.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + btnPay.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/pay.png"))); // NOI18N + btnPay.setText(AppLocal.getIntString("button.pay")); // NOI18N + btnPay.setToolTipText(bundle.getString("tooltip.customerpay.pay")); // NOI18N + btnPay.setFocusPainted(false); + btnPay.setFocusable(false); + btnPay.setMargin(new java.awt.Insets(8, 14, 8, 14)); + btnPay.setMaximumSize(new java.awt.Dimension(110, 44)); + btnPay.setMinimumSize(new java.awt.Dimension(110, 44)); + btnPay.setPreferredSize(new java.awt.Dimension(110, 45)); + btnPay.setRequestFocusEnabled(false); + btnPay.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnPayActionPerformed(evt); + } + }); + jPanel6.add(btnPay); + + btnPrePay.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + btnPrePay.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/customer_add_sml.png"))); // NOI18N + btnPrePay.setText(AppLocal.getIntString("button.prepay")); // NOI18N + btnPrePay.setToolTipText(bundle.getString("tooltip.prepay")); // NOI18N + btnPrePay.setFocusPainted(false); + btnPrePay.setFocusable(false); + btnPrePay.setMargin(new java.awt.Insets(8, 14, 8, 14)); + btnPrePay.setMaximumSize(new java.awt.Dimension(110, 44)); + btnPrePay.setMinimumSize(new java.awt.Dimension(110, 44)); + btnPrePay.setPreferredSize(new java.awt.Dimension(110, 45)); + btnPrePay.setRequestFocusEnabled(false); + btnPrePay.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnPrePayActionPerformed(evt); + } + }); + jPanel6.add(btnPrePay); + + jPanel2.add(jPanel6, java.awt.BorderLayout.LINE_START); + + add(jPanel2, java.awt.BorderLayout.PAGE_START); + + jPanel3.setLayout(new java.awt.BorderLayout()); + + jPanel4.setLayout(new javax.swing.BoxLayout(jPanel4, javax.swing.BoxLayout.Y_AXIS)); + + m_jKeys.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jKeysActionPerformed(evt); + } + }); + jPanel4.add(m_jKeys); + + jPanel5.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel5.setLayout(new java.awt.GridBagLayout()); + + editorcard.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + editorcard.setPreferredSize(new java.awt.Dimension(200, 30)); + jPanel5.add(editorcard, new java.awt.GridBagConstraints()); + + jButton1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jButton1.setFocusPainted(false); + jButton1.setFocusable(false); + jButton1.setMargin(new java.awt.Insets(8, 14, 8, 14)); + jButton1.setPreferredSize(new java.awt.Dimension(110, 45)); + jButton1.setRequestFocusEnabled(false); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + jPanel5.add(jButton1, gridBagConstraints); + + jPanel4.add(jPanel5); + + jPanel3.add(jPanel4, java.awt.BorderLayout.NORTH); + + add(jPanel3, java.awt.BorderLayout.LINE_END); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.name")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel12.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel12.setText(AppLocal.getIntString("label.notes")); // NOI18N + jLabel12.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.card")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtCard.setEditable(false); + txtCard.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtCard.setFocusable(false); + txtCard.setPreferredSize(new java.awt.Dimension(0, 30)); + txtCard.setRequestFocusEnabled(false); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLabel1.setText(AppLocal.getIntString("label.maxdebt")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(120, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLabel2.setText(AppLocal.getIntString("label.curdebt")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(120, 30)); + + txtCurdebt.setEditable(false); + txtCurdebt.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtCurdebt.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + txtCurdebt.setFocusable(false); + txtCurdebt.setPreferredSize(new java.awt.Dimension(120, 30)); + txtCurdebt.setRequestFocusEnabled(false); + + txtCurdate.setEditable(false); + txtCurdate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtCurdate.setHorizontalAlignment(javax.swing.JTextField.CENTER); + txtCurdate.setFocusable(false); + txtCurdate.setPreferredSize(new java.awt.Dimension(120, 30)); + txtCurdate.setRequestFocusEnabled(false); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLabel6.setText(AppLocal.getIntString("label.curdate")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(120, 30)); + + txtName.setEditable(false); + txtName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtName.setFocusable(false); + txtName.setPreferredSize(new java.awt.Dimension(0, 30)); + txtName.setRequestFocusEnabled(false); + + txtMaxdebt.setEditable(false); + txtMaxdebt.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtMaxdebt.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + txtMaxdebt.setFocusable(false); + txtMaxdebt.setPreferredSize(new java.awt.Dimension(120, 30)); + txtMaxdebt.setRequestFocusEnabled(false); + + txtPrePay.setForeground(new java.awt.Color(0, 204, 255)); + txtPrePay.setToolTipText(bundle.getString("tooltip.customerpay.prepay")); // NOI18N + txtPrePay.setEnabled(false); + txtPrePay.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + txtPrePay.setPreferredSize(new java.awt.Dimension(200, 30)); + + txtTaxId.setEditable(false); + txtTaxId.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtTaxId.setFocusable(false); + txtTaxId.setPreferredSize(new java.awt.Dimension(150, 30)); + txtTaxId.setRequestFocusEnabled(false); + + jLabel7.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel7.setText(AppLocal.getIntString("label.taxid")); // NOI18N + jLabel7.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.prepay")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(120, 30)); + + txtNotes.setToolTipText(bundle.getString("tooltip.customerpay.notes")); // NOI18N + txtNotes.setEnabled(false); + txtNotes.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtNotes.setPreferredSize(new java.awt.Dimension(250, 100)); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(txtName, javax.swing.GroupLayout.PREFERRED_SIZE, 240, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(txtCard, javax.swing.GroupLayout.PREFERRED_SIZE, 240, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(txtTaxId, javax.swing.GroupLayout.PREFERRED_SIZE, 240, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel12, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(txtPrePay, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtNotes, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE))))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(18, 18, 18) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(txtMaxdebt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtCurdebt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtCurdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtTaxId, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtCard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtNotes, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtPrePay, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(30, 30, 30) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(txtCurdebt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtMaxdebt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtCurdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + add(jPanel1, java.awt.BorderLayout.CENTER); + }// //GEN-END:initComponents + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + + readCustomer(); + + }//GEN-LAST:event_jButton1ActionPerformed + + private void m_jKeysActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jKeysActionPerformed + + readCustomer(); + + }//GEN-LAST:event_m_jKeysActionPerformed + + private void btnCustomerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCustomerActionPerformed + + JCustomerFinder finder = JCustomerFinder.getCustomerFinder(this, dlcustomers); + finder.search(null); + finder.setVisible(true); + CustomerInfo customer = finder.getSelectedCustomer(); + if (customer != null) { + try { + CustomerInfoExt c = dlsales.loadCustomerExt(customer.getId()); + if (c == null) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotfindcustomer")); + msg.show(this); + } else { + editCustomer(c); + } + } catch (BasicException ex) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotfindcustomer"), ex); + msg.show(this); + } + } + editorcard.reset(); + editorcard.activate(); + +}//GEN-LAST:event_btnCustomerActionPerformed + + private void btnPayActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPayActionPerformed + + paymentdialog.setPrintSelected(true); + + if (paymentdialog.showDialog(customerext.getAccdebt(), null)) { + + // Save the ticket + TicketInfo ticket = new TicketInfo(); + ticket.setTicketType(TicketInfo.RECEIPT_PAYMENT); + + List payments = paymentdialog.getSelectedPayments(); + + double total = 0.0; + for (PaymentInfo p : payments) { + total += p.getTotal(); + } + + payments.add(new PaymentInfoTicket(-total, "debtpaid")); + + ticket.setPayments(payments); + + ticket.setUser(app.getAppUserView().getUser().getUserInfo()); + ticket.setActiveCash(app.getActiveCashIndex()); + ticket.setDate(new Date()); + ticket.setCustomer(customerext); + + try { + dlsales.saveTicket(ticket, app.getInventoryLocation()); + } catch (BasicException eData) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, AppLocal.getIntString("message.nosaveticket"), eData); + msg.show(this); + } + + + // reload customer + CustomerInfoExt c; + try { + c = dlsales.loadCustomerExt(customerext.getId()); + if (c == null) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotfindcustomer")); + msg.show(this); + } else { + editCustomer(c); + } + } catch (BasicException ex) { + c = null; + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotfindcustomer"), ex); + msg.show(this); + } + + printTicket(paymentdialog.isPrintSelected() + ? "Printer.CustomerPaid" + : "Printer.CustomerPaid2", + ticket, c); + } + + editorcard.reset(); + editorcard.activate(); + +}//GEN-LAST:event_btnPayActionPerformed + + private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveActionPerformed + + if (dirty.isDirty()) { + save(); + + editorcard.reset(); + editorcard.activate(); + } + +}//GEN-LAST:event_btnSaveActionPerformed + + private void btnPrePayActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPrePayActionPerformed + + txtPrePay.setFocusable(true); + txtPrePay.requestFocusInWindow(); + + if (txtPrePay.getText() != null) { + double prepay = Double.parseDouble(txtPrePay.getText()); + Formats.CURRENCY.formatValue(RoundUtils.getValue(prepay)); + paymentdialog.setPrintSelected(true); + + if (paymentdialog.showDialog(prepay, null)) { + + TicketInfo ticket = new TicketInfo(); + ticket.setTicketType(TicketInfo.RECEIPT_PAYMENT); + List payments = paymentdialog.getSelectedPayments(); + + double total = 0.0; + for (PaymentInfo p : payments) { + total += p.getTotal(); + } + + total = Double.parseDouble(txtPrePay.getText()); + + payments.add(new PaymentInfoTicket(-total, "debtpaid")); + + ticket.setPayments(payments); + + ticket.setUser(app.getAppUserView().getUser().getUserInfo()); + ticket.setActiveCash(app.getActiveCashIndex()); + ticket.setDate(new Date()); + ticket.setCustomer(customerext); + + try { + dlsales.saveTicket(ticket, app.getInventoryLocation()); + } catch (BasicException eData) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, AppLocal.getIntString("message.nosaveticket"), eData); + msg.show(this); + } + + CustomerInfoExt c; + try { + c = dlsales.loadCustomerExt(customerext.getId()); + if (c == null) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotfindcustomer")); + msg.show(this); + } else { + editCustomer(c); + } + } catch (BasicException ex) { + c = null; + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotfindcustomer"), ex); + msg.show(this); + } + + printTicket(paymentdialog.isPrintSelected() + ? "Printer.CustomerPaid" + : "Printer.CustomerPaid2", + ticket, c); + } + + editorcard.reset(); + editorcard.activate(); + } + }//GEN-LAST:event_btnPrePayActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btnCustomer; + private javax.swing.JButton btnPay; + private javax.swing.JButton btnPrePay; + private javax.swing.JButton btnSave; + private com.unicenta.editor.JEditorString editorcard; + private javax.swing.JButton jButton1; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel12; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JPanel jPanel6; + private javax.swing.JSeparator jSeparator1; + private com.unicenta.editor.JEditorKeys m_jKeys; + private javax.swing.JTextField txtCard; + private javax.swing.JTextField txtCurdate; + private javax.swing.JTextField txtCurdebt; + private javax.swing.JTextField txtMaxdebt; + private javax.swing.JTextField txtName; + private com.unicenta.editor.JEditorString txtNotes; + private com.unicenta.editor.JEditorString txtPrePay; + private javax.swing.JTextField txtTaxId; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/customers/CustomersView.form b/src/main/java/com/unicenta/pos/customers/CustomersView.form new file mode 100644 index 0000000..9810dc5 --- /dev/null +++ b/src/main/java/com/unicenta/pos/customers/CustomersView.form @@ -0,0 +1,1373 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + </TableColumnModel> + </Property> + <Property name="gridColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="cc" red="66" type="rgb"/> + </Property> + <Property name="opaque" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[375, 500]"/> + </Property> + <Property name="rowHeight" type="int" value="25"/> + <Property name="showVerticalLines" type="boolean" value="false"/> + <Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor"> + <TableHeader reorderingAllowed="true" resizingAllowed="true"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JLabel" name="jLblTranCount"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription"> + <JTabbedPaneConstraints tabName="Photo"> + <Property name="tabTitle" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.photo" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + </JTabbedPaneConstraints> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel34" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="86" max="-2" attributes="0"/> + <Component id="m_jImage" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace pref="135" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jImage" min="-2" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + <Component id="jLabel34" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="com.unicenta.data.gui.JImageEditor" name="m_jImage"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 250]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel34"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.imagesize" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[500, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription"> + <JTabbedPaneConstraints tabName="Notes"> + <Property name="tabTitle" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.notes" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </JTabbedPaneConstraints> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jScrollPane1" min="-2" pref="458" max="-2" attributes="0"/> + <EmptySpace pref="177" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jScrollPane1" pref="247" max="32767" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Container class="javax.swing.JScrollPane" name="jScrollPane1"> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JTextArea" name="m_jNotes"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 0]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Component class="javax.swing.JLabel" name="jLblVIP"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.vip" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="m_jVip"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="f3" green="bc" red="0" type="rgb"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[21, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="m_jVipnone"/> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jVipActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLblDiscount"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.discount" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtDiscount"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblDiscountpercent"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="%"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[15, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="m_jbtndate"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/date.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Open Calendar"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jbtndateActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JTextField" name="m_jdate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[130, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel10"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.customerdate" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="verticalAlignment" type="int" value="3"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[130, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/customers/CustomersView.java b/src/main/java/com/unicenta/pos/customers/CustomersView.java new file mode 100644 index 0000000..fc65288 --- /dev/null +++ b/src/main/java/com/unicenta/pos/customers/CustomersView.java @@ -0,0 +1,1639 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.customers; + +import com.unicenta.basic.BasicException; +import com.unicenta.beans.JCalendarDialog; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.BeanFactoryException; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.util.StringUtils; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.JTableHeader; +import java.awt.*; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +/** + * + * @author Jack Gerrard + */ +@Slf4j +public final class CustomersView extends javax.swing.JPanel implements EditorRecord { + + private static final long serialVersionUID = 1L; + private Object m_oId; + + private SentenceList m_sentcat; + private List<CustomerTransaction> customerTransactionList; + private TransactionTableModel transactionModel; + private ComboBoxValModel m_CategoryModel; + + private DirtyManager m_Dirty; + private DataLogicSales dlSales; + + //HS updates to get last added Customer 06.03.2014 + private AppView appView; + private CustomerInfo customerInfo; + + /** Creates new form CustomersView + * @param app + * @param dirty */ + public CustomersView(AppView app, DirtyManager dirty) { + try { + setAppView(app); + dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + + + initComponents(); + + m_sentcat = dlSales.getTaxCustCategoriesList(); + m_CategoryModel = new ComboBoxValModel(); + + m_Dirty = dirty; + m_jTaxID.getDocument().addDocumentListener(dirty); + m_jSearchkey.getDocument().addDocumentListener(dirty); + m_jName.getDocument().addDocumentListener(dirty); + m_jCategory.addActionListener(dirty); + m_jNotes.getDocument().addDocumentListener(dirty); + txtMaxdebt.getDocument().addDocumentListener(dirty); + txtCurdebt.getDocument().addDocumentListener(dirty); + txtCurdate.getDocument().addDocumentListener(dirty); + m_jVisible.addActionListener(dirty); + m_jVip.addActionListener(dirty); + txtDiscount.getDocument().addDocumentListener(dirty); + + txtFirstName.getDocument().addDocumentListener(dirty); + txtLastName.getDocument().addDocumentListener(dirty); + txtEmail.getDocument().addDocumentListener(dirty); + txtPhone.getDocument().addDocumentListener(dirty); + txtPhone2.getDocument().addDocumentListener(dirty); + txtFax.getDocument().addDocumentListener(dirty); + m_jImage.addPropertyChangeListener(dirty); + + txtAddress.getDocument().addDocumentListener(dirty); + txtAddress2.getDocument().addDocumentListener(dirty); + txtPostal.getDocument().addDocumentListener(dirty); + txtCity.getDocument().addDocumentListener(dirty); + txtRegion.getDocument().addDocumentListener(dirty); + txtCountry.getDocument().addDocumentListener(dirty); + + m_jdate.getDocument().addDocumentListener(dirty); + + init(); + } catch (BeanFactoryException ex) { + log.error(ex.getMessage()); + } + } + + private void init() { + writeValueEOF(); + } + + /** + * Instantiate object + * @throws BasicException + */ + @SuppressWarnings("unchecked") + public void activate() throws BasicException { + + List a = m_sentcat.list(); + a.add(0, null); // The null item + m_CategoryModel = new ComboBoxValModel(a); + m_jCategory.setModel(m_CategoryModel); + String cId = null; + } + + /** + * Refresh object + */ + @Override + public void refresh() { + jLblTranCount.setText(null); + } + + /** + * Write EOF + */ + @Override + public void writeValueEOF() { + m_oId = null; + m_jTaxID.setText(null); + m_jSearchkey.setText(null); + m_jName.setText(null); + m_CategoryModel.setSelectedKey(null); + m_jNotes.setText(null); + + txtMaxdebt.setText(null); + txtCurdebt.setText(null); + txtCurdate.setText(null); + m_jVisible.setSelected(false); + m_jVip.setSelected(false); + txtDiscount.setText(null); + jcard.setText(null); + + txtFirstName.setText(null); + txtLastName.setText(null); + txtEmail.setText(null); + txtPhone.setText(null); + txtPhone2.setText(null); + txtFax.setText(null); + m_jImage.setImage(null); + + txtAddress.setText(null); + txtAddress2.setText(null); + txtPostal.setText(null); + txtCity.setText(null); + txtRegion.setText(null); + txtCountry.setText(null); + + m_jdate.setText(null); + + m_jTaxID.setEnabled(false); + m_jSearchkey.setEnabled(false); + m_jName.setEnabled(false); + m_jCategory.setEnabled(false); + m_jNotes.setEnabled(false); + txtMaxdebt.setEnabled(false); + txtCurdebt.setEnabled(false); + txtCurdate.setEnabled(false); + m_jVisible.setEnabled(false); + m_jVip.setEnabled(false); + txtDiscount.setEnabled(false); + jcard.setEnabled(false); + + txtFirstName.setEnabled(false); + txtLastName.setEnabled(false); + txtEmail.setEnabled(false); + txtPhone.setEnabled(false); + txtPhone2.setEnabled(false); + txtFax.setEnabled(false); + m_jImage.setEnabled(false); + + txtAddress.setEnabled(false); + txtAddress2.setEnabled(false); + txtPostal.setEnabled(false); + txtCity.setEnabled(false); + txtRegion.setEnabled(false); + txtCountry.setEnabled(false); + + jBtnCreateCard.setEnabled(false); + jBtnClearCard.setEnabled(false); + + m_jdate.setEnabled(false); + m_jbtndate.setEnabled(false); + + jTableCustomerTransactions.setEnabled(false); + + repaint(); + refresh(); + } + + @Override + public void writeValueInsert() { + + m_oId = null; + m_jTaxID.setText(null); + m_jSearchkey.setText(null); + m_jName.setText(null); + txtPhone.setText(null); + txtEmail.setText(null); + + m_CategoryModel.setSelectedKey(null); + m_jNotes.setText(null); + txtMaxdebt.setText(null); + txtCurdebt.setText(null); + txtCurdate.setText(null); + m_jVisible.setSelected(true); + m_jVip.setSelected(false); + txtDiscount.setText(null); + jcard.setText(null); + + txtFirstName.setText(null); + txtLastName.setText(null); + txtPhone2.setText(null); + txtFax.setText(null); + m_jImage.setImage(null); + + txtAddress.setText(null); + txtAddress2.setText(null); + txtPostal.setText(null); + txtCity.setText(null); + txtRegion.setText(null); + txtCountry.setText(null); + + m_jdate.setText(null); + + m_jTaxID.setEnabled(true); + m_jSearchkey.setEnabled(true); + m_jName.setEnabled(true); + m_jCategory.setEnabled(true); + m_jNotes.setEnabled(true); + txtMaxdebt.setEnabled(true); + txtCurdebt.setEnabled(true); + txtCurdate.setEnabled(true); + m_jVisible.setEnabled(true); + m_jVip.setEnabled(true); + txtDiscount.setEnabled(true); + jcard.setEnabled(true); + + txtFirstName.setEnabled(true); + txtLastName.setEnabled(true); + txtEmail.setEnabled(true); + webBtnMail.setEnabled(true); + txtPhone.setEnabled(true); + txtPhone2.setEnabled(true); + txtFax.setEnabled(true); + m_jImage.setEnabled(true); + + txtAddress.setEnabled(true); + txtAddress2.setEnabled(true); + txtPostal.setEnabled(true); + txtCity.setEnabled(true); + txtRegion.setEnabled(true); + txtCountry.setEnabled(true); + + jBtnCreateCard.setEnabled(true); + jBtnClearCard.setEnabled(true); + + jTableCustomerTransactions.setEnabled(false); + + m_jdate.setEnabled(true); + m_jbtndate.setEnabled(true); + + repaint(); + refresh(); + } + + /** + * Delete from object + * @param value + */ + @Override + public void writeValueDelete(Object value) { + + Object[] customer = (Object[]) value; + m_oId = customer[0]; + m_jSearchkey.setText((String) customer[1]); + m_jTaxID.setText((String) customer[2]); + m_jName.setText((String) customer[3]); + m_CategoryModel.setSelectedKey(customer[4]); + jcard.setText((String) customer[5]); + txtMaxdebt.setText(Formats.CURRENCY.formatValue(customer[6])); + txtAddress.setText(Formats.STRING.formatValue(customer[7])); + txtAddress2.setText(Formats.STRING.formatValue(customer[8])); + txtPostal.setText(Formats.STRING.formatValue(customer[9])); + txtCity.setText(Formats.STRING.formatValue(customer[10])); + txtRegion.setText(Formats.STRING.formatValue(customer[11])); + txtCountry.setText(Formats.STRING.formatValue(customer[12])); + txtFirstName.setText(Formats.STRING.formatValue(customer[13])); + txtLastName.setText(Formats.STRING.formatValue(customer[14])); + txtEmail.setText(Formats.STRING.formatValue(customer[15])); + txtPhone.setText(Formats.STRING.formatValue(customer[16])); + txtPhone2.setText(Formats.STRING.formatValue(customer[17])); + txtFax.setText(Formats.STRING.formatValue(customer[18])); + m_jNotes.setText((String) customer[19]); + m_jVisible.setSelected(((Boolean) customer[20])); + txtCurdate.setText(Formats.DATE.formatValue(customer[21])); + txtCurdebt.setText(Formats.CURRENCY.formatValue(customer[22])); + m_jImage.setImage((BufferedImage) customer[23]); + m_jVip.setSelected(((Boolean) customer[24])); + txtDiscount.setText(Formats.DOUBLE.formatValue(customer[25])); + m_jdate.setText(Formats.DATE.formatValue(customer[26])); + + m_jTaxID.setEnabled(false); + m_jSearchkey.setEnabled(false); + m_jName.setEnabled(false); + m_jNotes.setEnabled(false); + txtMaxdebt.setEnabled(false); + txtCurdebt.setEnabled(false); + txtCurdate.setEnabled(false); + m_jVisible.setEnabled(false); + m_jVip.setEnabled(false); + txtDiscount.setEnabled(false); + jcard.setEnabled(false); + + txtFirstName.setEnabled(false); + txtLastName.setEnabled(false); + txtEmail.setEnabled(false); + webBtnMail.setEnabled(false); + txtPhone.setEnabled(false); + txtPhone2.setEnabled(false); + txtFax.setEnabled(false); + m_jImage.setEnabled(true); + + txtAddress.setEnabled(false); + txtAddress2.setEnabled(false); + txtPostal.setEnabled(false); + txtCity.setEnabled(false); + txtRegion.setEnabled(false); + txtCountry.setEnabled(false); + + m_jCategory.setEnabled(false); + + jBtnCreateCard.setEnabled(false); + jBtnClearCard.setEnabled(false); + +// JG 3 Oct 2013 - for Transaction List table + transactionModel = new TransactionTableModel(getTransactionOfName((String) m_oId)); + jTableCustomerTransactions.setModel(transactionModel); + jTableCustomerTransactions.setEnabled(false); + + m_jdate.setEnabled(false); + m_jbtndate.setEnabled(false); + + repaint(); + refresh(); + } + + /** + * Edit object + * @param value + */ + @Override + public void writeValueEdit(Object value) { + Object[] customer = (Object[]) value; + m_oId = customer[0]; + m_jSearchkey.setText((String) customer[1]); + m_jTaxID.setText((String) customer[2]); + m_jName.setText((String) customer[3]); + m_CategoryModel.setSelectedKey(customer[4]); + jcard.setText((String) customer[5]); + txtMaxdebt.setText(Formats.CURRENCY.formatValue(customer[6])); + txtAddress.setText(Formats.STRING.formatValue(customer[7])); + txtAddress2.setText(Formats.STRING.formatValue(customer[8])); + txtPostal.setText(Formats.STRING.formatValue(customer[9])); + txtCity.setText(Formats.STRING.formatValue(customer[10])); + txtRegion.setText(Formats.STRING.formatValue(customer[11])); + txtCountry.setText(Formats.STRING.formatValue(customer[12])); + txtFirstName.setText(Formats.STRING.formatValue(customer[13])); + txtLastName.setText(Formats.STRING.formatValue(customer[14])); + txtEmail.setText(Formats.STRING.formatValue(customer[15])); + txtPhone.setText(Formats.STRING.formatValue(customer[16])); + txtPhone2.setText(Formats.STRING.formatValue(customer[17])); + txtFax.setText(Formats.STRING.formatValue(customer[18])); + m_jNotes.setText((String) customer[19]); + m_jVisible.setSelected(((Boolean) customer[20])); + txtCurdate.setText(Formats.DATE.formatValue(customer[21])); + txtCurdebt.setText(Formats.CURRENCY.formatValue(customer[22])); + m_jImage.setImage((BufferedImage) customer[23]); + m_jVip.setSelected(((Boolean) customer[24])); + txtDiscount.setText(Formats.DOUBLE.formatValue(customer[25])); + + m_jdate.setText(Formats.DATE.formatValue(customer[26])); + + m_jTaxID.setEnabled(true); + m_jSearchkey.setEnabled(true); + m_jName.setEnabled(true); + m_jNotes.setEnabled(true); + txtMaxdebt.setEnabled(true); + txtCurdebt.setEnabled(true); + txtCurdate.setEnabled(true); + m_jVisible.setEnabled(true); + m_jVip.setEnabled(true); + txtDiscount.setEnabled(true); + jcard.setEnabled(true); + + txtFirstName.setEnabled(true); + txtLastName.setEnabled(true); + txtEmail.setEnabled(true); + webBtnMail.setEnabled(true); + txtPhone.setEnabled(true); + txtPhone2.setEnabled(true); + txtFax.setEnabled(true); + m_jImage.setEnabled(true); + + txtAddress.setEnabled(true); + txtAddress2.setEnabled(true); + txtPostal.setEnabled(true); + txtCity.setEnabled(true); + txtRegion.setEnabled(true); + txtCountry.setEnabled(true); + + m_jCategory.setEnabled(true); + + m_jdate.setEnabled(true); + m_jbtndate.setEnabled(true); + + jBtnCreateCard.setEnabled(true); + jBtnClearCard.setEnabled(true); + + jTableCustomerTransactions.setVisible(false); + jTableCustomerTransactions.setEnabled(true); + resetTranxTable(); + + jTableCustomerTransactions.repaint(); + repaint(); + refresh(); + } + +public void resetTranxTable() { + + jTableCustomerTransactions.getColumnModel().getColumn(0).setPreferredWidth(50); + jTableCustomerTransactions.getColumnModel().getColumn(1).setPreferredWidth(70); + jTableCustomerTransactions.getColumnModel().getColumn(2).setPreferredWidth(280); + jTableCustomerTransactions.getColumnModel().getColumn(3).setPreferredWidth(30); + jTableCustomerTransactions.getColumnModel().getColumn(4).setPreferredWidth(50); + + // set font for headers + Font f = new Font("Arial", Font.BOLD, 14); + JTableHeader header = jTableCustomerTransactions.getTableHeader(); + header.setFont(f); + + jTableCustomerTransactions.getTableHeader().setReorderingAllowed(true); + jTableCustomerTransactions.setAutoCreateRowSorter(true); + jTableCustomerTransactions.repaint(); + + +} + + + /** + * Create object + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + Object[] customer = new Object[28]; + + customer[0] = m_oId == null ? UUID.randomUUID().toString() : m_oId; + customer[1] = m_jSearchkey.getText(); + customer[2] = m_jTaxID.getText(); + customer[3] = m_jName.getText(); + customer[4] = m_CategoryModel.getSelectedKey(); + customer[5] = Formats.STRING.parseValue(jcard.getText()); // Format to manage NULL values + customer[6] = Formats.CURRENCY.parseValue(txtMaxdebt.getText(), 0.0); + customer[7] = Formats.STRING.parseValue(txtAddress.getText()); + customer[8] = Formats.STRING.parseValue(txtAddress2.getText()); + customer[9] = Formats.STRING.parseValue(txtPostal.getText()); + customer[10] = Formats.STRING.parseValue(txtCity.getText()); + customer[11] = Formats.STRING.parseValue(txtRegion.getText()); + customer[12] = Formats.STRING.parseValue(txtCountry.getText()); + customer[13] = Formats.STRING.parseValue(txtFirstName.getText()); + customer[14] = Formats.STRING.parseValue(txtLastName.getText()); + customer[15] = Formats.STRING.parseValue(txtEmail.getText()); + customer[16] = Formats.STRING.parseValue(txtPhone.getText()); + customer[17] = Formats.STRING.parseValue(txtPhone2.getText()); + customer[18] = Formats.STRING.parseValue(txtFax.getText()); + customer[19] = m_jNotes.getText(); + customer[20] = m_jVisible.isSelected(); + customer[21] = Formats.TIMESTAMP.parseValue(txtCurdate.getText()); // not saved + customer[22] = Formats.CURRENCY.parseValue(txtCurdebt.getText()); // not saved + customer[23] = m_jImage.getImage(); + customer[24] = m_jVip.isSelected(); + customer[25] = Formats.CURRENCY.parseValue(txtDiscount.getText(), 0.0); + customer[26] = Formats.TIMESTAMP.parseValue(m_jdate.getText()); + customer[27] = (Object)getAppView(); + + if (m_jName.getText().contains("&")) { + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.ampersand")); + } + + return customer; + } + + //HS New methods to get last customer saved 06.03.2014 + public AppView getAppView() { + return appView; + } + + public void setAppView(AppView appView) { + this.appView = appView; + } + + @Override + public Component getComponent() { + return this; + } + +// JG 3 Oct 2013 - Customer Transaction List +// JG 10 April 2016 - Revision + private List<CustomerTransaction> getTransactionOfName(String cId) { + + try { + customerTransactionList = dlSales.getCustomersTransactionList(cId); + + + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + + List<CustomerTransaction> customerList = new ArrayList<>(); + + for (CustomerTransaction customerTransaction : customerTransactionList) { + String customerId = customerTransaction.getCustomerId(); + if (customerId.equals(cId)) { + customerList.add(customerTransaction); + } + } + + txtCurdate.repaint(); + txtCurdebt.repaint(); + + repaint(); + refresh(); + + return customerList; + } + + class TransactionTableModel extends AbstractTableModel { + String tkt = AppLocal.getIntString("label.tblHeaderCol1"); + String dte = AppLocal.getIntString("label.tblHeaderCol2"); + String prd = AppLocal.getIntString("label.tblHeaderCol3"); + String qty = AppLocal.getIntString("label.tblHeaderCol4"); + String ttl = AppLocal.getIntString("label.tblHeaderCol5"); + + + List<CustomerTransaction> transactionList; + String[] columnNames = {tkt, dte, prd, qty, ttl}; + public Double Tamount; + + public TransactionTableModel(List<CustomerTransaction> list) { + transactionList = list; + } + + @Override + public int getColumnCount() { + return 5; + } + + @Override + public int getRowCount() { + return transactionList.size(); + } + + // this method is called to set the value of each cell + @Override + public Object getValueAt(int row, int column) { + CustomerTransaction customerTransaction = transactionList.get(row); + + jTableCustomerTransactions.setRowHeight(25); + + switch (column) { + + case 0: + return customerTransaction.getTicketId(); + case 1: + Date transactionDate = customerTransaction.getTransactionDate(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); + String formattedDate = sdf.format(transactionDate); + return formattedDate; + case 2: + return customerTransaction.getProductName(); + case 3: + return customerTransaction.getUnit(); + case 4: + Double amount = customerTransaction.getTotal(); + DecimalFormat df = new DecimalFormat("#.##"); + String formattedAmount = df.format(amount); + return formattedAmount; + default: + return ""; + + } + } + + @Override + public String getColumnName(int col) { + return columnNames[col]; + } + } + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel7 = new javax.swing.JLabel(); + m_jTaxID = new javax.swing.JTextField(); + jLabel8 = new javax.swing.JLabel(); + m_jSearchkey = new javax.swing.JTextField(); + jLabel3 = new javax.swing.JLabel(); + m_jName = new javax.swing.JTextField(); + jLabel5 = new javax.swing.JLabel(); + jcard = new javax.swing.JTextField(); + jBtnCreateCard = new javax.swing.JButton(); + jBtnClearCard = new javax.swing.JButton(); + jLabel9 = new javax.swing.JLabel(); + m_jCategory = new javax.swing.JComboBox(); + jLabel4 = new javax.swing.JLabel(); + m_jVisible = new javax.swing.JCheckBox(); + jLabel1 = new javax.swing.JLabel(); + txtMaxdebt = new javax.swing.JTextField(); + jLabel2 = new javax.swing.JLabel(); + txtCurdebt = new javax.swing.JTextField(); + jLabel6 = new javax.swing.JLabel(); + txtCurdate = new javax.swing.JTextField(); + jTabbedPane1 = new javax.swing.JTabbedPane(); + jPanel1 = new javax.swing.JPanel(); + jLabel19 = new javax.swing.JLabel(); + txtFirstName = new javax.swing.JTextField(); + jLabel15 = new javax.swing.JLabel(); + txtLastName = new javax.swing.JTextField(); + jLabel16 = new javax.swing.JLabel(); + txtEmail = new javax.swing.JTextField(); + jLabel17 = new javax.swing.JLabel(); + txtPhone = new javax.swing.JTextField(); + jLabel18 = new javax.swing.JLabel(); + txtPhone2 = new javax.swing.JTextField(); + jLabel14 = new javax.swing.JLabel(); + txtFax = new javax.swing.JTextField(); + webBtnMail = new com.alee.laf.button.WebButton(); + jPanel2 = new javax.swing.JPanel(); + jLabel13 = new javax.swing.JLabel(); + txtAddress = new javax.swing.JTextField(); + jLabel20 = new javax.swing.JLabel(); + txtCountry = new javax.swing.JTextField(); + jLabel21 = new javax.swing.JLabel(); + txtAddress2 = new javax.swing.JTextField(); + jLabel22 = new javax.swing.JLabel(); + txtPostal = new javax.swing.JTextField(); + jLabel23 = new javax.swing.JLabel(); + txtCity = new javax.swing.JTextField(); + jLabel24 = new javax.swing.JLabel(); + txtRegion = new javax.swing.JTextField(); + jPanel4 = new javax.swing.JPanel(); + jBtnShowTrans = new javax.swing.JButton(); + jScrollPane3 = new javax.swing.JScrollPane(); + jTableCustomerTransactions = new javax.swing.JTable(); + jLblTranCount = new javax.swing.JLabel(); + jPanel5 = new javax.swing.JPanel(); + m_jImage = new com.unicenta.data.gui.JImageEditor(); + jLabel34 = new javax.swing.JLabel(); + jPanel3 = new javax.swing.JPanel(); + jScrollPane1 = new javax.swing.JScrollPane(); + m_jNotes = new javax.swing.JTextArea(); + jLblVIP = new javax.swing.JLabel(); + m_jVip = new javax.swing.JCheckBox(); + jLblDiscount = new javax.swing.JLabel(); + txtDiscount = new javax.swing.JTextField(); + jLblDiscountpercent = new javax.swing.JLabel(); + m_jbtndate = new javax.swing.JButton(); + m_jdate = new javax.swing.JTextField(); + jLabel10 = new javax.swing.JLabel(); + + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + setPreferredSize(new java.awt.Dimension(1000, 600)); + + jLabel7.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel7.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/info.png"))); // NOI18N + jLabel7.setText(AppLocal.getIntString("label.taxid")); // NOI18N + jLabel7.setMaximumSize(new java.awt.Dimension(150, 30)); + jLabel7.setMinimumSize(new java.awt.Dimension(140, 25)); + jLabel7.setPreferredSize(new java.awt.Dimension(150, 30)); + jLabel7.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + jLabel7MouseClicked(evt); + } + }); + + m_jTaxID.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jTaxID.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel8.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel8.setText(AppLocal.getIntString("label.searchkeym")); // NOI18N + jLabel8.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jSearchkey.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSearchkey.setPreferredSize(new java.awt.Dimension(140, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.namem")); // NOI18N + jLabel3.setMaximumSize(new java.awt.Dimension(140, 25)); + jLabel3.setMinimumSize(new java.awt.Dimension(140, 25)); + jLabel3.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(410, 30)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.card")); // NOI18N + jLabel5.setMaximumSize(new java.awt.Dimension(140, 25)); + jLabel5.setMinimumSize(new java.awt.Dimension(140, 25)); + jLabel5.setPreferredSize(new java.awt.Dimension(150, 30)); + + jcard.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcard.setPreferredSize(new java.awt.Dimension(150, 30)); + + jBtnCreateCard.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/encrypted.png"))); // NOI18N + jBtnCreateCard.setToolTipText("Create Key"); + jBtnCreateCard.setMaximumSize(new java.awt.Dimension(64, 32)); + jBtnCreateCard.setMinimumSize(new java.awt.Dimension(64, 32)); + jBtnCreateCard.setPreferredSize(new java.awt.Dimension(40, 35)); + jBtnCreateCard.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnCreateCardActionPerformed(evt); + } + }); + + jBtnClearCard.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/fileclose.png"))); // NOI18N + jBtnClearCard.setToolTipText("Clear Key"); + jBtnClearCard.setMaximumSize(new java.awt.Dimension(64, 32)); + jBtnClearCard.setMinimumSize(new java.awt.Dimension(64, 32)); + jBtnClearCard.setPreferredSize(new java.awt.Dimension(40, 35)); + jBtnClearCard.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnClearCardActionPerformed(evt); + } + }); + + jLabel9.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel9.setText(AppLocal.getIntString("label.custtaxcategory")); // NOI18N + jLabel9.setMaximumSize(new java.awt.Dimension(140, 25)); + jLabel9.setMinimumSize(new java.awt.Dimension(140, 25)); + jLabel9.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jCategory.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCategory.setPreferredSize(new java.awt.Dimension(180, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.visible")); // NOI18N + jLabel4.setMaximumSize(new java.awt.Dimension(140, 25)); + jLabel4.setMinimumSize(new java.awt.Dimension(140, 25)); + jLabel4.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jVisible.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jVisible.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + m_jVisible.setPreferredSize(new java.awt.Dimension(30, 30)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLabel1.setText(AppLocal.getIntString("label.maxdebt")); // NOI18N + jLabel1.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM); + jLabel1.setMaximumSize(new java.awt.Dimension(140, 25)); + jLabel1.setMinimumSize(new java.awt.Dimension(120, 25)); + jLabel1.setPreferredSize(new java.awt.Dimension(130, 30)); + + txtMaxdebt.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtMaxdebt.setHorizontalAlignment(javax.swing.JTextField.CENTER); + txtMaxdebt.setPreferredSize(new java.awt.Dimension(130, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLabel2.setText(AppLocal.getIntString("label.curdebt")); // NOI18N + jLabel2.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM); + jLabel2.setMaximumSize(new java.awt.Dimension(140, 25)); + jLabel2.setMinimumSize(new java.awt.Dimension(120, 25)); + jLabel2.setPreferredSize(new java.awt.Dimension(130, 30)); + + txtCurdebt.setEditable(false); + txtCurdebt.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtCurdebt.setHorizontalAlignment(javax.swing.JTextField.CENTER); + txtCurdebt.setPreferredSize(new java.awt.Dimension(130, 30)); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLabel6.setText(AppLocal.getIntString("label.curdate")); // NOI18N + jLabel6.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM); + jLabel6.setPreferredSize(new java.awt.Dimension(130, 30)); + + txtCurdate.setEditable(false); + txtCurdate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtCurdate.setHorizontalAlignment(javax.swing.JTextField.CENTER); + txtCurdate.setPreferredSize(new java.awt.Dimension(130, 30)); + + jTabbedPane1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTabbedPane1.setPreferredSize(new java.awt.Dimension(650, 300)); + + jPanel1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + + jLabel19.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel19.setText(AppLocal.getIntString("label.firstname")); // NOI18N + jLabel19.setAlignmentX(0.5F); + jLabel19.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtFirstName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtFirstName.setPreferredSize(new java.awt.Dimension(300, 30)); + + jLabel15.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel15.setText(AppLocal.getIntString("label.lastname")); // NOI18N + jLabel15.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtLastName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtLastName.setPreferredSize(new java.awt.Dimension(300, 30)); + + jLabel16.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel16.setText(AppLocal.getIntString("label.email")); // NOI18N + jLabel16.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtEmail.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtEmail.setPreferredSize(new java.awt.Dimension(300, 30)); + + jLabel17.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel17.setText(AppLocal.getIntString("label.phone")); // NOI18N + jLabel17.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtPhone.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtPhone.setPreferredSize(new java.awt.Dimension(300, 30)); + + jLabel18.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel18.setText(AppLocal.getIntString("label.phone2")); // NOI18N + jLabel18.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtPhone2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtPhone2.setPreferredSize(new java.awt.Dimension(300, 30)); + + jLabel14.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel14.setText(AppLocal.getIntString("label.fax")); // NOI18N + jLabel14.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtFax.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtFax.setPreferredSize(new java.awt.Dimension(300, 30)); + + webBtnMail.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/mail24.png"))); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + webBtnMail.setText(bundle.getString("button.email")); // NOI18N + webBtnMail.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + webBtnMail.setPreferredSize(new java.awt.Dimension(90, 30)); + webBtnMail.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + webBtnMailActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel15, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(txtLastName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel14, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(txtFax, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel16, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel17, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel18, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(txtPhone, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtEmail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtPhone2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel19, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(txtFirstName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(webBtnMail, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(76, Short.MAX_VALUE)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel19, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtFirstName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel15, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtLastName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel16, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtEmail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(webBtnMail, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel17, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtPhone, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel18, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtPhone2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(txtFax, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel14, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(57, 57, 57)) + ); + + jTabbedPane1.addTab(AppLocal.getIntString("label.contact"), jPanel1); // NOI18N + + jPanel2.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + + jLabel13.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel13.setText(AppLocal.getIntString("label.address")); // NOI18N + jLabel13.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtAddress.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtAddress.setPreferredSize(new java.awt.Dimension(300, 30)); + + jLabel20.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel20.setText(AppLocal.getIntString("label.country")); // NOI18N + jLabel20.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtCountry.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtCountry.setPreferredSize(new java.awt.Dimension(300, 30)); + + jLabel21.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel21.setText(AppLocal.getIntString("label.address2")); // NOI18N + jLabel21.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtAddress2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtAddress2.setPreferredSize(new java.awt.Dimension(300, 30)); + + jLabel22.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel22.setText(AppLocal.getIntString("label.postal")); // NOI18N + jLabel22.setPreferredSize(new java.awt.Dimension(110, 30)); + + txtPostal.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtPostal.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel23.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel23.setText(AppLocal.getIntString("label.city")); // NOI18N + jLabel23.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtCity.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtCity.setPreferredSize(new java.awt.Dimension(300, 30)); + + jLabel24.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel24.setText(AppLocal.getIntString("label.region")); // NOI18N + jLabel24.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtRegion.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtRegion.setPreferredSize(new java.awt.Dimension(300, 30)); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jLabel20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel24, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel23, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(txtCity, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(txtAddress, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(txtAddress2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(txtRegion, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(txtCountry, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(18, 18, 18) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(txtPostal, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel22, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtAddress, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtAddress2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel23, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtCity, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel22, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel24, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtRegion, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtPostal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtCountry, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + + jTabbedPane1.addTab(AppLocal.getIntString("label.locationaddress"), jPanel2); // NOI18N + + jPanel4.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel4.setPreferredSize(new java.awt.Dimension(535, 0)); + + jBtnShowTrans.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jBtnShowTrans.setText(bundle.getString("button.CustomerTrans")); // NOI18N + jBtnShowTrans.setToolTipText(""); + jBtnShowTrans.setPreferredSize(new java.awt.Dimension(140, 30)); + jBtnShowTrans.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnShowTransActionPerformed(evt); + } + }); + + jScrollPane3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jScrollPane3.setPreferredSize(new java.awt.Dimension(620, 500)); + + jTableCustomerTransactions.setAutoCreateRowSorter(true); + jTableCustomerTransactions.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTableCustomerTransactions.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null} + }, + new String [] { + "TicketID", "Date", "Product", "Qty", "Total" + } + )); + jTableCustomerTransactions.setGridColor(new java.awt.Color(102, 204, 255)); + jTableCustomerTransactions.setOpaque(false); + jTableCustomerTransactions.setPreferredSize(new java.awt.Dimension(375, 500)); + jTableCustomerTransactions.setRowHeight(25); + jTableCustomerTransactions.setShowVerticalLines(false); + jScrollPane3.setViewportView(jTableCustomerTransactions); + + jLblTranCount.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblTranCount.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLblTranCount.setOpaque(true); + jLblTranCount.setPreferredSize(new java.awt.Dimension(50, 30)); + + javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); + jPanel4.setLayout(jPanel4Layout); + jPanel4Layout.setHorizontalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addComponent(jBtnShowTrans, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(jLblTranCount, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(424, 424, 424)) + .addGroup(jPanel4Layout.createSequentialGroup() + .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + ); + jPanel4Layout.setVerticalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jBtnShowTrans, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLblTranCount, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 233, Short.MAX_VALUE)) + ); + + jTabbedPane1.addTab(bundle.getString("label.Transactions"), jPanel4); // NOI18N + + m_jImage.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jImage.setPreferredSize(new java.awt.Dimension(300, 250)); + + jLabel34.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel34.setText(bundle.getString("label.imagesize")); // NOI18N + jLabel34.setPreferredSize(new java.awt.Dimension(500, 30)); + + javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5); + jPanel5.setLayout(jPanel5Layout); + jPanel5Layout.setHorizontalGroup( + jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel5Layout.createSequentialGroup() + .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel5Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel34, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel5Layout.createSequentialGroup() + .addGap(86, 86, 86) + .addComponent(m_jImage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(135, Short.MAX_VALUE)) + ); + jPanel5Layout.setVerticalGroup( + jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel5Layout.createSequentialGroup() + .addContainerGap() + .addComponent(m_jImage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel34, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + + jTabbedPane1.addTab(bundle.getString("label.photo"), jPanel5); // NOI18N + + jPanel3.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + + m_jNotes.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jNotes.setPreferredSize(new java.awt.Dimension(0, 0)); + jScrollPane1.setViewportView(m_jNotes); + + javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); + jPanel3.setLayout(jPanel3Layout); + jPanel3Layout.setHorizontalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 458, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(177, Short.MAX_VALUE)) + ); + jPanel3Layout.setVerticalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 247, Short.MAX_VALUE) + .addContainerGap()) + ); + + jTabbedPane1.addTab(AppLocal.getIntString("label.notes"), jPanel3); // NOI18N + + jLblVIP.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblVIP.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLblVIP.setText(AppLocal.getIntString("label.vip")); // NOI18N + jLblVIP.setPreferredSize(new java.awt.Dimension(50, 30)); + + m_jVip.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jVip.setForeground(new java.awt.Color(0, 188, 243)); + m_jVip.setPreferredSize(new java.awt.Dimension(21, 30)); + m_jVip.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + m_jVipnone(evt); + } + }); + m_jVip.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jVipActionPerformed(evt); + } + }); + + jLblDiscount.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblDiscount.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLblDiscount.setText(AppLocal.getIntString("label.discount")); // NOI18N + jLblDiscount.setPreferredSize(new java.awt.Dimension(70, 30)); + + txtDiscount.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtDiscount.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + txtDiscount.setPreferredSize(new java.awt.Dimension(50, 30)); + + jLblDiscountpercent.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblDiscountpercent.setText("%"); + jLblDiscountpercent.setPreferredSize(new java.awt.Dimension(15, 30)); + + m_jbtndate.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/date.png"))); // NOI18N + m_jbtndate.setToolTipText("Open Calendar"); + m_jbtndate.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtndateActionPerformed(evt); + } + }); + + m_jdate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jdate.setPreferredSize(new java.awt.Dimension(130, 30)); + + jLabel10.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel10.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLabel10.setText(bundle.getString("label.customerdate")); // NOI18N + jLabel10.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM); + jLabel10.setPreferredSize(new java.awt.Dimension(130, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel7, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel9, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLblVIP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jVip, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLblDiscount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(txtDiscount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLblDiscountpercent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(m_jName, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jcard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jTaxID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jVisible, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jSearchkey, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addComponent(jBtnCreateCard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jBtnClearCard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))))) + .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(txtMaxdebt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtCurdebt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(txtCurdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jbtndate, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jSearchkey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jTaxID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jBtnCreateCard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jcard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jBtnClearCard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jVisible, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLblDiscount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtDiscount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblDiscountpercent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jVip, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblVIP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(35, 35, 35) + .addComponent(txtMaxdebt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(txtCurdebt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtCurdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(m_jbtndate, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + private void jBtnCreateCardActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnCreateCardActionPerformed + if (JOptionPane.showConfirmDialog(this, + AppLocal.getIntString("message.cardnew"), + AppLocal.getIntString("title.editor"), + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { + jcard.setText("c" + StringUtils.getCardNumber()); + m_Dirty.setDirty(true); + } + }//GEN-LAST:event_jBtnCreateCardActionPerformed + + private void jBtnClearCardActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnClearCardActionPerformed + if (JOptionPane.showConfirmDialog(this, + AppLocal.getIntString("message.cardremove"), + AppLocal.getIntString("title.editor"), + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { + jcard.setText(null); + m_Dirty.setDirty(true); + } + }//GEN-LAST:event_jBtnClearCardActionPerformed + + private void webBtnMailActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_webBtnMailActionPerformed + + if(!"".equals(txtEmail.getText())) { + Desktop desktop; + + if (Desktop.isDesktopSupported() + && (desktop = Desktop.getDesktop()).isSupported(Desktop.Action.MAIL)) { + URI mailto = null; + try { + mailto = new URI("mailto:" + + txtEmail.getText()); + } catch (URISyntaxException ex) { + log.error(ex.getMessage()); + } + try { + desktop.mail(mailto); + } catch (IOException ex) { + log.error(ex.getMessage()); + } + } else { + JOptionPane.showMessageDialog(this, + AppLocal.getIntString("message.email"), + "Email", JOptionPane.INFORMATION_MESSAGE); + } + } + + }//GEN-LAST:event_webBtnMailActionPerformed + + private void jBtnShowTransActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnShowTransActionPerformed + String cId = m_oId.toString(); + if (cId != null) { + transactionModel = new TransactionTableModel(getTransactionOfName(cId)); + jTableCustomerTransactions.setModel(transactionModel); + if (transactionModel.getRowCount()> 0){ + jTableCustomerTransactions.setVisible(true); + String TranCount = String.valueOf(transactionModel.getRowCount()); + jLblTranCount.setText(TranCount + " for " + m_jName.getText()); + }else{ + jTableCustomerTransactions.setVisible(false); + JOptionPane.showMessageDialog(null, "No Transactions for this Customer", "Transactions", JOptionPane.INFORMATION_MESSAGE); + } + resetTranxTable(); + } + }//GEN-LAST:event_jBtnShowTransActionPerformed + + private void m_jVipnone(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_m_jVipnone + + }//GEN-LAST:event_m_jVipnone + + private void m_jVipActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jVipActionPerformed + +// AbstractButton abstractButton = (AbstractButton)evt.getSource(); +// boolean selected = abstractButton.getModel().isSelected(); +// jLblDiscountpercent.setVisible(selected); +// txtDiscount.setVisible(selected); +// jLblDiscount.setVisible(selected); + + }//GEN-LAST:event_m_jVipActionPerformed + + private void m_jbtndateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtndateActionPerformed + + Date date; + try { + date = (Date) Formats.TIMESTAMP.parseValue(m_jdate.getText()); + } catch (BasicException e) { + date = null; + } + date = JCalendarDialog.showCalendarTime(this, date); + if (date != null) { + m_jdate.setText(Formats.TIMESTAMP.formatValue(date)); + } + }//GEN-LAST:event_m_jbtndateActionPerformed + + private void jLabel7MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabel7MouseClicked + + if (evt.getClickCount() == 2) { + String uuidString = m_oId.toString(); + StringSelection stringSelection = new StringSelection(uuidString); + Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard(); + clpbrd.setContents(stringSelection, null); + + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.uuidcopy")); + } + }//GEN-LAST:event_jLabel7MouseClicked + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jBtnClearCard; + private javax.swing.JButton jBtnCreateCard; + private javax.swing.JButton jBtnShowTrans; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel10; + private javax.swing.JLabel jLabel13; + private javax.swing.JLabel jLabel14; + private javax.swing.JLabel jLabel15; + private javax.swing.JLabel jLabel16; + private javax.swing.JLabel jLabel17; + private javax.swing.JLabel jLabel18; + private javax.swing.JLabel jLabel19; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel20; + private javax.swing.JLabel jLabel21; + private javax.swing.JLabel jLabel22; + private javax.swing.JLabel jLabel23; + private javax.swing.JLabel jLabel24; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel34; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JLabel jLabel9; + private javax.swing.JLabel jLblDiscount; + private javax.swing.JLabel jLblDiscountpercent; + private javax.swing.JLabel jLblTranCount; + private javax.swing.JLabel jLblVIP; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JScrollPane jScrollPane3; + private javax.swing.JTabbedPane jTabbedPane1; + private javax.swing.JTable jTableCustomerTransactions; + private javax.swing.JTextField jcard; + private javax.swing.JComboBox m_jCategory; + private com.unicenta.data.gui.JImageEditor m_jImage; + private javax.swing.JTextField m_jName; + private javax.swing.JTextArea m_jNotes; + private javax.swing.JTextField m_jSearchkey; + private javax.swing.JTextField m_jTaxID; + private javax.swing.JCheckBox m_jVip; + private javax.swing.JCheckBox m_jVisible; + private javax.swing.JButton m_jbtndate; + private javax.swing.JTextField m_jdate; + private javax.swing.JTextField txtAddress; + private javax.swing.JTextField txtAddress2; + private javax.swing.JTextField txtCity; + private javax.swing.JTextField txtCountry; + private javax.swing.JTextField txtCurdate; + private javax.swing.JTextField txtCurdebt; + private javax.swing.JTextField txtDiscount; + private javax.swing.JTextField txtEmail; + private javax.swing.JTextField txtFax; + private javax.swing.JTextField txtFirstName; + private javax.swing.JTextField txtLastName; + private javax.swing.JTextField txtMaxdebt; + private javax.swing.JTextField txtPhone; + private javax.swing.JTextField txtPhone2; + private javax.swing.JTextField txtPostal; + private javax.swing.JTextField txtRegion; + private com.alee.laf.button.WebButton webBtnMail; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/customers/DataLogicCustomers.java b/src/main/java/com/unicenta/pos/customers/DataLogicCustomers.java new file mode 100644 index 0000000..4d473d9 --- /dev/null +++ b/src/main/java/com/unicenta/pos/customers/DataLogicCustomers.java @@ -0,0 +1,381 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.customers; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.*; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.BeanFactoryDataSingle; +import com.unicenta.pos.voucher.VoucherInfo; + +/** + * @author JG uniCenta + * @author adrianromero + */ +public class DataLogicCustomers extends BeanFactoryDataSingle { + + /** + * Main Method for customer object + */ + protected Session s; + private TableDefinition tcustomers; + private static final Datas[] customerdatas = new Datas[] { + Datas.STRING, + Datas.TIMESTAMP, + Datas.TIMESTAMP, + Datas.STRING, + Datas.STRING, + Datas.STRING, + Datas.STRING, + Datas.INT, + Datas.BOOLEAN, + Datas.STRING}; + + /** + * + * @param s + */ + @Override + public void init(Session s){ +// JG 03 Oct - Added Customer Image + this.s = s; + tcustomers = new TableDefinition(s + , "customers" + , new String[] { + "ID", + "SEARCHKEY", + "TAXID", + "NAME", + "TAXCATEGORY", + "CARD", + "MAXDEBT", + "ADDRESS", + "ADDRESS2", + "POSTAL", + "CITY", + "REGION", + "COUNTRY", + "FIRSTNAME", + "LASTNAME", + "EMAIL", + "PHONE", + "PHONE2", + "FAX", + "NOTES", + "VISIBLE", + "CURDATE", + "CURDEBT", + "IMAGE", + "ISVIP", + "DISCOUNT", + "MEMODATE" + } + , new String[] { + "ID", + AppLocal.getIntString("label.searchkey"), + AppLocal.getIntString("label.taxid"), + AppLocal.getIntString("label.name"), + "TAXCATEGORY", + "CARD", + AppLocal.getIntString("label.maxdebt"), + AppLocal.getIntString("label.address"), + AppLocal.getIntString("label.address2"), + AppLocal.getIntString("label.postal"), + AppLocal.getIntString("label.city"), + AppLocal.getIntString("label.region"), + AppLocal.getIntString("label.country"), + AppLocal.getIntString("label.firstname"), + AppLocal.getIntString("label.lastname"), + AppLocal.getIntString("label.email"), + AppLocal.getIntString("label.phone"), + AppLocal.getIntString("label.phone2"), + AppLocal.getIntString("label.fax"), + AppLocal.getIntString("label.notes"), + "VISIBLE", + AppLocal.getIntString("label.curdate"), + AppLocal.getIntString("label.curdebt"), + "IMAGE", + "ISVIP", + "DISCOUNT", + "MEMODATE" + } + , new Datas[] { + Datas.STRING, //id + Datas.STRING, //searchkey + Datas.STRING, //taxid + Datas.STRING, //name + Datas.STRING, //taxcat + Datas.STRING, //card + Datas.DOUBLE, //maxdebt + Datas.STRING, //add + Datas.STRING, //add2 + Datas.STRING, //postal + Datas.STRING, //city + Datas.STRING, //region + Datas.STRING, //cntry + Datas.STRING, //fname + Datas.STRING, //lname + Datas.STRING, //email + Datas.STRING, //phone + Datas.STRING, //phone2 + Datas.STRING, //fax + Datas.STRING, //notes + Datas.BOOLEAN, //visible + Datas.TIMESTAMP, //curdate + Datas.DOUBLE, //curdebt + Datas.IMAGE, //image + Datas.BOOLEAN, //isvip + Datas.DOUBLE, //discount + Datas.TIMESTAMP //memodate + } + , new Formats[] { + Formats.STRING, //id + Formats.STRING, //searchkey + Formats.STRING, //taxid + Formats.STRING, //name + Formats.STRING, //taxcat + Formats.STRING, //card + Formats.CURRENCY, //maxdebt + Formats.STRING, //add + Formats.STRING, //add2 + Formats.STRING, //postal + Formats.STRING, //city + Formats.STRING, //region + Formats.STRING, //cntry + Formats.STRING, //fname + Formats.STRING, //lname + Formats.STRING, //email + Formats.STRING, //phone + Formats.STRING, //phone2 + Formats.STRING, //fax + Formats.STRING, //notes + Formats.BOOLEAN, //visible + Formats.TIMESTAMP, //curdate + Formats.CURRENCY, //curdebt + Formats.NULL, //image + Formats.BOOLEAN, //isvip + Formats.DOUBLE, //discount + Formats.TIMESTAMP //memodate + } + , new int[] {0} + ); + } + + /** + * called from Find Customer + * @return customer data + */ + public SentenceList getCustomerList() { + return new StaticSentence(s + , new QBFBuilder("SELECT " + + "ID, TAXID, SEARCHKEY, NAME, " + + "POSTAL, EMAIL, PHONE, IMAGE " + + "FROM customers " + + "WHERE VISIBLE = " + s.DB.TRUE() + " AND ?(QBF_FILTER) ORDER BY NAME" + , new String[] {"TAXID", "SEARCHKEY", "NAME", "POSTAL", "PHONE", "EMAIL"}) + , new SerializerWriteBasic(new Datas[] { + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING}) + , (DataRead dr) -> { + CustomerInfo c = new CustomerInfo(dr.getString(1)); + c.setTaxid(dr.getString(2)); + c.setSearchkey(dr.getString(3)); + c.setName(dr.getString(4)); + c.setPcode(dr.getString(5)); + c.setPhone1(dr.getString(6)); + c.setCemail(dr.getString(7)); + c.setImage(ImageUtils.readImage(dr.getBytes(8))); +// c.setCurDebt(dr.getDouble(9)); + + return c; + }); + } + + public final CustomerInfo getCustomerInfo(String id) throws BasicException { + return (CustomerInfo) new PreparedSentence(s + ,"SELECT " + + "ID, TAXID, SEARCHKEY, NAME, POSTAL " + + "FROM customers WHERE VISIBLE = " + s.DB.TRUE() + " " + + "AND ID = ?" + , SerializerWriteString.INSTANCE , (DataRead dr) -> { + CustomerInfo c = new CustomerInfo(dr.getString(1)); + c.setTaxid(dr.getString(2)); + c.setSearchkey(dr.getString(3)); + c.setName(dr.getString(4)); + c.setPcode(dr.getString(5)); +// c.setisVip(dr.getBoolean(6)); +// c.setDiscount(dr.getDouble(7)); + return c; + }).find(id); + } + + /** + * + * @param customer + * @return + * @throws BasicException + */ + public int updateCustomerExt(final CustomerInfoExt customer) throws BasicException { + + return new PreparedSentence(s + , "UPDATE customers SET NOTES = ? WHERE ID = ?" + , SerializerWriteParams.INSTANCE + ).exec(new DataParams() {@Override + public void writeValues() throws BasicException { + setString(1, customer.getNotes()); + setString(2, customer.getId()); + }}); + } + + /** + * + * @return customer's existing reservation (restaurant mode) + */ + public final SentenceList getReservationsList() { + return new PreparedSentence(s + , "SELECT R.ID, R.CREATED, R.DATENEW, C.CUSTOMER, customers.TAXID, customers.SEARCHKEY, COALESCE(customers.NAME, R.TITLE), R.CHAIRS, R.ISDONE, R.DESCRIPTION " + + "FROM reservations R LEFT OUTER JOIN reservation_customers C ON R.ID = C.ID LEFT OUTER JOIN customers ON C.CUSTOMER = customers.ID " + + "WHERE R.DATENEW >= ? AND R.DATENEW < ?" + , new SerializerWriteBasic(new Datas[] {Datas.TIMESTAMP, Datas.TIMESTAMP}) + , new SerializerReadBasic(customerdatas)); + } + + /** + * + * @return create/update customer reservation (restaurant mode) + */ + public final SentenceExec getReservationsUpdate() { + return new SentenceExecTransaction(s) { + @Override + public int execInTransaction(Object params) throws BasicException { + + new PreparedSentence(s + , "DELETE FROM reservation_customers WHERE ID = ?" + , new SerializerWriteBasicExt(customerdatas, new int[]{0})).exec(params); + if (((Object[]) params)[3] != null) { + new PreparedSentence(s + , "INSERT INTO reservation_customers (ID, CUSTOMER) VALUES (?, ?)" + , new SerializerWriteBasicExt(customerdatas, new int[]{0, 3})).exec(params); + } + return new PreparedSentence(s + , "UPDATE reservations SET ID = ?, CREATED = ?, DATENEW = ?, TITLE = ?, CHAIRS = ?, ISDONE = ?, DESCRIPTION = ? WHERE ID = ?" + , new SerializerWriteBasicExt(customerdatas, new int[]{0, 1, 2, 6, 7, 8, 9, 0})).exec(params); + } + }; + } + + /** + * + * @return delete customer reservation (restaurant mode) + */ + public final SentenceExec getReservationsDelete() { + return new SentenceExecTransaction(s) { + @Override + public int execInTransaction(Object params) throws BasicException { + + new PreparedSentence(s + , "DELETE FROM reservation_customers WHERE ID = ?" + , new SerializerWriteBasicExt(customerdatas, new int[]{0})).exec(params); + return new PreparedSentence(s + , "DELETE FROM reservations WHERE ID = ?" + , new SerializerWriteBasicExt(customerdatas, new int[]{0})).exec(params); + } + }; + } + + /** + * + * @return insert a new customer reservation (restaurant mode) + */ + public final SentenceExec getReservationsInsert() { + return new SentenceExecTransaction(s) { + @Override + public int execInTransaction(Object params) throws BasicException { + + int i = new PreparedSentence(s + , "INSERT INTO reservations (ID, CREATED, DATENEW, TITLE, CHAIRS, ISDONE, DESCRIPTION) VALUES (?, ?, ?, ?, ?, ?, ?)" + , new SerializerWriteBasicExt(customerdatas, new int[]{0, 1, 2, 6, 7, 8, 9})).exec(params); + + if (((Object[]) params)[3] != null) { + new PreparedSentence(s + , "INSERT INTO reservation_customers (ID, CUSTOMER) VALUES (?, ?)" + , new SerializerWriteBasicExt(customerdatas, new int[]{0, 3})).exec(params); + } + return i; + } + }; + } + + /** + * + * @return customer table + */ + public final TableDefinition getTableCustomers() { + return tcustomers; + } + + public final PreparedSentence getVoucherNumber() { + return new PreparedSentence(s, + "SELECT SUBSTRING(MAX(VOUCHER_NUMBER),10,3) AS LAST_NUMBER FROM vouchers " + + "WHERE SUBSTRING(VOUCHER_NUMBER,1,8) = ?" + , SerializerWriteString.INSTANCE + , (DataRead dr) -> dr.getString(1)); + } + + +/* public final VoucherInfo getVoucherInfo(String id) throws BasicException { + return (VoucherInfo) new PreparedSentence(s + , "SELECT vouchers.ID, VOUCHER_NUMBER, CUSTOMER, " + + "customers.NAME, AMOUNT, STATUS " + + "FROM vouchers " + + "JOIN customers ON customers.id = vouchers.CUSTOMER " + + "WHERE STATUS='A' AND vouchers.ID=?" +// "WHERE STATUS='A' " + , SerializerWriteString.INSTANCE + , VoucherInfo.getSerializerRead()).find(id); + } +*/ + + public final VoucherInfo getVoucherInfo(String id) throws BasicException { + return (VoucherInfo) new PreparedSentence(s + , "SELECT vouchers.ID, VOUCHER_NUMBER, CUSTOMER, AMOUNT, STATUS " + + "FROM vouchers " + + "WHERE STATUS='A' AND vouchers.ID=?" + , SerializerWriteString.INSTANCE + , VoucherInfo.getSerializerRead()).find(id); + } + + public final VoucherInfo getVoucherInfoAll(String id) throws BasicException { + return (VoucherInfo) new PreparedSentence(s + , "SELECT vouchers.ID, VOUCHER_NUMBER, CUSTOMER, " + + "customers.NAME, AMOUNT, STATUS " + + "FROM vouchers " + + "JOIN customers ON customers.id = vouchers.CUSTOMER " + + "WHERE vouchers.ID=?" + , SerializerWriteString.INSTANCE + , VoucherInfo.getSerializerRead()).find(id); + } + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/customers/JCustomerFinder.form b/src/main/java/com/unicenta/pos/customers/JCustomerFinder.form new file mode 100644 index 0000000..3e33c67 --- /dev/null +++ b/src/main/java/com/unicenta/pos/customers/JCustomerFinder.form @@ -0,0 +1,551 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.5" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="form.customertitle" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor"> + <Color id="Default Cursor"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[750, 600]"/> + </Property> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,122,0,0,2,-10"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Properties> + <Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor"> + <Color id="Default Cursor"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="After"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Component class="com.unicenta.editor.JEditorKeys" name="m_jKeys"> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="JCustomerFinder_m_jKeys"/> + </AuxValues> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + </Component> + <Container class="javax.swing.JPanel" name="jPanel8"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Last"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="After"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JButton" name="jcmdCancel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.Cancel" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jcmdCancelActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jcmdOK"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.OK" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[103, 44]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[103, 44]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jcmdOKActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Component class="com.unicenta.data.gui.JImageViewerCustomer" name="jImageViewerCustomer"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[450, 0]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="First"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel7"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLblName" min="-2" max="-2" attributes="0"/> + <Component id="jLblSearchKey" min="-2" max="-2" attributes="0"/> + <Component id="jLblPostal" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jtxtSearchKey" min="-2" max="-2" attributes="0"/> + <Component id="m_jtxtPostal" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="m_jtxtName" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLblTaxID" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jtxtTaxID" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="1" max="-2" attributes="0"> + <Component id="jLblEmail" max="-2" attributes="0"/> + <Component id="jLblPhone" alignment="0" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jtxtPhone" min="-2" max="-2" attributes="0"/> + <Component id="m_jtxtName2" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jtxtTaxID" min="-2" max="-2" attributes="0"/> + <Component id="jLblTaxID" alignment="1" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jtxtSearchKey" min="-2" max="-2" attributes="0"/> + <Component id="jLblSearchKey" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLblPostal" min="-2" max="-2" attributes="0"/> + <Component id="m_jtxtPostal" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jtxtName" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="jLblName" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jtxtPhone" min="-2" max="-2" attributes="0"/> + <Component id="jLblPhone" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLblEmail" min="-2" max="-2" attributes="0"/> + <Component id="m_jtxtName2" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLblTaxID"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.taxid" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 15]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 15]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jtxtTaxID"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblSearchKey"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.searchkey" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 15]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 15]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jtxtSearchKey"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblPostal"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="Postal"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 15]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 15]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="JCustomerFinder_jLblPostal"/> + </AuxValues> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jtxtPostal"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="JCustomerFinder_m_jtxtPostal"/> + </AuxValues> + </Component> + <Component class="javax.swing.JLabel" name="jLblName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodname" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 15]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 15]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jtxtName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleName" type="java.lang.String" value=""/> + </AccessibilityProperties> + </Component> + <Component class="javax.swing.JLabel" name="jLblPhone"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.companytelephone" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblEmail"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.companyemail" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jtxtPhone"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jtxtName2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[450, 140]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JScrollPane" name="jScrollPane1"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[400, 147]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JList" name="jListCustomers"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.editors2.ListModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="focusable" type="boolean" value="false"/> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="jListCustomersMouseClicked"/> + <EventHandler event="valueChanged" listener="javax.swing.event.ListSelectionListener" parameters="javax.swing.event.ListSelectionEvent" handler="jListCustomersValueChanged"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel6"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="First"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JButton" name="jbtnReset"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/reload.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.reset" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Clear Filter"/> + <Property name="actionCommand" type="java.lang.String" value="Reset "/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" value=""/> + </AccessibilityProperties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnResetActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jbtnExecute"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.executefilter" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Execute Filter"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" value=""/> + </AccessibilityProperties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnExecuteActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/customers/JCustomerFinder.java b/src/main/java/com/unicenta/pos/customers/JCustomerFinder.java new file mode 100644 index 0000000..9ebb65c --- /dev/null +++ b/src/main/java/com/unicenta/pos/customers/JCustomerFinder.java @@ -0,0 +1,699 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.customers; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.QBFCompareEnum; +import com.unicenta.data.user.EditorCreator; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import java.awt.*; +import java.util.ArrayList; +import javax.swing.JFrame; +import javax.swing.*; + +import java.awt.event.KeyEvent; //Jack + +/** + * + * @author adrianromero + */ +public class JCustomerFinder extends javax.swing.JDialog implements EditorCreator { + + private CustomerInfo m_ReturnCustomer; + private ListProvider lpr; + private AppView appView; + + public class Global { +// public static String s = "(new SearchKey)"; +// public static String n = m_jtxtName; + + } + + /* Keyboard Events + */ + + public void searchKey() { + jbtnExecute.setMnemonic(KeyEvent.VK_E); // Jack + executeSearch(); + + + } + + public void resetKey() { + jbtnReset.setMnemonic(KeyEvent.VK_R); // Jack + m_jtxtTaxID.reset(); + m_jtxtSearchKey.reset(); + m_jtxtName.reset(); + m_jtxtPostal.reset(); + m_jtxtPhone.reset(); + m_jtxtName2.reset(); + + m_jtxtTaxID.activate(); + + cleanSearch(); + + } + + public void setAppView(AppView appView) { + this.appView = appView; + } + + /** Creates new form JCustomerFinder */ + private JCustomerFinder(java.awt.Frame parent, boolean modal) { + super(parent, modal); + } + + /** + * Creates new form JCustomerFinder + */ + private JCustomerFinder(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + } + + /** + * + * @param parent + * @param dlCustomers + * @return + */ + public static JCustomerFinder getCustomerFinder(Component parent, DataLogicCustomers dlCustomers) { + Window window = getWindow(parent); + + JCustomerFinder myMsg; + if (window instanceof Frame) { + myMsg = new JCustomerFinder((Frame) window, true); + } else { + myMsg = new JCustomerFinder((Dialog) window, true); + } + myMsg.init(dlCustomers); + myMsg.applyComponentOrientation(parent.getComponentOrientation()); + + return myMsg; + } + + /** + * + * @return + */ + public CustomerInfo getSelectedCustomer() { + return m_ReturnCustomer; + } + + private void init(DataLogicCustomers dlCustomers) { + + initComponents(); + + jScrollPane1.getVerticalScrollBar().setPreferredSize(new Dimension(35, 35)); + + m_jtxtTaxID.addEditorKeys(m_jKeys); + m_jtxtSearchKey.addEditorKeys(m_jKeys); + m_jtxtName.addEditorKeys(m_jKeys); + m_jtxtPostal.addEditorKeys(m_jKeys); + m_jtxtPhone.addEditorKeys(m_jKeys); + m_jtxtName2.addEditorKeys(m_jKeys); + + m_jtxtTaxID.reset(); + m_jtxtSearchKey.reset(); + m_jtxtName.reset(); + m_jtxtPostal.reset(); + m_jtxtPhone.reset(); + m_jtxtName2.reset(); + + m_jtxtTaxID.activate(); + + lpr = new ListProviderCreator(dlCustomers.getCustomerList(), this); + + jListCustomers.setCellRenderer(new CustomerRenderer()); + + getRootPane().setDefaultButton(jcmdOK); + + m_ReturnCustomer = null; + m_jKeys.setCustomerFinder(this); + + } + + /** + * + * @param customer + */ + public void search(CustomerInfo customer) { + + if (customer == null || customer.getName() == null || customer.getName().equals("")) { + + m_jtxtTaxID.reset(); + m_jtxtSearchKey.reset(); + m_jtxtName.reset(); + m_jtxtPostal.reset(); + m_jtxtPhone.reset(); + m_jtxtName2.reset(); + + m_jtxtTaxID.activate(); + + cleanSearch(); + } else { + + m_jtxtTaxID.setText(customer.getTaxid()); + m_jtxtSearchKey.setText(customer.getSearchkey()); + m_jtxtName.setText(customer.getName()); + m_jtxtPostal.setText(customer.getPcode()); + m_jtxtPhone.setText(customer.getPhone1()); + m_jtxtName2.setText(customer.getCemail()); + + m_jtxtTaxID.activate(); + + executeSearch(); + } + } + + private void cleanSearch() { + m_jtxtTaxID.setText(""); + m_jtxtSearchKey.setText(""); + m_jtxtName.setText(""); + m_jtxtPostal.setText(""); + m_jtxtPhone.setText(""); + m_jtxtName2.setText(""); + + jListCustomers.setModel(new MyListData(new ArrayList())); + } + + /** + * This method actions the customer data search + */ + public void executeSearch() { + + try { + jListCustomers.setModel(new MyListData(lpr.loadData())); + if (jListCustomers.getModel().getSize() > 0) { + jListCustomers.setSelectedIndex(0); + } else { + if(!m_jtxtName.getText().equals("")) { + + int n = JOptionPane.showConfirmDialog( + null, + AppLocal.getIntString("message.customernotfound"), + AppLocal.getIntString("title.editor"), + JOptionPane.YES_NO_OPTION); + + if (n != 1) { + CustomerInfoGlobal customerInfoGlobal = CustomerInfoGlobal.getInstance(); + CustomerInfoExt customerInfoExt = customerInfoGlobal.getCustomerInfoExt(); + this.setVisible(false); + appView.getAppUserView().showTask("com.unicenta.pos.customers.CustomersPanel"); + JOptionPane.showMessageDialog(null, + "You must complete Account and Search Key Then Save to add to Ticket", + "Create Customer",JOptionPane.OK_OPTION); + } + } + } + } catch (BasicException e) { + } + } + + /** + * + * @return creates object for search method + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + Object[] afilter = new Object[12]; + + // TaxID + if (m_jtxtTaxID.getText() == null || m_jtxtTaxID.getText().equals("")) { + afilter[0] = QBFCompareEnum.COMP_NONE; + afilter[1] = null; + } else { + afilter[0] = QBFCompareEnum.COMP_RE; + afilter[1] = "%" + m_jtxtTaxID.getText() + "%"; + } + + // SearchKey + if (m_jtxtSearchKey.getText() == null || m_jtxtSearchKey.getText().equals("")) { + afilter[2] = QBFCompareEnum.COMP_NONE; + afilter[3] = null; + } else { + afilter[2] = QBFCompareEnum.COMP_RE; + afilter[3] = "%" + m_jtxtSearchKey.getText() + "%"; + } + + // Name + if (m_jtxtName.getText() == null || m_jtxtName.getText().equals("")) { + afilter[4] = QBFCompareEnum.COMP_NONE; + afilter[5] = null; + } else { + afilter[4] = QBFCompareEnum.COMP_RE; + afilter[5] = "%" + m_jtxtName.getText() + "%"; + } + +// Added JG 20 Sept 12 + // Postal + if (m_jtxtPostal.getText() == null || m_jtxtPostal.getText().equals("")) { + afilter[6] = QBFCompareEnum.COMP_NONE; + afilter[7] = null; + } else { + afilter[6] = QBFCompareEnum.COMP_RE; + afilter[7] = "%" + m_jtxtPostal.getText() + "%"; + } + +// Added JG 20 Sept 12 + // Phone + if (m_jtxtPhone.getText() == null || m_jtxtPhone.getText().equals("")) { + afilter[8] = QBFCompareEnum.COMP_NONE; + afilter[9] = null; + } else { + afilter[8] = QBFCompareEnum.COMP_RE; + afilter[9] = "%" + m_jtxtPhone.getText() + "%"; + } + +// Added JG 20 Sept 12 + // Email + if (m_jtxtName2.getText() == null || m_jtxtName2.getText().equals("")) { + afilter[10] = QBFCompareEnum.COMP_NONE; + afilter[11] = null; + } else { + afilter[10] = QBFCompareEnum.COMP_RE; + afilter[11] = "%" + m_jtxtName2.getText() + "%"; + } + + return afilter; + } + + private static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window) parent; + } else { + return getWindow(parent.getParent()); + } + } + + private static class MyListData extends javax.swing.AbstractListModel { + + private final java.util.List m_data; + + public MyListData(java.util.List data) { + m_data = data; + } + + @Override + public Object getElementAt(int index) { + return m_data.get(index); + } + + @Override + public int getSize() { + return m_data.size(); + } + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel2 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel8 = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + jcmdCancel = new javax.swing.JButton(); + jcmdOK = new javax.swing.JButton(); + jImageViewerCustomer = new com.unicenta.data.gui.JImageViewerCustomer(); + jPanel3 = new javax.swing.JPanel(); + jPanel5 = new javax.swing.JPanel(); + jPanel7 = new javax.swing.JPanel(); + jLblTaxID = new javax.swing.JLabel(); + m_jtxtTaxID = new com.unicenta.editor.JEditorString(); + jLblSearchKey = new javax.swing.JLabel(); + m_jtxtSearchKey = new com.unicenta.editor.JEditorString(); + jLblPostal = new javax.swing.JLabel(); + m_jtxtPostal = new com.unicenta.editor.JEditorString(); + jLblName = new javax.swing.JLabel(); + m_jtxtName = new com.unicenta.editor.JEditorString(); + jLblPhone = new javax.swing.JLabel(); + jLblEmail = new javax.swing.JLabel(); + m_jtxtPhone = new com.unicenta.editor.JEditorString(); + m_jtxtName2 = new com.unicenta.editor.JEditorString(); + jPanel4 = new javax.swing.JPanel(); + jScrollPane1 = new javax.swing.JScrollPane(); + jListCustomers = new javax.swing.JList(); + jPanel6 = new javax.swing.JPanel(); + jbtnReset = new javax.swing.JButton(); + jbtnExecute = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(AppLocal.getIntString("form.customertitle")); // NOI18N + setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + setPreferredSize(new java.awt.Dimension(750, 600)); + + jPanel2.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + jPanel2.setLayout(new java.awt.BorderLayout()); + jPanel2.add(m_jKeys, java.awt.BorderLayout.NORTH); + + jPanel8.setLayout(new java.awt.BorderLayout()); + + jcmdCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + jcmdCancel.setText(AppLocal.getIntString("button.Cancel")); // NOI18N + jcmdCancel.setFocusPainted(false); + jcmdCancel.setFocusable(false); + jcmdCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdCancel.setPreferredSize(new java.awt.Dimension(110, 45)); + jcmdCancel.setRequestFocusEnabled(false); + jcmdCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdCancelActionPerformed(evt); + } + }); + jPanel1.add(jcmdCancel); + + jcmdOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jcmdOK.setText(AppLocal.getIntString("button.OK")); // NOI18N + jcmdOK.setEnabled(false); + jcmdOK.setFocusPainted(false); + jcmdOK.setFocusable(false); + jcmdOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdOK.setMaximumSize(new java.awt.Dimension(103, 44)); + jcmdOK.setMinimumSize(new java.awt.Dimension(103, 44)); + jcmdOK.setPreferredSize(new java.awt.Dimension(110, 45)); + jcmdOK.setRequestFocusEnabled(false); + jcmdOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdOKActionPerformed(evt); + } + }); + jPanel1.add(jcmdOK); + + jPanel8.add(jPanel1, java.awt.BorderLayout.LINE_END); + + jPanel2.add(jPanel8, java.awt.BorderLayout.PAGE_END); + jPanel2.add(jImageViewerCustomer, java.awt.BorderLayout.CENTER); + + getContentPane().add(jPanel2, java.awt.BorderLayout.LINE_END); + + jPanel3.setPreferredSize(new java.awt.Dimension(450, 0)); + jPanel3.setLayout(new java.awt.BorderLayout()); + + jPanel5.setLayout(new java.awt.BorderLayout()); + + jLblTaxID.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblTaxID.setText(AppLocal.getIntString("label.taxid")); // NOI18N + jLblTaxID.setMaximumSize(new java.awt.Dimension(60, 15)); + jLblTaxID.setMinimumSize(new java.awt.Dimension(60, 15)); + jLblTaxID.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jtxtTaxID.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jtxtTaxID.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLblSearchKey.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblSearchKey.setText(AppLocal.getIntString("label.searchkey")); // NOI18N + jLblSearchKey.setMaximumSize(new java.awt.Dimension(60, 15)); + jLblSearchKey.setMinimumSize(new java.awt.Dimension(60, 15)); + jLblSearchKey.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jtxtSearchKey.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jtxtSearchKey.setPreferredSize(new java.awt.Dimension(250, 30)); + + jLblPostal.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblPostal.setText("Postal"); + jLblPostal.setMaximumSize(new java.awt.Dimension(60, 15)); + jLblPostal.setMinimumSize(new java.awt.Dimension(60, 15)); + jLblPostal.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jtxtPostal.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jtxtPostal.setPreferredSize(new java.awt.Dimension(250, 30)); + + jLblName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblName.setText(AppLocal.getIntString("label.prodname")); // NOI18N + jLblName.setMaximumSize(new java.awt.Dimension(60, 15)); + jLblName.setMinimumSize(new java.awt.Dimension(60, 15)); + jLblName.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jtxtName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jtxtName.setPreferredSize(new java.awt.Dimension(250, 30)); + + jLblPhone.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jLblPhone.setText(bundle.getString("label.companytelephone")); // NOI18N + jLblPhone.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLblEmail.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblEmail.setText(bundle.getString("label.companyemail")); // NOI18N + jLblEmail.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jtxtPhone.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jtxtPhone.setMinimumSize(new java.awt.Dimension(150, 30)); + m_jtxtPhone.setPreferredSize(new java.awt.Dimension(250, 30)); + + m_jtxtName2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jtxtName2.setMinimumSize(new java.awt.Dimension(150, 30)); + m_jtxtName2.setPreferredSize(new java.awt.Dimension(250, 30)); + + javax.swing.GroupLayout jPanel7Layout = new javax.swing.GroupLayout(jPanel7); + jPanel7.setLayout(jPanel7Layout); + jPanel7Layout.setHorizontalGroup( + jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel7Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel7Layout.createSequentialGroup() + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLblName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblSearchKey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblPostal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jtxtSearchKey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jtxtPostal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jtxtName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanel7Layout.createSequentialGroup() + .addComponent(jLblTaxID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jtxtTaxID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel7Layout.createSequentialGroup() + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(jLblEmail, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblPhone, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jtxtPhone, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jtxtName2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addContainerGap()) + ); + jPanel7Layout.setVerticalGroup( + jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel7Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jtxtTaxID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblTaxID, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jtxtSearchKey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblSearchKey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(jPanel7Layout.createSequentialGroup() + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLblPostal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jtxtPostal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jtxtName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jLblName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jtxtPhone, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblPhone, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLblEmail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jtxtName2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + + m_jtxtName.getAccessibleContext().setAccessibleName(""); + + jPanel5.add(jPanel7, java.awt.BorderLayout.CENTER); + + jPanel3.add(jPanel5, java.awt.BorderLayout.PAGE_START); + + jPanel4.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel4.setPreferredSize(new java.awt.Dimension(450, 140)); + jPanel4.setLayout(new java.awt.BorderLayout()); + + jScrollPane1.setPreferredSize(new java.awt.Dimension(400, 147)); + + jListCustomers.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jListCustomers.setFocusable(false); + jListCustomers.setRequestFocusEnabled(false); + jListCustomers.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + jListCustomersMouseClicked(evt); + } + }); + jListCustomers.addListSelectionListener(new javax.swing.event.ListSelectionListener() { + public void valueChanged(javax.swing.event.ListSelectionEvent evt) { + jListCustomersValueChanged(evt); + } + }); + jScrollPane1.setViewportView(jListCustomers); + + jPanel4.add(jScrollPane1, java.awt.BorderLayout.CENTER); + + jbtnReset.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnReset.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reload.png"))); // NOI18N + jbtnReset.setText(bundle.getString("button.reset")); // NOI18N + jbtnReset.setToolTipText("Clear Filter"); + jbtnReset.setActionCommand("Reset "); + jbtnReset.setFocusable(false); + jbtnReset.setPreferredSize(new java.awt.Dimension(110, 45)); + jbtnReset.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnResetActionPerformed(evt); + } + }); + jPanel6.add(jbtnReset); + jbtnReset.getAccessibleContext().setAccessibleDescription(""); + + jbtnExecute.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnExecute.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jbtnExecute.setText(AppLocal.getIntString("button.executefilter")); // NOI18N + jbtnExecute.setToolTipText("Execute Filter"); + jbtnExecute.setFocusPainted(false); + jbtnExecute.setPreferredSize(new java.awt.Dimension(110, 45)); + jbtnExecute.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnExecuteActionPerformed(evt); + } + }); + jPanel6.add(jbtnExecute); + jbtnExecute.getAccessibleContext().setAccessibleDescription(""); + + jPanel4.add(jPanel6, java.awt.BorderLayout.PAGE_START); + + jPanel3.add(jPanel4, java.awt.BorderLayout.CENTER); + + getContentPane().add(jPanel3, java.awt.BorderLayout.CENTER); + + setSize(new java.awt.Dimension(758, 634)); + setLocationRelativeTo(null); + }// </editor-fold>//GEN-END:initComponents + private void jcmdOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdOKActionPerformed + + m_ReturnCustomer = (CustomerInfo) jListCustomers.getSelectedValue(); + dispose(); + + }//GEN-LAST:event_jcmdOKActionPerformed + + private void jcmdCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdCancelActionPerformed + + dispose(); + + }//GEN-LAST:event_jcmdCancelActionPerformed + + private void jbtnExecuteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnExecuteActionPerformed + + m_ReturnCustomer=null; + executeSearch(); + + }//GEN-LAST:event_jbtnExecuteActionPerformed + + private void jListCustomersValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_jListCustomersValueChanged + + m_ReturnCustomer = (CustomerInfo) jListCustomers.getSelectedValue(); + + if (m_ReturnCustomer != null) { + m_ReturnCustomer = (CustomerInfo) jListCustomers.getSelectedValue(); + + if (m_ReturnCustomer != null) { + jImageViewerCustomer.setImage(m_ReturnCustomer.getImage()); + } + } + + jcmdOK.setEnabled(jListCustomers.getSelectedValue() != null); + + }//GEN-LAST:event_jListCustomersValueChanged + + private void jListCustomersMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jListCustomersMouseClicked + + m_ReturnCustomer = (CustomerInfo) jListCustomers.getSelectedValue(); + + if (m_ReturnCustomer != null) { + m_ReturnCustomer = (CustomerInfo) jListCustomers.getSelectedValue(); + + if (m_ReturnCustomer != null) { + jImageViewerCustomer.setImage(m_ReturnCustomer.getImage()); + } + } + + }//GEN-LAST:event_jListCustomersMouseClicked + +private void jbtnResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnResetActionPerformed + + m_jtxtTaxID.reset(); + m_jtxtSearchKey.reset(); + m_jtxtName.reset(); + m_jtxtPostal.reset(); + m_jtxtPhone.reset(); + m_jtxtName2.reset(); + + m_jtxtTaxID.activate(); + + cleanSearch(); +}//GEN-LAST:event_jbtnResetActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private com.unicenta.data.gui.JImageViewerCustomer jImageViewerCustomer; + private javax.swing.JLabel jLblEmail; + private javax.swing.JLabel jLblName; + private javax.swing.JLabel jLblPhone; + private javax.swing.JLabel jLblPostal; + private javax.swing.JLabel jLblSearchKey; + private javax.swing.JLabel jLblTaxID; + private javax.swing.JList jListCustomers; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JPanel jPanel6; + private javax.swing.JPanel jPanel7; + private javax.swing.JPanel jPanel8; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JButton jbtnExecute; + private javax.swing.JButton jbtnReset; + private javax.swing.JButton jcmdCancel; + private javax.swing.JButton jcmdOK; + private com.unicenta.editor.JEditorKeys m_jKeys; + private com.unicenta.editor.JEditorString m_jtxtName; + private com.unicenta.editor.JEditorString m_jtxtName2; + private com.unicenta.editor.JEditorString m_jtxtPhone; + private com.unicenta.editor.JEditorString m_jtxtPostal; + private com.unicenta.editor.JEditorString m_jtxtSearchKey; + private com.unicenta.editor.JEditorString m_jtxtTaxID; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/customers/JDialogNewCustomer.form b/src/main/java/com/unicenta/pos/customers/JDialogNewCustomer.form new file mode 100644 index 0000000..7fd5b30 --- /dev/null +++ b/src/main/java/com/unicenta/pos/customers/JDialogNewCustomer.form @@ -0,0 +1,582 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.customer" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[610, 430]"/> + </Property> + <Property name="resizable" type="boolean" value="false"/> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-57,0,0,2,-117"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleName" type="java.lang.String" value=""/> + </AccessibilityProperties> + <AuxValues> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,26,0,0,4,11"/> + </AuxValues> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLblEmail" alignment="0" max="-2" attributes="1"/> + <Component id="jLblTelephone1" alignment="0" max="-2" attributes="1"/> + <Component id="jLblTelephone2" alignment="1" max="-2" attributes="1"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="txtEmail" alignment="0" max="-2" attributes="2"/> + <Component id="txtPhone" max="-2" attributes="2"/> + <Component id="txtPhone2" max="-2" attributes="1"/> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLblFirstName" max="-2" attributes="1"/> + <Component id="jLblLastName" alignment="1" max="-2" attributes="1"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="txtLastName" max="-2" attributes="2"/> + <Component id="txtFirstName" max="-2" attributes="1"/> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="1" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLblName" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jName" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLblCustTaxCat" min="-2" max="-2" attributes="0"/> + <Component id="jLblVIP" alignment="1" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jCategory" alignment="0" min="-2" pref="163" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Component id="m_jVip" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jLblDiscount" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="txtDiscount" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLblDiscountpercent" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="m_jSearchkey" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Component id="jLblSearchkey" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" max="-2" attributes="0"> + <Component id="jLabel1" alignment="0" pref="0" max="32767" attributes="1"/> + <Component id="jLblTaxID" alignment="0" pref="140" max="32767" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jTaxID" min="-2" max="-2" attributes="0"/> + <Component id="txtMaxdebt" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace min="62" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLblName" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLblSearchkey" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jSearchkey" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLblTaxID" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jTaxID" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLblCustTaxCat" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCategory" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtMaxdebt" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" alignment="0" groupAlignment="0" attributes="0"> + <Component id="jLblVIP" min="-2" max="-2" attributes="0"/> + <Group type="103" alignment="1" groupAlignment="3" attributes="0"> + <Component id="jLblDiscount" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtDiscount" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLblDiscountpercent" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Component id="m_jVip" min="-2" pref="25" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="txtFirstName" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLblFirstName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLblLastName" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtLastName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLblEmail" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtEmail" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLblTelephone1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtPhone" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLblTelephone2" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtPhone2" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLblName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.namem" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 25]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblSearchkey"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.searchkeym" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jSearchkey"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblTaxID"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.taxid" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jTaxID"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="CustomersView_m_jTaxID"/> + </AuxValues> + </Component> + <Component class="javax.swing.JLabel" name="jLblCustTaxCat"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.custtaxcategory" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 25]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCategory"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblVIP"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.vip" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="m_jVip"> + <Properties> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="f3" green="bc" red="0" type="rgb"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[21, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="m_jVipnone"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLblDiscount"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.discount" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[55, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtDiscount"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblDiscountpercent"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="%"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[12, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblFirstName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.firstname" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="alignmentX" type="float" value="0.5"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtFirstName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblLastName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.lastname" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtLastName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblEmail"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.email" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtEmail"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblTelephone1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.phone" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtPhone"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblTelephone2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.phone2" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtPhone2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.maxdebt" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 25]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtMaxdebt"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="2"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="m_jBtnOK"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="Button.OK" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jBtnOKActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jBtnCancel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="Button.Cancel" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jBtnCancelActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/customers/JDialogNewCustomer.java b/src/main/java/com/unicenta/pos/customers/JDialogNewCustomer.java new file mode 100644 index 0000000..a580664 --- /dev/null +++ b/src/main/java/com/unicenta/pos/customers/JDialogNewCustomer.java @@ -0,0 +1,520 @@ +package com.unicenta.pos.customers; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.loader.LocalRes; +import com.unicenta.data.loader.SentenceExec; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.loader.TableDefinition; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.Window; +import java.util.List; +import java.util.UUID; +import javax.swing.JFrame; +import javax.swing.JOptionPane; + +public class JDialogNewCustomer extends javax.swing.JDialog { + + private DataLogicCustomers dlCustomer; + private DataLogicSales dlSales; + private ComboBoxValModel m_CategoryModel; + private SentenceList m_sentcat; + private SentenceExec m_sentinsert; + private TableDefinition tcustomers; + private CustomerInfoExt selectedCustomer; + private Object m_oId; + + /** Creates new form quick New Customer + * @param parent */ + protected JDialogNewCustomer(java.awt.Frame parent) { + super(parent, true); + } + + /** Creates new form quick New Customer + * @param parent */ + protected JDialogNewCustomer(java.awt.Dialog parent) { + super(parent, true); + } + + private void init(AppView app) { + + try { + dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + dlCustomer = (DataLogicCustomers) app.getBean("com.unicenta.pos.customers.DataLogicCustomers"); + m_sentcat = dlSales.getTaxCustCategoriesList(); + tcustomers = dlCustomer.getTableCustomers(); + + initComponents(); + + m_CategoryModel = new ComboBoxValModel(); + List a = m_sentcat.list(); + a.add(0, null); + + m_CategoryModel = new ComboBoxValModel(a); + m_jCategory.setModel(m_CategoryModel); + + getRootPane().setDefaultButton(m_jBtnOK); + } catch (BasicException ex) { + } + } + + + public Object createValue() throws BasicException { + Object[] customer = new Object[27]; + customer[0] = m_oId; + customer[1] = m_jSearchkey.getText(); + customer[2] = m_jTaxID.getText(); + customer[3] = m_jName.getText(); + customer[4] = m_CategoryModel.getSelectedKey(); + customer[5] = null; + customer[6] = Formats.CURRENCY.parseValue(txtMaxdebt.getText(), 0.0); + customer[7] = null; + customer[8] = null; + customer[9] = null; + customer[10] = null; + customer[11] = null; + customer[12] = null; + customer[13] = Formats.STRING.parseValue(txtFirstName.getText()); + customer[14] = Formats.STRING.parseValue(txtLastName.getText()); + customer[15] = Formats.STRING.parseValue(txtEmail.getText()); + customer[16] = Formats.STRING.parseValue(txtPhone.getText()); + customer[17] = Formats.STRING.parseValue(txtPhone2.getText()); + customer[18] = null; + customer[19] = null; + customer[20] = true; + customer[21] = null; + customer[22] = 0.0; + customer[23] = null; + customer[24] = m_jVip.isSelected(); + customer[25] = Formats.DOUBLE.parseValue(txtDiscount.getText()); + customer[26] = null; + + return customer; + } + + + private void selectedVip(boolean value){ + m_jVip.setSelected(value); + jLblDiscountpercent.setVisible(value); + txtDiscount.setVisible(value); + + } + + public static JDialogNewCustomer getDialog(Component parent,AppView app) { + + Window window = getWindow(parent); + + JDialogNewCustomer quicknewcustomer; + + if (window instanceof Frame) { + quicknewcustomer = new JDialogNewCustomer((Frame) window); + } else { + quicknewcustomer = new JDialogNewCustomer((Dialog) window); + } + + quicknewcustomer.init(app); + + return quicknewcustomer; + } + + protected static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window)parent; + } else { + return getWindow(parent.getParent()); + } + } + + public CustomerInfoExt getSelectedCustomer() { + return selectedCustomer; + } + + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel3 = new javax.swing.JPanel(); + jLblName = new javax.swing.JLabel(); + m_jName = new javax.swing.JTextField(); + jLblSearchkey = new javax.swing.JLabel(); + m_jSearchkey = new javax.swing.JTextField(); + jLblTaxID = new javax.swing.JLabel(); + m_jTaxID = new javax.swing.JTextField(); + jLblCustTaxCat = new javax.swing.JLabel(); + m_jCategory = new javax.swing.JComboBox(); + jLblVIP = new javax.swing.JLabel(); + m_jVip = new javax.swing.JCheckBox(); + jLblDiscount = new javax.swing.JLabel(); + txtDiscount = new javax.swing.JTextField(); + jLblDiscountpercent = new javax.swing.JLabel(); + jLblFirstName = new javax.swing.JLabel(); + txtFirstName = new javax.swing.JTextField(); + jLblLastName = new javax.swing.JLabel(); + txtLastName = new javax.swing.JTextField(); + jLblEmail = new javax.swing.JLabel(); + txtEmail = new javax.swing.JTextField(); + jLblTelephone1 = new javax.swing.JLabel(); + txtPhone = new javax.swing.JTextField(); + jLblTelephone2 = new javax.swing.JLabel(); + txtPhone2 = new javax.swing.JTextField(); + jLabel1 = new javax.swing.JLabel(); + txtMaxdebt = new javax.swing.JTextField(); + jPanel2 = new javax.swing.JPanel(); + m_jBtnOK = new javax.swing.JButton(); + m_jBtnCancel = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(AppLocal.getIntString("label.customer")); // NOI18N + setPreferredSize(new java.awt.Dimension(610, 430)); + setResizable(false); + + jPanel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + + jLblName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblName.setText(AppLocal.getIntString("label.namem")); // NOI18N + jLblName.setMaximumSize(new java.awt.Dimension(140, 25)); + jLblName.setMinimumSize(new java.awt.Dimension(140, 25)); + jLblName.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(300, 30)); + + jLblSearchkey.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblSearchkey.setText(AppLocal.getIntString("label.searchkeym")); // NOI18N + jLblSearchkey.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jSearchkey.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSearchkey.setHorizontalAlignment(javax.swing.JTextField.LEFT); + m_jSearchkey.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLblTaxID.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblTaxID.setText(AppLocal.getIntString("label.taxid")); // NOI18N + jLblTaxID.setMaximumSize(new java.awt.Dimension(150, 30)); + jLblTaxID.setMinimumSize(new java.awt.Dimension(140, 25)); + jLblTaxID.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jTaxID.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jTaxID.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLblCustTaxCat.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblCustTaxCat.setText(AppLocal.getIntString("label.custtaxcategory")); // NOI18N + jLblCustTaxCat.setMaximumSize(new java.awt.Dimension(140, 25)); + jLblCustTaxCat.setMinimumSize(new java.awt.Dimension(140, 25)); + jLblCustTaxCat.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jCategory.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCategory.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLblVIP.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblVIP.setText(AppLocal.getIntString("label.vip")); // NOI18N + jLblVIP.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jVip.setForeground(new java.awt.Color(0, 188, 243)); + m_jVip.setPreferredSize(new java.awt.Dimension(21, 30)); + m_jVip.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + m_jVipnone(evt); + } + }); + + jLblDiscount.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblDiscount.setText(AppLocal.getIntString("label.discount")); // NOI18N + jLblDiscount.setPreferredSize(new java.awt.Dimension(55, 30)); + + txtDiscount.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtDiscount.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + txtDiscount.setPreferredSize(new java.awt.Dimension(50, 30)); + + jLblDiscountpercent.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblDiscountpercent.setText("%"); + jLblDiscountpercent.setPreferredSize(new java.awt.Dimension(12, 30)); + + jLblFirstName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblFirstName.setText(AppLocal.getIntString("label.firstname")); // NOI18N + jLblFirstName.setAlignmentX(0.5F); + jLblFirstName.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtFirstName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtFirstName.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLblLastName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblLastName.setText(AppLocal.getIntString("label.lastname")); // NOI18N + jLblLastName.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtLastName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtLastName.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLblEmail.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblEmail.setText(AppLocal.getIntString("label.email")); // NOI18N + jLblEmail.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtEmail.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtEmail.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLblTelephone1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblTelephone1.setText(AppLocal.getIntString("label.phone")); // NOI18N + jLblTelephone1.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtPhone.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtPhone.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLblTelephone2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblTelephone2.setText(AppLocal.getIntString("label.phone2")); // NOI18N + jLblTelephone2.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtPhone2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtPhone2.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.maxdebt")); // NOI18N + jLabel1.setMaximumSize(new java.awt.Dimension(140, 25)); + jLabel1.setMinimumSize(new java.awt.Dimension(140, 25)); + jLabel1.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtMaxdebt.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtMaxdebt.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + txtMaxdebt.setPreferredSize(new java.awt.Dimension(100, 30)); + + javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); + jPanel3.setLayout(jPanel3Layout); + jPanel3Layout.setHorizontalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLblEmail, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblTelephone1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblTelephone2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(txtEmail, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtPhone, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtPhone2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanel3Layout.createSequentialGroup() + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLblFirstName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblLastName, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(txtLastName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtFirstName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanel3Layout.createSequentialGroup() + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel3Layout.createSequentialGroup() + .addComponent(jLblName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel3Layout.createSequentialGroup() + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLblCustTaxCat, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblVIP, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, 163, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel3Layout.createSequentialGroup() + .addComponent(m_jVip, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLblDiscount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtDiscount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLblDiscountpercent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(m_jSearchkey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(jLblSearchkey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(jLabel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 1, Short.MAX_VALUE) + .addComponent(jLblTaxID, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE)))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jTaxID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtMaxdebt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel3Layout.setVerticalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLblName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLblSearchkey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jSearchkey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblTaxID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jTaxID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLblCustTaxCat, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtMaxdebt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLblVIP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLblDiscount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtDiscount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblDiscountpercent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(m_jVip, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(txtFirstName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblFirstName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLblLastName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtLastName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLblEmail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtEmail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLblTelephone1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtPhone, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLblTelephone2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtPhone2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + ); + + getContentPane().add(jPanel3, java.awt.BorderLayout.NORTH); + jPanel3.getAccessibleContext().setAccessibleName(""); + + jPanel2.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT)); + + m_jBtnOK.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jBtnOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + m_jBtnOK.setText(AppLocal.getIntString("Button.OK")); // NOI18N + m_jBtnOK.setFocusPainted(false); + m_jBtnOK.setFocusable(false); + m_jBtnOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jBtnOK.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jBtnOK.setRequestFocusEnabled(false); + m_jBtnOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jBtnOKActionPerformed(evt); + } + }); + jPanel2.add(m_jBtnOK); + + m_jBtnCancel.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jBtnCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + m_jBtnCancel.setText(AppLocal.getIntString("Button.Cancel")); // NOI18N + m_jBtnCancel.setFocusPainted(false); + m_jBtnCancel.setFocusable(false); + m_jBtnCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jBtnCancel.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jBtnCancel.setRequestFocusEnabled(false); + m_jBtnCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jBtnCancelActionPerformed(evt); + } + }); + jPanel2.add(m_jBtnCancel); + + getContentPane().add(jPanel2, java.awt.BorderLayout.SOUTH); + + setSize(new java.awt.Dimension(651, 455)); + setLocationRelativeTo(null); + }// </editor-fold>//GEN-END:initComponents + + private void m_jBtnOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jBtnOKActionPerformed + + if ("".equals(m_jSearchkey.getText()) + || "".equals(m_jName.getText())) { + JOptionPane.showMessageDialog( + null, + AppLocal.getIntString("message.customercheck"), + "Customer check", + JOptionPane.ERROR_MESSAGE); + } else { + try { + m_oId = UUID.randomUUID().toString(); + Object customer = createValue(); + + int status = tcustomers.getInsertSentence().exec(customer); + + if (status>0){ + selectedCustomer = dlSales.loadCustomerExt(m_oId.toString()); + dispose(); + } else { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, + LocalRes.getIntString("message.nosave"), "Error save"); + msg.show(this); + } + + } catch (BasicException ex) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, + LocalRes.getIntString("message.nosave"), ex); + msg.show(this); + } + } + }//GEN-LAST:event_m_jBtnOKActionPerformed + + private void m_jBtnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jBtnCancelActionPerformed + + dispose(); + + }//GEN-LAST:event_m_jBtnCancelActionPerformed + +private void m_jVipnone(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_m_jVipnone + +}//GEN-LAST:event_m_jVipnone + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLblCustTaxCat; + private javax.swing.JLabel jLblDiscount; + private javax.swing.JLabel jLblDiscountpercent; + private javax.swing.JLabel jLblEmail; + private javax.swing.JLabel jLblFirstName; + private javax.swing.JLabel jLblLastName; + private javax.swing.JLabel jLblName; + private javax.swing.JLabel jLblSearchkey; + private javax.swing.JLabel jLblTaxID; + private javax.swing.JLabel jLblTelephone1; + private javax.swing.JLabel jLblTelephone2; + private javax.swing.JLabel jLblVIP; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JButton m_jBtnCancel; + private javax.swing.JButton m_jBtnOK; + private javax.swing.JComboBox m_jCategory; + private javax.swing.JTextField m_jName; + private javax.swing.JTextField m_jSearchkey; + private javax.swing.JTextField m_jTaxID; + private javax.swing.JCheckBox m_jVip; + private javax.swing.JTextField txtDiscount; + private javax.swing.JTextField txtEmail; + private javax.swing.JTextField txtFirstName; + private javax.swing.JTextField txtLastName; + private javax.swing.JTextField txtMaxdebt; + private javax.swing.JTextField txtPhone; + private javax.swing.JTextField txtPhone2; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/customers/OrderCustomerList.form b/src/main/java/com/unicenta/pos/customers/OrderCustomerList.form new file mode 100644 index 0000000..739a009 --- /dev/null +++ b/src/main/java/com/unicenta/pos/customers/OrderCustomerList.form @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[256, 560]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[256, 560]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,88,0,0,1,44"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanelCustomers"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignCardLayout"/> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/customers/OrderCustomerList.java b/src/main/java/com/unicenta/pos/customers/OrderCustomerList.java new file mode 100644 index 0000000..22f651a --- /dev/null +++ b/src/main/java/com/unicenta/pos/customers/OrderCustomerList.java @@ -0,0 +1,360 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.customers; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.pos.catalog.JCatalogTab; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.sales.DataLogicReceipts; +import com.unicenta.pos.sales.SharedTicketInfo; +import com.unicenta.pos.sales.TicketsEditor; +import com.unicenta.pos.ticket.TicketInfo; +import com.unicenta.pos.util.ThumbNailBuilder; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.swing.*; +import javax.swing.event.EventListenerList; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.*; + +/** + * @author JG uniCenta - outline/prep for uniCenta mobile + eCommerce connector + */ +@Slf4j +public class OrderCustomerList extends JPanel implements TicketSelector { + + /** + * Source origin and Ticket + */ + protected AppView application; + private String currentTicket; + + /** + * This instance interface + */ + protected TicketsEditor panelticket; + + /** + * Set listeners for new/change Customer/Receipt events + */ + protected EventListenerList listeners = new EventListenerList(); + private final DataLogicCustomers dataLogicCustomers; + private final DataLogicReceipts dataLogicReceipts; + private final ThumbNailBuilder tnbbutton; + + /** + * Creates new form CustomersList + * + * @param dlCustomers + * @param app + * @param panelticket + */ + public OrderCustomerList(DataLogicCustomers dlCustomers, AppView app, TicketsEditor panelticket) { + this.application = app; + this.panelticket = panelticket; + this.dataLogicCustomers = dlCustomers; + this.dataLogicReceipts = (DataLogicReceipts) application.getBean("com.unicenta.pos.sales.DataLogicReceipts"); + tnbbutton = new ThumbNailBuilder(90, 98); + +// orderSynchroniseHelper = new OrdersSynchroniseHelper(application, dataLogicReceipts, panelticket.getActiveTicket()); + + initComponents(); + } + + /** + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * @throws BasicException + */ + public void reloadCustomers() throws BasicException { +// synchroniseData(); + loadCustomers(); + } + + /** + * @throws BasicException + */ + @Override + public void loadCustomers() throws BasicException { + + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + + long time = System.currentTimeMillis(); + jPanelCustomers.removeAll(); + + JCatalogTab flowTab = new JCatalogTab(); + jPanelCustomers.add(flowTab); + + List<CustomerInfoExt> customers = null; + List<SharedTicketInfo> ticketList = null; + try { + +// customers = dataLogicCustomers.getCustomers(); + log.info("Time of getCustomersWithOutImage {}", (System.currentTimeMillis() - time)); + time = System.currentTimeMillis(); + + ticketList = dataLogicReceipts.getSharedTicketList(); + log.info("Time of getSharedTicketList {}", (System.currentTimeMillis() - time)); + time = System.currentTimeMillis(); + + + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + HashMap<SharedTicketInfo, CustomerInfoExt> orderMap = new HashMap<>(); + + for (SharedTicketInfo sharedTicketInfo : ticketList) { + + String ticketName = sharedTicketInfo.getName().trim(); + + if (ticketName.contains("[") && ticketName.contains("]")) { + + // found order + if (ticketName.startsWith("[")) { + // order without customer + orderMap.put(sharedTicketInfo, null); + } else if (!customers.isEmpty()) { + // find customer to ticket + for (CustomerInfoExt customer : customers) { + if (customer != null) { + String name = customer.getName().trim(); + if (ticketName.startsWith(name)) { + orderMap.put(sharedTicketInfo, customer); + break; + } + } + } + } + } + } + // sort + CustomerComparator bvc = new CustomerComparator(orderMap); + TreeMap<SharedTicketInfo, CustomerInfoExt> sortedMap = new TreeMap<>(bvc); + sortedMap.putAll(orderMap); + + log.info("Time of orderMap {}", (System.currentTimeMillis() - time)); + time = System.currentTimeMillis(); + + // set button list + for (Map.Entry<SharedTicketInfo, CustomerInfoExt> entry : sortedMap.entrySet()) { + SharedTicketInfo ticket = entry.getKey(); + CustomerInfoExt customer = entry.getValue(); + + String name = ticket.getName(); + BufferedImage image = null; + +// if (customer != null) { +// try { +// image = dataLogicCustomers.getCustomerImage(customer.getId()); +// } catch (BasicException ex) { +// +// } +// } + if (image == null) { + try { + InputStream is = getClass().getResourceAsStream("/com/unicenta/images/no_image.png"); + if (is != null) { + image = ImageIO.read(is); + } + } catch (IOException ex) { + log.error(ex.getMessage()); + } + } + String username; + if (name.indexOf("[") != 0) { + username = name.substring(0, name.indexOf("[") - 1); + username = username.replace("-", ""); + } else { + username = "unknown"; + } + String orderId = name.substring(name.indexOf("["), name.indexOf("]") + 1); + String text = "<html><center>" + username.trim() + "<br/>" + orderId.trim() + "</center></html>"; + + ImageIcon icon = new ImageIcon(tnbbutton.getThumbNailText(image, text)); +// flowTab.addButton(icon, new SelectedCustomerAction(ticket.getId())); + } + log.info("Time of finished loadCustomerOrders {}", (System.currentTimeMillis() - time)); + } + }); + } + + /** + * @param value + */ + @Override + public void setComponentEnabled(boolean value) { + jPanelCustomers.setEnabled(value); + + synchronized (jPanelCustomers.getTreeLock()) { + int compCount = jPanelCustomers.getComponentCount(); + for (int i = 0; i < compCount; i++) { + jPanelCustomers.getComponent(i).setEnabled(value); + } + } + this.setEnabled(value); + } + + /** + * @param l + */ + @Override + public void addActionListener(ActionListener l) { + listeners.add(ActionListener.class, l); + } + + /** + * @param l + */ + @Override + public void removeActionListener(ActionListener l) { + listeners.remove(ActionListener.class, l); + } + + private void setActiveTicket(String id) throws BasicException { + + currentTicket = panelticket.getActiveTicket().getId(); + + // save current ticket +// if (currentTicket != null) { +// try { +// dataLogicReceipts.insertSharedTicket(currentTicket, panelticket.getActiveTicket()); +// } catch (BasicException e) { +// new MessageInf(e).show(this); +// } +// } + // set ticket + // BEGIN TRANSACTION + TicketInfo ticket = dataLogicReceipts.getSharedTicket(id); + if (ticket == null) { + // Does not exists ??? + throw new BasicException(AppLocal.getIntString("message.noticket")); + } else { + dataLogicReceipts.deleteSharedTicket(id); + currentTicket = id; + panelticket.setActiveTicket(ticket, null); + fireTicketSelectionChanged(ticket.getId()); + } + // END TRANSACTION + } + +// private void synchroniseData() { +// try { + // get tickets only from selected customer or show all + // add newest tickets from provider +// orderSynchroniseHelper.synchSharedTickets(panelticket.getActiveTicket()); +// } catch (Exception e) { +// } +// } + + private void fireTicketSelectionChanged(String ticketId) { + EventListener[] l = listeners.getListeners(ActionListener.class); + ActionEvent e = null; + for (EventListener l1 : l) { + if (e == null) { + e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, ticketId); + } + ((ActionListener) l1).actionPerformed(e); + } + } + + private class SelectedCustomerAction implements ActionListener { + + private final String ticketId; + + public SelectedCustomerAction(String ticketId) { + this.ticketId = ticketId; + } + + @Override + public void actionPerformed(ActionEvent e) { + try { + if (ticketId != null) { + setActiveTicket(ticketId); + } + } catch (BasicException ex) { + new MessageInf(ex).show(OrderCustomerList.this); + } + } + } + + class CustomerComparator implements Comparator<SharedTicketInfo> { + + Map<SharedTicketInfo, CustomerInfoExt> base; + + public CustomerComparator(Map<SharedTicketInfo, CustomerInfoExt> base) { + this.base = base; + } + + // Note: this comparator imposes orderings that are inconsistent with equals. + @Override + public int compare(SharedTicketInfo a, SharedTicketInfo b) { + String nameA = base.get(a).getName(); + String nameB = base.get(b).getName(); + + if (nameA.compareToIgnoreCase(nameB) < 0) { + return -1; + } else { + return 1; + } + } + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanelCustomers = new javax.swing.JPanel(); + + setMinimumSize(new java.awt.Dimension(256, 560)); + setPreferredSize(new java.awt.Dimension(256, 560)); + setLayout(new java.awt.BorderLayout()); + + jPanelCustomers.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanelCustomers.setLayout(new java.awt.CardLayout()); + add(jPanelCustomers, java.awt.BorderLayout.CENTER); + }// </editor-fold>//GEN-END:initComponents + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanelCustomers; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/customers/TicketSelector.java b/src/main/java/com/unicenta/pos/customers/TicketSelector.java new file mode 100644 index 0000000..b4a2f1a --- /dev/null +++ b/src/main/java/com/unicenta/pos/customers/TicketSelector.java @@ -0,0 +1,46 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.unicenta.pos.customers; + +import com.unicenta.basic.BasicException; +import java.awt.Component; +import java.awt.event.ActionListener; + +/** + * + * @author JG uniCenta - outline/prep for uniCenta mobile + eCommerce connector + */ +public interface TicketSelector { + + /** + * + * @throws BasicException + */ + public void loadCustomers() throws BasicException; + + /** + * + * @param value + */ + public void setComponentEnabled(boolean value); + + /** + * + * @return + */ + public Component getComponent(); + + /** + * + * @param l + */ + public void addActionListener(ActionListener l); + + /** + * + * @param l + */ + public void removeActionListener(ActionListener l); +} diff --git a/src/main/java/com/unicenta/pos/epm/Break.java b/src/main/java/com/unicenta/pos/epm/Break.java new file mode 100644 index 0000000..f07e8d3 --- /dev/null +++ b/src/main/java/com/unicenta/pos/epm/Break.java @@ -0,0 +1,110 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.epm; + +/** + * + * @author Ali Safdar and Aneeqa Baber + */ +public class Break { + + private String m_sId; + private String m_sName; + private String m_sNotes; + private boolean m_sVisible; + + /** + * + * @param id + * @param name + * @param notes + * @param visible + */ + public Break(String id, String name, String notes, boolean visible) { + m_sId = id; + m_sName = name; + m_sNotes = notes; + m_sVisible = visible; + } + + /** + * + * @return + */ + public String getId() { + return m_sId; + } + + /** + * + * @param Id + */ + public void setId(String Id) { + this.m_sId = Id; + } + + /** + * + * @return + */ + public String getName() { + return m_sName; + } + + /** + * + * @param Name + */ + public void setName(String Name) { + this.m_sName = Name; + } + + /** + * + * @return + */ + public String getNotes() { + return m_sNotes; + } + + /** + * + * @param Notes + */ + public void setNotes(String Notes) { + this.m_sNotes = Notes; + } + + /** + * + * @return + */ + public boolean isVisible() { + return m_sVisible; + } + + /** + * + * @param Visible + */ + public void setVisible(boolean Visible) { + this.m_sVisible = Visible; + } +} diff --git a/src/main/java/com/unicenta/pos/epm/BreaksInfo.java b/src/main/java/com/unicenta/pos/epm/BreaksInfo.java new file mode 100644 index 0000000..a1873f1 --- /dev/null +++ b/src/main/java/com/unicenta/pos/epm/BreaksInfo.java @@ -0,0 +1,89 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.epm; + +import com.unicenta.data.loader.IKeyed; + +/** + * + * @author Ali Safdar and Aneeqa Baber + */ +public class BreaksInfo implements IKeyed { + + private static final long serialVersionUID = 8936482715929L; + private String m_sID; + private String m_sName; + + /** + * + * @param id + * @param name + */ + public BreaksInfo(String id, String name) { + m_sID = id; + m_sName = name; + } + + /** + * + * @return + */ + @Override + public Object getKey() { + return m_sID; + } + + /** + * + * @param sID + */ + public void setID(String sID) { + m_sID = sID; + } + + /** + * + * @return + */ + public String getID() { + return m_sID; + } + + /** + * + * @return + */ + public String getName() { + return m_sName; + } + + /** + * + * @param sName + */ + public void setName(String sName) { + m_sName = sName; + } + + @Override + public String toString(){ + return m_sName; + } +} diff --git a/src/main/java/com/unicenta/pos/epm/BreaksPanel.java b/src/main/java/com/unicenta/pos/epm/BreaksPanel.java new file mode 100644 index 0000000..6646807 --- /dev/null +++ b/src/main/java/com/unicenta/pos/epm/BreaksPanel.java @@ -0,0 +1,133 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.epm; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ListCellRendererBasic; +import com.unicenta.data.loader.ComparatorCreator; +import com.unicenta.data.loader.TableDefinition; +import com.unicenta.data.loader.Vectorer; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.panels.JPanelTable; +import javax.swing.ListCellRenderer; + +/** + * + * @author Ali Safdar and Aneeqa Baber + */ +public class BreaksPanel extends JPanelTable { + + private TableDefinition tbreaks; + private BreaksView jeditor; + + /** + * + */ + public BreaksPanel() { + } + + /** + * + */ + @Override + protected void init() { + DataLogicPresenceManagement dlPresenceManagement = (DataLogicPresenceManagement) app.getBean("com.unicenta.pos.epm.DataLogicPresenceManagement"); + tbreaks = dlPresenceManagement.getTableBreaks(); + jeditor = new BreaksView(app, dirty); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + + jeditor.activate(); + super.activate(); + } + + /** + * + * @return + */ + @Override + public ListProvider getListProvider() { + return new ListProviderCreator(tbreaks); + } + + /** + * + * @return + */ + @Override + public SaveProvider getSaveProvider() { + return new SaveProvider(tbreaks, new int[] {0, 1, 2, 3}); + } + + /** + * + * @return + */ + @Override + public Vectorer getVectorer() { + return tbreaks.getVectorerBasic(new int[]{1, 2}); + } + + /** + * + * @return + */ + @Override + public ComparatorCreator getComparatorCreator() { + return tbreaks.getComparatorCreator(new int[] {1, 2}); + } + + /** + * + * @return + */ + @Override + public ListCellRenderer getListCellRenderer() { + return new ListCellRendererBasic(tbreaks.getRenderStringBasic(new int[]{1})); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return jeditor; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.Breaks"); + } +} diff --git a/src/main/java/com/unicenta/pos/epm/BreaksView.form b/src/main/java/com/unicenta/pos/epm/BreaksView.form new file mode 100644 index 0000000..2def88c --- /dev/null +++ b/src/main/java/com/unicenta/pos/epm/BreaksView.form @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="jLabel1" alignment="0" pref="126" max="32767" attributes="1"/> + <Component id="m_Name3" alignment="0" pref="126" max="32767" attributes="1"/> + <Component id="m_Ncx" alignment="0" pref="126" max="32767" attributes="1"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="m_jVisible" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="m_jBreakName" alignment="0" max="32767" attributes="1"/> + <Component id="jScrollPane1" alignment="0" min="-2" pref="223" max="-2" attributes="1"/> + </Group> + <EmptySpace min="-2" pref="214" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jBreakName" alignment="3" min="-2" pref="25" max="-2" attributes="0"/> + <Component id="jLabel1" alignment="3" min="-2" pref="25" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="m_Ncx" min="-2" pref="25" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_Name3" min="-2" pref="25" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="m_jVisible" min="-2" pref="25" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jScrollPane1" min="-2" pref="138" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace pref="35" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JTextField" name="m_jBreakName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + </Component> + <Container class="javax.swing.JScrollPane" name="jScrollPane1"> + <AuxValues> + <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JTextArea" name="m_jBreakDescription"> + <Properties> + <Property name="columns" type="int" value="20"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="lineWrap" type="boolean" value="true"/> + <Property name="rows" type="int" value="5"/> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JCheckBox" name="m_jVisible"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_Ncx"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.epm.visible" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_Name3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.epm.notes" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.epm.employee" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/epm/BreaksView.java b/src/main/java/com/unicenta/pos/epm/BreaksView.java new file mode 100644 index 0000000..ee12d4c --- /dev/null +++ b/src/main/java/com/unicenta/pos/epm/BreaksView.java @@ -0,0 +1,239 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.epm; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import java.awt.Component; +import java.util.List; +import java.util.UUID; + +/** + * + * @author Ali Safdar and Aneeqa Baber + */ +public final class BreaksView extends javax.swing.JPanel implements EditorRecord { + + private Object m_oId; + private SentenceList m_sentcat; + private DirtyManager m_Dirty; + + /** Creates new form BreaksView + * @param app + * @param dirty */ + public BreaksView(AppView app, DirtyManager dirty) { + + DataLogicPresenceManagement dlPresenceManagement = (DataLogicPresenceManagement) app.getBean("com.unicenta.pos.epm.DataLogicPresenceManagement"); + initComponents(); + m_sentcat = dlPresenceManagement.getBreaksList(); + m_Dirty = dirty; + m_jBreakName.getDocument().addDocumentListener(dirty); + m_jVisible.addActionListener(dirty); + m_jBreakDescription.getDocument().addDocumentListener(dirty); + writeValueEOF(); + } + + void activate() throws BasicException { + List a = m_sentcat.list(); + a.add(0, null); + } + + /** + * + */ + @Override + public void writeValueEOF() { + m_oId = null; + m_jBreakName.setText(null); + m_jBreakDescription.setText(null); + m_jVisible.setSelected(false); + m_jBreakName.setEditable(false); + m_jBreakDescription.setEnabled(false); + m_jVisible.setEnabled(false); + } + + /** + * + */ + @Override + public void writeValueInsert() { + m_oId = null; + m_jBreakName.setText(null); + m_jBreakDescription.setText(null); + m_jVisible.setSelected(true); + m_jBreakName.setEditable(true); + m_jBreakDescription.setEnabled(true); + m_jVisible.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueEdit(Object value) { + Object[] breaks = (Object[]) value; + m_oId = breaks[0]; + m_jBreakName.setText((String) breaks[1]); + m_jBreakDescription.setText((String) breaks[2]); + m_jVisible.setSelected(((Boolean) breaks[3]).booleanValue()); + m_jBreakName.setEditable(true); + m_jBreakDescription.setEnabled(true); + m_jVisible.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueDelete(Object value) { + Object[] breaks = (Object[]) value; + m_oId = breaks[0]; + m_jBreakName.setText((String) breaks[1]); + m_jBreakDescription.setText((String) breaks[2]); + m_jVisible.setSelected(((Boolean) breaks[3]).booleanValue()); + m_jBreakName.setEditable(false); + m_jBreakDescription.setEnabled(false); + m_jVisible.setEnabled(false); + } + + /** + * + */ + @Override + public void refresh() { + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + Object[] breaks = new Object[4]; + breaks[0] = m_oId == null ? UUID.randomUUID().toString() : m_oId; + breaks[1] = m_jBreakName.getText(); + breaks[2] = m_jBreakDescription.getText(); + breaks[3] = Boolean.valueOf(m_jVisible.isSelected()); + + return breaks; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jBreakName = new javax.swing.JTextField(); + jScrollPane1 = new javax.swing.JScrollPane(); + m_jBreakDescription = new javax.swing.JTextArea(); + m_jVisible = new javax.swing.JCheckBox(); + m_Ncx = new javax.swing.JLabel(); + m_Name3 = new javax.swing.JLabel(); + jLabel1 = new javax.swing.JLabel(); + + m_jBreakName.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + + m_jBreakDescription.setColumns(20); + m_jBreakDescription.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jBreakDescription.setLineWrap(true); + m_jBreakDescription.setRows(5); + jScrollPane1.setViewportView(m_jBreakDescription); + + m_jVisible.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + + m_Ncx.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_Ncx.setText(AppLocal.getIntString("label.epm.visible")); // NOI18N + + m_Name3.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_Name3.setText(AppLocal.getIntString("label.epm.notes")); // NOI18N + + jLabel1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jLabel1.setText(bundle.getString("label.epm.employee")); // NOI18N + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 126, Short.MAX_VALUE) + .addComponent(m_Name3, javax.swing.GroupLayout.DEFAULT_SIZE, 126, Short.MAX_VALUE) + .addComponent(m_Ncx, javax.swing.GroupLayout.DEFAULT_SIZE, 126, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(m_jVisible) + .addComponent(m_jBreakName) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 223, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(214, 214, 214)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jBreakName, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(m_Ncx, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_Name3, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(m_jVisible, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 138, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(35, Short.MAX_VALUE)) + ); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JLabel m_Name3; + private javax.swing.JLabel m_Ncx; + private javax.swing.JTextArea m_jBreakDescription; + private javax.swing.JTextField m_jBreakName; + private javax.swing.JCheckBox m_jVisible; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/epm/DataLogicPresenceManagement.java b/src/main/java/com/unicenta/pos/epm/DataLogicPresenceManagement.java new file mode 100644 index 0000000..70642a6 --- /dev/null +++ b/src/main/java/com/unicenta/pos/epm/DataLogicPresenceManagement.java @@ -0,0 +1,450 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.epm; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.*; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.BeanFactoryDataSingle; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +/** + * + * @author Ali Safdar and Aneeqa Baber + */ +public class DataLogicPresenceManagement extends BeanFactoryDataSingle { + + /** + * + */ + protected Session s; + + private SentenceExec m_checkin; + private SentenceExec m_checkout; + private SentenceFind m_checkdate; + + private SentenceList m_breaksvisible; + private SentenceExec m_startbreak; + private SentenceExec m_endbreak; + + private SentenceFind m_isonbreak; + private SentenceFind m_isonleave; + private SentenceFind m_shiftid; + + private SentenceFind m_lastcheckin; + private SentenceFind m_lastcheckout; + private SentenceFind m_startbreaktime; + + private SentenceFind m_lastbreakid; + private SentenceFind m_breakname; + + private SerializerRead breakread; + private TableDefinition tbreaks; + private TableDefinition tleaves; + + /** + * + */ + public DataLogicPresenceManagement() { + } + + /** + * + * @param s + */ + @Override + public void init(Session s){ + + this.s = s; + breakread = new SerializerRead() { + @Override + public Object readValues(DataRead dr) throws BasicException { + return new Break( + dr.getString(1), + dr.getString(2), + dr.getString(3), + dr.getBoolean(4)); + } + }; + + tbreaks = new TableDefinition(s + , "breaks" + , new String[] { "ID", "NAME", "NOTES", "VISIBLE"} + , new String[] { "ID", AppLocal.getIntString("label.epm.employee"), AppLocal.getIntString("label.epm.notes"), "VISIBLE"} + , new Datas[] { Datas.STRING, Datas.STRING, Datas.STRING, Datas.BOOLEAN} + , new Formats[] { Formats.STRING, Formats.STRING, Formats.STRING, Formats.BOOLEAN} + , new int[] {0} + ); + + tleaves = new TableDefinition(s + , "leaves" + , new String[] { "ID", "PPLID", "NAME", "STARTDATE", "ENDDATE", "NOTES"} + , new String[] { "ID", AppLocal.getIntString("label.epm.employee.id"), AppLocal.getIntString("label.epm.employee"), AppLocal.getIntString("label.StartDate"), AppLocal.getIntString("label.EndDate"), AppLocal.getIntString("label.notes")} + , new Datas[] { Datas.STRING, Datas.STRING, Datas.STRING, Datas.TIMESTAMP, Datas.TIMESTAMP, Datas.STRING} + , new Formats[] { Formats.STRING, Formats.STRING, Formats.STRING, Formats.TIMESTAMP, Formats.TIMESTAMP, Formats.STRING} + , new int[] {0} + ); + + m_breaksvisible = new StaticSentence(s + , "SELECT ID, NAME, NOTES, VISIBLE FROM breaks WHERE VISIBLE = " + s.DB.TRUE() + , null + , breakread); + + m_checkin = new PreparedSentence(s + , "INSERT INTO shifts(ID, STARTSHIFT, PPLID) VALUES (?, ?, ?)" + , new SerializerWriteBasic(new Datas[] {Datas.STRING, Datas.TIMESTAMP, Datas.STRING})); + + m_checkout = new StaticSentence(s + , "UPDATE shifts SET ENDSHIFT = ? WHERE ENDSHIFT IS NULL AND PPLID = ?" + ,new SerializerWriteBasic(new Datas[] {Datas.TIMESTAMP, Datas.STRING})); + + m_checkdate = new StaticSentence(s + , "SELECT COUNT(*) FROM shifts WHERE ENDSHIFT IS NULL AND PPLID = ?" + , SerializerWriteString.INSTANCE + , SerializerReadString.INSTANCE); + + m_startbreak = new PreparedSentence(s + , "INSERT INTO shift_breaks(ID, SHIFTID, BREAKID, STARTTIME) VALUES (?, ?, ?, ?)" + , new SerializerWriteBasic(new Datas[] {Datas.STRING, Datas.STRING, Datas.STRING, Datas.TIMESTAMP})); + + m_endbreak = new StaticSentence(s + , "UPDATE shift_breaks SET ENDTIME = ? WHERE ENDTIME IS NULL AND SHIFTID = ?" + ,new SerializerWriteBasic(new Datas[] {Datas.TIMESTAMP, Datas.STRING})); + + m_isonbreak = new StaticSentence(s +// , "SELECT COUNT(*) FROM shift_breaks WHERE ENDTIME IS NULL AND SHIFTID = ?" + , "SELECT COUNT(*) FROM shift_breaks WHERE ENDTIME IS NULL" + , SerializerWriteString.INSTANCE + , SerializerReadString.INSTANCE); + + m_shiftid = new StaticSentence(s + , "SELECT ID FROM shifts WHERE ENDSHIFT IS NULL AND PPLID = ?" + , SerializerWriteString.INSTANCE + , SerializerReadString.INSTANCE); + + m_isonleave = new StaticSentence(s + , "SELECT COUNT(*) FROM leaves WHERE STARTDATE < ? AND ENDDATE > ? AND PPLID = ?" + , new SerializerWriteBasic(new Datas[] {Datas.TIMESTAMP, Datas.TIMESTAMP, Datas.STRING}) + , SerializerReadString.INSTANCE); + + m_lastcheckin = new StaticSentence(s + , "SELECT STARTSHIFT FROM shifts WHERE ENDSHIFT IS NULL AND PPLID = ?" + , SerializerWriteString.INSTANCE + , SerializerReadDate.INSTANCE); + + m_lastcheckout = new StaticSentence(s + , "SELECT MAX(ENDSHIFT) FROM shifts WHERE PPLID = ?" + , SerializerWriteString.INSTANCE + , SerializerReadDate.INSTANCE); + + m_startbreaktime = new StaticSentence(s + , "SELECT STARTTIME FROM shift_breaks WHERE ENDTIME IS NULL AND SHIFTID = ?" + , SerializerWriteString.INSTANCE + , SerializerReadDate.INSTANCE); + + m_lastbreakid = new StaticSentence(s + , "SELECT BREAKID FROM shift_breaks WHERE ENDTIME IS NULL AND SHIFTID = ?" + , SerializerWriteString.INSTANCE + , SerializerReadString.INSTANCE); + + m_breakname = new StaticSentence(s + , "SELECT NAME FROM breaks WHERE ID = ?" + , SerializerWriteString.INSTANCE + , SerializerReadString.INSTANCE); + } + + /** + * + * @return + */ + public final SentenceList getBreaksList() { + return new StaticSentence(s + , "SELECT ID, NAME FROM breaks ORDER BY NAME" + , null + , new SerializerRead() {@Override + public Object readValues(DataRead dr) throws BasicException { + return new BreaksInfo(dr.getString(1), dr.getString(2)); + }}); + } + + /** + * + * @return + */ + public final SentenceList getLeavesList() { + return new StaticSentence(s + , "SELECT ID, PPLID, NAME, STARTDATE, ENDDATE, NOTES FROM leaves ORDER BY NAME" + , null + , new SerializerRead() {@Override + public Object readValues(DataRead dr) throws BasicException { + return new LeavesInfo(dr.getString(1), dr.getString(2), dr.getString(3), dr.getString(4), dr.getString(5), dr.getString(6)); + }}); + } + + /** + * + * @return + * @throws BasicException + */ + public final List listBreaksVisible()throws BasicException { + return m_breaksvisible.list(); + } + + /** + * + * @param user + * @throws BasicException + */ + public final void CheckIn(String user) throws BasicException { + Object[] value = new Object[] {UUID.randomUUID().toString(), new Date(), user}; + m_checkin.exec(value); + } + + /** + * + * @param user + * @throws BasicException + */ + public final void CheckOut(String user) throws BasicException { + Object[] value = new Object[] {new Date(), user}; + m_checkout.exec(value); + } + + /** + * + * @param user + * @return + * @throws BasicException + */ + public final boolean IsCheckedIn(String user) throws BasicException { + String Data = (String) m_checkdate.find(user); + // "0" rows shows user is not checked in + if (Data.equals("0")) { + return false; + } + return true; + } + + /** + * + * @param UserID + * @param BreakID + * @throws BasicException + */ + public final void StartBreak(String UserID, String BreakID) throws BasicException { + String ShiftID = GetShiftID(UserID); + Object[] value = new Object[] {UUID.randomUUID().toString(), ShiftID, BreakID, new Date()}; + m_startbreak.exec(value); + } + + /** + * + * @param UserID + * @throws BasicException + */ + public final void EndBreak(String UserID) throws BasicException { + String ShiftID = GetShiftID(UserID); + Object[] value = new Object[] {new Date(), ShiftID}; + m_endbreak.exec(value); + } + + /** + * + * @param user + * @return + * @throws BasicException + */ + public final boolean IsOnBreak(String user) throws BasicException { + String ShiftID = GetShiftID(user); + String Data = (String) m_isonbreak.find(ShiftID); + // "0" rows shows user is not on break + if (Data.equals("0")) { + return false; + } + return true; + } + + /** + * + * @param user + * @return + * @throws BasicException + */ + public final String GetShiftID(String user) throws BasicException { + return (String) m_shiftid.find(user); + } + + /** + * + * @param user + * @return + * @throws BasicException + */ + public final Date GetLastCheckIn(String user) throws BasicException { + return (Date) m_lastcheckin.find(user); + } + + /** + * + * @param user + * @return + * @throws BasicException + */ + public final Date GetLastCheckOut(String user) throws BasicException { + return (Date) m_lastcheckout.find(user); + } + + /** + * + * @param ShiftID + * @return + * @throws BasicException + */ + public final Date GetStartBreakTime(String ShiftID) throws BasicException { + return (Date) m_startbreaktime.find(ShiftID); + } + + /** + * + * @param ShiftID + * @return + * @throws BasicException + */ + public final String GetLastBreakID(String ShiftID) throws BasicException { + return (String) m_lastbreakid.find(ShiftID); + } + + /** + * + * @param ShiftID + * @return + * @throws BasicException + */ + public final String GetLastBreakName(String ShiftID) throws BasicException { + String BreakID = GetLastBreakID(ShiftID); + return (String) m_breakname.find(BreakID); + } + + /** + * + * @param user + * @return + * @throws BasicException + */ + public final Object [] GetLastBreak(String user) throws BasicException { + String ShiftID = GetShiftID(user); + Date StartBreakTime = GetStartBreakTime(ShiftID); + String BreakName = GetLastBreakName(ShiftID); + return new Object[] {BreakName, StartBreakTime}; + } + + /** + * + * @param user + * @return + * @throws BasicException + */ + public final boolean IsOnLeave(String user) throws BasicException { + Object[] value = new Object[] {new Date(), new Date(), user}; + String Data = (String) m_isonleave.find(value); + // "0" rows shows user is not on leave + if (Data.equals("0")) { + return false; + } + return true; + } + + // EmployeeList list + // Changed ='4' to !='0' --it lists all the users except admin who doesn´t clock in + + /** + * + * @return + */ + public SentenceList getEmployeeList() { + return new StaticSentence(s + , new QBFBuilder("SELECT ID, NAME FROM people WHERE ROLE != '0' AND VISIBLE = " + s.DB.TRUE() + " AND ?(QBF_FILTER) ORDER BY NAME", new String[] {"NAME"}) + , new SerializerWriteBasic(new Datas[] {Datas.OBJECT, Datas.STRING}) + , new SerializerRead() { + @Override + public Object readValues(DataRead dr) throws BasicException { + EmployeeInfo c = new EmployeeInfo(dr.getString(1)); + c.setName(dr.getString(2)); + return c; + } + }); + } + + /** + * + * @param user + * @throws BasicException + */ + public void BlockEmployee(String user) throws BasicException { + boolean isOnBreak = IsOnBreak(user); + if (isOnBreak) { + EndBreak(user); + } + CheckOut(user); + } + + TableDefinition getTableBreaks() { + return tbreaks; + } + + TableDefinition getTableLeaves() { + return tleaves; + } + + /** + * + * @param id + * @return + * @throws BasicException + */ + public EmployeeInfoExt loadEmployeeExt(String id) throws BasicException { + return (EmployeeInfoExt) new PreparedSentence(s + , "SELECT ID, NAME FROM people WHERE ID = ?" + , SerializerWriteString.INSTANCE + , new EmployeeExtRead()).find(id); + } + + /** + * + */ + protected static class EmployeeExtRead implements SerializerRead { + + /** + * + * @param dr + * @return + * @throws BasicException + */ + @Override + public Object readValues(DataRead dr) throws BasicException { + EmployeeInfoExt c = new EmployeeInfoExt(dr.getString(1)); + c.setName(dr.getString(2)); + return c; + } + } +} diff --git a/src/main/java/com/unicenta/pos/epm/EmployeeInfo.java b/src/main/java/com/unicenta/pos/epm/EmployeeInfo.java new file mode 100644 index 0000000..f06c6cd --- /dev/null +++ b/src/main/java/com/unicenta/pos/epm/EmployeeInfo.java @@ -0,0 +1,87 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.epm; + +import com.unicenta.pos.util.StringUtils; +import java.io.Serializable; + +/** + * + * @author Ali Safdar and Aneeqa Baber + */ +public class EmployeeInfo implements Serializable { + + private static final long serialVersionUID = 9083257536541L; + + /** + * + */ + protected String id; + + /** + * + */ + protected String name; + + /** Creates a new instance of EmployeeInfo + * @param id */ + public EmployeeInfo(String id) { + this.id = id; + this.name = null; + } + + /** + * + * @return + */ + public String getId() { + return id; + } + + /** + * + * @return + */ + public String getName() { + return name; + } + + /** + * + * @param name + */ + public void setName(String name) { + this.name = name; + } + + /** + * + * @return + */ + public String printName() { + return StringUtils.encodeXML(name); + } + + @Override + public String toString() { + return getName(); + } +} + diff --git a/src/main/java/com/unicenta/pos/epm/EmployeeInfoExt.java b/src/main/java/com/unicenta/pos/epm/EmployeeInfoExt.java new file mode 100644 index 0000000..f9ff965 --- /dev/null +++ b/src/main/java/com/unicenta/pos/epm/EmployeeInfoExt.java @@ -0,0 +1,54 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.epm; + +/** + * + * @author Ali Safadr and Aneeqa Baber + */ +public class EmployeeInfoExt extends EmployeeInfo { + + /** + * + */ + protected boolean visible; + + /** Creates a new instance of EmployeeInfoExt + * @param id */ + public EmployeeInfoExt(String id) { + super(id); + } + + /** + * + * @return + */ + public boolean isVisible() { + return visible; + } + + /** + * + * @param visible + */ + public void setVisible(boolean visible) { + this.visible = visible; + } +} diff --git a/src/main/java/com/unicenta/pos/epm/EmployeeRenderer.java b/src/main/java/com/unicenta/pos/epm/EmployeeRenderer.java new file mode 100644 index 0000000..08f5823 --- /dev/null +++ b/src/main/java/com/unicenta/pos/epm/EmployeeRenderer.java @@ -0,0 +1,48 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.epm; + +import java.awt.Component; +import javax.swing.DefaultListCellRenderer; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JList; + +/** + * + * @author Ali Safdar and Aneeqa Baber + */ +public class EmployeeRenderer extends DefaultListCellRenderer { + + private Icon icoemployee; + + /** Creates a new instance of EmployeeRenderer */ + public EmployeeRenderer() { + icoemployee = new ImageIcon(getClass().getClassLoader().getResource("com/unicenta/images/user.png")); + } + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, null, index, isSelected, cellHasFocus); + setText(value.toString()); + setIcon(icoemployee); + return this; + } +} diff --git a/src/main/java/com/unicenta/pos/epm/JEmployeeFinder.form b/src/main/java/com/unicenta/pos/epm/JEmployeeFinder.form new file mode 100644 index 0000000..753d1c5 --- /dev/null +++ b/src/main/java/com/unicenta/pos/epm/JEmployeeFinder.form @@ -0,0 +1,288 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="form.customertitle" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-17,0,0,2,-85"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="After"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Component class="com.unicenta.editor.JEditorKeys" name="m_jKeys"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + </Component> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Last"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JButton" name="jcmdCancel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="Button.Cancel" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jcmdCancelActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jcmdOK"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="Button.OK" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jcmdOKActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="First"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel7"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel5" min="-2" pref="126" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="m_jtxtName" min="-2" pref="220" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel5" alignment="0" min="-2" pref="25" max="-2" attributes="0"/> + <Component id="m_jtxtName" alignment="0" min="-2" pref="25" max="-2" attributes="0"/> + </Group> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.epm.employee" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jtxtName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel6"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JButton" name="jButton1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/reload.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.clean" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton1ActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jButton3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.executefilter" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton3ActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JScrollPane" name="jScrollPane1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JList" name="jListEmployees"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="focusable" type="boolean" value="false"/> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="jListEmployeesMouseClicked"/> + <EventHandler event="valueChanged" listener="javax.swing.event.ListSelectionListener" parameters="javax.swing.event.ListSelectionEvent" handler="jListEmployeesValueChanged"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel8"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/epm/JEmployeeFinder.java b/src/main/java/com/unicenta/pos/epm/JEmployeeFinder.java new file mode 100644 index 0000000..c6e4509 --- /dev/null +++ b/src/main/java/com/unicenta/pos/epm/JEmployeeFinder.java @@ -0,0 +1,383 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.epm; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.QBFCompareEnum; +import com.unicenta.data.user.EditorCreator; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.pos.forms.AppLocal; +import java.awt.*; +import java.util.ArrayList; +import javax.swing.JFrame; + +/** + * + * @author Ali Safdar and Aneeqa Baber + */ +public class JEmployeeFinder extends javax.swing.JDialog implements EditorCreator { + + private EmployeeInfo selectedEmployee; + private ListProvider lpr; + + /** Creates new form JEmployeeFinder */ + private JEmployeeFinder(java.awt.Frame parent, boolean modal) { + super(parent, modal); + } + + /** Creates new form JEmployeeFinder */ + private JEmployeeFinder(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + } + + /** + * + * @param parent + * @param dlPresenceManagement + * @return + */ + public static JEmployeeFinder getEmployeeFinder(Component parent, DataLogicPresenceManagement dlPresenceManagement) { + Window window = getWindow(parent); + JEmployeeFinder myMsg; + if (window instanceof Frame) { + myMsg = new JEmployeeFinder((Frame) window, true); + } else { + myMsg = new JEmployeeFinder((Dialog) window, true); + } + myMsg.init(dlPresenceManagement); + myMsg.applyComponentOrientation(parent.getComponentOrientation()); + return myMsg; + } + + /** + * + * @return + */ + public EmployeeInfo getSelectedEmployee() { + return selectedEmployee; + } + + private void init(DataLogicPresenceManagement dlPresenceManagement) { + initComponents(); + jScrollPane1.getVerticalScrollBar().setPreferredSize(new Dimension(35, 35)); + m_jtxtName.addEditorKeys(m_jKeys); + m_jtxtName.reset(); + lpr = new ListProviderCreator(dlPresenceManagement.getEmployeeList(), this); + jListEmployees.setCellRenderer(new EmployeeRenderer()); + getRootPane().setDefaultButton(jcmdOK); + selectedEmployee = null; + } + + /** + * + * @param employee + */ + public void search(EmployeeInfo employee) { + if (employee == null || employee.getName() == null || employee.getName().equals("")) { + m_jtxtName.reset(); + cleanSearch(); + } else { + m_jtxtName.setText(employee.getName()); + executeSearch(); + } + } + + private void cleanSearch() { + jListEmployees.setModel(new MyListData(new ArrayList())); + } + + /** + * + */ + public void executeSearch() { + try { + jListEmployees.setModel(new MyListData(lpr.loadData())); + if (jListEmployees.getModel().getSize() > 0) { + jListEmployees.setSelectedIndex(0); + } + } catch (BasicException e) { + } + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + Object[] afilter = new Object[2]; + // Name + if (m_jtxtName.getText() == null || m_jtxtName.getText().equals("")) { + afilter[0] = QBFCompareEnum.COMP_NONE; + afilter[1] = null; + } else { + afilter[0] = QBFCompareEnum.COMP_RE; + afilter[1] = "%" + m_jtxtName.getText() + "%"; + } + return afilter; + } + + private static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window) parent; + } else { + return getWindow(parent.getParent()); + } + } + + private static class MyListData extends javax.swing.AbstractListModel { + private java.util.List m_data; + public MyListData(java.util.List data) { + m_data = data; + } + + @Override + public Object getElementAt(int index) { + return m_data.get(index); + } + + @Override + public int getSize() { + return m_data.size(); + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel2 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel1 = new javax.swing.JPanel(); + jcmdCancel = new javax.swing.JButton(); + jcmdOK = new javax.swing.JButton(); + jPanel3 = new javax.swing.JPanel(); + jPanel5 = new javax.swing.JPanel(); + jPanel7 = new javax.swing.JPanel(); + jLabel5 = new javax.swing.JLabel(); + m_jtxtName = new com.unicenta.editor.JEditorString(); + jPanel6 = new javax.swing.JPanel(); + jButton1 = new javax.swing.JButton(); + jButton3 = new javax.swing.JButton(); + jPanel4 = new javax.swing.JPanel(); + jScrollPane1 = new javax.swing.JScrollPane(); + jListEmployees = new javax.swing.JList(); + jPanel8 = new javax.swing.JPanel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(AppLocal.getIntString("form.customertitle")); // NOI18N + + jPanel2.setLayout(new java.awt.BorderLayout()); + jPanel2.add(m_jKeys, java.awt.BorderLayout.NORTH); + + jcmdCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + jcmdCancel.setText(AppLocal.getIntString("button.cancel")); // NOI18N + jcmdCancel.setFocusPainted(false); + jcmdCancel.setFocusable(false); + jcmdCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdCancel.setPreferredSize(new java.awt.Dimension(110, 45)); + jcmdCancel.setRequestFocusEnabled(false); + jcmdCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdCancelActionPerformed(evt); + } + }); + jPanel1.add(jcmdCancel); + + jcmdOK.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jcmdOK.setText(AppLocal.getIntString("button.OK")); // NOI18N + jcmdOK.setEnabled(false); + jcmdOK.setFocusPainted(false); + jcmdOK.setFocusable(false); + jcmdOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdOK.setPreferredSize(new java.awt.Dimension(110, 45)); + jcmdOK.setRequestFocusEnabled(false); + jcmdOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdOKActionPerformed(evt); + } + }); + jPanel1.add(jcmdOK); + + jPanel2.add(jPanel1, java.awt.BorderLayout.PAGE_END); + + getContentPane().add(jPanel2, java.awt.BorderLayout.LINE_END); + + jPanel3.setLayout(new java.awt.BorderLayout()); + + jPanel5.setLayout(new java.awt.BorderLayout()); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.epm.employee")); // NOI18N + + m_jtxtName.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + + javax.swing.GroupLayout jPanel7Layout = new javax.swing.GroupLayout(jPanel7); + jPanel7.setLayout(jPanel7Layout); + jPanel7Layout.setHorizontalGroup( + jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel7Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 126, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(m_jtxtName, javax.swing.GroupLayout.PREFERRED_SIZE, 220, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel7Layout.setVerticalGroup( + jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel7Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jtxtName, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + jPanel5.add(jPanel7, java.awt.BorderLayout.CENTER); + + jButton1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jButton1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reload.png"))); // NOI18N + jButton1.setText(AppLocal.getIntString("button.clean")); // NOI18N + jButton1.setPreferredSize(new java.awt.Dimension(110, 45)); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + jPanel6.add(jButton1); + + jButton3.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jButton3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jButton3.setText(AppLocal.getIntString("button.executefilter")); // NOI18N + jButton3.setFocusPainted(false); + jButton3.setFocusable(false); + jButton3.setPreferredSize(new java.awt.Dimension(110, 45)); + jButton3.setRequestFocusEnabled(false); + jButton3.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton3ActionPerformed(evt); + } + }); + jPanel6.add(jButton3); + + jPanel5.add(jPanel6, java.awt.BorderLayout.SOUTH); + + jPanel3.add(jPanel5, java.awt.BorderLayout.PAGE_START); + + jPanel4.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel4.setLayout(new java.awt.BorderLayout()); + + jListEmployees.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jListEmployees.setFocusable(false); + jListEmployees.setRequestFocusEnabled(false); + jListEmployees.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + jListEmployeesMouseClicked(evt); + } + }); + jListEmployees.addListSelectionListener(new javax.swing.event.ListSelectionListener() { + public void valueChanged(javax.swing.event.ListSelectionEvent evt) { + jListEmployeesValueChanged(evt); + } + }); + jScrollPane1.setViewportView(jListEmployees); + + jPanel4.add(jScrollPane1, java.awt.BorderLayout.CENTER); + + jPanel3.add(jPanel4, java.awt.BorderLayout.CENTER); + + jPanel8.setLayout(new java.awt.BorderLayout()); + jPanel3.add(jPanel8, java.awt.BorderLayout.SOUTH); + + getContentPane().add(jPanel3, java.awt.BorderLayout.CENTER); + + setSize(new java.awt.Dimension(683, 495)); + setLocationRelativeTo(null); + }// </editor-fold>//GEN-END:initComponents + private void jcmdOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdOKActionPerformed + + selectedEmployee = (EmployeeInfo) jListEmployees.getSelectedValue(); + dispose(); + + }//GEN-LAST:event_jcmdOKActionPerformed + + private void jcmdCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdCancelActionPerformed + + dispose(); + + }//GEN-LAST:event_jcmdCancelActionPerformed + + private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed + + executeSearch(); + + }//GEN-LAST:event_jButton3ActionPerformed + + private void jListEmployeesValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_jListEmployeesValueChanged + + jcmdOK.setEnabled(jListEmployees.getSelectedValue() != null); + +}//GEN-LAST:event_jListEmployeesValueChanged + + private void jListEmployeesMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jListEmployeesMouseClicked + + if (evt.getClickCount() == 2) { + selectedEmployee = (EmployeeInfo) jListEmployees.getSelectedValue(); + dispose(); + } + +}//GEN-LAST:event_jListEmployeesMouseClicked + +private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + + m_jtxtName.reset(); + cleanSearch(); +}//GEN-LAST:event_jButton1ActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + private javax.swing.JButton jButton3; + private javax.swing.JLabel jLabel5; + private javax.swing.JList jListEmployees; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JPanel jPanel6; + private javax.swing.JPanel jPanel7; + private javax.swing.JPanel jPanel8; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JButton jcmdCancel; + private javax.swing.JButton jcmdOK; + private com.unicenta.editor.JEditorKeys m_jKeys; + private com.unicenta.editor.JEditorString m_jtxtName; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/epm/JPanelEmployeePresence.form b/src/main/java/com/unicenta/pos/epm/JPanelEmployeePresence.form new file mode 100644 index 0000000..56a112d --- /dev/null +++ b/src/main/java/com/unicenta/pos/epm/JPanelEmployeePresence.form @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 45]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="btnCheckIn" min="-2" pref="256" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + <Component id="btnCheckOut" min="-2" pref="248" max="-2" attributes="0"/> + </Group> + <Component id="jScrollPane1" alignment="0" max="32767" attributes="0"/> + <Component id="message" alignment="1" max="32767" attributes="0"/> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="message" min="-2" pref="50" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="btnCheckIn" alignment="3" min="-2" pref="49" max="-2" attributes="0"/> + <Component id="btnCheckOut" alignment="3" min="-2" pref="49" max="-2" attributes="0"/> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="jScrollPane1" min="-2" max="-2" attributes="0"/> + <EmptySpace pref="80" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="btnCheckIn"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="Check In"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[85, 23]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnCheckInActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="btnCheckOut"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="Check Out"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnCheckOutActionPerformed"/> + </Events> + </Component> + <Container class="javax.swing.JScrollPane" name="jScrollPane1"> + <Properties> + <Property name="horizontalScrollBarPolicy" type="int" value="31"/> + <Property name="verticalScrollBarPolicy" type="int" value="22"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[570, 120]"/> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + </Container> + <Component class="javax.swing.JLabel" name="message"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" id="white" palette="0" red="ff" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 25]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/epm/JPanelEmployeePresence.java b/src/main/java/com/unicenta/pos/epm/JPanelEmployeePresence.java new file mode 100644 index 0000000..12378ef --- /dev/null +++ b/src/main/java/com/unicenta/pos/epm/JPanelEmployeePresence.java @@ -0,0 +1,327 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + + +package com.unicenta.pos.epm; + +import com.unicenta.basic.BasicException; +import com.unicenta.beans.JFlowPanel; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.*; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.util.Date; +import javax.swing.*; + +/** + * + * @author Ali Safdar and Aneeqa Baber + */ +public class JPanelEmployeePresence extends javax.swing.JPanel implements JPanelView, BeanFactoryApp { + + private AppView app; + private DataLogicPresenceManagement dlpresencemanagement; + private JFlowPanel jBreaks; + + /** Creates new form JPanelEmployeePresence */ + public JPanelEmployeePresence() { + initComponents(); + this.setVisible(true); + } + + /** + * + * @param app + * @throws BeanFactoryException + */ + @Override + public void init(AppView app) throws BeanFactoryException { + this.app = app; + dlpresencemanagement = (DataLogicPresenceManagement) app.getBean("com.unicenta.pos.epm.DataLogicPresenceManagement"); + } + + private void listBreaks() + { + try { + jScrollPane1.getViewport().setView(null); + jBreaks = new JFlowPanel(); + jBreaks.applyComponentOrientation(getComponentOrientation()); + java.util.List breaks = dlpresencemanagement.listBreaksVisible(); + for (int i = 0; i < breaks.size(); i++) { + + Break m_break = (Break) breaks.get(i); + + JButton btn = new JButton(new BreakAction(m_break)); + btn.applyComponentOrientation(getComponentOrientation()); + btn.setFocusPainted(false); + btn.setFocusable(false); + btn.setRequestFocusEnabled(false); + btn.setHorizontalAlignment(SwingConstants.LEADING); + btn.setMaximumSize(new Dimension(190, 50)); + btn.setPreferredSize(new Dimension(190, 50)); + btn.setMinimumSize(new Dimension(190, 50)); + + jBreaks.add(btn); + } + jScrollPane1.getViewport().setView(jBreaks); + + } catch (BasicException ee) { + } + } + + private class BreakAction extends AbstractAction { + + private Break m_break; + + public BreakAction(Break aBreak) { + m_break = aBreak; + putValue(Action.NAME, m_break.getName()); + } + + public Break getBreak() { + return m_break; + } + + @Override + public void actionPerformed(ActionEvent evt) { + try { + dlpresencemanagement.StartBreak(app.getAppUserView().getUser().getId(), m_break.getId()); + message.setText(app.getAppUserView().getUser().getName()+" "+AppLocal.getIntString("message.leavefor")+" "+ m_break.getName()+" "+AppLocal.getIntString("message.at")+" "+Formats.TIMESTAMP.formatValue(new Date())); + BreakAction(); + } catch (BasicException ex) { + message.setText(AppLocal.getIntString("message.probleminbreak")); + } + } + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.CheckInCheckOut"); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + boolean isOnLeave = dlpresencemanagement.IsOnLeave(app.getAppUserView().getUser().getId()); + listBreaks(); + if (isOnLeave) { + message.setText(app.getAppUserView().getUser().getName()+" "+AppLocal.getIntString("message.leavecontrol")); + LeaveAction(); + } else { + boolean isCheckedIn = dlpresencemanagement.IsCheckedIn(app.getAppUserView().getUser().getId()); + if (isCheckedIn) { + Date lastCheckIn = dlpresencemanagement.GetLastCheckIn(app.getAppUserView().getUser().getId()); + message.setText(app.getAppUserView().getUser().getName()+" "+AppLocal.getIntString("message.checkedin")+" "+Formats.TIMESTAMP.formatValue(lastCheckIn)); + CheckInAction(); + } else { + Date lastCheckOut = dlpresencemanagement.GetLastCheckOut(app.getAppUserView().getUser().getId()); + if (lastCheckOut != null) { + message.setText(app.getAppUserView().getUser().getName()+" "+AppLocal.getIntString("message.checkedout")+" "+Formats.TIMESTAMP.formatValue(lastCheckOut)); + } else { + message.setText(app.getAppUserView().getUser().getName()+" "+AppLocal.getIntString("message.noshift")); + } + CheckOutAction(); + } + boolean isOnBreak = dlpresencemanagement.IsOnBreak(app.getAppUserView().getUser().getId()); + if (isOnBreak) { + Object[] LastBreak = (Object[]) dlpresencemanagement.GetLastBreak(app.getAppUserView().getUser().getId()); + message.setText(app.getAppUserView().getUser().getName()+" "+AppLocal.getIntString("message.leavefor")+" "+(String) LastBreak[0] +" "+AppLocal.getIntString("message.at")+" "+ Formats.TIMESTAMP.formatValue((Date) LastBreak[1])); + BreakAction(); + } + } + } + + /** + * + * @return + */ + @Override + public boolean deactivate() { + return true; + } + + /** + * + * @return + */ + @Override + public JComponent getComponent() { + return this; + } + + /** + * + * @return + */ + @Override + public Object getBean() { + return this; + } + + private void CheckInAction() { + btnCheckIn.setEnabled(false); + btnCheckOut.setEnabled(true); + jBreaks.setEnabled(true); + } + + private void CheckOutAction() { + btnCheckIn.setEnabled(true); + btnCheckOut.setEnabled(false); + jBreaks.setEnabled(false); + } + + private void BreakAction() { + btnCheckIn.setEnabled(true); + btnCheckOut.setEnabled(true); + jBreaks.setEnabled(false); + } + + private void LeaveAction() { + btnCheckIn.setEnabled(false); + btnCheckOut.setEnabled(false); + jBreaks.setEnabled(false); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + btnCheckIn = new javax.swing.JButton(); + btnCheckOut = new javax.swing.JButton(); + jScrollPane1 = new javax.swing.JScrollPane(); + message = new javax.swing.JLabel(); + + setPreferredSize(new java.awt.Dimension(0, 45)); + + btnCheckIn.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + btnCheckIn.setText("Check In"); + btnCheckIn.setMaximumSize(new java.awt.Dimension(85, 23)); + btnCheckIn.setPreferredSize(new java.awt.Dimension(0, 45)); + btnCheckIn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnCheckInActionPerformed(evt); + } + }); + + btnCheckOut.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + btnCheckOut.setText("Check Out"); + btnCheckOut.setPreferredSize(new java.awt.Dimension(0, 45)); + btnCheckOut.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnCheckOutActionPerformed(evt); + } + }); + + jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + jScrollPane1.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + jScrollPane1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jScrollPane1.setPreferredSize(new java.awt.Dimension(570, 120)); + + message.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + message.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + message.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + message.setOpaque(true); + message.setPreferredSize(new java.awt.Dimension(160, 25)); + message.setRequestFocusEnabled(false); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(btnCheckIn, javax.swing.GroupLayout.PREFERRED_SIZE, 256, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnCheckOut, javax.swing.GroupLayout.PREFERRED_SIZE, 248, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(message, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(message, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(btnCheckIn, javax.swing.GroupLayout.PREFERRED_SIZE, 49, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(btnCheckOut, javax.swing.GroupLayout.PREFERRED_SIZE, 49, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(80, Short.MAX_VALUE)) + ); + }// </editor-fold>//GEN-END:initComponents + + private void btnCheckInActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCheckInActionPerformed + try { + boolean isOnBreak = dlpresencemanagement.IsOnBreak(app.getAppUserView().getUser().getId()); + if (isOnBreak) { + dlpresencemanagement.EndBreak(app.getAppUserView().getUser().getId()); + message.setText(app.getAppUserView().getUser().getName()+AppLocal.getIntString("message.breakoverandcheckedin")+" "+Formats.TIMESTAMP.formatValue(new Date())); + } else { + dlpresencemanagement.CheckIn(app.getAppUserView().getUser().getId()); + message.setText(app.getAppUserView().getUser().getName()+" "+AppLocal.getIntString("message.checkedin")+" "+Formats.TIMESTAMP.formatValue(new Date())); + } + } catch (BasicException ex) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotcheckin")); + msg.show(this); + } + CheckInAction(); +}//GEN-LAST:event_btnCheckInActionPerformed + + private void btnCheckOutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCheckOutActionPerformed + try { + boolean isOnBreak = dlpresencemanagement.IsOnBreak(app.getAppUserView().getUser().getId()); + if (isOnBreak) { + dlpresencemanagement.EndBreak(app.getAppUserView().getUser().getId()); + message.setText(app.getAppUserView().getUser().getName()+" "+AppLocal.getIntString("message.breakoverandcheckedout")+" "+Formats.TIMESTAMP.formatValue(new Date())); + } else { + message.setText(app.getAppUserView().getUser().getName()+" "+AppLocal.getIntString("message.checkedout")+" "+Formats.TIMESTAMP.formatValue(new Date())); + } + dlpresencemanagement.CheckOut(app.getAppUserView().getUser().getId()); + } catch (BasicException ex) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotcheckout")); + msg.show(this); + } + CheckOutAction(); +}//GEN-LAST:event_btnCheckOutActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btnCheckIn; + private javax.swing.JButton btnCheckOut; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JLabel message; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/epm/LeavesInfo.java b/src/main/java/com/unicenta/pos/epm/LeavesInfo.java new file mode 100644 index 0000000..ca07052 --- /dev/null +++ b/src/main/java/com/unicenta/pos/epm/LeavesInfo.java @@ -0,0 +1,164 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.epm; + +import com.unicenta.data.loader.IKeyed; + +/** + * + * @author Ali Safdar and Aneeqa Baber + */ +public class LeavesInfo implements IKeyed { + + private static final long serialVersionUID = 8936482715929L; + private String m_sID; + private String m_sName; + private String m_sEmployeeID; + private String m_sStartDate; + private String m_sEndDate; + private String m_sNotes; + + + /** Creates new LeavesInfo + * @param id + * @param name + * @param notes + * @param startdate + * @param employeeid + * @param enddate */ + public LeavesInfo(String id, String name, String employeeid, String startdate, String enddate, String notes) { + m_sID = id; + m_sName = name; + m_sEmployeeID = employeeid; + m_sStartDate = startdate; + m_sEndDate = enddate; + m_sNotes = notes; + } + + /** + * + * @return + */ + @Override + public Object getKey() { + return m_sID; + } + + /** + * + * @param sID + */ + public void setID(String sID) { + m_sID = sID; + } + + /** + * + * @return + */ + public String getID() { + return m_sID; + } + + /** + * + * @return + */ + public String getName() { + return m_sName; + } + + /** + * + * @param sName + */ + public void setName(String sName) { + m_sName = sName; + } + + @Override + public String toString(){ + return m_sName; + } + + /** + * + * @return + */ + public String getEmployeeID() { + return m_sEmployeeID; + } + + /** + * + * @param EmployeeID + */ + public void setEmployeeID(String EmployeeID) { + this.m_sEmployeeID = EmployeeID; + } + + /** + * + * @return + */ + public String getStartDate() { + return m_sStartDate; + } + + /** + * + * @param StartDate + */ + public void setStartDate(String StartDate) { + this.m_sStartDate = StartDate; + } + + /** + * + * @return + */ + public String getEndDate() { + return m_sEndDate; + } + + /** + * + * @param EndDate + */ + public void setEndDate(String EndDate) { + this.m_sEndDate = EndDate; + } + + /** + * + * @return + */ + public String getNotes() { + return m_sNotes; + } + + /** + * + * @param Notes + */ + public void setNotes(String Notes) { + this.m_sNotes = Notes; + } +} diff --git a/src/main/java/com/unicenta/pos/epm/LeavesPanel.java b/src/main/java/com/unicenta/pos/epm/LeavesPanel.java new file mode 100644 index 0000000..f06af70 --- /dev/null +++ b/src/main/java/com/unicenta/pos/epm/LeavesPanel.java @@ -0,0 +1,130 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.epm; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ListCellRendererBasic; +import com.unicenta.data.loader.ComparatorCreator; +import com.unicenta.data.loader.TableDefinition; +import com.unicenta.data.loader.Vectorer; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.panels.JPanelTable; +import javax.swing.ListCellRenderer; + +/** + * + * @author Ali Safdar and Aneeqa Baber + */ +public class LeavesPanel extends JPanelTable { + + private TableDefinition tleaves; + private LeavesView jeditor; + + /** Creates a new instance of LeavesPanel */ + public LeavesPanel() { + } + + /** + * + */ + @Override + protected void init() { + DataLogicPresenceManagement dlPresenceManagement = (DataLogicPresenceManagement) app.getBean("com.unicenta.pos.epm.DataLogicPresenceManagement"); + tleaves = dlPresenceManagement.getTableLeaves(); + jeditor = new LeavesView(app, dirty); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + jeditor.activate(); + super.activate(); + } + + /** + * + * @return + */ + @Override + public ListProvider getListProvider() { + return new ListProviderCreator(tleaves); + } + + /** + * + * @return + */ + @Override + public SaveProvider getSaveProvider() { + return new SaveProvider(tleaves, new int[] {0, 1, 2, 3, 4, 5}); + } + + /** + * + * @return + */ + @Override + public Vectorer getVectorer() { + return tleaves.getVectorerBasic(new int[]{2, 5}); + } + + /** + * + * @return + */ + @Override + public ComparatorCreator getComparatorCreator() { + return tleaves.getComparatorCreator(new int[] {2, 3, 4, 5}); + } + + /** + * + * @return + */ + @Override + public ListCellRenderer getListCellRenderer() { + return new ListCellRendererBasic(tleaves.getRenderStringBasic(new int[]{2})); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return jeditor; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.Leaves"); + } +} diff --git a/src/main/java/com/unicenta/pos/epm/LeavesView.form b/src/main/java/com/unicenta/pos/epm/LeavesView.form new file mode 100644 index 0000000..49c8fe4 --- /dev/null +++ b/src/main/java/com/unicenta/pos/epm/LeavesView.form @@ -0,0 +1,237 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="m_Notes" alignment="1" pref="126" max="32767" attributes="1"/> + <Component id="m_EndDate" pref="126" max="32767" attributes="1"/> + <Component id="m_StartDate" alignment="0" pref="126" max="32767" attributes="1"/> + <Component id="m_Name" alignment="0" pref="126" max="32767" attributes="1"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="m_jEndDate" alignment="0" max="32767" attributes="1"/> + <Component id="m_jStartDate" max="32767" attributes="1"/> + <Component id="m_jEmployeeName" alignment="0" pref="172" max="32767" attributes="1"/> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="btnStartDate" alignment="0" max="32767" attributes="1"/> + <Component id="btnEmployee" alignment="0" max="32767" attributes="1"/> + <Component id="btnEndDate" alignment="0" max="32767" attributes="1"/> + </Group> + </Group> + <Component id="jScrollPane1" pref="258" max="32767" attributes="1"/> + </Group> + <EmptySpace min="-2" pref="77" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" alignment="0" groupAlignment="3" attributes="0"> + <Component id="m_Name" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jEmployeeName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="btnEmployee" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" alignment="0" groupAlignment="3" attributes="0"> + <Component id="m_StartDate" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jStartDate" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="btnStartDate" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="btnEndDate" min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_EndDate" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jEndDate" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace type="separate" max="32767" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_Notes" min="-2" pref="25" max="-2" attributes="0"/> + <Component id="jScrollPane1" min="-2" pref="141" max="-2" attributes="0"/> + </Group> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JTextField" name="m_jEmployeeName"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Container class="javax.swing.JScrollPane" name="jScrollPane1"> + <AuxValues> + <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JTextArea" name="m_jLeaveNote"> + <Properties> + <Property name="columns" type="int" value="20"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Monospaced" size="14" style="0"/> + </Property> + <Property name="lineWrap" type="boolean" value="true"/> + <Property name="rows" type="int" value="5"/> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JLabel" name="m_Name"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.epm.employee" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_StartDate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.epm.startdate" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_EndDate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.epm.enddate" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jStartDate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_Notes"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.epm.notes" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="btnEmployee"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/user_sml.png"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[57, 33]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[57, 33]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnEmployeeActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="btnEndDate"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/date.png"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnEndDateActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="btnStartDate"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/date.png"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnStartDateActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JTextField" name="m_jEndDate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/epm/LeavesView.java b/src/main/java/com/unicenta/pos/epm/LeavesView.java new file mode 100644 index 0000000..94e3588 --- /dev/null +++ b/src/main/java/com/unicenta/pos/epm/LeavesView.java @@ -0,0 +1,432 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.epm; + +import com.unicenta.basic.BasicException; +import com.unicenta.beans.JCalendarDialog; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import java.awt.Component; +import java.util.Date; +import java.util.List; +import java.util.UUID; +import java.util.Calendar; + +/** + * + * @author Ali Safdar and Aneeqa Baber + */ +public final class LeavesView extends javax.swing.JPanel implements EditorRecord { + + private Object m_oId; + private Object m_employeeid; + private SentenceList m_sentcat; + + private DirtyManager m_Dirty; + private DataLogicPresenceManagement dlPresenceManagement; + + /** Creates new form LeavesView + * @param app + * @param dirty */ + public LeavesView(AppView app, DirtyManager dirty) { + + dlPresenceManagement = (DataLogicPresenceManagement) app.getBean("com.unicenta.pos.epm.DataLogicPresenceManagement"); + initComponents(); + + m_sentcat = dlPresenceManagement.getLeavesList(); + m_Dirty = dirty; + m_jEmployeeName.getDocument().addDocumentListener(dirty); + m_jStartDate.getDocument().addDocumentListener(dirty); + m_jEndDate.getDocument().addDocumentListener(dirty); + m_jLeaveNote.getDocument().addDocumentListener(dirty); + writeValueEOF(); + } + + void activate() throws BasicException { + List a = m_sentcat.list(); + a.add(0, null); + } + + /** + * + */ + @Override + public void writeValueEOF() { + m_oId = null; + m_jEmployeeName.setText(null); + m_jStartDate.setText(null); + m_jEndDate.setText(null); + m_jLeaveNote.setText(null); + m_jEmployeeName.setEditable(false); + m_jStartDate.setEnabled(false); + m_jEndDate.setEnabled(false); + m_jLeaveNote.setEnabled(false); + } + + /** + * + */ + @Override + public void writeValueInsert() { + m_oId = null; + m_jEmployeeName.setText(null); + m_jStartDate.setText(null); + m_jEndDate.setText(null); + m_jLeaveNote.setText(null); + m_jEmployeeName.setEditable(true); + m_jStartDate.setEnabled(true); + m_jEndDate.setEnabled(true); + m_jLeaveNote.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueEdit(Object value) { + Object[] leaves = (Object[]) value; + m_oId = leaves[0]; + m_employeeid = leaves[1]; + m_jEmployeeName.setText((String) leaves[2]); + m_jStartDate.setText(Formats.TIMESTAMP.formatValue((Date) leaves[3])); + m_jEndDate.setText(Formats.TIMESTAMP.formatValue((Date) leaves[4])); + m_jLeaveNote.setText((String) leaves[5]); + m_jEmployeeName.setEditable(true); + m_jStartDate.setEnabled(true); + m_jEndDate.setEnabled(true); + m_jLeaveNote.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueDelete(Object value) { + Object[] leaves = (Object[]) value; + m_oId = leaves[0]; + m_employeeid = leaves[1]; + m_jEmployeeName.setText((String) leaves[2]); + m_jStartDate.setText(Formats.TIMESTAMP.formatValue((Date) leaves[3])); + m_jEndDate.setText(Formats.TIMESTAMP.formatValue((Date) leaves[4])); + m_jLeaveNote.setText((String) leaves[5]); + m_jEmployeeName.setEditable(false); + m_jStartDate.setEnabled(false); + m_jEndDate.setEnabled(false); + m_jLeaveNote.setEnabled(false); + } + + /** + * + */ + @Override + public void refresh() { + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + Object[] leaves = new Object[6]; + leaves[0] = m_oId == null ? UUID.randomUUID().toString() : m_oId; + leaves[1] = m_employeeid; + leaves[2] = m_jEmployeeName.getText(); + leaves[3] = (Date) Formats.TIMESTAMP.parseValue(m_jStartDate.getText()); + leaves[4] = (Date) Formats.TIMESTAMP.parseValue(m_jEndDate.getText()); + leaves[5] = m_jLeaveNote.getText(); + boolean isCheckedIn = dlPresenceManagement.IsCheckedIn((String) m_employeeid); + Date startDate = (Date) Formats.TIMESTAMP.parseValue(m_jStartDate.getText()); + Date endDate = (Date) Formats.TIMESTAMP.parseValue(m_jEndDate.getText()); + Date systemDate = new Date(); + if (isCheckedIn && startDate.before(systemDate) && endDate.after(systemDate)) { + dlPresenceManagement.BlockEmployee((String) m_employeeid); + } + return leaves; + } +// TODO - rewrite IsValidEndDate using Apache commons or Calendar + + private boolean IsValidEndDate(Date date) { + Date systemDate = new Date(); + if (! m_jStartDate.getText().equals("")) { + Date startdate; + try { + startdate = (Date) Formats.TIMESTAMP.parseValue(m_jStartDate.getText()); + return (startdate.before(date) + || (startdate.getDate() == date.getDate() + && startdate.getMonth() == date.getMonth() + && startdate.getYear() == date.getYear())); + + } catch (BasicException ex) { + } + } + return (systemDate.before(date) + || (systemDate.getDate() == date.getDate() + && systemDate.getMonth() == date.getMonth() + && systemDate.getYear() == date.getYear())); + } + +// TODO - rewrite IsValidStartDate using Apache commons or Calendar + + private boolean IsValidStartDate(Date date) { + Date systemDate = new Date(); + boolean validEndDate = true; + if (! m_jEndDate.getText().equals("")) { + try { + Date enddate = (Date) Formats.TIMESTAMP.parseValue(m_jEndDate.getText()); + validEndDate = (enddate.after(date) + || (enddate.getDate() == date.getDate() + && enddate.getMonth() == date.getMonth() + && enddate.getYear() == date.getYear())); + } catch (BasicException ex) { + } + } + return validEndDate && (systemDate.before(date) + || (systemDate.getDate() == date.getDate() + && systemDate.getMonth() == date.getMonth() + && systemDate.getYear() == date.getYear())); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jEmployeeName = new javax.swing.JTextField(); + jScrollPane1 = new javax.swing.JScrollPane(); + m_jLeaveNote = new javax.swing.JTextArea(); + m_Name = new javax.swing.JLabel(); + m_StartDate = new javax.swing.JLabel(); + m_EndDate = new javax.swing.JLabel(); + m_jStartDate = new javax.swing.JTextField(); + m_Notes = new javax.swing.JLabel(); + btnEmployee = new javax.swing.JButton(); + btnEndDate = new javax.swing.JButton(); + btnStartDate = new javax.swing.JButton(); + m_jEndDate = new javax.swing.JTextField(); + + m_jEmployeeName.setEditable(false); + m_jEmployeeName.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jEmployeeName.setPreferredSize(new java.awt.Dimension(0, 30)); + + m_jLeaveNote.setColumns(20); + m_jLeaveNote.setFont(new java.awt.Font("Monospaced", 0, 14)); // NOI18N + m_jLeaveNote.setLineWrap(true); + m_jLeaveNote.setRows(5); + jScrollPane1.setViewportView(m_jLeaveNote); + + m_Name.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + m_Name.setText(bundle.getString("label.epm.employee")); // NOI18N + m_Name.setPreferredSize(new java.awt.Dimension(0, 30)); + + m_StartDate.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_StartDate.setText(AppLocal.getIntString("label.epm.startdate")); // NOI18N + m_StartDate.setPreferredSize(new java.awt.Dimension(0, 30)); + + m_EndDate.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_EndDate.setText(AppLocal.getIntString("label.epm.enddate")); // NOI18N + m_EndDate.setPreferredSize(new java.awt.Dimension(0, 30)); + + m_jStartDate.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jStartDate.setPreferredSize(new java.awt.Dimension(0, 30)); + + m_Notes.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_Notes.setText(AppLocal.getIntString("label.epm.notes")); // NOI18N + m_Notes.setPreferredSize(new java.awt.Dimension(0, 30)); + + btnEmployee.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/user_sml.png"))); // NOI18N + btnEmployee.setFocusPainted(false); + btnEmployee.setFocusable(false); + btnEmployee.setMaximumSize(new java.awt.Dimension(57, 33)); + btnEmployee.setMinimumSize(new java.awt.Dimension(57, 33)); + btnEmployee.setPreferredSize(new java.awt.Dimension(80, 45)); + btnEmployee.setRequestFocusEnabled(false); + btnEmployee.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnEmployeeActionPerformed(evt); + } + }); + + btnEndDate.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/date.png"))); // NOI18N + btnEndDate.setPreferredSize(new java.awt.Dimension(80, 45)); + btnEndDate.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnEndDateActionPerformed(evt); + } + }); + + btnStartDate.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/date.png"))); // NOI18N + btnStartDate.setPreferredSize(new java.awt.Dimension(80, 45)); + btnStartDate.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnStartDateActionPerformed(evt); + } + }); + + m_jEndDate.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jEndDate.setPreferredSize(new java.awt.Dimension(0, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(m_Notes, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 126, Short.MAX_VALUE) + .addComponent(m_EndDate, javax.swing.GroupLayout.DEFAULT_SIZE, 126, Short.MAX_VALUE) + .addComponent(m_StartDate, javax.swing.GroupLayout.DEFAULT_SIZE, 126, Short.MAX_VALUE) + .addComponent(m_Name, javax.swing.GroupLayout.DEFAULT_SIZE, 126, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(m_jEndDate, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(m_jStartDate, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(m_jEmployeeName, javax.swing.GroupLayout.DEFAULT_SIZE, 172, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(btnStartDate, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnEmployee, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnEndDate, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 258, Short.MAX_VALUE)) + .addGap(77, 77, 77)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_Name, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jEmployeeName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(btnEmployee, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_StartDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jStartDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(btnStartDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(btnEndDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_EndDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jEndDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(18, 18, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_Notes, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 141, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + }// </editor-fold>//GEN-END:initComponents + + private void btnEmployeeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnEmployeeActionPerformed + + JEmployeeFinder finder = JEmployeeFinder.getEmployeeFinder(this, dlPresenceManagement); + finder.search(null); + finder.setVisible(true); + + try { + m_jEmployeeName.setText(finder.getSelectedEmployee() == null + ? null + : dlPresenceManagement.loadEmployeeExt(finder.getSelectedEmployee().getId()).toString()); + m_employeeid = finder.getSelectedEmployee() == null + ? null + :finder.getSelectedEmployee().getId(); + } catch (BasicException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotfindemployee"), e); + msg.show(this); + } +}//GEN-LAST:event_btnEmployeeActionPerformed + + private void btnEndDateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnEndDateActionPerformed + Date date; + try { + date = (Date) Formats.TIMESTAMP.parseValue(m_jEndDate.getText()); + } catch (BasicException e) { + date = null; + } + date = JCalendarDialog.showCalendarTimeHours(this, date); + if (date != null) { + if (IsValidEndDate(date)) { + m_jEndDate.setText(Formats.TIMESTAMP.formatValue(date)); + } else { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.invalidenddate")); + msg.show(this); + } + } +}//GEN-LAST:event_btnEndDateActionPerformed + + private void btnStartDateActionPerformed(java.awt.event.ActionEvent evt) { + Date date; + try { + date = (Date) Formats.TIMESTAMP.parseValue(m_jStartDate.getText()); + } catch (BasicException e) { + date = null; + } + date = JCalendarDialog.showCalendarTimeHours(this, date); + if (date != null) { + if (IsValidStartDate(date)) { + m_jStartDate.setText(Formats.TIMESTAMP.formatValue(date)); + } else { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.invalidstartdate")); + msg.show(this); + } + } +} + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btnEmployee; + private javax.swing.JButton btnEndDate; + private javax.swing.JButton btnStartDate; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JLabel m_EndDate; + private javax.swing.JLabel m_Name; + private javax.swing.JLabel m_Notes; + private javax.swing.JLabel m_StartDate; + private javax.swing.JTextField m_jEmployeeName; + private javax.swing.JTextField m_jEndDate; + private javax.swing.JTextArea m_jLeaveNote; + private javax.swing.JTextField m_jStartDate; + // End of variables declaration//GEN-END:variables +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/forms/AppConfig.java b/src/main/java/com/unicenta/pos/forms/AppConfig.java new file mode 100644 index 0000000..0e7ce61 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/AppConfig.java @@ -0,0 +1,400 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/> + +package com.unicenta.pos.forms; + +import lombok.extern.slf4j.Slf4j; + +import java.io.*; +import java.util.Locale; +import java.util.Properties; + + +/** + * Creation and Editing of stored settings + * + * @author JG uniCenta + */ +@Slf4j +public class AppConfig implements AppProperties { + + private static AppConfig m_instance = null; + private Properties properties; + private File configfile; + + /** + * Set configuration array + * + * @param args array strings + */ + public AppConfig(String[] args) { + if (args.length == 0) { + init(getDefaultConfig()); + } else { + init(new File(args[0])); + } + } + + /** + * unicenta resources file + * + * @param configfile resource file + */ + public AppConfig(File configfile) { + init(configfile); + this.configfile = configfile; + properties = new Properties(); + load(); + //log.debug("Reading configuration file: {}", configfile.getAbsolutePath()); + } + + private void init(File configfile) { + this.configfile = configfile; + properties = new Properties(); + //log.debug("Reading configuration file: {}", configfile.getAbsolutePath()); + } + + private File getDefaultConfig() { + return new File(new File(System.getProperty("user.home")) + , AppLocal.APP_ID + ".properties"); + } + + /** + * Get key pair value from properties resource + * + * @param sKey key pair value + * @return key pair from .properties filename + */ + @Override + public String getProperty(String sKey) { + return properties.getProperty(sKey); + } + + /** + * @return Machine name + */ + @Override + public String getHost() { + return getProperty("machine.hostname"); + } + + /** + * @return .properties filename + */ + @Override + public File getConfigFile() { + return configfile; + } + + + public String getTicketHeaderLine1() { + return getProperty("tkt.header1"); + } + + public String getTicketHeaderLine2() { + return getProperty("tkt.header2"); + } + + public String getTicketHeaderLine3() { + return getProperty("tkt.header3"); + } + + public String getTicketHeaderLine4() { + return getProperty("tkt.header4"); + } + + public String getTicketHeaderLine5() { + return getProperty("tkt.header5"); + } + + public String getTicketHeaderLine6() { + return getProperty("tkt.header6"); + } + + public String getTicketFooterLine1() { + return getProperty("tkt.footer1"); + } + + public String getTicketFooterLine2() { + return getProperty("tkt.footer2"); + } + + public String getTicketFooterLine3() { + return getProperty("tkt.footer3"); + } + + public String getTicketFooterLine4() { + return getProperty("tkt.footer4"); + } + + public String getTicketFooterLine5() { + return getProperty("tkt.footer5"); + } + + public String getTicketFooterLine6() { + return getProperty("tkt.footer6"); + } + + /** + * Update .properties resource key pair values + * + * @param sKey key pair left side + * @param sValue key pair right side value + */ + public void setProperty(String sKey, String sValue) { + if (sValue == null) { + properties.remove(sKey); + } else { + properties.setProperty(sKey, sValue); + } + } + + /** + * Local machine identity + * + * @return Machine name from OS + */ + private String getLocalHostName() { + try { + return java.net.InetAddress.getLocalHost().getHostName(); + } catch (java.net.UnknownHostException eUH) { + return "localhost"; + } + } + + public static AppConfig getInstance() { + + if (m_instance == null) { + m_instance = new AppConfig(new File(System.getProperty("user.home") + , AppLocal.APP_ID + ".properties")); + } + return m_instance; + } + + public Boolean getBoolean(String sKey) { + return Boolean.valueOf(properties.getProperty(sKey)); + } + + public void setBoolean(String sKey, Boolean sValue) { + if (sValue == null) { + properties.remove(sKey); + } else if (sValue) { + properties.setProperty(sKey, "true"); + } else { + properties.setProperty(sKey, "false"); + } + } + + /** + * @return Delete .properties filename + */ + public boolean delete() { + loadDefault(); + return configfile.delete(); + } + + /** + * Get instance settings + */ + public void load() { + + loadDefault(); + + try { + InputStream in = new FileInputStream(configfile); + if (in != null) { + properties.load(in); + in.close(); + } + } catch (IOException e) { + loadDefault(); + } + + } + + private void refreshProperties() { + try { + InputStream in = new FileInputStream(configfile); + if (in != null) { + properties.load(in); + in.close(); + } + } catch (IOException e) { + loadDefault(); + } + } + + /** + * @return 0 or 00 number keypad boolean true/false + */ + public Boolean isPriceWith00() { + String prop = getProperty("pricewith00"); + if (prop == null) { + return false; + } else { + return prop.equals("true"); + } + } + + public void saveWithExistingProperties() throws IOException { + + refreshProperties(); + + OutputStream out = new FileOutputStream(configfile); + if (out != null) { + properties.store(out, AppLocal.APP_NAME + ". Configuration file."); + out.close(); + } + } + + /** + * Save values to properties file + * + * @throws java.io.IOException explicit on OS + */ + public void save() throws IOException { + + OutputStream out = new FileOutputStream(configfile); + if (out != null) { + properties.store(out, AppLocal.APP_NAME + ". Configuration file."); + out.close(); + } + } + + + private void loadDefault() { + + properties = new Properties(); + String dirname = System.getProperty("dirname.path"); + dirname = dirname == null ? "./" : dirname; + + setDatabaseProperties(properties, dirname); + setPrinterProperties(properties); + setLocalProperties(properties); + setPaymentProperties(properties); + setDeviceProperties(properties); + setTableProperties(properties); + + } + + + private void setTableProperties(Properties properties){ + properties.setProperty("table.showcustomerdetails", "true"); + properties.setProperty("table.customercolour", "#58B000"); + properties.setProperty("table.showwaiterdetails", "true"); + properties.setProperty("table.waitercolour", "#258FB0"); + properties.setProperty("table.tablecolour", "#D62E52"); + properties.setProperty("till.amountattop", "true"); + properties.setProperty("till.hideinfo", "true"); + } + + private void setDeviceProperties(Properties properties) { + properties.setProperty("machine.display", "screen"); + properties.setProperty("machine.scale", "Not defined"); + properties.setProperty("machine.screenmode", "fullscreen"); + properties.setProperty("machine.ticketsbag", "standard"); + properties.setProperty("machine.scanner", "Not defined"); + properties.setProperty("machine.iButton", "false"); + properties.setProperty("machine.iButtonResponse", "5"); + properties.setProperty("machine.uniqueinstance", "true"); + + properties.setProperty("machine.hostname", getLocalHostName()); + properties.setProperty("swing.defaultlaf", System.getProperty("swing.defaultlaf","javax.swing.plaf.metal.MetalLookAndFeel")); + } + + private void setPaymentProperties(Properties properties) { + properties.setProperty("payment.gateway", "external"); + properties.setProperty("payment.magcardreader", "Not defined"); + properties.setProperty("payment.testmode", "true"); + properties.setProperty("payment.commerceid", ""); + properties.setProperty("payment.commercepassword", "password"); + } + + private void setLocalProperties(Properties properties) { + Locale l = Locale.getDefault(); + properties.setProperty("user.language", l.getLanguage()); + properties.setProperty("user.country", l.getCountry()); + properties.setProperty("user.variant", l.getVariant()); + } + + private void setPrinterProperties(Properties properties) { + // Receipt printer paper set to 72mmx200mm + properties.setProperty("paper.receipt.x", "10"); + properties.setProperty("paper.receipt.y", "10"); + properties.setProperty("paper.receipt.width", "190"); + properties.setProperty("paper.receipt.height", "546"); + properties.setProperty("paper.receipt.mediasizename", "A4"); + + // Normal printer paper for A4 + properties.setProperty("paper.standard.x", "72"); + properties.setProperty("paper.standard.y", "72"); + properties.setProperty("paper.standard.width", "451"); + properties.setProperty("paper.standard.height", "698"); + properties.setProperty("paper.standard.mediasizename", "A4"); + + properties.setProperty("tkt.header1", "uniCenta oPOS"); + properties.setProperty("tkt.header2", "Touch Friendly Point Of Sale"); + properties.setProperty("tkt.header3", "Copyright (c) 2009-2018 uniCenta"); + properties.setProperty("tkt.header4", "Change header text in Configuration"); + + properties.setProperty("tkt.footer1", "Change footer text in Configuration"); + properties.setProperty("tkt.footer2", "Thank you for your custom"); + properties.setProperty("tkt.footer3", "Please Call Again"); + + properties.setProperty("machine.printer", "screen"); + properties.setProperty("machine.printer.2", "Not defined"); + properties.setProperty("machine.printer.3", "Not defined"); + properties.setProperty("machine.printer.4", "Not defined"); + properties.setProperty("machine.printer.5", "Not defined"); + properties.setProperty("machine.printer.6", "Not defined"); + + properties.setProperty("machine.printername", "(Default)"); + properties.setProperty("screen.receipt.columns", "42"); + } + + private void setDatabaseProperties(Properties properties, String dirname) { + + properties.setProperty("db.multi", "false"); + properties.setProperty("override.check", "false"); + properties.setProperty("override.pin", ""); + + // Default database + properties.setProperty("db.driverlib", new File(new File(dirname), "derby-10.14.2.0.jar").getAbsolutePath()); + properties.setProperty("db.engine", "Derby"); + properties.setProperty("db.driver", "org.apache.derby.jdbc.EmbeddedDriver"); + + properties.setProperty("db.name", "Main DB"); + properties.setProperty("db.URL", "jdbc:derby:" + System.getProperty("user.home")+"/.unicenta/"); + properties.setProperty("db.schema", "unicentaopos-database;create=true"); + properties.setProperty("db.options", ""); + properties.setProperty("db.user", ""); + properties.setProperty("db.password", ""); + + +// secondary DB + properties.setProperty("db1.name", ""); + properties.setProperty("db1.URL", "jdbc:mysql://localhost:3306/"); + properties.setProperty("db1.schema", "unicentaopos"); + properties.setProperty("db1.options", "?zeroDateTimeBehavior=convertToNull"); + properties.setProperty("db1.user", ""); + properties.setProperty("db1.password", ""); + + } + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/forms/AppLocal.java b/src/main/java/com/unicenta/pos/forms/AppLocal.java new file mode 100644 index 0000000..5729fbf --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/AppLocal.java @@ -0,0 +1,65 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/> + +package com.unicenta.pos.forms; + +import com.unicenta.beans.LocaleResources; + +/** + * @author Jack Gerrard + * @author adrianromero + */ +public class AppLocal { + + + public static final String APP_NAME = "uniCenta oPOS"; + public static final String APP_ID = "unicentaopos"; + public static final String APP_VERSION = "5.0"; + + private static final LocaleResources m_resources; + + static { + m_resources = new LocaleResources(); + m_resources.addBundleName("pos_messages"); + m_resources.addBundleName("erp_messages"); + } + + /** Creates a new instance of AppLocal */ + private AppLocal() { + } + + /** + * + * @param sKey local values + * @return string values + */ + public static String getIntString(String sKey) { + return m_resources.getString(sKey); + } + + /** + * + * @param sKey local values + * @param sValues string values + * @return string values + */ + public static String getIntString(String sKey, Object ... sValues) { + return m_resources.getString(sKey, sValues); + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/forms/AppProperties.java b/src/main/java/com/unicenta/pos/forms/AppProperties.java new file mode 100644 index 0000000..a9ddae1 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/AppProperties.java @@ -0,0 +1,48 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import java.io.File; + +/** + * + * @author adrianromero + */ +public interface AppProperties { + + /** + * Gets the configuration properties settings + * @return config file + */ + public File getConfigFile(); + + /** + * Gets the Host machine name + * @return host name + */ + public String getHost(); + + /** + * Read the property from the key pair + * @param sKey key pair value + * @return key pair property + */ + public String getProperty(String sKey); +} diff --git a/src/main/java/com/unicenta/pos/forms/AppUser.java b/src/main/java/com/unicenta/pos/forms/AppUser.java new file mode 100644 index 0000000..15f96a3 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/AppUser.java @@ -0,0 +1,304 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import com.unicenta.data.loader.LocalRes; +import com.unicenta.pos.ticket.UserInfo; +import com.unicenta.pos.util.Hashcypher; +import lombok.extern.slf4j.Slf4j; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import javax.swing.*; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import java.io.IOException; +import java.io.StringReader; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +/** + * @author adrianromero + */ +@Slf4j +public class AppUser { + + private static SAXParser m_sp = null; + private static HashMap<String, String> m_oldclasses; // This is for backwards compatibility purposes + + private final String m_sId; + private final String m_sName; + private final String m_sCard; + private String m_sPassword; + private final String m_sRole; + private final Icon m_Icon; + + private Set<String> m_apermissions; + + static { + initOldClasses(); + } + + /** + * Creates a new instance of AppUser + * + * @param id + * @param name + * @param card + * @param password + * @param icon + * @param role + */ + public AppUser(String id, String name, String password, String card, String role, Icon icon) { + m_sId = id; + m_sName = name; + m_sPassword = password; + m_sCard = card; + m_sRole = role; + m_Icon = icon; + m_apermissions = null; + } + + /** + * Gets the User's button icon + */ + public Icon getIcon() { + return m_Icon; + } + + /** + * Get the user's ID + */ + public String getId() { + return m_sId; + } + + /** + * Get the User's Name + */ + public String getName() { + return m_sName; + } + + /** + * Set the User's Password + */ + public void setPassword(String sValue) { + m_sPassword = sValue; + } + + /** + * Get the User's Password + */ + public String getPassword() { + return m_sPassword; + } + + /** + * Get the User's Role + */ + public String getRole() { + return m_sRole; + } + + /** + * Get the User's Card + */ + public String getCard() { + return m_sCard; + } + + /** + * Validate User's Password + * + * @return + */ + public boolean authenticate() { + return m_sPassword == null || m_sPassword.equals("") || m_sPassword.startsWith("empty:"); + } + + /** + * Eval User's Password + * + * @param sPwd + * @return + */ + public boolean authenticate(String sPwd) { + return Hashcypher.authenticate(sPwd, m_sPassword); + } + + /** + * Load User's Permissions + * + * @param dlSystem + */ + public void fillPermissions(DataLogicSystem dlSystem) { + + // JG 16 May use diamond inference + m_apermissions = new HashSet<>(); + // Y lo que todos tienen permisos + m_apermissions.add("com.unicenta.pos.forms.JPanelMenu"); + m_apermissions.add("Menu.Exit"); + + String sRolePermisions = dlSystem.findRolePermissions(m_sRole); + + if (sRolePermisions != null) { + try { + if (m_sp == null) { + SAXParserFactory spf = SAXParserFactory.newInstance(); + m_sp = spf.newSAXParser(); + } + m_sp.parse(new InputSource(new StringReader(sRolePermisions)), new ConfigurationHandler()); + + } catch (ParserConfigurationException ePC) { + log.error(LocalRes.getIntString("exception.parserconfig"), ePC); + } catch (SAXException eSAX) { + log.error(LocalRes.getIntString("exception.xmlfile"), eSAX); + } catch (IOException eIO) { + log.error(LocalRes.getIntString("exception.iofile"), eIO); + } + } + + } + + /** + * Validate User's Permissions + * + * @param classname + * @return + */ + public boolean hasPermission(String classname) { + + return (m_apermissions == null) ? false : m_apermissions.contains(classname); + } + + /** + * Get User's ID/Name + * + * @return + */ + public UserInfo getUserInfo() { + return new UserInfo(m_sId, m_sName); + } + + private static String mapNewClass(String classname) { + String newclass = m_oldclasses.get(classname); + return newclass == null + ? classname + : newclass; + } + + private static void initOldClasses() { + // JG 16 May use diamond inference + m_oldclasses = new HashMap<>(); + + // update permissions from 0.0.24 to 2.20 + m_oldclasses.put("net.adrianromero.tpv.panelsales.JPanelTicketSales", "com.unicenta.pos.sales.JPanelTicketSales"); + m_oldclasses.put("net.adrianromero.tpv.panelsales.JPanelTicketEdits", "com.unicenta.pos.sales.JPanelTicketEdits"); + m_oldclasses.put("net.adrianromero.tpv.panels.JPanelPayments", "com.unicenta.pos.panels.JPanelPayments"); + m_oldclasses.put("net.adrianromero.tpv.panels.JPanelCloseMoney", "com.unicenta.pos.panels.JPanelCloseMoney"); + m_oldclasses.put("net.adrianromero.tpv.reports.JReportClosedPos", "/com/unicenta/reports/closedpos.bs"); + + m_oldclasses.put("Menu.StockManagement", "com.unicenta.pos.forms.MenuStockManagement"); + m_oldclasses.put("net.adrianromero.tpv.inventory.ProductsPanel", "com.unicenta.pos.inventory.ProductsPanel"); + m_oldclasses.put("net.adrianromero.tpv.inventory.ProductsWarehousePanel", "com.unicenta.pos.inventory.ProductsWarehousePanel"); + m_oldclasses.put("net.adrianromero.tpv.inventory.CategoriesPanel", "com.unicenta.pos.inventory.CategoriesPanel"); + m_oldclasses.put("net.adrianromero.tpv.panels.JPanelTax", "com.unicenta.pos.inventory.TaxPanel"); + m_oldclasses.put("net.adrianromero.tpv.inventory.StockDiaryPanel", "com.unicenta.pos.inventory.StockDiaryPanel"); + m_oldclasses.put("net.adrianromero.tpv.inventory.StockManagement", "com.unicenta.pos.inventory.StockManagement"); + m_oldclasses.put("net.adrianromero.tpv.reports.JReportProducts", "/com/unicenta/reports/products.bs"); + m_oldclasses.put("net.adrianromero.tpv.reports.JReportCatalog", "/com/unicenta/reports/productscatalog.bs"); + m_oldclasses.put("net.adrianromero.tpv.reports.JReportInventory", "/com/unicenta/reports/inventory.bs"); + m_oldclasses.put("net.adrianromero.tpv.reports.JReportInventory2", "/com/unicenta/reports/inventoryb.bs"); + m_oldclasses.put("net.adrianromero.tpv.reports.JReportInventoryBroken", "/com/unicenta/reports/inventorybroken.bs"); + m_oldclasses.put("net.adrianromero.tpv.reports.JReportInventoryDiff", "/com/unicenta/reports/inventorydiff.bs"); + + m_oldclasses.put("Menu.SalesManagement", "com.unicenta.pos.forms.MenuSalesManagement"); + m_oldclasses.put("net.adrianromero.tpv.reports.JReportUserSales", "/com/unicenta/reports/usersales.bs"); + m_oldclasses.put("net.adrianromero.tpv.reports.JReportClosedProducts", "/com/unicenta/reports/closedproducts.bs"); + m_oldclasses.put("net.adrianromero.tpv.reports.JReportTaxes", "/com/unicenta/reports/taxes.bs"); + m_oldclasses.put("net.adrianromero.tpv.reports.JChartSales", "/com/unicenta/reports/chartsales.bs"); + + m_oldclasses.put("Menu.Maintenance", "com.unicenta.pos.forms.MenuMaintenance"); + m_oldclasses.put("net.adrianromero.tpv.admin.PeoplePanel", "com.unicenta.pos.admin.PeoplePanel"); + m_oldclasses.put("net.adrianromero.tpv.admin.RolesPanel", "com.unicenta.pos.admin.RolesPanel"); + m_oldclasses.put("net.adrianromero.tpv.admin.ResourcesPanel", "com.unicenta.pos.admin.ResourcesPanel"); + m_oldclasses.put("net.adrianromero.tpv.inventory.LocationsPanel", "com.unicenta.pos.inventory.LocationsPanel"); + m_oldclasses.put("net.adrianromero.tpv.mant.JPanelFloors", "com.unicenta.pos.mant.JPanelFloors"); + m_oldclasses.put("net.adrianromero.tpv.mant.JPanelPlaces", "com.unicenta.pos.mant.JPanelPlaces"); + m_oldclasses.put("com.unicenta.possync.ProductsSync", "com.unicenta.possync.ProductsSyncCreate"); + m_oldclasses.put("com.unicenta.possync.OrdersSync", "com.unicenta.possync.OrdersSyncCreate"); + + m_oldclasses.put("Menu.ChangePassword", "Menu.ChangePassword"); + m_oldclasses.put("net.adrianromero.tpv.panels.JPanelPrinter", "com.unicenta.pos.panels.JPanelPrinter"); + m_oldclasses.put("net.adrianromero.tpv.config.JPanelConfiguration", "com.unicenta.pos.config.JPanelConfiguration"); + + // update permissions from 2.00 to 2.20 + m_oldclasses.put("com.unicenta.pos.reports.JReportCustomers", "/com/unicenta/reports/customers.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportCustomersB", "/com/unicenta/reports/customersb.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportClosedPos", "/com/unicenta/reports/closedpos.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportClosedProducts", "/com/unicenta/reports/closedproducts.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JChartSales", "/com/unicenta/reports/chartsales.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportInventory", "/com/unicenta/reports/inventory.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportInventory2", "/com/unicenta/reports/inventoryb.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportInventoryBroken", "/com/unicenta/reports/inventorybroken.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportInventoryDiff", "/com/unicenta/reports/inventorydiff.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportPeople", "/com/unicenta/reports/people.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportTaxes", "/com/unicenta/reports/taxes.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportUserSales", "/com/unicenta/reports/usersales.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportProducts", "/com/unicenta/reports/products.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportCatalog", "/com/unicenta/reports/productscatalog.bs"); + + // update permissions from 2.10 to 2.20 + m_oldclasses.put("com.unicenta.pos.panels.JPanelTax", "com.unicenta.pos.inventory.TaxPanel"); + + } + + private class ConfigurationHandler extends DefaultHandler { + @Override + public void startDocument() throws SAXException { + } + + @Override + public void endDocument() throws SAXException { + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + if ("class".equals(qName)) { + m_apermissions.add(mapNewClass(attributes.getValue("name"))); + } + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + } + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + } + } + + +} diff --git a/src/main/java/com/unicenta/pos/forms/AppUserView.java b/src/main/java/com/unicenta/pos/forms/AppUserView.java new file mode 100644 index 0000000..0c54161 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/AppUserView.java @@ -0,0 +1,52 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +/** + * + * @author adrianromero + */ +public interface AppUserView { + + /** + * + */ + public static final String ACTION_TASKNAME = "taskname"; + + // Acciones de la aplicacion + + /** + * + * @return + */ + public AppUser getUser(); // Usuario logado + + /** + * + * @param sTaskClass + */ + public void showTask(String sTaskClass); + + /** + * + * @param sTaskClass + */ + public void executeTask(String sTaskClass); +} diff --git a/src/main/java/com/unicenta/pos/forms/AppView.java b/src/main/java/com/unicenta/pos/forms/AppView.java new file mode 100644 index 0000000..9770c14 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/AppView.java @@ -0,0 +1,74 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import com.unicenta.data.loader.Session; +import com.unicenta.pos.printer.DeviceTicket; +import com.unicenta.pos.scale.DeviceScale; +import com.unicenta.pos.scanpal2.DeviceScanner; +import java.util.Date; + +/** + * + * @author adrianromero + */ +public interface AppView { + + public DeviceScale getDeviceScale(); + public DeviceTicket getDeviceTicket(); + public DeviceScanner getDeviceScanner(); + public Session getSession(); + public AppProperties getProperties(); + + /** + * + * @param beanfactory + * @return + * @throws BeanFactoryException + */ + public Object getBean(String beanfactory) throws BeanFactoryException; + + /** + * + * @param value + * @param iSeq + * @param dStart + * @param dEnd + */ + public void setActiveCash(String value, int iSeq, Date dStart, Date dEnd); + public String getActiveCashIndex(); + public int getActiveCashSequence(); + public Date getActiveCashDateStart(); + public Date getActiveCashDateEnd(); + + public void setClosedCash(String value, int iSeq, Date dStart, Date dEnd); + public String getClosedCashIndex(); + public int getClosedCashSequence(); + public Date getClosedCashDateStart(); + public Date getClosedCashDateEnd(); + + public String getInventoryLocation(); + + public void waitCursorBegin(); + public void waitCursorEnd(); + public AppUserView getAppUserView(); + +} + diff --git a/src/main/java/com/unicenta/pos/forms/AppViewConnection.java b/src/main/java/com/unicenta/pos/forms/AppViewConnection.java new file mode 100644 index 0000000..188cb58 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/AppViewConnection.java @@ -0,0 +1,145 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.Session; +import com.unicenta.pos.util.AltEncrypter; +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.sql.Driver; +import java.sql.DriverManager; +import java.sql.SQLException; +import javax.swing.ImageIcon; +import javax.swing.JOptionPane; + +/** + * + * @author adrianromero + */ +public class AppViewConnection { + + /** Creates a new instance of AppViewConnection */ + private AppViewConnection() { + } + + /** + * + * @param props + * @return + * @throws BasicException + */ + public static Session createSession(AppProperties props) throws BasicException { + try { + String dbURL=null; + String sDBUser=null; + String sDBPassword=null; + String sUserPath = System.getProperty("user.home"); + String filePath = sUserPath + "\\open.db"; + + if (isJavaWebStart()) { + Class.forName(props.getProperty("db.driver"), true, Thread.currentThread().getContextClassLoader()); + } else { + URL[] urls = {new File(props.getProperty("db.driverlib")).toURI().toURL()}; + ClassLoader cloader = new URLClassLoader(urls); + String driver = props.getProperty("db.driver"); + DriverWrapper driverWrapper = new DriverWrapper((Driver) Class.forName(driver, true, cloader).newInstance()); + DriverManager.registerDriver(driverWrapper); + } + if("true".equals(props.getProperty("db.multi"))) { + if (!Files.exists(Paths.get(filePath))) { + ImageIcon icon = new ImageIcon("/com/unicenta/images/unicentaopos.png"); + Object[] dbs = { + "0 - " + props.getProperty("db.name"), + "1 - " + props.getProperty("db1.name")}; + + Object s = (Object)JOptionPane.showInputDialog( + null, AppLocal.getIntString("message.databasechoose"), + "Selection", JOptionPane.OK_OPTION, + icon, dbs, props.getProperty("db.name")); + + if (s.toString().startsWith("1")) { + sDBUser = props.getProperty("db1.user"); + sDBPassword = props.getProperty("db1.password"); + if (sDBUser != null && sDBPassword != null && sDBPassword.startsWith("crypt:")) { + AltEncrypter cypher = new AltEncrypter("cypherkey" + sDBUser); + sDBPassword = cypher.decrypt(sDBPassword.substring(6)); + } + dbURL = props.getProperty("db1.URL") + + props.getProperty("db1.schema") + + props.getProperty("db1.options"); + } else { + sDBUser = props.getProperty("db.user"); + sDBPassword = props.getProperty("db.password"); + if (sDBUser != null && sDBPassword != null && sDBPassword.startsWith("crypt:")) { + AltEncrypter cypher = new AltEncrypter("cypherkey" + sDBUser); + sDBPassword = cypher.decrypt(sDBPassword.substring(6)); + } + dbURL = props.getProperty("db.URL") + + props.getProperty("db.schema") + + props.getProperty("db.options"); + } + } else { + sDBUser = props.getProperty("db.user"); + sDBPassword = props.getProperty("db.password"); + if (sDBUser != null && sDBPassword != null && sDBPassword.startsWith("crypt:")) { + AltEncrypter cypher = new AltEncrypter("cypherkey" + sDBUser); + sDBPassword = cypher.decrypt(sDBPassword.substring(6)); + } + dbURL = props.getProperty("db.URL") + + props.getProperty("db.schema") + + props.getProperty("db.options"); + } + + } else { + sDBUser = props.getProperty("db.user"); + sDBPassword = props.getProperty("db.password"); + if (sDBUser != null && sDBPassword != null && sDBPassword.startsWith("crypt:")) { + AltEncrypter cypher = new AltEncrypter("cypherkey" + sDBUser); + sDBPassword = cypher.decrypt(sDBPassword.substring(6)); + } + + dbURL = props.getProperty("db.URL") + + props.getProperty("db.schema") + + props.getProperty("db.options"); + } + return new Session(dbURL, sDBUser,sDBPassword); + + } catch (InstantiationException | IllegalAccessException | MalformedURLException | ClassNotFoundException e) { + throw new BasicException(AppLocal.getIntString("message.databasedrivererror"), e); + } catch (SQLException eSQL) { + throw new BasicException(AppLocal.getIntString("message.databaseconnectionerror"), eSQL); + } + } + + private static boolean isJavaWebStart() { + + try { + Class.forName("javax.jnlp.ServiceManager"); + return true; + } catch (ClassNotFoundException ue) { + return false; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/forms/BeanFactory.java b/src/main/java/com/unicenta/pos/forms/BeanFactory.java new file mode 100644 index 0000000..0d9bb0b --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/BeanFactory.java @@ -0,0 +1,33 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +/** + * + * @author adrianromero + */ +public interface BeanFactory { + + /** + * + * @return + */ + public Object getBean(); +} diff --git a/src/main/java/com/unicenta/pos/forms/BeanFactoryApp.java b/src/main/java/com/unicenta/pos/forms/BeanFactoryApp.java new file mode 100644 index 0000000..c6a5dcf --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/BeanFactoryApp.java @@ -0,0 +1,35 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +/** + * + * @author adrianromero + */ +public interface BeanFactoryApp extends BeanFactory { + + /** + * + * @param app + * @throws BeanFactoryException + */ + public void init(AppView app) throws BeanFactoryException; + +} diff --git a/src/main/java/com/unicenta/pos/forms/BeanFactoryCache.java b/src/main/java/com/unicenta/pos/forms/BeanFactoryCache.java new file mode 100644 index 0000000..8c693bd --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/BeanFactoryCache.java @@ -0,0 +1,56 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +/** + * + * @author adrianromero + */ +public abstract class BeanFactoryCache implements BeanFactoryApp { + + private Object bean = null; + + /** + * + * @param app + * @return + * @throws BeanFactoryException + */ + public abstract Object constructBean(AppView app) throws BeanFactoryException; + + /** + * + * @param app + * @throws BeanFactoryException + */ + @Override + public void init(AppView app) throws BeanFactoryException { + bean = constructBean(app); + } + + /** + * + * @return + */ + @Override + public Object getBean() { + return bean; + } +} diff --git a/src/main/java/com/unicenta/pos/forms/BeanFactoryData.java b/src/main/java/com/unicenta/pos/forms/BeanFactoryData.java new file mode 100644 index 0000000..12fa1a1 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/BeanFactoryData.java @@ -0,0 +1,64 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +/** + * + * @author adrianromero + */ +public class BeanFactoryData implements BeanFactoryApp { + + private BeanFactoryApp bf; + + /** Creates a new instance of BeanFactoryData */ + public BeanFactoryData() { + } + + /** + * + * @param app + * @throws BeanFactoryException + */ + @Override + public void init(AppView app) throws BeanFactoryException { + + try { + + String sfactoryname = this.getClass().getName(); + if (sfactoryname.endsWith("Create")) { + sfactoryname = sfactoryname.substring(0, sfactoryname.length() - 6); + } + bf = (BeanFactoryApp) Class.forName(sfactoryname + app.getSession().DB.getName()).newInstance(); + bf.init(app); +// JG 16 May use multicatch + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | BeanFactoryException ex) { + throw new BeanFactoryException(ex); + } + } + + /** + * + * @return + */ + @Override + public Object getBean() { + return bf.getBean(); + } +} diff --git a/src/main/java/com/unicenta/pos/forms/BeanFactoryDataSingle.java b/src/main/java/com/unicenta/pos/forms/BeanFactoryDataSingle.java new file mode 100644 index 0000000..02c92be --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/BeanFactoryDataSingle.java @@ -0,0 +1,58 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import com.unicenta.data.loader.Session; + +/** + * + * @author adrianromero + */ +public abstract class BeanFactoryDataSingle implements BeanFactoryApp { + + /** Creates a new instance of BeanFactoryData */ + public BeanFactoryDataSingle() { + } + + /** + * + * @param s + */ + public abstract void init(Session s); + + /** + * + * @param app + * @throws BeanFactoryException + */ + @Override + public void init(AppView app) throws BeanFactoryException { + init(app.getSession()); + } + + /** + * + * @return + */ + @Override + public Object getBean() { + return this; + } +} diff --git a/src/main/java/com/unicenta/pos/forms/BeanFactoryException.java b/src/main/java/com/unicenta/pos/forms/BeanFactoryException.java new file mode 100644 index 0000000..c22b9f5 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/BeanFactoryException.java @@ -0,0 +1,50 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +/** + * + * @author adrianromero + */ +public class BeanFactoryException extends java.lang.RuntimeException { + + /** + * Creates a new instance of <code>BeanFactoryException</code> without detail message. + */ + public BeanFactoryException() { + } + + + /** + * Constructs an instance of <code>BeanFactoryException</code> with the specified detail message. + * @param msg the detail message. + */ + public BeanFactoryException(String msg) { + super(msg); + } + + /** + * + * @param e + */ + public BeanFactoryException(Throwable e) { + super(e); + } +} diff --git a/src/main/java/com/unicenta/pos/forms/BeanFactoryObj.java b/src/main/java/com/unicenta/pos/forms/BeanFactoryObj.java new file mode 100644 index 0000000..80a35fc --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/BeanFactoryObj.java @@ -0,0 +1,45 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +/** + * + * @author adrianromero + */ +public class BeanFactoryObj implements BeanFactory { + + private Object bean = null; + + /** Creates a new instance of BeanFactoryObj + * @param bean */ + public BeanFactoryObj(Object bean) { + this.bean = bean; + } + + /** + * + * @return + */ + @Override + public Object getBean() { + return bean; + } + +} diff --git a/src/main/java/com/unicenta/pos/forms/BeanFactoryScript.java b/src/main/java/com/unicenta/pos/forms/BeanFactoryScript.java new file mode 100644 index 0000000..0b19479 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/BeanFactoryScript.java @@ -0,0 +1,82 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import com.unicenta.pos.scripting.ScriptEngine; +import com.unicenta.pos.scripting.ScriptException; +import com.unicenta.pos.scripting.ScriptFactory; +import com.unicenta.pos.util.StringUtils; +import java.io.IOException; + +/** + * + * @author adrianromero + */ +public class BeanFactoryScript implements BeanFactoryApp { + + private BeanFactory bean = null; + private String script; + + /** + * + * @param script + */ + public BeanFactoryScript(String script) { + this.script = script; + } + + /** + * + * @param app + * @throws BeanFactoryException + */ + @Override + public void init(AppView app) throws BeanFactoryException { + + // Resource + try { + ScriptEngine eng = ScriptFactory.getScriptEngine(ScriptFactory.BEANSHELL); + eng.put("app", app); + + bean = (BeanFactory) eng.eval(StringUtils.readResource(script)); + if (bean == null) { + // old definition + bean = (BeanFactory) eng.get("bean"); + } + + // todo // llamar al init del bean + if (bean instanceof BeanFactoryApp) { + ((BeanFactoryApp) bean).init(app); + } +// JG 16 May use multicatch + } catch (ScriptException | IOException e) { + throw new BeanFactoryException(e); + } + } + + /** + * + * @return + */ + @Override + public Object getBean() { + return bean.getBean(); + } +} diff --git a/src/main/java/com/unicenta/pos/forms/DataLogicOrders.java b/src/main/java/com/unicenta/pos/forms/DataLogicOrders.java new file mode 100644 index 0000000..b976723 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/DataLogicOrders.java @@ -0,0 +1,81 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.*; + +/** + * + * @author uniCenta + */ +public class DataLogicOrders extends BeanFactoryDataSingle { + private SentenceExec m_addOrder; + private SentenceExec m_resetPickup; + + /** Creates a new instance of DataLogicOrders */ + public DataLogicOrders() { + } + + /** + * + * @param s + */ + @Override + public void init(Session s){ + + m_addOrder = new StaticSentence(s + , "INSERT INTO orders (orderid, qty, details, attributes, " + + "notes, ticketid, ordertime, displayid, auxiliary, " + + "completetime) " + + "VALUES (?, ?, ?, ?, ?, " + + "?, ?, ?, ?, ? ) " + , new SerializerWriteBasic(new Datas[] { + Datas.STRING, // OrderId + Datas.INT, // Qty + Datas.STRING, // Details + Datas.STRING, // Attributes + Datas.STRING, // Notes + Datas.STRING, // TicketId + Datas.STRING, // OrderTime + Datas.INT, // DisplayId + Datas.INT, // Auxiliary + Datas.STRING // CompleteTime + })); + + m_resetPickup = new PreparedSentence(s + , "UPDATE pickup_number SET id=1" + , SerializerWriteParams.INSTANCE); + } + + + public final void addOrder(String orderId, Integer qty, + String details, String attributes, String notes, String ticketId, + String ordertime, Integer displayId, String auxiliary, String completetime + ) throws BasicException { + + m_addOrder.exec(orderId, qty, details, attributes, notes, ticketId, + ordertime, displayId, auxiliary, completetime); + } + + public final void resetPickup() throws BasicException { + m_resetPickup.exec(); + } +} diff --git a/src/main/java/com/unicenta/pos/forms/DataLogicSales.java b/src/main/java/com/unicenta/pos/forms/DataLogicSales.java new file mode 100644 index 0000000..0712453 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/DataLogicSales.java @@ -0,0 +1,2828 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.*; +import com.unicenta.data.model.Field; +import com.unicenta.data.model.Row; +import com.unicenta.format.Formats; +import com.unicenta.pos.catalog.CategoryStock; +import com.unicenta.pos.customers.CustomerInfoExt; +import com.unicenta.pos.customers.CustomerTransaction; +import com.unicenta.pos.inventory.*; +import com.unicenta.pos.mant.FloorsInfo; +import com.unicenta.pos.payment.PaymentInfo; +import com.unicenta.pos.payment.PaymentInfoMagcard; +import com.unicenta.pos.payment.PaymentInfoTicket; +import com.unicenta.pos.sales.ReprintTicketInfo; +import com.unicenta.pos.suppliers.SupplierInfo; +import com.unicenta.pos.suppliers.SupplierInfoExt; +import com.unicenta.pos.ticket.*; +import com.unicenta.pos.voucher.VoucherInfo; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Date; +import java.util.List; +import java.util.UUID; +import java.util.logging.Logger; +import java.io.File; + +/** + * + * @author adrianromero + * @author jackgerrard + */ +public class DataLogicSales extends BeanFactoryDataSingle { + + protected Session s; + + protected Datas[] auxiliarDatas; + protected Datas[] stockdiaryDatas; + protected Datas[] paymenttabledatas; + protected Datas[] stockdatas; + protected Datas[] stockAdjustDatas; + + protected Row productsRow; + protected Row customersRow; + + private String pName; + private Double getTotal; + private Double getTendered; + private String getRetMsg; + private String getVoucher; + + public static final String DEBT = "debt"; + public static final String DEBT_PAID = "debtpaid"; + protected static final String PREPAY = "prepay"; + private static final Logger logger = Logger.getLogger("com.unicenta.pos.forms.DataLogicSales"); + + private String getCardName; + protected SentenceExec m_createCat; + protected SentenceExec m_createSupp; + + protected AppView m_App; + + private AppConfig m_config; + + public DataLogicSales() { + AppView app = null; + m_config = new AppConfig(new File((System.getProperty("user.home")), AppLocal.APP_ID + ".properties")); + m_config.load(); + m_App = app; + + stockdiaryDatas = new Datas[] { + Datas.STRING, Datas.TIMESTAMP, Datas.INT, Datas.STRING, + Datas.STRING, Datas.STRING, Datas.DOUBLE, Datas.DOUBLE, + Datas.STRING, Datas.STRING, Datas.STRING}; + + paymenttabledatas = new Datas[] { + Datas.STRING, Datas.STRING, Datas.TIMESTAMP, + Datas.STRING, Datas.STRING, Datas.DOUBLE, + Datas.STRING}; + + stockdatas = new Datas[] { + Datas.STRING, Datas.STRING, Datas.STRING, + Datas.DOUBLE, Datas.DOUBLE, Datas.DOUBLE}; + + stockAdjustDatas = new Datas[] { + Datas.STRING, + Datas.STRING, + Datas.STRING, + Datas.DOUBLE}; + + auxiliarDatas = new Datas[] { + Datas.STRING, Datas.STRING, Datas.STRING, + Datas.STRING, Datas.STRING, Datas.STRING}; + + productsRow = new Row( + new Field("ID", Datas.STRING, Formats.STRING), + new Field(AppLocal.getIntString("label.prodref"), Datas.STRING, Formats.STRING, true, true, true), + new Field(AppLocal.getIntString("label.prodbarcode"), Datas.STRING, Formats.STRING, false, true, true), + new Field(AppLocal.getIntString("label.prodbarcodetype"), Datas.STRING, Formats.STRING, false, true, true), + new Field(AppLocal.getIntString("label.prodname"), Datas.STRING, Formats.STRING, true, true, true), + new Field(AppLocal.getIntString("label.prodpricebuy"), Datas.DOUBLE, Formats.CURRENCY, false, true, true), + new Field(AppLocal.getIntString("label.prodpricesell"), Datas.DOUBLE, Formats.CURRENCY, false, true, true), + new Field(AppLocal.getIntString("label.prodcategory"), Datas.STRING, Formats.STRING, false, false, true), + new Field(AppLocal.getIntString("label.taxcategory"), Datas.STRING, Formats.STRING, false, false, true), + new Field(AppLocal.getIntString("label.attributeset"), Datas.STRING, Formats.STRING, false, false, true), + new Field("STOCKCOST", Datas.DOUBLE, Formats.CURRENCY), + new Field("STOCKVOLUME", Datas.DOUBLE, Formats.DOUBLE), + new Field("IMAGE", Datas.IMAGE, Formats.NULL), + new Field("ISCOM", Datas.BOOLEAN, Formats.BOOLEAN), + new Field("ISSCALE", Datas.BOOLEAN, Formats.BOOLEAN), + new Field("ISCONSTANT", Datas.BOOLEAN, Formats.BOOLEAN), + new Field("PRINTKB", Datas.BOOLEAN, Formats.BOOLEAN), + new Field("SENDSTATUS", Datas.BOOLEAN, Formats.BOOLEAN), + new Field("ISSERVICE", Datas.BOOLEAN, Formats.BOOLEAN), + new Field("PROPERTIES", Datas.BYTES, Formats.NULL), + new Field(AppLocal.getIntString("label.display"), Datas.STRING, Formats.STRING, false, true, true), + new Field("ISVPRICE", Datas.BOOLEAN, Formats.BOOLEAN), + new Field("ISVERPATRIB", Datas.BOOLEAN, Formats.BOOLEAN), + new Field("TEXTTIP", Datas.STRING, Formats.STRING), + new Field("WARRANTY", Datas.BOOLEAN, Formats.BOOLEAN), + new Field(AppLocal.getIntString("label.stockunits"), Datas.DOUBLE, Formats.DOUBLE), + new Field("PRINTTO", Datas.STRING, Formats.STRING), + new Field(AppLocal.getIntString("label.prodsupplier"), Datas.STRING, Formats.STRING, false, false, true), + new Field(AppLocal.getIntString("label.UOM"), Datas.STRING, Formats.STRING), + new Field("MEMODATE", Datas.TIMESTAMP, Formats.DATE), + + new Field("ISCATALOG", Datas.BOOLEAN, Formats.BOOLEAN), + new Field("CATORDER", Datas.INT, Formats.INT) + ); + +// creating customers object here for now for future global reuse +// LOYALTY, MEMBERSHIP & etc as will be more system centric than customer + + customersRow = new Row( + new Field("ID", Datas.STRING, Formats.STRING), + new Field("SEARCHKEY", Datas.STRING, Formats.STRING), + new Field("TAXID", Datas.STRING, Formats.STRING), + new Field("NAME", Datas.STRING, Formats.STRING), + new Field("TAXCATEGORY", Datas.STRING, Formats.STRING), + new Field("CARD", Datas.STRING, Formats.STRING), + new Field("MAXDEBT", Datas.DOUBLE, Formats.CURRENCY), + new Field("ADDRESS", Datas.STRING, Formats.STRING), + new Field("ADDRESS2", Datas.STRING, Formats.STRING), + new Field("POSTAL", Datas.STRING, Formats.STRING), + new Field("CITY", Datas.STRING, Formats.STRING), + new Field("REGION", Datas.STRING, Formats.STRING), + new Field("COUNTRY", Datas.STRING, Formats.STRING), + new Field("FIRSTNAME", Datas.STRING, Formats.STRING), + new Field("LASTNAME", Datas.STRING, Formats.STRING), + new Field("EMAIL", Datas.STRING, Formats.STRING), + new Field("PHONE", Datas.STRING, Formats.STRING), + new Field("PHONE2", Datas.STRING, Formats.STRING), + new Field("FAX", Datas.STRING, Formats.STRING), + new Field("NOTES", Datas.STRING, Formats.STRING), + new Field("VISIBLE", Datas.BOOLEAN, Formats.BOOLEAN), + new Field("CURDATE", Datas.STRING, Formats.TIMESTAMP), + new Field("CURDEBT", Datas.DOUBLE, Formats.CURRENCY), + new Field("IMAGE", Datas.BYTES, Formats.NULL), + new Field("ISVIP", Datas.BOOLEAN, Formats.BOOLEAN), + new Field("DISCOUNT", Datas.DOUBLE, Formats.CURRENCY), + new Field("MEMODATE", Datas.STRING, Formats.TIMESTAMP) + ); + + } + + /** + * + * @param s + */ + @Override + public void init(Session s){ + this.s = s; + + m_createCat = new StaticSentence(s, + "INSERT INTO categories ( ID, NAME, CATSHOWNAME ) " + + "VALUES (?, ?, ?)" + , new SerializerWriteBasic(new Datas[]{ + Datas.STRING, + Datas.STRING, + Datas.BOOLEAN}) + ); + + m_createSupp = new StaticSentence(s, + "INSERT INTO suppliers ( ID, NAME, SEARCHKEY, VISIBLE ) " + + "VALUES (?, ?, ?, ?)" + , new SerializerWriteBasic(new Datas[]{ + Datas.STRING, + Datas.STRING, + Datas.STRING, + Datas.BOOLEAN}) + ); + } + + // Import Creates + public final void createCategory(Object[] category) throws BasicException { + m_createCat.exec(category); + } + + public final void createSupplier(Object[] supplier) throws BasicException { + m_createSupp.exec(supplier); + } +// End Import Creates + + public final Row getProductsRow() { + return productsRow; + } + + public final Row getCustomersRow() { + return customersRow; + } + + /** + * + * @param id + * @return + * @throws BasicException + */ + public final ProductInfoExt getProductInfo(String id) throws BasicException { + return (ProductInfoExt) new PreparedSentence(s + , "SELECT " + + "ID, " + + "REFERENCE, " + + "CODE, " + + "CODETYPE, " + + "NAME, " + + "PRICEBUY, " + + "PRICESELL, " + + "CATEGORY, " + + "TAXCAT, " + + "ATTRIBUTESET_ID, " + + "STOCKCOST, " + + "STOCKVOLUME, " + + "IMAGE, " + + "ISCOM, " + + "ISSCALE, " + + "ISCONSTANT, " + + "PRINTKB, " + + "SENDSTATUS, " + + "ISSERVICE, " + + "ATTRIBUTES, " + + "DISPLAY, " + + "ISVPRICE, " + + "ISVERPATRIB, " + + "TEXTTIP, " + + "WARRANTY, " + + "STOCKUNITS, " + + "PRINTTO, " + + "SUPPLIER, " + + "UOM, " + + "MEMODATE " + + "FROM products WHERE ID = ?" + , SerializerWriteString.INSTANCE + , ProductInfoExt.getSerializerRead()).find(id); + } + + public final ProductInfoExt getProductInfoByCode(String sCode) throws BasicException { +// if (sCode.length() == 13 && (sCode.startsWith("2") || sCode.startsWith("02"))) +// return getProductInfoByShortCode(sCode); +// else { + return (ProductInfoExt) new PreparedSentence(s + , "SELECT " + + "ID, " + + "REFERENCE, " + + "CODE, " + + "CODETYPE, " + + "NAME, " + + "PRICEBUY, " + + "PRICESELL, " + + "CATEGORY, " + + "TAXCAT, " + + "ATTRIBUTESET_ID, " + + "STOCKCOST, " + + "STOCKVOLUME, " + + "IMAGE, " + + "ISCOM, " + + "ISSCALE, " + + "ISCONSTANT, " + + "PRINTKB, " + + "SENDSTATUS, " + + "ISSERVICE, " + + "ATTRIBUTES, " + + "DISPLAY, " + + "ISVPRICE, " + + "ISVERPATRIB, " + + "TEXTTIP, " + + "WARRANTY, " + + "STOCKUNITS, " + + "PRINTTO, " + + "SUPPLIER, " + + "UOM, " + + "MEMODATE " + + "FROM products WHERE CODE = ?" + , SerializerWriteString.INSTANCE + , ProductInfoExt.getSerializerRead()).find(sCode); +// } + } + + public final ProductInfoExt getProductInfoByShortCode(String sCode) throws BasicException { + + return (ProductInfoExt) new PreparedSentence(s + , "SELECT " + + "ID, " + + "REFERENCE, " + + "CODE, " + + "CODETYPE, " + + "NAME, " + + "PRICEBUY, " + + "PRICESELL, " + + "CATEGORY, " + + "TAXCAT, " + + "ATTRIBUTESET_ID, " + + "STOCKCOST, " + + "STOCKVOLUME, " + + "IMAGE, " + + "ISCOM, " + + "ISSCALE, " + + "ISCONSTANT, " + + "PRINTKB, " + + "SENDSTATUS, " + + "ISSERVICE, " + + "ATTRIBUTES, " + + "DISPLAY, " + + "ISVPRICE, " + + "ISVERPATRIB, " + + "TEXTTIP, " + + "WARRANTY, " + + "STOCKUNITS, " + + "PRINTTO, " + + "SUPPLIER, " + + "UOM, " + + "MEMODATE " + + "FROM products " + + "WHERE SUBSTRING( CODE, 3, 6 ) = ?" + , SerializerWriteString.INSTANCE + , ProductInfoExt.getSerializerRead()).find(sCode.substring(2, 8)); + } + + /* + * Important Note: + * Deliberately extracted from other code to force strict UPC-A (full 12 digits) + * Why? Because other manf' or in-store codes may exist and we just need a single + * record returned. Also, handling things this way will allow use (future) of a + * COUPON code (5 or 9 normally used) in-store + * + */ + public final ProductInfoExt getProductInfoByUShortCode(String sCode) throws BasicException { + + return (ProductInfoExt) new PreparedSentence(s + , "SELECT " + + "ID, " + + "REFERENCE, " + + "CODE, " + + "CODETYPE, " + + "NAME, " + + "PRICEBUY, " + + "PRICESELL, " + + "CATEGORY, " + + "TAXCAT, " + + "ATTRIBUTESET_ID, " + + "STOCKCOST, " + + "STOCKVOLUME, " + + "IMAGE, " + + "ISCOM, " + + "ISSCALE, " + + "ISCONSTANT, " + + "PRINTKB, " + + "SENDSTATUS, " + + "ISSERVICE, " + + "ATTRIBUTES, " + + "DISPLAY, " + + "ISVPRICE, " + + "ISVERPATRIB, " + + "TEXTTIP, " + + "WARRANTY, " + + "STOCKUNITS, " + + "PRINTTO, " + + "SUPPLIER, " + + "UOM, " + + "MEMODATE " + + "FROM products " + + "WHERE LEFT( CODE, 7 ) = ? AND CODETYPE = 'UPC-A' " +// selection of 7 digits ie: 2123456 specific to allow for other 12 digit +// codes that may be in use at positions 234567 +// last digit (position 7) can be used to identify COUPON (5 or 9) - FUTURE + , SerializerWriteString.INSTANCE + , ProductInfoExt.getSerializerRead()) + .find(sCode.substring(0, 7)); + } + + /** + * + * @param sReference + * @return + * @throws BasicException + */ + public final ProductInfoExt getProductInfoByReference(String sReference) throws BasicException { + return (ProductInfoExt) new PreparedSentence(s + , "SELECT " + + "ID, " + + "REFERENCE, " + + "CODE, " + + "CODETYPE, " + + "NAME, " + + "PRICEBUY, " + + "PRICESELL, " + + "CATEGORY, " + + "TAXCAT, " + + "ATTRIBUTESET_ID, " + + "STOCKCOST, " + + "STOCKVOLUME, " + + "IMAGE, " + + "ISCOM, " + + "ISSCALE, " + + "ISCONSTANT, " + + "PRINTKB, " + + "SENDSTATUS, " + + "ISSERVICE, " + + "ATTRIBUTES, " + + "DISPLAY, " + + "ISVPRICE, " + + "ISVERPATRIB, " + + "TEXTTIP, " + + "WARRANTY, " + + "STOCKUNITS, " + + "PRINTTO, " + + "SUPPLIER, " + + "UOM, " + + "MEMODATE " + + "FROM products WHERE REFERENCE = ?" + , SerializerWriteString.INSTANCE + , ProductInfoExt.getSerializerRead()).find(sReference); + } + + /** + * + * @return + * @throws BasicException + */ + public final List<CategoryInfo> getRootCategories() throws BasicException { + return new PreparedSentence(s + , "SELECT " + + "ID, " + + "NAME, " + + "IMAGE, " + + "TEXTTIP, " + + "CATSHOWNAME, " + + "CATORDER " + + "FROM categories " + + "WHERE PARENTID IS NULL AND CATSHOWNAME = " + s.DB.TRUE() + " " + + "ORDER BY CATORDER, NAME" + , null + , CategoryInfo.getSerializerRead()).list(); + } + + /** + * + * @param category + * @return + * @throws BasicException + */ + public final List<CategoryInfo> getSubcategories(String category) throws BasicException { + return new PreparedSentence(s + , "SELECT " + + "ID, " + + "NAME, " + + "IMAGE, " + + "TEXTTIP, " + + "CATSHOWNAME, " + + "CATORDER " + + "FROM categories WHERE PARENTID = ? " + + "ORDER BY CATORDER, NAME" + , SerializerWriteString.INSTANCE + , CategoryInfo.getSerializerRead()).list(category); + } + + /** + * + * @param category + * @return + * @throws BasicException + */ + public List<ProductInfoExt> getProductCatalog(String category) throws BasicException { + return new PreparedSentence(s + , "SELECT " + + "P.ID, " + + "P.REFERENCE, " + + "P.CODE, " + + "P.CODETYPE, " + + "P.NAME, " + + "P.PRICEBUY, " + + "P.PRICESELL, " + + "P.CATEGORY, " + + "P.TAXCAT, " + + "P.ATTRIBUTESET_ID, " + + "P.STOCKCOST, " + + "P.STOCKVOLUME, " + + "P.IMAGE, " + + "P.ISCOM, " + + "P.ISSCALE, " + + "P.ISCONSTANT, " + + "P.PRINTKB, " + + "P.SENDSTATUS, " + + "P.ISSERVICE, " + + "P.ATTRIBUTES, " + + "P.DISPLAY, " + + "P.ISVPRICE, " + + "P.ISVERPATRIB, " + + "P.TEXTTIP, " + + "P.WARRANTY, " + + "P.STOCKUNITS, " + + "P.PRINTTO, " + + "P.SUPPLIER, " + + "P.UOM, " + + "P.MEMODATE " + + "FROM products P, products_cat O " + + "WHERE P.ID = O.PRODUCT AND P.CATEGORY = ? " + + "ORDER BY O.CATORDER, P.NAME " + , SerializerWriteString.INSTANCE + , ProductInfoExt.getSerializerRead()).list(category); + } + + /** + * + * @param id + * @return + * @throws BasicException + */ + public List<ProductInfoExt> getProductComments(String id) throws BasicException { + return new PreparedSentence(s + , "SELECT " + + "P.ID, " + + "P.REFERENCE, " + + "P.CODE, " + + "P.CODETYPE, " + + "P.NAME, " + + "P.PRICEBUY, " + + "P.PRICESELL, " + + "P.CATEGORY, " + + "P.TAXCAT, " + + "P.ATTRIBUTESET_ID, " + + "P.STOCKCOST, " + + "P.STOCKVOLUME, " + + "P.IMAGE, " + + "P.ISCOM, " + + "P.ISSCALE, " + + "P.ISCONSTANT, " + + "P.PRINTKB, " + + "P.SENDSTATUS, " + + "P.ISSERVICE, " + + "P.ATTRIBUTES, " + + "P.DISPLAY, " + + "P.ISVPRICE, " + + "P.ISVERPATRIB, " + + "P.TEXTTIP, " + + "P.WARRANTY, " + + "P.STOCKUNITS, " + + "P.PRINTTO, " + + "P.SUPPLIER, " + + "P.UOM, " + + "P.MEMODATE " + + "FROM products P, " + + "products_cat O, products_com M " + + "WHERE P.ID = O.PRODUCT AND P.ID = M.PRODUCT2 AND M.PRODUCT = ? " + + "AND P.ISCOM = " + s.DB.TRUE() + " " + + "ORDER BY O.CATORDER, P.NAME" + , SerializerWriteString.INSTANCE + , ProductInfoExt.getSerializerRead()).list(id); + } + + // JG uniCenta June 2014 includes StockUnits + /** + * + * @return + * @throws BasicException + */ + public List<ProductInfoExt> getProductConstant() throws BasicException { + return new PreparedSentence(s + , "SELECT " + + "products.ID, " + + "products.REFERENCE, " + + "products.CODE, " + + "products.CODETYPE, " + + "products.NAME, " + + "products.PRICEBUY, " + + "products.PRICESELL, " + + "products.CATEGORY, " + + "products.TAXCAT, " + + "products.ATTRIBUTESET_ID, " + + "products.STOCKCOST, " + + "products.STOCKVOLUME, " + + "products.IMAGE, " + + "products.ISCOM, " + + "products.ISSCALE, " + + "products.ISCONSTANT, " + + "products.PRINTKB, " + + "products.SENDSTATUS, " + + "products.ISSERVICE, " + + "products.ATTRIBUTES, " + + "products.DISPLAY, " + + "products.ISVPRICE, " + + "products.ISVERPATRIB, " + + "products.TEXTTIP, " + + "products.WARRANTY, " + + "products.STOCKUNITS, " + + "products.PRINTTO, " + + "products.SUPPLIER, " + + "products.UOM, " + + "products.MEMODATE " + + "FROM categories INNER JOIN products ON (products.CATEGORY = categories.ID) " + + "WHERE products.ISCONSTANT = " +s.DB.TRUE()+ " " + + "ORDER BY categories.NAME, products.NAME", + null, + ProductInfoExt.getSerializerRead()).list(); + + + } + + /** + * + * @param id + * @return + * @throws BasicException + */ + public final CategoryInfo getCategoryInfo(String id) throws BasicException { + return (CategoryInfo) new PreparedSentence(s + , "SELECT " + + "ID, " + + "NAME, " + + "IMAGE, " + + "TEXTTIP, " + + "CATSHOWNAME, " + + "CATORDER " + + "FROM categories " + + "WHERE ID = ? " + + "ORDER BY CATORDER, NAME" + , SerializerWriteString.INSTANCE + , CategoryInfo.getSerializerRead()).find(id); + } + + /** + * JG Dec 2017 + * @param pId + * @return + * @throws BasicException + */ + @SuppressWarnings("unchecked") + public final List<CategoryStock> getCategorysProductList(String pId) throws BasicException { + return new PreparedSentence(s, + "SELECT products.ID, " + + "products.NAME AS Name, " + + "products.CODE AS Barcode, " + + "categories.ID AS Category " + + "FROM products products " + + "INNER JOIN categories categories ON (products.CATEGORY = categories.ID) " + + "WHERE products.category = ? " + + "ORDER BY products.NAME ASC", + SerializerWriteString.INSTANCE, + CategoryStock.getSerializerRead()).list(pId); + } + + /** + * + * @return + */ + + public final SentenceList getProductList() { + return new StaticSentence(s + , new QBFBuilder( + "SELECT " + + "ID, " + + "REFERENCE, " + + "CODE, " + + "CODETYPE, " + + "NAME, " + + "PRICEBUY, " + + "PRICESELL, " + + "CATEGORY, " + + "TAXCAT, " + + "ATTRIBUTESET_ID, " + + "STOCKCOST, " + + "STOCKVOLUME, " + + "IMAGE, " + + "ISCOM, " + + "ISSCALE, " + + "ISCONSTANT, " + + "PRINTKB, " + + "SENDSTATUS, " + + "ISSERVICE, " + + "ATTRIBUTES, " + + "DISPLAY, " + + "ISVPRICE, " + + "ISVERPATRIB, " + + "TEXTTIP, " + + "WARRANTY, " + + "STOCKUNITS, " + + "PRINTTO, " + + "SUPPLIER, " + + "UOM, " + + "MEMODATE " + + "FROM products " + + "WHERE ?(QBF_FILTER) " + + "ORDER BY REFERENCE", + new String[] {"NAME", "PRICEBUY", "PRICESELL", "CATEGORY", "CODE"}) + , new SerializerWriteBasic(new Datas[] { + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.DOUBLE, + Datas.OBJECT, Datas.DOUBLE, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING}) + , ProductInfoExt.getSerializerRead()); + } + + /** + * + * @return + */ + public SentenceList getProductListNormal() { + return new StaticSentence(s + , new QBFBuilder( + "SELECT " + + "ID, " + + "REFERENCE, " + + "CODE, " + + "CODETYPE, " + + "NAME, " + + "PRICEBUY, " + + "PRICESELL, " + + "CATEGORY, " + + "TAXCAT, " + + "ATTRIBUTESET_ID, " + + "STOCKCOST, " + + "STOCKVOLUME, " + + "IMAGE, " + + "ISCOM, " + + "ISSCALE, " + + "ISCONSTANT, " + + "PRINTKB, " + + "SENDSTATUS, " + + "ISSERVICE, " + + "ATTRIBUTES, " + + "DISPLAY, " + + "ISVPRICE, " + + "ISVERPATRIB, " + + "TEXTTIP, " + + "WARRANTY, " + + "STOCKUNITS, " + + "PRINTTO, " + + "SUPPLIER, " + + "UOM, " + + "MEMODATE " + + "FROM products " + + "WHERE ISCOM = " + s.DB.FALSE() + " AND ?(QBF_FILTER) ORDER BY REFERENCE", + new String[] {"NAME", "PRICEBUY", "PRICESELL", "CATEGORY", "CODE"}) + , new SerializerWriteBasic(new Datas[] { + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.DOUBLE, + Datas.OBJECT, Datas.DOUBLE, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING}) + , ProductInfoExt.getSerializerRead()); + } + + /** + * + * @return + */ + public SentenceList getProductsList() { + return new StaticSentence(s + , "SELECT " + + "ID, " + + "REFERENCE, " + + "CODE, " + + "CODETYPE, " + + "NAME, " + + "PRICEBUY, " + + "PRICESELL, " + + "CATEGORY, " + + "TAXCAT, " + + "ATTRIBUTESET_ID, " + + "STOCKCOST, " + + "STOCKVOLUME, " + + "IMAGE, " + + "ISCOM, " + + "ISSCALE, " + + "ISCONSTANT, " + + "PRINTKB, " + + "SENDSTATUS, " + + "ISSERVICE, " + + "ATTRIBUTES, " + + "DISPLAY, " + + "ISVPRICE, " + + "ISVERPATRIB, " + + "TEXTTIP, " + + "WARRANTY, " + + "STOCKUNITS, " + + "PRINTTO, " + + "SUPPLIER, " + + "UOM, " + + "MEMODATE " + + "FROM products " + + "ORDER BY NAME" + , null + , ProductInfo.getSerializerRead()); + } + + public SentenceList getProductList2() { + return new StaticSentence(s + , new QBFBuilder( + "SELECT " + + "products.id, " + + "products.name, " + + "stockcurrent.units, " + + "locations.name, " + + "products.pricesell, " + + "taxes.rate, " + + "products.pricesell + (products.pricesell * taxes.rate) AS SellIncTax " + + " FROM (((stockcurrent stockcurrent " + + "INNER JOIN locations locations " + + "ON (stockcurrent.location = locations.id)) " + + "INNER JOIN products products " + + "ON (stockcurrent.product = products.id)) " + + "INNER JOIN taxcategories taxcategories " + + "ON (products.taxcat = taxcategories.id)) " + + "INNER JOIN taxes taxes " + + "ON (taxes.category = taxcategories.id) " + + "WHERE ?(QBF_FILTER) " + + "GROUP BY products.name ", + new String[] {"NAME", "UNITS", "SellIncTax", "LOCATION",}) + , new SerializerWriteBasic(new Datas[] { + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.DOUBLE, + Datas.OBJECT, Datas.DOUBLE, + Datas.OBJECT, Datas.STRING}) + , ProductInfoExt.getSerializerRead()); + } + + /** + * + * @return + */ + public SentenceList getProductListAuxiliar() { + return new StaticSentence(s + , new QBFBuilder( + "SELECT " + + "ID, " + + "REFERENCE, " + + "CODE, " + + "CODETYPE, " + + "NAME, " + + "PRICEBUY, " + + "PRICESELL, " + + "CATEGORY, " + + "TAXCAT, " + + "ATTRIBUTESET_ID, " + + "STOCKCOST, " + + "STOCKVOLUME, " + + "IMAGE, " + + "ISCOM, " + + "ISSCALE, " + + "ISCONSTANT, " + + "PRINTKB, " + + "SENDSTATUS, " + + "ISSERVICE, " + + "ATTRIBUTES, " + + "DISPLAY, " + + "ISVPRICE, " + + "ISVERPATRIB, " + + "TEXTTIP, " + + "WARRANTY, " + + "STOCKUNITS, " + + "PRINTTO, " + + "SUPPLIER, " + + "UOM, " + + "MEMODATE " + + "FROM products " + + "WHERE ISCOM = " + s.DB.TRUE() + " AND ?(QBF_FILTER) " + + "ORDER BY REFERENCE", new String[] {"NAME", "PRICEBUY", "PRICESELL", "CATEGORY", "CODE"}) + , new SerializerWriteBasic(new Datas[] { + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.DOUBLE, + Datas.OBJECT, Datas.DOUBLE, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING}) + , ProductInfoExt.getSerializerRead()); + } + + /** + * + * @param productId The product id to look for bundle + * @return List of products part of the searched product + * @throws BasicException + */ + public final List<ProductsBundleInfo> getProductsBundle(String productId) throws BasicException { + return new PreparedSentence(s + , "SELECT " + + "ID, " + + "PRODUCT, " + + "PRODUCT_BUNDLE, " + + "QUANTITY " + + "FROM products_bundle WHERE PRODUCT = ?" + , SerializerWriteString.INSTANCE + , ProductsBundleInfo.getSerializerRead()).list(productId); + } + + /** + * JG Oct 2016 + * Called from JPanelTicket + * @param pId + * @param location + * @return + * @throws BasicException + */ + public final ProductStock getProductStockState(String pId, String location) throws BasicException { + + PreparedSentence preparedSentence = new PreparedSentence(s, + "SELECT " + + "MIN(products.id), " + + "locations.id as Location, " + + "MIN(stockcurrent.units), " + + "MIN(stocklevel.stocksecurity) AS Minimum, " + + "MIN(stocklevel.stockmaximum) AS Maximum, " + + "MIN(products.pricebuy), " + + "MIN(products.pricesell), " + + "MIN(products.memodate) " + + "FROM locations " + + "INNER JOIN ((products " + + "INNER JOIN stockcurrent " + + "ON products.id = stockcurrent.product) " + + "LEFT JOIN stocklevel ON products.id = stocklevel.product) " + + "ON locations.id = stockcurrent.location " + + "WHERE products.id = ? " + + "AND locations.id = ?" + , SerializerWriteString.INSTANCE + , ProductStock.getSerializerRead()); + + ProductStock productStock = (ProductStock) preparedSentence.find(pId, location); + + return productStock; + } + + /** + * JG May 2016 + * Called from StockManagement + * @param pId + * @return + * @throws BasicException + */ + @SuppressWarnings("unchecked") + public final List<ProductStock> getProductStockList(String pId) throws BasicException { + return new PreparedSentence(s, + "SELECT MIN(products.id), " + + "MIN(locations.name) AS Location, " + + "MIN(stockcurrent.units) AS stockcurrent, " + + "MIN(stocklevel.stocksecurity) AS Minimum, " + + "MIN(stocklevel.stockmaximum) AS Maximum, " + + "MIN(products.pricebuy) AS PriceBuy, " + + "(MIN(products.pricesell) * MIN(taxes.rate)) + MIN(products.pricesell) AS PriceSell, " + + "MIN(products.memodate) " + + "FROM ((((taxcategories TC " + + "INNER JOIN taxes taxes " + + "ON (TC.id = taxes.category)) " + + "RIGHT OUTER JOIN products products " + + "ON (products.TAXCAT = TC.id)) " + + "LEFT OUTER JOIN stocklevel stocklevel " + + "ON (stocklevel.product = products.ID)) " + + "LEFT OUTER JOIN stockcurrent stockcurrent " + + "ON (products.ID = stockcurrent.product)) " + + "INNER JOIN locations locations " + + "ON (stockcurrent.location = locations.id) " + + "WHERE products.id= ? " + + "GROUP BY locations.name", + SerializerWriteString.INSTANCE, + ProductStock.getSerializerRead()).list(pId); + } + + /** + * JG Sept 2017 + * @return + * @throws BasicException + */ + @SuppressWarnings("unchecked") + public final List<ReprintTicketInfo> getReprintTicketList() throws BasicException { + + //payment queries + List<ReprintTicketInfo> ticketInfoList = (List<ReprintTicketInfo>) new StaticSentence(s + , "SELECT " + + "T.TICKETID, " + + "T.TICKETTYPE, " + + "R.DATENEW, " + + "P.NAME, " + + "C.NAME, " + + "SUM(PM.TOTAL), " + + "T.STATUS " + + "FROM receipts " + + "R JOIN tickets T ON R.ID = T.ID LEFT OUTER JOIN payments PM " + + "ON R.ID = PM.RECEIPT LEFT OUTER JOIN customers C " + + "ON C.ID = T.CUSTOMER LEFT OUTER JOIN people P ON T.PERSON = P.ID " + + "GROUP BY " + + "T.ID, " + + "T.TICKETID, " + + "T.TICKETTYPE, " + + "R.DATENEW, " + + "P.NAME, " + + "C.NAME " + + "ORDER BY R.DATENEW DESC, T.TICKETID " + + "LIMIT 10 " + , null + , new SerializerReadClass(ReprintTicketInfo.class)).list(); + + return ticketInfoList; + } + + /** + * + * @param Id + * @return + * @throws BasicException + */ + public final TicketInfo getReprintTicket(String Id) throws BasicException { + + //payment queries + + if (Id == null) { + return null; + } else { + Object[]record = (Object[]) new StaticSentence(s + , "SELECT " + + "T.TICKETID, " + + "SUM(PM.TOTAL), " + + "R.DATENEW, " + + "P.NAME, " + + "T.TICKETTYPE, " + + "C.NAME, " + + "T.STATUS " + + "FROM receipts R " + + "JOIN tickets T ON R.ID = T.ID LEFT OUTER JOIN payments PM " + + "ON R.ID = PM.RECEIPT LEFT OUTER JOIN customers C " + + "ON C.ID = T.CUSTOMER LEFT OUTER JOIN people P ON T.PERSON = P.ID " + + "WHERE T.TICKETID = ?" + , SerializerWriteString.INSTANCE + , new SerializerReadBasic(new Datas[] {Datas.SERIALIZABLE})).find(Id); + return record == null ? null : (TicketInfo) record[0]; + } + } + + //Tickets and Receipt list + + // Payment queries + public SentenceList getTicketsList() { + + + StaticSentence staticSentence = new StaticSentence(s + , new QBFBuilder( + "SELECT " + + "T.TICKETID, " + + "T.TICKETTYPE, " + + "R.DATENEW, " + + "P.NAME, " + + "C.NAME, " + + "SUM(PM.TOTAL), " + + "SUM(T.STATUS), " + + "PM.notes " + + "FROM receipts R " + + "JOIN tickets T ON R.ID = T.ID LEFT OUTER JOIN payments PM " + + "ON R.ID = PM.RECEIPT LEFT OUTER JOIN customers C " + + "ON C.ID = T.CUSTOMER LEFT OUTER JOIN people P ON T.PERSON = P.ID " + + "WHERE ?(QBF_FILTER) " + + "GROUP BY T.ID, T.TICKETID, T.TICKETTYPE, R.DATENEW, P.NAME, C.NAME, PM.notes " + + "ORDER BY R.DATENEW DESC, T.TICKETID", + new String[]{ + "T.TICKETID", "T.TICKETTYPE", "PM.TOTAL", "R.DATENEW", "R.DATENEW", "P.NAME", "C.NAME", "PM.NOTES"}) + , new SerializerWriteBasic(new Datas[]{ + Datas.OBJECT, Datas.INT, + Datas.OBJECT, Datas.INT, + Datas.OBJECT, Datas.DOUBLE, + Datas.OBJECT, Datas.TIMESTAMP, + Datas.OBJECT, Datas.TIMESTAMP, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING}) + , new SerializerReadClass(FindTicketsInfo.class)); + + return staticSentence; + } + + //User list + + /** + * + * @return + */ + public final SentenceList getUserList() { + return new StaticSentence(s + , "SELECT " + + "ID, " + + "NAME " + + "FROM people " + + "ORDER BY NAME" + , null + , (DataRead dr) -> new TaxCategoryInfo( + dr.getString(1), + dr.getString(2))); + } + + /** + * + * @return + */ + public final SentenceList getTaxList() { + return new StaticSentence(s + , "SELECT " + + "ID, " + + "NAME, " + + "CATEGORY, " + + "CUSTCATEGORY, " + + "PARENTID, " + + "RATE, " + + "RATECASCADE, " + + "RATEORDER " + + "FROM taxes " + + "ORDER BY NAME" + , null + , (DataRead dr) -> new TaxInfo( + dr.getString(1), + dr.getString(2), + dr.getString(3), + dr.getString(4), + dr.getString(5), + dr.getDouble(6), + dr.getBoolean(7), + dr.getInt(8))); + } + + /** + * + * @return + */ + public final SentenceList getCategoriesList() { + return new StaticSentence(s + , "SELECT " + + "ID, " + + "NAME, " + + "IMAGE, " + + "TEXTTIP, " + + "CATSHOWNAME, " + + "CATORDER " + + "FROM categories " + + "ORDER BY NAME" + , null + , CategoryInfo.getSerializerRead()); + } + /** + * JG Feb 2017 + * Returns all PARENT categories + * @return + */ + public final SentenceList getCategoriesList_1() { + return new StaticSentence(s + , "SELECT " + + "ID, " + + "NAME, " + + "IMAGE, " + + "TEXTTIP, " + + "CATSHOWNAME, " + + "CATORDER " + + "FROM categories " + + "WHERE PARENTID IS NULL " + + "ORDER BY NAME" + , null + , CategoryInfo.getSerializerRead()); + } + /** + * + * @return + */ + public final SentenceList getSuppList() { + return new StaticSentence(s + , "SELECT " + + "ID, " + + "SEARCHKEY, " + + "NAME " + + "FROM suppliers " + + "ORDER BY NAME" + , null + , (DataRead dr) -> new SupplierInfo( + dr.getString(1), + dr.getString(2), + dr.getString(3))); + } + + /** + * + * @return + */ + public final SentenceList getTaxCustCategoriesList() { + return new StaticSentence(s + , "SELECT " + + "ID, " + + "NAME " + + "FROM taxcustcategories " + + "ORDER BY NAME" + , null + , (DataRead dr) -> new TaxCustCategoryInfo( + dr.getString(1), + dr.getString(2))); + } + + /** + * + * @param id + * @return + * @throws BasicException + */ + public final CustomerInfoExt getCustomerInfo(String id) throws BasicException { + return (CustomerInfoExt) new PreparedSentence(s + , "SELECT " + + "ID, " + + "SEARCHKEY, " + + "TAXID, " + + "NAME, " + + "TAXCATEGORY, " + + "CARD, " + + "MAXDEBT, " + + "ADDRESS, " + + "ADDRESS2, " + + "POSTAL, " + + "CITY, " + + "REGION, " + + "COUNTRY, " + + "FIRSTNAME, " + + "LASTNAME, " + + "EMAIL, " + + "PHONE, " + + "PHONE2, " + + "FAX, " + + "NOTES, " + + "VISIBLE, " + + "CURDATE, " + + "CURDEBT, " + + "IMAGE, " + + "ISVIP, " + + "DISCOUNT, " + + "MEMODATE " + + "FROM customers WHERE ID = ?" + , SerializerWriteString.INSTANCE + , new CustomerExtRead()).find(id); + } + + /** + * JG Apr 2017 - Revised to return Customer Id - cId param + * @param cId + * @return + * @throws BasicException + */ + @SuppressWarnings("unchecked") + public final List<CustomerTransaction> getCustomersTransactionList(String cId) throws BasicException { + + return new PreparedSentence(s, + "SELECT tickets.TICKETID, " + + "products.NAME AS PNAME, " + + "SUM(ticketlines.UNITS) AS UNITS, " + + "SUM(ticketlines.UNITS * ticketlines.PRICE) AS AMOUNT, " + + "SUM(ticketlines.UNITS * ticketlines.PRICE * (1.0 + taxes.RATE)) AS TOTAL, " + + "receipts.DATENEW, " + + "customers.ID AS CID " + + "FROM ((((ticketlines ticketlines " + + "CROSS JOIN taxes taxes ON (ticketlines.TAXID = taxes.ID)) " + + "INNER JOIN tickets tickets ON (tickets.ID = ticketlines.TICKET)) " + + "INNER JOIN customers customers ON (customers.ID = tickets.CUSTOMER)) " + + "INNER JOIN receipts receipts ON (tickets.ID = receipts.ID)) " + + "LEFT OUTER JOIN products products ON (ticketlines.PRODUCT = products.ID) " + + "WHERE tickets.CUSTOMER = ? " + + "GROUP BY customers.ID, receipts.DATENEW, tickets.TICKETID, " + + "products.NAME, tickets.TICKETTYPE " + + "ORDER BY receipts.DATENEW DESC", + SerializerWriteString.INSTANCE, + CustomerTransaction.getSerializerRead()).list(cId); + } + + /** + * + * @return + */ + public final SentenceList getTaxCategoriesList() { + return new StaticSentence(s + , "SELECT " + + "ID, " + + "NAME " + + "FROM taxcategories " + + "ORDER BY NAME" + , null + , (DataRead dr) -> new TaxCategoryInfo(dr.getString(1), dr.getString(2))); + } + + /** + * + * @return + */ + public final SentenceList getAttributeSetList() { + return new StaticSentence(s + , "SELECT " + + "ID, " + + "NAME " + + "FROM attributeset " + + "ORDER BY NAME" + , null + , (DataRead dr) -> new AttributeSetInfo(dr.getString(1), dr.getString(2))); + } + + /** + * + * @return + */ + public final SentenceList getLocationsList() { + return new StaticSentence(s + , "SELECT " + + "ID, " + + "NAME, " + + "ADDRESS FROM locations " + + "ORDER BY NAME" + , null + , new SerializerReadClass(LocationInfo.class)); + } + + /** + * + * @return + */ + public final SentenceList getFloorsList() { + return new StaticSentence(s + , "SELECT ID, NAME FROM floors ORDER BY NAME" + , null + , new SerializerReadClass(FloorsInfo.class)); + } + /** + * + * @return + */ + public final SentenceList getFloorTablesList() { + return new StaticSentence(s + , "SELECT ID, NAME, SEATS, width, height FROM places ORDER BY NAME" + , null + , new SerializerReadClass(FloorsInfo.class)); + } + + + /** + * + * @param card + * @return + * @throws BasicException + */ + public CustomerInfoExt findCustomerExt(String card) throws BasicException { + return (CustomerInfoExt) new PreparedSentence(s + , "SELECT " + + "ID, " + + "TAXID, " + + "SEARCHKEY, " + + "NAME, " + + "TAXCATEGORY, " + + "CARD, " + + "MAXDEBT, " + + "ADDRESS, " + + "ADDRESS2, " + + "POSTAL, " + + "CITY, " + + "REGION, " + + "COUNTRY, " + + "FIRSTNAME, " + + "LASTNAME, " + + "EMAIL, " + + "PHONE, " + + "PHONE2, " + + "FAX, " + + "NOTES, " + + "VISIBLE, " + + "CURDATE, " + + "CURDEBT, " + + "IMAGE, " + + "ISVIP, " + + "DISCOUNT, " + + "MEMODATE " + + "FROM customers " + + "WHERE CARD = ? AND VISIBLE = " + s.DB.TRUE() + " " + + "ORDER BY NAME" + , SerializerWriteString.INSTANCE + , new CustomerExtRead()).find(card); + } + /** + * + * @param name + * @return + * @throws BasicException + */ + public CustomerInfoExt findCustomerName(String name) throws BasicException { + return (CustomerInfoExt) new PreparedSentence(s + , "SELECT " + + "ID, " + + "SEARCHKEY, " + + "TAXID, " + + "NAME, " + + "TAXCATEGORY, " + + "CARD, " + + "MAXDEBT, " + + "ADDRESS, " + + "ADDRESS2, " + + "POSTAL, " + + "CITY, " + + "REGION, " + + "COUNTRY, " + + "FIRSTNAME, " + + "LASTNAME, " + + "EMAIL, " + + "PHONE, " + + "PHONE2, " + + "FAX, " + + "NOTES, " + + "VISIBLE, " + + "CURDATE, " + + "CURDEBT, " + + "IMAGE, " + + "ISVIP, " + + "DISCOUNT, " + + "MEMODATE " + + "FROM customers " + + "WHERE NAME = ? AND VISIBLE = " + s.DB.TRUE() + " " + + "ORDER BY NAME" + , SerializerWriteString.INSTANCE + , new CustomerExtRead()).find(name); + } + + /** + * + * @param id + * @return + * @throws BasicException + */ + public CustomerInfoExt loadCustomerExt(String id) throws BasicException { + return (CustomerInfoExt) new PreparedSentence(s + , "SELECT " + + "ID, " + + "SEARCHKEY, " + + "TAXID, " + + "NAME, " + + "TAXCATEGORY, " + + "CARD, " + + "MAXDEBT, " + + "ADDRESS, " + + "ADDRESS2, " + + "POSTAL, " + + "CITY, " + + "REGION, " + + "COUNTRY, " + + "FIRSTNAME, " + + "LASTNAME, " + + "EMAIL, " + + "PHONE, " + + "PHONE2, " + + "FAX, " + + "NOTES, " + + "VISIBLE, " + + "CURDATE, " + + "CURDEBT, " + + "IMAGE, " + + "ISVIP, " + + "DISCOUNT, " + + "MEMODATE " + + "FROM customers WHERE ID = ?" + , SerializerWriteString.INSTANCE + , new CustomerExtRead()).find(id); + } + + /** + * Quick Customer create + * @param id + * @return + * @throws BasicException + */ + public CustomerInfoExt qCustomerExt(String id) throws BasicException { + return (CustomerInfoExt) new PreparedSentence(s + , "SELECT " + + "ID, " + + "SEARCHKEY, " + + "TAXID, " + + "NAME, " + + "TAXCATEGORY, " + + "MAXDEBT, " + + "FIRSTNAME, " + + "LASTNAME, " + + "EMAIL, " + + "PHONE, " + + "PHONE2, " + + "ISVIP, " + + "DISCOUNT " + + "FROM customers WHERE ID = ?" + , SerializerWriteString.INSTANCE + , new CustomerExtRead()).find(id); + } + + /** + * + * @param id + * @return + * @throws BasicException + */ + public final boolean isCashActive(String id) throws BasicException { + + return new PreparedSentence(s, + "SELECT MONEY FROM closedcash WHERE DATEEND IS NULL AND MONEY = ?", + SerializerWriteString.INSTANCE, + SerializerReadString.INSTANCE).find(id) + != null; + } + + /** + * + * @param tickettype + * @param ticketid + * @return + * @throws BasicException + */ + public final TicketInfo loadTicket(final int tickettype, final int ticketid) throws BasicException { + TicketInfo ticket = (TicketInfo) new PreparedSentence(s + , "SELECT " + + "T.ID, " + + "T.TICKETTYPE, " + + "T.TICKETID, " + + "R.DATENEW, " + + "R.MONEY, " + + "R.ATTRIBUTES, " + + "P.ID, " + + "P.NAME, " + + "T.CUSTOMER, " + + "T.STATUS " + + "FROM receipts R " + + "JOIN tickets T ON R.ID = T.ID " + + "LEFT OUTER JOIN people P ON T.PERSON = P.ID " + + "WHERE T.TICKETTYPE = ? AND T.TICKETID = ? " + + "ORDER BY R.DATENEW DESC" + , SerializerWriteParams.INSTANCE + , new SerializerReadClass(TicketInfo.class)) + .find(new DataParams() { + @Override + public void writeValues() throws BasicException { + setInt(1, tickettype); + setInt(2, ticketid); + }}); + + if (ticket != null) { + + String customerid = ticket.getCustomerId(); + ticket.setCustomer(customerid == null + ? null + : loadCustomerExt(customerid)); + + ticket.setLines(new PreparedSentence(s + , "SELECT L.TICKET, L.LINE, L.PRODUCT, L.ATTRIBUTESETINSTANCE_ID, " + + "L.UNITS, L.PRICE, T.ID, T.NAME, T.CATEGORY, T.CUSTCATEGORY, " + + "T.PARENTID, T.RATE, T.RATECASCADE, T.RATEORDER, L.ATTRIBUTES " + + "FROM ticketlines L, taxes T " + + "WHERE L.TAXID = T.ID AND L.TICKET = ? ORDER BY L.LINE" + , SerializerWriteString.INSTANCE + , new SerializerReadClass(TicketLineInfo.class)).list(ticket.getId())); + + ticket.setPayments(new PreparedSentence(s + , "SELECT PAYMENT, TOTAL, TRANSID, TENDERED, CARDNAME FROM payments WHERE RECEIPT = ?" + , SerializerWriteString.INSTANCE + , new SerializerReadClass(PaymentInfoTicket.class)).list(ticket.getId())); + } + return ticket; + } + + /** + * + * @param ticket + * @param location + * @throws BasicException + */ + public final void saveTicket(final TicketInfo ticket, final String location) throws BasicException { + + Transaction t; + t = new Transaction(s) { + @Override + public Object transact() throws BasicException { + + // Set Receipt Id + if (ticket.getTicketId() == 0) { + switch (ticket.getTicketType()) { + case TicketInfo.RECEIPT_NORMAL: + ticket.setTicketId(getNextTicketIndex()); + break; + case TicketInfo.RECEIPT_REFUND: + ticket.setTicketId(getNextTicketRefundIndex()); + break; + case TicketInfo.RECEIPT_PAYMENT: + ticket.setTicketId(getNextTicketPaymentIndex()); + break; + case TicketInfo.RECEIPT_NOSALE: + ticket.setTicketId(getNextTicketPaymentIndex()); + break; + default: + throw new BasicException(); + } + } + + new PreparedSentence(s + , "INSERT INTO receipts (ID, MONEY, DATENEW, ATTRIBUTES, PERSON) VALUES (?, ?, ?, ?, ?)" + , SerializerWriteParams.INSTANCE ) + .exec(new DataParams() { + + @Override + public void writeValues() throws BasicException { + setString(1, ticket.getId()); + setString(2, ticket.getActiveCash()); + setTimestamp(3, ticket.getDate()); + + try { + ByteArrayOutputStream o = new ByteArrayOutputStream(); + ticket.getProperties().storeToXML(o, AppLocal.APP_NAME, "UTF-8"); + setBytes(4, o.toByteArray()); + } catch (IOException e) { + setBytes(4, null); + } + setString(5, ticket.getProperty("person")); + } + }); + + // new ticket + new PreparedSentence(s + , "INSERT INTO tickets (ID, TICKETTYPE, TICKETID, PERSON, CUSTOMER, STATUS) " + + "VALUES (?, ?, ?, ?, ?, ?)" + , SerializerWriteParams.INSTANCE ) + .exec(new DataParams() { + + @Override + public void writeValues() throws BasicException { + setString(1, ticket.getId()); + setInt(2, ticket.getTicketType()); + setInt(3, ticket.getTicketId()); + setString(4, ticket.getUser().getId()); + setString(5, ticket.getCustomerId()); + setInt(6, ticket.getTicketStatus()); + } + }); + + // update status of existing ticket + new PreparedSentence(s + , "UPDATE tickets SET STATUS = ? " + + "WHERE TICKETTYPE = 0 AND TICKETID = ?" + , SerializerWriteParams.INSTANCE ) + .exec(new DataParams() { + + @Override + public void writeValues() throws BasicException { + setInt(1, ticket.getTicketId()); + setInt(2, ticket.getTicketStatus()); + } + }); + + SentenceExec ticketlineinsert = new PreparedSentence(s + , "INSERT INTO ticketlines (TICKET, LINE, " + + "PRODUCT, ATTRIBUTESETINSTANCE_ID, " + + "UNITS, PRICE, TAXID, ATTRIBUTES) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?)" + , SerializerWriteBuilder.INSTANCE); + + for (TicketLineInfo l : ticket.getLines()) { + ticketlineinsert.exec(l); + + if (l.getProductID() != null && l.isProductService() != true) { + getStockDiaryInsert().exec(new Object[] { + UUID.randomUUID().toString(), + ticket.getDate(), + l.getMultiply() < 0.0 + ? MovementReason.IN_REFUND.getKey() + : MovementReason.OUT_SALE.getKey(), + location, + l.getProductID(), + l.getProductAttSetInstId(), -l.getMultiply(), l.getPrice(), + ticket.getUser().getName() + }); + } + } + + final Payments payments = new Payments(); + SentenceExec paymentinsert = new PreparedSentence(s + , "INSERT INTO payments (ID, RECEIPT, PAYMENT, TOTAL, TRANSID, RETURNMSG, " + + "TENDERED, CARDNAME, VOUCHER, NOTES) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + , SerializerWriteParams.INSTANCE); + + ticket.getPayments().forEach((p) -> { + if (p instanceof PaymentInfoMagcard) { + payments.addPayment(p.getName(),p.getTotal(), p.getPaid(),ticket.getReturnMessage(), p.getVoucher(), ((PaymentInfoMagcard) p).getLastFourDigits()); + }else { + payments.addPayment(p.getName(),p.getTotal(), p.getPaid(),ticket.getReturnMessage(), p.getVoucher(), null); + } + + }); + while (payments.getSize()>=1){ + paymentinsert.exec(new DataParams() { + @Override + public void writeValues() throws BasicException { + pName = payments.getFirstElement(); + getTotal = payments.getPaidAmount(pName); + getTendered = payments.getTendered(pName); + getRetMsg = payments.getRtnMessage(pName); + + if (pName.contains("voucher")) { + getVoucher = payments.getVoucher(pName); + } + payments.removeFirst(pName); + + setString(1, UUID.randomUUID().toString()); + setString(2, ticket.getId()); + setString(3, pName); + setDouble(4, getTotal); + setString(5, ticket.getTransactionID()); + setBytes(6, (byte[]) Formats.BYTEA.parseValue(getRetMsg)); + setDouble(7, getTendered); + setString(8, getCardName); + setString(9, getVoucher); + setString(10, payments.getNote(pName)); + payments.removeFirst(pName); + } + }); + + if (pName.contains("voucher")) { + getVoucherNonActive().exec(payments.getVoucher(pName)); + } + + if ("debt".equals(pName) || "debtpaid".equals(pName)) { + ticket.getCustomer().updateCurDebt(getTotal, ticket.getDate()); + getDebtUpdate().exec(new DataParams() { + + @Override + public void writeValues() throws BasicException { + setDouble(1, ticket.getCustomer().getAccdebt()); + setTimestamp(2, ticket.getCustomer().getCurdate()); + setString(3, ticket.getCustomer().getId()); + } + }); + } + } + + SentenceExec taxlinesinsert = new PreparedSentence(s + , "INSERT INTO taxlines (ID, RECEIPT, TAXID, BASE, AMOUNT) " + + "VALUES (?, ?, ?, ?, ?)" + , SerializerWriteParams.INSTANCE); + + if (ticket.getTaxes() != null) { + for (final TicketTaxInfo tickettax: ticket.getTaxes()) { + taxlinesinsert.exec(new DataParams() { + @Override + public void writeValues() throws BasicException { + setString(1, UUID.randomUUID().toString()); + setString(2, ticket.getId()); + setString(3, tickettax.getTaxInfo().getId()); + setDouble(4, tickettax.getSubTotal()); + setDouble(5, tickettax.getTax()); + } + }); + } + } + return null; + } + }; + + t.execute(); + } + + /** + * + * @param ticket + * @param location + * @throws BasicException + */ + public final void deleteTicket(final TicketInfo ticket, final String location) throws BasicException { + + Transaction t; + t = new Transaction(s) { + @Override + public Object transact() throws BasicException { + + // update the inventory + Date d = new Date(); + for (int i = 0; i < ticket.getLinesCount(); i++) { + if (ticket.getLine(i).getProductID() != null) { + // Hay que actualizar el stock si el hay producto + getStockDiaryInsert().exec( new Object[] { + UUID.randomUUID().toString(), + d, + ticket.getLine(i).getMultiply() >= 0.0 + ? MovementReason.IN_REFUND.getKey() + : MovementReason.OUT_SALE.getKey(), + location, + ticket.getLine(i).getProductID(), + ticket.getLine(i).getProductAttSetInstId(), ticket.getLine(i).getMultiply(), ticket.getLine(i).getPrice(), + ticket.getUser().getName() + }); + } +// For productBundle + List<ProductsBundleInfo> bundle = getProductsBundle((String)ticket.getLine(i).getProductID()); + + if (bundle.size() > 0) { + for (ProductsBundleInfo bundleComponent : bundle) { + ProductInfoExt bundleProduct = getProductInfo(bundleComponent.getProductBundleId()); + + getStockDiaryInsert().exec(new Object[]{ + UUID.randomUUID().toString(), + d, + ticket.getLine(i).getMultiply() * bundleComponent.getQuantity() >= 0.0 + ? MovementReason.IN_REFUND.getKey() + : MovementReason.OUT_SALE.getKey(), + location, + bundleComponent.getProductBundleId(), + null, ticket.getLine(i).getMultiply() * bundleComponent.getQuantity() + , bundleProduct.getPriceSell(), + ticket.getUser().getName()}); + } + } + } + + // update customer debts + for (PaymentInfo p : ticket.getPayments()) { + if ("debt".equals(p.getName()) || "debtpaid".equals(p.getName())) { + + // udate customer fields... + ticket.getCustomer().updateCurDebt(-p.getTotal(), ticket.getDate()); + + // save customer fields... + getDebtUpdate().exec(new DataParams() { + @Override + public void writeValues() throws BasicException { + setDouble(1, ticket.getCustomer().getAccdebt()); + setTimestamp(2, ticket.getCustomer().getCurdate()); + setString(3, ticket.getCustomer().getId()); + }}); + } + } + + // and delete the receipt + new StaticSentence(s + , "DELETE FROM taxlines WHERE RECEIPT = ?" + , SerializerWriteString.INSTANCE).exec(ticket.getId()); + new StaticSentence(s + , "DELETE FROM payments WHERE RECEIPT = ?" + , SerializerWriteString.INSTANCE).exec(ticket.getId()); + new StaticSentence(s + , "DELETE FROM ticketlines WHERE TICKET = ?" + , SerializerWriteString.INSTANCE).exec(ticket.getId()); + new StaticSentence(s + , "DELETE FROM tickets WHERE ID = ?" + , SerializerWriteString.INSTANCE).exec(ticket.getId()); + new StaticSentence(s + , "DELETE FROM receipts WHERE ID = ?" + , SerializerWriteString.INSTANCE).exec(ticket.getId()); + return null; + } + }; + t.execute(); + } + + /** + * + * @return + * @throws BasicException + */ + public final Integer getNextPickupIndex() throws BasicException { + return (Integer) s.DB.getSequenceSentence(s, "pickup_number").find(); + } + + /** + * + * @return + * @throws BasicException + */ + public final Integer getNextTicketIndex() throws BasicException { + return (Integer) s.DB.getSequenceSentence(s, "ticketsnum").find(); + } + + /** + * + * @return + * @throws BasicException + */ + public final Integer getNextTicketRefundIndex() throws BasicException { + return (Integer) s.DB.getSequenceSentence(s, "ticketsnum_refund").find(); + } + + /** + * + * @return + * @throws BasicException + */ + public final Integer getNextTicketPaymentIndex() throws BasicException { + return (Integer) s.DB.getSequenceSentence(s, "ticketsnum_payment").find(); + } + + // JG 3 Feb 16 - Product load speedup + public final SentenceFind getProductImage() { + return new PreparedSentence(s, + "SELECT IMAGE FROM products WHERE ID = ?", + SerializerWriteString.INSTANCE + , (DataRead dr) -> ImageUtils.readImage(dr.getBytes(1))); + } + + /** + * Loads on ProductsEditor + * @return + */ + public final SentenceList getProductCatQBF() { + return new StaticSentence(s + , new QBFBuilder( + "SELECT " + + "P.ID, " + + "P.REFERENCE, " + + "P.CODE, " + + "P.CODETYPE, " + + "P.NAME, " + + "P.PRICEBUY, " + + "P.PRICESELL, " + + "P.CATEGORY, " + + "P.TAXCAT, " + + "P.ATTRIBUTESET_ID, " + + "P.STOCKCOST, " + + "P.STOCKVOLUME, " +// JG 3 feb 16 speedup + "P.IMAGE, " + + s.DB.CHAR_NULL() + "," + + "P.ISCOM, " + + "P.ISSCALE, " + + "P.ISCONSTANT, " + + "P.PRINTKB, " + + "P.SENDSTATUS, " + + "P.ISSERVICE, " + + "P.ATTRIBUTES, " + + "P.DISPLAY, " + + "P.ISVPRICE, " + + "P.ISVERPATRIB, " + + "P.TEXTTIP, " + + "P.WARRANTY, " + + "P.STOCKUNITS, " + + "P.PRINTTO, " + + "P.SUPPLIER, " + + "P.UOM, " + + "P.MEMODATE, " + + "CASE WHEN " + + "C.PRODUCT IS NULL " + + "THEN " + s.DB.FALSE() + + " ELSE " + s.DB.TRUE() + + " END, " + + "C.CATORDER " + + "FROM products P LEFT OUTER JOIN products_cat C " + + "ON P.ID = C.PRODUCT " + + "WHERE ?(QBF_FILTER) " + + "ORDER BY P.REFERENCE", + new String[] { + "P.NAME", "P.PRICEBUY", "P.PRICESELL", "P.CATEGORY", "P.CODE"}) + , new SerializerWriteBasic(new Datas[] { + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.DOUBLE, + Datas.OBJECT, Datas.DOUBLE, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING}) + , productsRow.getSerializerRead()); + } + + /** + * + * @return + */ + + public final SentenceExec getProductCatInsert() { + return new SentenceExecTransaction(s) { + @Override + public int execInTransaction(Object params) throws BasicException { + Object[] values = (Object[]) params; + int i = new PreparedSentence(s + , "INSERT INTO products (" + + "ID, " + + "REFERENCE, " + + "CODE, " + + "CODETYPE, " + + "NAME, " + + "PRICEBUY, " + + "PRICESELL, " + + "CATEGORY, " + + "TAXCAT, " + + "ATTRIBUTESET_ID, " + + "STOCKCOST, " + + "STOCKVOLUME, " + + "IMAGE, " + + "ISCOM, " + + "ISSCALE, " + + "ISCONSTANT, " + + "PRINTKB, " + + "SENDSTATUS, " + + "ISSERVICE, " + + "ATTRIBUTES, " + + "DISPLAY, " + + "ISVPRICE, " + + "ISVERPATRIB, " + + "TEXTTIP, " + + "WARRANTY, " + + "STOCKUNITS, " + + "PRINTTO, " + + "SUPPLIER, " + + "UOM, " + + "MEMODATE ) " + + "VALUES (" + + "?, ?, ?, ?, ?, ?, " + + "?, ?, ?, ?, ?, ?, " + + "?, ?, ?, ?, ?, ?, " + + "?, ?, ?, ?, ?, ?, " + + "?, ?, ?, ?, ?, ?)" + , new SerializerWriteBasicExt(productsRow.getDatas(), + new int[]{0, + 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29})) + + .exec(params); + + if (i > 0 && ((Boolean)values[30])) { + return new PreparedSentence(s + , "INSERT INTO products_cat (PRODUCT, CATORDER) VALUES (?, ?)" + , new SerializerWriteBasicExt(productsRow.getDatas(), new int[] {0, 31})) + + .exec(params); + } else { + return i; + } + } + }; + } + + /** + * + * @return + */ + public final SentenceExec getProductCatUpdate() { + return new SentenceExecTransaction(s) { + @Override + public int execInTransaction(Object params) throws BasicException { + Object[] values = (Object[]) params; + int i = new PreparedSentence(s + , "UPDATE products SET " + + "ID = ?, " + + "REFERENCE = ?, " + + "CODE = ?, " + + "CODETYPE = ?, " + + "NAME = ?, " + + "PRICEBUY = ?, " + + "PRICESELL = ?, " + + "CATEGORY = ?, " + + "TAXCAT = ?, " + + "ATTRIBUTESET_ID = ?, " + + "STOCKCOST = ?, " + + "STOCKVOLUME = ?, " + + "IMAGE = ?, " + + "ISCOM = ?, " + + "ISSCALE = ?, " + + "ISCONSTANT = ?, " + + "PRINTKB = ?, " + + "SENDSTATUS = ?, " + + "ISSERVICE = ?, " + + "ATTRIBUTES = ?," + + "DISPLAY = ?, " + + "ISVPRICE = ?, " + + "ISVERPATRIB = ?, " + + "TEXTTIP = ?, " + + "WARRANTY = ?, " + + "STOCKUNITS = ?, " + + "PRINTTO = ?, " + + "SUPPLIER = ?, " + + "UOM = ?, " + + "MEMODATE = ? " + + "WHERE ID = ?" + , new SerializerWriteBasicExt(productsRow.getDatas(), + new int[]{0, + 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, + 26, 27, 28, 29, 0})) + .exec(params); + if (i > 0) { + if (((Boolean)values[30])) { + if (new PreparedSentence(s + , "UPDATE products_cat SET CATORDER = ? WHERE PRODUCT = ?" + , new SerializerWriteBasicExt(productsRow.getDatas() + , new int[] {31, 0})).exec(params) == 0) { + new PreparedSentence(s + , "INSERT INTO products_cat (PRODUCT, CATORDER) VALUES (?, ?)" + , new SerializerWriteBasicExt(productsRow.getDatas(), new int[] {0, 31})).exec(params); + } + } else { + new PreparedSentence(s + , "DELETE FROM products_cat WHERE PRODUCT = ?" + , new SerializerWriteBasicExt(productsRow.getDatas(), new int[] {0})).exec(params); + } + } + return i; + } + }; + } + + /** + * + * @return + */ + public final SentenceExec getProductCatDelete() { + return new SentenceExecTransaction(s) { + @Override + public int execInTransaction(Object params) throws BasicException { + new PreparedSentence(s + , "DELETE FROM products_cat WHERE PRODUCT = ?" + , new SerializerWriteBasicExt(productsRow.getDatas(), new int[] {0})).exec(params); + return new PreparedSentence(s + , "DELETE FROM products WHERE ID = ?" + , new SerializerWriteBasicExt(productsRow.getDatas(), new int[] {0})).exec(params); + } + }; + } + + /** + * + * @return + */ + public final SentenceExec getDebtUpdate() { + + return new PreparedSentence(s + , "UPDATE customers SET CURDEBT = ?, CURDATE = ? WHERE ID = ?" + , SerializerWriteParams.INSTANCE); + } + + /** + * ProductBundle version + * @return + */ + public final SentenceExec getStockDiaryInsert() { + return new SentenceExecTransaction(s) { + @Override + /** + * @param params[0] String STOCKDIARY.ID + * @param params[1] Date Timestamp + * @param params[2] Integer Reason + * @param params[3] String Location + * @param params[4] String Product ID + * @param params[5] String Attribute instance ID + * @param params[6] Double Units + * @param params[7] Double Price + * @param params[8] String Application User + */ + public int execInTransaction(Object params) throws BasicException { + + Object[] adjustParams = new Object[4]; + Object[] paramsArray = (Object[]) params; + adjustParams[0] = paramsArray[4]; //product ->Location + adjustParams[1] = paramsArray[3]; //location -> Product + adjustParams[2] = paramsArray[5]; //attributesetinstance + adjustParams[3] = paramsArray[6]; //units + adjustStock(adjustParams); + + return new PreparedSentence(s + , "INSERT INTO stockdiary (ID, DATENEW, REASON, LOCATION, " + + "PRODUCT, ATTRIBUTESETINSTANCE_ID, " + + "UNITS, PRICE, AppUser) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)" + , new SerializerWriteBasicExt(stockdiaryDatas + , new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8})) + .exec(params); + } + }; + } + + /** + * + * @return + */ + public final SentenceExec getStockDiaryInsert1() { + return new SentenceExecTransaction(s) { + @Override + public int execInTransaction(Object params) throws BasicException { + + int updateresult = ((Object[]) params)[5] == null + ? new PreparedSentence(s + , "UPDATE stockcurrent SET UNITS = (UNITS + ?) " + + "WHERE LOCATION = ? AND PRODUCT = ? " + + "AND ATTRIBUTESETINSTANCE_ID IS NULL" + , new SerializerWriteBasicExt(stockdiaryDatas, new int[] {6, 3, 4})).exec(params) + : new PreparedSentence(s + , "UPDATE stockcurrent SET UNITS = (UNITS + ?) " + + "WHERE LOCATION = ? AND PRODUCT = ? " + + "AND ATTRIBUTESETINSTANCE_ID = ?" + , new SerializerWriteBasicExt(stockdiaryDatas, new int[] {6, 3, 4, 5})).exec(params); + + if (updateresult == 0) { + new PreparedSentence(s + , "INSERT INTO stockcurrent (LOCATION, PRODUCT, " + + "ATTRIBUTESETINSTANCE_ID, UNITS) " + + "VALUES (?, ?, ?, ?)" + , new SerializerWriteBasicExt(stockdiaryDatas, new int[] {3, 4, 5, 6})).exec(params); + } + return new PreparedSentence(s + , "INSERT INTO stockdiary (ID, DATENEW, REASON, LOCATION, PRODUCT, " + + "ATTRIBUTESETINSTANCE_ID, UNITS, PRICE, AppUser, " + + "SUPPLIER, SUPPLIERDOC) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + , new SerializerWriteBasicExt(stockdiaryDatas, + new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10})).exec(params); + + } + }; + } + + /** + * + * @return + */ + public final SentenceExec getStockDiaryDelete() { + return new SentenceExecTransaction(s) { + @Override + public int execInTransaction(Object params) throws BasicException { + int updateresult = ((Object[]) params)[5] == null // if ATTRIBUTESETINSTANCE_ID is null + ? new PreparedSentence(s + , "UPDATE stockcurrent SET UNITS = (UNITS - ?) " + + "WHERE LOCATION = ? AND PRODUCT = ? " + + "AND ATTRIBUTESETINSTANCE_ID IS NULL" + , new SerializerWriteBasicExt(stockdiaryDatas, new int[] {6, 3, 4})).exec(params) + : new PreparedSentence(s + , "UPDATE stockcurrent SET UNITS = (UNITS - ?) " + + "WHERE LOCATION = ? AND PRODUCT = ? " + + "AND ATTRIBUTESETINSTANCE_ID = ?" + , new SerializerWriteBasicExt(stockdiaryDatas, new int[] {6, 3, 4, 5})).exec(params); + + if (updateresult == 0) { + new PreparedSentence(s + , "INSERT INTO stockcurrent (LOCATION, PRODUCT, " + + "ATTRIBUTESETINSTANCE_ID, UNITS) " + + "VALUES (?, ?, ?, -(?))" + , new SerializerWriteBasicExt(stockdiaryDatas, new int[] {3, 4, 5, 6})).exec(params); + } + return new PreparedSentence(s + , "DELETE FROM stockdiary WHERE ID = ?" + , new SerializerWriteBasicExt(stockdiaryDatas, new int[] {0})).exec(params); + } + }; + } + + + private void adjustStock(Object params) throws BasicException { + + List<ProductsBundleInfo> bundle = getProductsBundle((String) ((Object[])params)[0]); + + if (bundle.size() > 0) { + + for (ProductsBundleInfo component : bundle) { + Object[] adjustParams = new Object[4]; + adjustParams[0] = component.getProductBundleId(); + adjustParams[1] = ((Object[])params)[1]; + adjustParams[2] = ((Object[])params)[2]; + adjustParams[3] = ((Double)((Object[])params)[3]) * component.getQuantity(); + adjustStock(adjustParams); + } + } else { + + int updateresult = ((Object[]) params)[2] == null + ? new PreparedSentence(s + , "UPDATE stockcurrent SET UNITS = (UNITS + ?) " + + "WHERE LOCATION = ? AND PRODUCT = ? " + + "AND ATTRIBUTESETINSTANCE_ID IS NULL" + , new SerializerWriteBasicExt(stockAdjustDatas + , new int[] {3, 1, 0})) + .exec(params) + : new PreparedSentence(s + , "UPDATE stockcurrent SET UNITS = (UNITS + ?) " + + "WHERE LOCATION = ? AND PRODUCT = ? " + + "AND ATTRIBUTESETINSTANCE_ID = ?" + , new SerializerWriteBasicExt(stockAdjustDatas + , new int[] {3, 1, 0, 2})) + .exec(params); + + if (updateresult == 0) { + + new PreparedSentence(s + , "INSERT INTO stockcurrent (LOCATION, PRODUCT, " + + "ATTRIBUTESETINSTANCE_ID, UNITS) " + + "VALUES (?, ?, ?, ?)" + , new SerializerWriteBasicExt(stockAdjustDatas + , new int[] {1, 0, 2, 3})) + .exec(params); + } + } + } + + /** + * + * @return + */ + public final SentenceExec getPaymentMovementInsert() { + return new SentenceExecTransaction(s) { + @Override + public int execInTransaction(Object params) throws BasicException { + new PreparedSentence(s + , "INSERT INTO receipts (ID, MONEY, DATENEW) " + + "VALUES (?, ?, ?)" + , new SerializerWriteBasicExt(paymenttabledatas, + new int[] {0, 1, 2})).exec(params); + return new PreparedSentence(s + , "INSERT INTO payments (ID, RECEIPT, PAYMENT, TOTAL, NOTES) " + + "VALUES (?, ?, ?, ?, ?)" + , new SerializerWriteBasicExt(paymenttabledatas, + new int[] {3, 0, 4, 5, 6})).exec(params); + } + }; + } + + /** + * + * @return + */ + public final SentenceExec getPaymentMovementDelete() { + return new SentenceExecTransaction(s) { + @Override + public int execInTransaction(Object params) throws BasicException { + new PreparedSentence(s + , "DELETE FROM payments WHERE ID = ?" + , new SerializerWriteBasicExt(paymenttabledatas, new int[] {3})).exec(params); + return new PreparedSentence(s + , "DELETE FROM receipts WHERE ID = ?" + , new SerializerWriteBasicExt(paymenttabledatas, new int[] {0})).exec(params); + } + }; + } + + /** + * + * @param warehouse + * @param id + * @param attsetinstid + * @return + * @throws BasicException + */ + public final double findProductStock(String warehouse, String id, String attsetinstid) throws BasicException { + + PreparedSentence p = attsetinstid == null + ? new PreparedSentence(s, "SELECT UNITS FROM stockcurrent " + + "WHERE LOCATION = ? AND PRODUCT = ? AND ATTRIBUTESETINSTANCE_ID IS NULL" + , new SerializerWriteBasic(Datas.STRING, Datas.STRING) + , SerializerReadDouble.INSTANCE) + : new PreparedSentence(s, "SELECT UNITS FROM stockcurrent " + + "WHERE LOCATION = ? AND PRODUCT = ? AND ATTRIBUTESETINSTANCE_ID = ?" + , new SerializerWriteBasic(Datas.STRING, Datas.STRING, Datas.STRING) + , SerializerReadDouble.INSTANCE); + + Double d = (Double) p.find(warehouse, id, attsetinstid); + return d == null ? 0.0 : d; + } + + /** + * + * @return + */ + public final SentenceExec getCatalogCategoryAdd() { + return new StaticSentence(s + , "INSERT INTO products_cat(PRODUCT, CATORDER) SELECT ID, " + s.DB.INTEGER_NULL() + " FROM products WHERE CATEGORY = ?" + , SerializerWriteString.INSTANCE); + } + + /** + * + * @return + */ + public final SentenceExec getCatalogCategoryDel() { + return new StaticSentence(s + , "DELETE FROM products_cat WHERE PRODUCT = ANY (SELECT ID " + + "FROM products WHERE CATEGORY = ?)" + , SerializerWriteString.INSTANCE); + } + + /** + * + * @return + */ + public final TableDefinition getTableCategories() { + return new TableDefinition(s, + "categories" + , new String[] {"ID", "NAME", "PARENTID", "IMAGE", "TEXTTIP", "CATSHOWNAME", "CATORDER"} + , new String[] {"ID", AppLocal.getIntString("label.name"), "", AppLocal.getIntString("label.image")} + , new Datas[] {Datas.STRING, Datas.STRING, Datas.STRING, + Datas.IMAGE, Datas.STRING, Datas.BOOLEAN, Datas.STRING} + , new Formats[] {Formats.STRING, Formats.STRING, Formats.STRING, + Formats.NULL, Formats.STRING, Formats.BOOLEAN, Formats.STRING} + , new int[] {0} + ); + } + + /** + * + * @return + */ + public final TableDefinition getTableTaxes() { + return new TableDefinition(s, + "taxes" + , new String[] {"ID", "NAME", "CATEGORY", "CUSTCATEGORY", "PARENTID", "RATE", "RATECASCADE", "RATEORDER"} + , new String[] {"ID", AppLocal.getIntString("label.name"), AppLocal.getIntString("label.taxcategory"), AppLocal.getIntString("label.custtaxcategory"), AppLocal.getIntString("label.taxparent"), AppLocal.getIntString("label.dutyrate"), AppLocal.getIntString("label.cascade"), AppLocal.getIntString("label.order")} + , new Datas[] {Datas.STRING, Datas.STRING, Datas.STRING, Datas.STRING, Datas.STRING, Datas.DOUBLE, Datas.BOOLEAN, Datas.INT} + , new Formats[] {Formats.STRING, Formats.STRING, Formats.STRING, Formats.STRING, Formats.STRING, Formats.PERCENT, Formats.BOOLEAN, Formats.INT} + , new int[] {0} + ); + } + + /** + * + * @return + */ + public final TableDefinition getTableTaxCustCategories() { + return new TableDefinition(s, + "taxcustcategories" + , new String[] {"ID", "NAME"} + , new String[] {"ID", AppLocal.getIntString("label.name")} + , new Datas[] {Datas.STRING, Datas.STRING} + , new Formats[] {Formats.STRING, Formats.STRING} + , new int[] {0} + ); + } + + /** + * + * @return + */ + public final TableDefinition getTableTaxCategories() { + return new TableDefinition(s, + "taxcategories" + , new String[] {"ID", "NAME"} + , new String[] {"ID", AppLocal.getIntString("label.name")} + , new Datas[] {Datas.STRING, Datas.STRING} + , new Formats[] {Formats.STRING, Formats.STRING} + , new int[] {0} + ); + } + + /** + * + * @return + */ + public final TableDefinition getTableLocations() { + return new TableDefinition(s, + "locations" + , new String[] {"ID", "NAME", "ADDRESS"} + , new String[] {"ID", AppLocal.getIntString("label.locationname"), + AppLocal.getIntString("label.locationaddress")} + , new Datas[] {Datas.STRING, Datas.STRING, Datas.STRING} + , new Formats[] {Formats.STRING, Formats.STRING, Formats.STRING} + , new int[] {0} + ); + } + + + /** + * + */ + protected static class CustomerExtRead implements SerializerRead { + + /** + * + * @param dr + * @return + * @throws BasicException + */ + @Override + public Object readValues(DataRead dr) throws BasicException { + CustomerInfoExt c = new CustomerInfoExt(dr.getString(1)); + c.setSearchkey(dr.getString(2)); + c.setTaxid(dr.getString(3)); + c.setTaxCustomerID(dr.getString(3)); + c.setName(dr.getString(4)); + c.setTaxCustCategoryID(dr.getString(5)); + c.setCard(dr.getString(6)); + c.setMaxdebt(dr.getDouble(7)); + c.setAddress(dr.getString(8)); + c.setAddress2(dr.getString(9)); + c.setPcode(dr.getString(10)); + c.setCity(dr.getString(11)); + c.setRegion(dr.getString(12)); + c.setCountry(dr.getString(13)); + c.setFirstname(dr.getString(14)); + c.setLastname(dr.getString(15)); + c.setCemail(dr.getString(16)); + c.setPhone1(dr.getString(17)); + c.setPhone2(dr.getString(18)); + c.setFax(dr.getString(19)); + c.setNotes(dr.getString(20)); + c.setVisible(dr.getBoolean(21)); + c.setCurdate(dr.getTimestamp(22)); + c.setAccdebt(dr.getDouble(23)); + c.setImage(ImageUtils.readImage(dr.getString(24))); + c.setisVIP(dr.getBoolean(25)); + c.setDiscount(dr.getDouble(26)); + c.setMemoDate(dr.getString(27)); + + return c; + } + } + + public final UomInfo getUomInfoById(String id) throws BasicException { + return (UomInfo) new PreparedSentence(s, + "SELECT " + + "id, name " + + "FROM uom " + + "WHERE id = ?" + , SerializerWriteString.INSTANCE, UomInfo.getSerializerRead()).find(id); + } + + public final TableDefinition getTableUom() { + return new TableDefinition(s, + "uom", + new String[]{"id", "name"}, + new String[]{"id", + AppLocal.getIntString("Label.Name")}, + new Datas[]{ + Datas.STRING, Datas.STRING}, + new Formats[]{ + Formats.STRING, Formats.STRING}, + new int[]{0} + ); + } + + public final SentenceList getUomList() { + return new StaticSentence(s, "SELECT ID, NAME FROM uom ORDER BY NAME", null, UomInfo.getSerializerRead()); + } + +/* public final SentenceList getVoucherList() { + return new StaticSentence(s, + "SELECT " + + "vouchers.ID,vouchers.VOUCHER_NUMBER,vouchers.CUSTOMER, " + + "customers.NAME,AMOUNT, STATUS " + + "FROM vouchers " + + "JOIN customers ON customers.id = vouchers.CUSTOMER " + + "WHERE STATUS='A' " + + "ORDER BY vouchers.VOUCHER_NUMBER ASC" + , null, VoucherInfo.getSerializerRead()); + } +*/ + + public final SentenceList getVoucherList() { + return new StaticSentence(s, + "SELECT " + + "vouchers.ID,vouchers.VOUCHER_NUMBER,vouchers.CUSTOMER, " + + "vouchers.AMOUNT, vouchers.STATUS " + + "FROM vouchers " + + "WHERE STATUS='A' " + + "ORDER BY vouchers.VOUCHER_NUMBER ASC" + , null, VoucherInfo.getSerializerRead()); + } + + public final SentenceExec getVoucherNonActive() { + return new PreparedSentence(s, + "UPDATE vouchers SET STATUS = 'D' " + + "WHERE VOUCHER_NUMBER = ?" + , SerializerWriteString.INSTANCE); + } + public final SentenceExec setVoucherPending() { + return new PreparedSentence(s, + "UPDATE vouchers SET STATUS = 'P' " + + "WHERE VOUCHER_NUMBER = ?" + , SerializerWriteString.INSTANCE); + } + + public final SentenceExec resetPickupId() { + + return new PreparedSentence(s, + "UPDATE pickup_number SET ID=1 " + , SerializerWriteString.INSTANCE); + + } + + /** + * + * @param id + * @return + * @throws BasicException + */ + public SupplierInfoExt loadSupplierExt(String id) throws BasicException { + return (SupplierInfoExt) new PreparedSentence(s + , "SELECT " + + "ID, " + + "SEARCHKEY, " + + "TAXID, " + + "NAME, " + + "MAXDEBT, " + + "ADDRESS, " + + "ADDRESS2, " + + "POSTAL, " + + "CITY, " + + "REGION, " + + "COUNTRY, " + + "FIRSTNAME, " + + "LASTNAME, " + + "EMAIL, " + + "PHONE, " + + "PHONE2, " + + "FAX, " + + "NOTES, " + + "VISIBLE, " + + "CURDATE, " + + "CURDEBT, " + + "VATID " + + "FROM suppliers WHERE ID = ?" + , SerializerWriteString.INSTANCE + , new SupplierExtRead()).find(id); + } + + /** + * + */ + protected static class SupplierExtRead implements SerializerRead { + + /** + * + * @param dr + * @return + * @throws BasicException + */ + @Override + public Object readValues(DataRead dr) throws BasicException { + SupplierInfoExt s = new SupplierInfoExt(dr.getString(1)); + s.setSearchkey(dr.getString(2)); + s.setTaxid(dr.getString(3)); + s.setName(dr.getString(4)); + s.setMaxdebt(dr.getDouble(5)); + s.setAddress(dr.getString(6)); + s.setAddress2(dr.getString(7)); + s.setPostal(dr.getString(8)); + s.setCity(dr.getString(9)); + s.setRegion(dr.getString(10)); + s.setCountry(dr.getString(11)); + s.setFirstname(dr.getString(12)); + s.setLastname(dr.getString(13)); + s.setEmail(dr.getString(14)); + s.setPhone(dr.getString(15)); + s.setPhone2(dr.getString(16)); + s.setFax(dr.getString(17)); + s.setNotes(dr.getString(18)); + s.setVisible(dr.getBoolean(19)); + s.setCurdate(dr.getTimestamp(20)); + s.setCurdebt(dr.getDouble(21)); + s.setSupplierVATID(dr.getString(22)); + + return s; + } + } + + /** + * + * @return + */ + + public final SentenceExec getCustomerInsert() { + return new SentenceExecTransaction(s) { + @Override + public int execInTransaction(Object params) throws BasicException { + Object[] values = (Object[]) params; + int i = new PreparedSentence(s + , "INSERT INTO customers (" + + "ID, " + + "SEARCHKEY, " + + "TAXID, " + + "NAME, " + + "TAXCATEGORY, " + + "CARD, " + + "MAXDEBT, " + + "ADDRESS, " + + "ADDRESS2, " + + "POSTAL, " + + "CITY, " + + "REGION, " + + "COUNTRY, " + + "FIRSTNAME, " + + "LASTNAME, " + + "EMAIL, " + + "PHONE, " + + "PHONE2, " + + "FAX, " + + "NOTES, " + + "VISIBLE, " + + "CURDATE, " + + "CURDEBT, " + + "IMAGE, " + + "ISVIP, " + + "DISCOUNT, " + + "MEMODATE ) " + + "VALUES (" + + "?, ?, ?, ?, ?, ?, " + + "?, ?, ?, ?, ?, ?, " + + "?, ?, ?, ?, ?, ?, " + + "?, ?, ?, ?, ?, ?, " + + "?, ?, ?)" + , new SerializerWriteBasicExt(customersRow.getDatas(), + new int[]{0, + 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, + 25, 26})) + + .exec(params); + return i; + } + }; + } + + /** + * + * @return + */ + public final SentenceExec getCustomerUpdate() { + return new SentenceExecTransaction(s) { + @Override + public int execInTransaction(Object params) throws BasicException { + Object[] values = (Object[]) params; + int i = new PreparedSentence(s + , "UPDATE customers SET " + + "ID = ?, " + + "SEARCHKEY = ?, " + + "TAXID = ?, " + + "NAME = ?, " + + "TAXCATEGORY = ?, " + + "CARD = ?, " + + "MAXDEBT = ?, " + + "ADDRESS = ?, " + + "ADDRESS2 = ?, " + + "POSTAL = ?, " + + "CITY = ?, " + + "REGION = ?, " + + "COUNTRY = ?, " + + "FIRSTNAME = ?, " + + "LASTNAME = ?, " + + "EMAIL = ?, " + + "PHONE = ?, " + + "PHONE2 = ?, " + + "FAX = ?, " + + "NOTES = ?," + + "VISIBLE = ?, " + + "CURDATE = ?, " + + "CURDEBT = ?, " + + "IMAGE = ?, " + + "ISVIP = ?, " + + "DISCOUNT = ?, " + + "MEMODATE = ? " + + "WHERE ID = ?" + , new SerializerWriteBasicExt(customersRow.getDatas(), + new int[]{0, + 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, + 26, 0})) + .exec(params); + +/* + * Use this block workflow as template to pump LOYALTY, MEMBERSHIP & etc + * updates to internal or external DB table + if (i > 0) { + if (((Boolean)values[n0])) { + if (new PreparedSentence(s + , "UPDATE tablename SET FIELD = ? WHERE CUSTOMER = ?" + , new SerializerWriteBasicExt(customersRow.getDatas() + , new int[] {n1, 0})).exec(params) == 0) { + new PreparedSentence(s + , "INSERT INTO other_tablename (CUSTOMER, FIELD) VALUES (?, ?)" + , new SerializerWriteBasicExt(productsRow.getDatas(), new int[] {0, n1})).exec(params); + } + } else { + new PreparedSentence(s + , "DELETE FROM FIELD WHERE CUSTOMER = ?" + , new SerializerWriteBasicExt(customersRow.getDatas(), new int[] {0})).exec(params); + } + } +*/ + return i; + } + }; + } + + /** + * + * @return + */ + public final SentenceExec getCustomerDelete() { + return new SentenceExecTransaction(s) { + @Override + public int execInTransaction(Object params) throws BasicException { + return new PreparedSentence(s + , "DELETE FROM customers WHERE ID = ?" + , new SerializerWriteBasicExt(customersRow.getDatas(), + new int[] {0} + )).exec(params); + } + }; + } + + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/forms/DataLogicSystem.java b/src/main/java/com/unicenta/pos/forms/DataLogicSystem.java new file mode 100644 index 0000000..b4357b8 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/DataLogicSystem.java @@ -0,0 +1,891 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.*; +import com.unicenta.format.Formats; +import com.unicenta.pos.util.ThumbNailBuilder; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.*; +import javax.imageio.ImageIO; +import javax.swing.ImageIcon; + +/** + * + * @author JG uniCenta + */ +public class DataLogicSystem extends BeanFactoryDataSingle { + + protected String m_sInitScript; + private SentenceFind m_version; + private SentenceExec m_dummy; + private String m_dbVersion; + protected SentenceList m_peoplevisible; + protected SentenceFind m_peoplebycard; + protected SerializerRead peopleread; + protected SentenceList m_permissionlist; + protected SerializerRead productIdRead; + protected SerializerRead customerIdRead; + + private SentenceFind m_rolepermissions; + private SentenceExec m_changepassword; + private SentenceFind m_locationfind; + private SentenceExec m_insertCSVEntry; + private SentenceExec m_insertStockUpdateEntry; + + private SentenceFind m_getProductAllFields; + private SentenceFind m_getProductRefAndCode; + private SentenceFind m_getProductRefAndName; + private SentenceFind m_getProductCodeAndName; + private SentenceFind m_getProductByReference; + private SentenceFind m_getProductByCode; + private SentenceFind m_getProductByName; + + private SentenceExec m_insertCustomerCSVEntry; + private SentenceFind m_getCustomerAllFields; + private SentenceFind m_getCustomerSearchKeyAndName; + private SentenceFind m_getCustomerBySearchKey; + private SentenceFind m_getCustomerByName; + + private SentenceFind m_resourcebytes; + private SentenceExec m_resourcebytesinsert; + private SentenceExec m_resourcebytesupdate; + + protected SentenceFind m_sequencecash; + protected SentenceFind m_activecash; + protected SentenceFind m_closedcash; + protected SentenceExec m_insertcash; + protected SentenceExec m_draweropened; + protected SentenceExec m_updatepermissions; + protected SentenceExec m_lineremoved; + protected SentenceExec m_ticketremoved; + + private String SQL; + private Map<String, byte[]> resourcescache; + + private SentenceList m_voucherlist; + + protected SentenceExec m_addOrder; + protected SentenceExec m_updateOrder; + protected SentenceExec m_deleteOrder; + + private SentenceExec m_resetPickup; + + private SentenceExec m_updatePlaces; + + /** Creates a new instance of DataLogicSystem */ + public DataLogicSystem() { + } + + /** + * + * @param s + */ + @Override + public void init(Session s){ + + m_sInitScript = "/com/unicenta/pos/scripts/" + s.DB.getName(); + m_dbVersion = s.DB.getName(); + + m_version = new PreparedSentence(s, "SELECT VERSION FROM applications WHERE ID = ?" + , SerializerWriteString.INSTANCE, SerializerReadString.INSTANCE); + + m_dummy = new StaticSentence(s, "SELECT * FROM people WHERE 1 = 0"); + + final ThumbNailBuilder tnb = new ThumbNailBuilder(32, 32, "com/unicenta/images/user.png"); + + peopleread = (DataRead dr) -> new AppUser( + dr.getString(1), + dr.getString(2), + dr.getString(3), + dr.getString(4), + dr.getString(5), + new ImageIcon(tnb.getThumbNail(ImageUtils.readImage(dr.getBytes(6))))); + +// START OF PRODUCT ************************************************************ + productIdRead =(DataRead dr) -> ( + dr.getString(1) + ); + + m_getProductAllFields = new PreparedSentence(s + , "SELECT ID FROM products WHERE REFERENCE=? AND CODE=? AND NAME=? " + , new SerializerWriteBasic(new Datas[] {Datas.STRING, Datas.STRING, Datas.STRING}) + , productIdRead + ); + + m_getProductRefAndCode = new PreparedSentence(s + , "SELECT ID FROM products WHERE REFERENCE=? AND CODE=?" + , new SerializerWriteBasic(new Datas[] {Datas.STRING, Datas.STRING}) + , productIdRead + ); + + m_getProductRefAndName = new PreparedSentence(s + , "SELECT ID FROM products WHERE REFERENCE=? AND NAME=? " + , new SerializerWriteBasic(new Datas[] {Datas.STRING, Datas.STRING}) + , productIdRead + ); + + m_getProductCodeAndName = new PreparedSentence(s + , "SELECT ID FROM products WHERE CODE=? AND NAME=? " + , new SerializerWriteBasic(new Datas[] {Datas.STRING, Datas.STRING}) + , productIdRead + ); + + m_getProductByReference = new PreparedSentence(s + , "SELECT ID FROM products WHERE REFERENCE=? " + , SerializerWriteString.INSTANCE //(Datas.STRING) + , productIdRead + ); + + m_getProductByCode = new PreparedSentence(s + , "SELECT ID FROM products WHERE CODE=? " + , SerializerWriteString.INSTANCE //(Datas.STRING) + //, new SerializerWriteBasic(Datas.STRING) + , productIdRead + ); + + m_getProductByName = new PreparedSentence(s + , "SELECT ID FROM products WHERE NAME=? " + , SerializerWriteString.INSTANCE //(Datas.STRING) + //, new SerializerWriteBasic(Datas.STRING) + , productIdRead + ); + + // END OF PRODUCT ************************************************************* + +// START OF CUSTOMER *********************************************************** + customerIdRead =(DataRead dr) -> ( + dr.getString(1) + ); +// duplicate this for now as will extend in future release + m_getCustomerAllFields = new PreparedSentence(s + , "SELECT ID FROM customers WHERE SEARCHKEY=? AND NAME=? " + , new SerializerWriteBasic(new Datas[] { + Datas.STRING, Datas.STRING}) + , customerIdRead + ); + + m_getCustomerSearchKeyAndName = new PreparedSentence(s + , "SELECT ID FROM customers WHERE SEARCHKEY=? AND NAME=? " + , new SerializerWriteBasic(new Datas[] { + Datas.STRING, Datas.STRING}) + , customerIdRead + ); + + m_getCustomerBySearchKey = new PreparedSentence(s + , "SELECT ID FROM customers WHERE SEARCHKEY=? " + , SerializerWriteString.INSTANCE + , customerIdRead + ); + + m_getCustomerByName = new PreparedSentence(s + , "SELECT ID FROM customers WHERE NAME=? " + , SerializerWriteString.INSTANCE + , customerIdRead + ); + + // END OF CUSTOMER ****************************************************************** + + m_peoplevisible = new StaticSentence(s + , "SELECT ID, NAME, APPPASSWORD, CARD, ROLE, IMAGE FROM people WHERE VISIBLE = " + s.DB.TRUE() + " ORDER BY NAME" + , null + , peopleread); + + m_peoplebycard = new PreparedSentence(s + , "SELECT ID, NAME, APPPASSWORD, CARD, ROLE, IMAGE FROM people WHERE CARD = ? AND VISIBLE = " + s.DB.TRUE() + , SerializerWriteString.INSTANCE + , peopleread); + + m_resourcebytes = new PreparedSentence(s + , "SELECT CONTENT FROM resources WHERE NAME = ?" + , SerializerWriteString.INSTANCE + , SerializerReadBytes.INSTANCE); + + Datas[] resourcedata = new Datas[] { + Datas.STRING, Datas.STRING, + Datas.INT, Datas.BYTES}; + + m_resourcebytesinsert = new PreparedSentence(s + , "INSERT INTO resources(ID, NAME, RESTYPE, CONTENT) VALUES (?, ?, ?, ?)" + , new SerializerWriteBasic(resourcedata)); + + m_resourcebytesupdate = new PreparedSentence(s + , "UPDATE resources SET NAME = ?, RESTYPE = ?, CONTENT = ? WHERE NAME = ?" + , new SerializerWriteBasicExt(resourcedata, new int[] {1, 2, 3, 1})); + + m_rolepermissions = new PreparedSentence(s + , "SELECT PERMISSIONS FROM roles WHERE ID = ?" + , SerializerWriteString.INSTANCE + , SerializerReadBytes.INSTANCE); + + m_changepassword = new StaticSentence(s + , "UPDATE people SET APPPASSWORD = ? WHERE ID = ?" + ,new SerializerWriteBasic(new Datas[] {Datas.STRING, Datas.STRING})); + + m_sequencecash = new StaticSentence(s, + "SELECT MAX(HOSTSEQUENCE) FROM closedcash WHERE HOST = ?", + SerializerWriteString.INSTANCE, + SerializerReadInteger.INSTANCE); + + m_activecash = new StaticSentence(s + , "SELECT HOST, HOSTSEQUENCE, DATESTART, DATEEND, NOSALES FROM closedcash WHERE MONEY = ?" + , SerializerWriteString.INSTANCE + , new SerializerReadBasic(new Datas[] { + Datas.STRING, + Datas.INT, + Datas.TIMESTAMP, + Datas.TIMESTAMP, + Datas.INT})); + + m_closedcash = new StaticSentence(s + , "SELECT HOST, HOSTSEQUENCE, DATESTART, DATEEND, NOSALES " + + "FROM closedcash WHERE HOSTSEQUENCE = ?" + , SerializerWriteString.INSTANCE + , new SerializerReadBasic(new Datas[] { + Datas.STRING, + Datas.INT, + Datas.TIMESTAMP, + Datas.TIMESTAMP, + Datas.INT})); + + m_insertcash = new StaticSentence(s + , "INSERT INTO closedcash(MONEY, HOST, HOSTSEQUENCE, DATESTART, DATEEND) " + + "VALUES (?, ?, ?, ?, ?)" + , new SerializerWriteBasic(new Datas[] { + Datas.STRING, + Datas.STRING, + Datas.INT, + Datas.TIMESTAMP, + Datas.TIMESTAMP})); + + m_draweropened = new StaticSentence(s + , "INSERT INTO draweropened ( NAME, TICKETID) " + + "VALUES (?, ?)" + , new SerializerWriteBasic(new Datas[] { + Datas.STRING, + Datas.STRING})); + + m_lineremoved = new StaticSentence(s, + "INSERT INTO lineremoved (NAME, TICKETID, PRODUCTID, PRODUCTNAME, UNITS) " + + "VALUES (?, ?, ?, ?, ?)", + new SerializerWriteBasic(new Datas[] { + Datas.STRING, Datas.STRING, + Datas.STRING, Datas.STRING, + Datas.DOUBLE + })); + + m_ticketremoved = new StaticSentence(s, + "INSERT INTO lineremoved (NAME, TICKETID, PRODUCTNAME, UNITS) " + + "VALUES (?, ?, ?, ?)", + new SerializerWriteBasic(new Datas[] { + Datas.STRING, Datas.STRING, + Datas.STRING, Datas.DOUBLE + })); + + m_locationfind = new StaticSentence(s + , "SELECT NAME FROM locations WHERE ID = ?" + , SerializerWriteString.INSTANCE + , SerializerReadString.INSTANCE); + + m_permissionlist = new StaticSentence(s + , "SELECT PERMISSIONS FROM permissions WHERE ID = ?" + , SerializerWriteString.INSTANCE + , new SerializerReadBasic(new Datas[] { + Datas.STRING + })); + + m_updatepermissions = new StaticSentence(s + , "INSERT INTO permissions (ID, PERMISSIONS) " + + "VALUES (?, ?)" + , new SerializerWriteBasic(new Datas[] { + Datas.STRING, + Datas.STRING})); + + +// Push Products into CSVImport table + m_insertCSVEntry = new StaticSentence(s + , "INSERT INTO csvimport ( " + + "ID, ROWNUMBER, CSVERROR, REFERENCE, " + + "CODE, NAME, PRICEBUY, PRICESELL, " + + "PREVIOUSBUY, PREVIOUSSELL, CATEGORY, TAX) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + , new SerializerWriteBasic(new Datas[] { + Datas.STRING, + Datas.STRING, + Datas.STRING, + Datas.STRING, + Datas.STRING, + Datas.STRING, + Datas.DOUBLE, + Datas.DOUBLE, + Datas.DOUBLE, + Datas.DOUBLE, + Datas.STRING, + Datas.STRING + })); + +// Push Product Quantity Update into CSVImport table + m_insertStockUpdateEntry = new StaticSentence(s + , "INSERT INTO csvimport ( " + + "ID, ROWNUMBER, CSVERROR, REFERENCE, " + + "CODE, PRICEBUY ) " + + "VALUES (?, ?, ?, ?, ?, ?)" + , new SerializerWriteBasic(new Datas[] { + Datas.STRING, + Datas.STRING, + Datas.STRING, + Datas.STRING, + Datas.STRING, + Datas.DOUBLE + })); + +// Push Customers into CSVImport table + m_insertCustomerCSVEntry = new StaticSentence(s + , "INSERT INTO csvimport ( " + + "ID, ROWNUMBER, CSVERROR, SEARCHKEY, NAME) " + + "VALUES (?, ?, ?, ?, ?)" + , new SerializerWriteBasic(new Datas[] { + Datas.STRING, + Datas.STRING, + Datas.STRING, + Datas.STRING, + Datas.STRING + })); + + m_addOrder = new StaticSentence(s + , "INSERT INTO orders (ORDERID, QTY, DETAILS, ATTRIBUTES, " + + "NOTES, TICKETID, ORDERTIME, DISPLAYID, AUXILIARY, " + + "COMPLETETIME) " + + "VALUES (?, ?, ?, ?, ?, " + + "?, ?, ?, ?, ? ) " + , new SerializerWriteBasic(new Datas[] { + Datas.STRING, // OrderId + Datas.INT, // Qty + Datas.STRING, // Details + Datas.STRING, // Attributes + Datas.STRING, // Notes + Datas.STRING, // TicketId + Datas.STRING, // OrderTime + Datas.INT, // DisplayId + Datas.INT, // Auxiliary + Datas.STRING // CompleteTime + })); + + m_updateOrder = new StaticSentence(s + , "UPDATE orders SET " + + "ORDERID = ?, " + + "QTY = ?, " + + "DETAILS = ?, " + + "ATTRIBUTES = ?, " + + "NOTES = ?, " + + "TICKETID = ?, " + + "ORDERTIME = ?, " + + "DISPLAYID = ?, " + + "AUXILIARY = ?, " + + "COMPLETETIME = ? " + + "WHERE ORDERID = ? " + , new SerializerWriteBasic(new Datas[] { + Datas.STRING, // OrderId + Datas.INT, // Qty + Datas.STRING, // Details + Datas.STRING, // Attributes + Datas.STRING, // Notes + Datas.STRING, // TicketId + Datas.STRING, // OrderTime + Datas.INT, // DisplayId + Datas.INT, // Auxiliary + Datas.STRING // CompleteTime + })); + + m_deleteOrder = new StaticSentence(s + , "DELETE FROM orders WHERE ORDERID = ?" + , SerializerWriteString.INSTANCE); + + m_updatePlaces = new StaticSentence(s + , "UPDATE places SET X = ?, Y = ? " + + "WHERE ID = ? " + , new SerializerWriteBasic(new Datas[]{ + Datas.INT, + Datas.INT, + Datas.STRING + })); + + m_resetPickup = new StaticSentence(s + , "UPDATE pickup_number SET id=1" + , SerializerWriteInteger.INSTANCE); + + resetResourcesCache(); + } + + /** + * + * @return + */ + public String getInitScript() { + return m_sInitScript; + } + + /** + * + * @return + */ + public String getDBVersion(){ + return m_dbVersion; + } + + /** + * + * @return + * @throws BasicException + */ + public final String findVersion() throws BasicException { + return (String) m_version.find(AppLocal.APP_ID); + } + + /** + * + * @return + * @throws BasicException + */ + public final String getUser() throws BasicException { + return (""); + + } + + /** + * + * @throws BasicException + */ + public final void execDummy() throws BasicException { + m_dummy.exec(); + } + + /** + * + * @return + * @throws BasicException + */ + public final List listPeopleVisible() throws BasicException { + return m_peoplevisible.list(); + } + + /** + * + * @param role + * @return + * @throws BasicException + */ + public final List<String> getPermissions(String role)throws BasicException { + return m_permissionlist.list(role); + } + + /** + * + * @param card + * @return + * @throws BasicException + */ + public final AppUser findPeopleByCard(String card) throws BasicException { + return (AppUser) m_peoplebycard.find(card); + } + + /** + * + * @param sRole + * @return + */ + public final String findRolePermissions(String sRole) { + + try { + return Formats.BYTEA.formatValue(m_rolepermissions.find(sRole)); + } catch (BasicException e) { + return null; + } + } + + /** + * + * @param userdata + * @throws BasicException + */ + public final void execChangePassword(Object[] userdata) throws BasicException { + m_changepassword.exec(userdata); + } + + /** + * + */ + public final void resetResourcesCache() { + resourcescache = new HashMap<>(); + } + + private byte[] getResource(String name) { + + byte[] resource; + + resource = resourcescache.get(name); + + if (resource == null) { + try { + resource = (byte[]) m_resourcebytes.find(name); + resourcescache.put(name, resource); + } catch (BasicException e) { + resource = null; + } + } + + return resource; + } + + /** + * + * @param name + * @param type + * @param data + */ + public final void setResource(String name, int type, byte[] data) { + + Object[] value = new Object[] { + UUID.randomUUID().toString(), + name, + type, + data + }; + try { + if (m_resourcebytesupdate.exec(value) == 0) { + m_resourcebytesinsert.exec(value); + } + resourcescache.put(name, data); + } catch (BasicException e) { + } + } + + /** + * + * @param sName + * @param data + */ + public final void setResourceAsBinary(String sName, byte[] data) { + setResource(sName, 2, data); + } + + /** + * + * @param sName + * @return + */ + public final byte[] getResourceAsBinary(String sName) { + return getResource(sName); + } + + /** + * + * @param sName + * @return + */ + public final String getResourceAsText(String sName) { + return Formats.BYTEA.formatValue(getResource(sName)); + } + + /** + * + * @param sName + * @return + */ + public final String getResourceAsXML(String sName) { + return Formats.BYTEA.formatValue(getResource(sName)); + } + + /** + * + * @param sName + * @return + */ + public final BufferedImage getResourceAsImage(String sName) { + try { + byte[] img = getResource(sName); // , ".png" + return img == null ? null : ImageIO.read(new ByteArrayInputStream(img)); + } catch (IOException e) { + return null; + } + } + + /** + * + * @param sName + * @param p + */ + public final void setResourceAsProperties(String sName, Properties p) { + if (p == null) { + setResource(sName, 0, null); // texto + } else { + try { + ByteArrayOutputStream o = new ByteArrayOutputStream(); + p.storeToXML(o, AppLocal.APP_NAME, "UTF8"); + setResource(sName, 0, o.toByteArray()); // El texto de las propiedades + } catch (IOException e) { // no deberia pasar nunca + } + } + } + + /** + * + * @param sName + * @return + */ + public final Properties getResourceAsProperties(String sName) { + + Properties p = new Properties(); + try { + byte[] img = getResourceAsBinary(sName); + if (img != null) { + p.loadFromXML(new ByteArrayInputStream(img)); + } + } catch (IOException e) { + } + return p; + } + + /** + * + * @param host + * @return + * @throws BasicException + */ + public final int getSequenceCash(String host) throws BasicException { + Integer i = (Integer) m_sequencecash.find(host); + return (i == null) ? 1 : i; + } + + /** + * + * @param sActiveCashIndex + * @return + * @throws BasicException + */ + public final Object[] findActiveCash(String sActiveCashIndex) throws BasicException { + return (Object[]) m_activecash.find(sActiveCashIndex); + } + /** + * + * @param sClosedCashIndex + * @return + * @throws BasicException + */ + public final Object[] findClosedCash(String sClosedCashIndex) throws BasicException { + return (Object[]) m_activecash.find(sClosedCashIndex); + } + + + /** + * + * @param cash + * @throws BasicException + */ + public final void execInsertCash(Object[] cash) throws BasicException { + m_insertcash.exec(cash); + } + + /** + * + * @param drawer + * @throws BasicException + */ + public final void execDrawerOpened(Object[] drawer) throws BasicException { + m_draweropened.exec(drawer); + } + + /** + * + * @param permissions + * @throws BasicException + */ + public final void execUpdatePermissions(Object[] permissions) throws BasicException { + m_updatepermissions.exec(permissions); + } + + /** + * + * @param line + */ + public final void execLineRemoved(Object[] line) { + try { + m_lineremoved.exec(line); + } catch (BasicException e) { + } + } + + /** + * + * @param ticket + */ + public final void execTicketRemoved(Object[] ticket) { + try { + m_ticketremoved.exec(ticket); + } catch (BasicException e) { + } + } + + /** + * + * @param iLocation + * @return + * @throws BasicException + */ + public final String findLocationName(String iLocation) throws BasicException { + return (String) m_locationfind.find(iLocation); + } + + /** + * + * @param csv + * @throws BasicException + */ + public final void execCSVStockUpdate(Object[] csv) throws BasicException { + m_insertStockUpdateEntry.exec(csv); + + } + /** + * + * @param csv + * @throws BasicException + */ + public final void execAddCSVEntry(Object[] csv) throws BasicException { + m_insertCSVEntry.exec(csv); + + } + + /** + * + * @param csv + * @throws BasicException + */ + public final void execCustomerAddCSVEntry(Object[] csv) throws BasicException { + m_insertCustomerCSVEntry.exec(csv); + + } + + +// This is used by CSVimport to detect what type of product insert we are looking at, or what error occured + + /** + * + * @param myProduct + * @return + * @throws BasicException + */ + public final String getProductRecordType(Object[] myProduct) throws BasicException { + // check if the product exist with all the details, if so return product ID + if (m_getProductAllFields.find(myProduct) != null){ + return m_getProductAllFields.find(myProduct).toString(); + } + // check if the product exists with matching reference and code, but a different name + if (m_getProductRefAndCode.find(myProduct[0],myProduct[1]) != null){ + return "Name change"; + } + + if (m_getProductRefAndName.find(myProduct[0],myProduct[2]) != null){ + return "Barcode change"; + } + + if (m_getProductCodeAndName.find(myProduct[1],myProduct[2]) != null){ + return "Reference change"; + } + + if (m_getProductByReference.find(myProduct[0]) != null){ + return "Duplicate Reference found."; + } + + if (m_getProductByCode.find(myProduct[1]) != null){ + return "Duplicate Barcode found."; + } + + if (m_getProductByName.find(myProduct[2]) != null){ + return "Duplicate Description found."; + } + + return "new"; + } + + /** + * + * @param myCustomer + * @return + * @throws BasicException + */ + public final String getCustomerRecordType(Object[] myCustomer) throws BasicException { + + if (m_getCustomerAllFields.find(myCustomer) != null){ + return m_getCustomerAllFields.find(myCustomer).toString(); + } + + if (m_getCustomerSearchKeyAndName.find(myCustomer[0],myCustomer[1]) != null){ + return "reference error"; + } + + if (m_getCustomerBySearchKey.find(myCustomer[0]) != null){ + return "Duplicate Search Key found."; + } + + if (m_getCustomerByName.find(myCustomer[1]) != null){ + return "Duplicate Name found."; + } + + return "new"; + } + + public final void updatePlaces(int x, int y, String id) throws BasicException { + m_updatePlaces.exec(x, y, id); + } + + public final void resetPickup(int x) throws BasicException { + m_resetPickup.exec(x); + } + + public final SentenceList getVouchersActiveList() { + return m_voucherlist; + } + + public final void addOrder(String orderId, Integer qty, + String details, String attributes, String notes, String ticketId, + String ordertime, Integer displayId, String auxiliary, String completetime + ) throws BasicException { + + m_addOrder.exec(orderId, qty, details, attributes, notes, ticketId, + ordertime, displayId, auxiliary, completetime); + } + + public final void updateOrder(String orderId, Integer qty, + String details, String attributes, String notes, String ticketId, + String ordertime, Integer displayId, String auxiliary, String completetime + ) throws BasicException { + + m_updateOrder.exec(orderId, qty, details, attributes, notes, ticketId, + ordertime, displayId, auxiliary, completetime); + } + + public void deleteOrder(String orderId) throws BasicException { + m_deleteOrder.exec(orderId); + } +} diff --git a/src/main/java/com/unicenta/pos/forms/DriverWrapper.java b/src/main/java/com/unicenta/pos/forms/DriverWrapper.java new file mode 100644 index 0000000..b55f491 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/DriverWrapper.java @@ -0,0 +1,73 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import lombok.extern.slf4j.Slf4j; + +import java.sql.*; +import java.util.Properties; +import java.util.logging.Logger; + +/** + * + * @author adrianromero + */ +@Slf4j +public class DriverWrapper implements Driver { + + private Driver driver; + + /** + * + * @param d + */ + public DriverWrapper(Driver d) { + driver = d; + } + @Override + public boolean acceptsURL(String u) throws SQLException { + return driver.acceptsURL(u); + } + @Override + public Connection connect(String u, Properties p) throws SQLException { + return driver.connect(u, p); + } + @Override + public int getMajorVersion() { + return driver.getMajorVersion(); + } + @Override + public int getMinorVersion() { + return driver.getMinorVersion(); + } + @Override + public DriverPropertyInfo[] getPropertyInfo(String u, Properties p) throws SQLException { + return driver.getPropertyInfo(u, p); + } + @Override + public boolean jdbcCompliant() { + return driver.jdbcCompliant(); + } + + @Override + public Logger getParentLogger() throws SQLFeatureNotSupportedException { + throw new UnsupportedOperationException("Not supported yet."); + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/forms/JDlgChangePassword.form b/src/main/java/com/unicenta/pos/forms/JDlgChangePassword.form new file mode 100644 index 0000000..4f14d87 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/JDlgChangePassword.form @@ -0,0 +1,219 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="title.changepassword" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="resizable" type="boolean" value="false"/> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-22,0,0,1,-96"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_formBundle" type="java.lang.String" value="pos_messages"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="2"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="jcmdCancel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.cancel" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jcmdCancelActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jcmdOK"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.OK" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jcmdOKActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="11" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jtxtPasswordOld" min="-2" pref="180" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jtxtPasswordNew" min="-2" pref="180" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jtxtPasswordRepeat" min="-2" pref="180" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace min="-2" pref="88" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jtxtPasswordOld" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jtxtPasswordNew" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jtxtPasswordRepeat" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.passwordold" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JPasswordField" name="jtxtPasswordOld"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.passwordnew" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JPasswordField" name="jtxtPasswordNew"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JPasswordField" name="jtxtPasswordRepeat"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.passwordrepeat" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/forms/JDlgChangePassword.java b/src/main/java/com/unicenta/pos/forms/JDlgChangePassword.java new file mode 100644 index 0000000..4d8d4a3 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/JDlgChangePassword.java @@ -0,0 +1,242 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import com.unicenta.data.gui.JMessageDialog; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.pos.util.Hashcypher; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.Window; +import javax.swing.JFrame; + +/** + * + * @author adrianromero + */ +public class JDlgChangePassword extends javax.swing.JDialog { + + private String m_sOldPassword; + private String m_sNewPassword; + + /** Creates new form ChangePassword */ + private JDlgChangePassword(java.awt.Frame parent, boolean modal) { + super(parent, modal); + } + /** Creates new form ChangePassword */ + private JDlgChangePassword(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + } + + private String init(String sOldPassword) { + + initComponents(); + + getRootPane().setDefaultButton(jcmdOK); + + m_sOldPassword = sOldPassword; + m_sNewPassword = null; + + //show(); + setVisible(true); + + return m_sNewPassword; + } + + + private static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window)parent; + } else { + return getWindow(parent.getParent()); + } + } + + /** + * + * @param parent + * @param sOldPassword + * @return + */ + public static String showMessage(Component parent, String sOldPassword) { + + Window window = getWindow(parent); + + JDlgChangePassword myMsg; + if (window instanceof Frame) { + myMsg = new JDlgChangePassword((Frame) window, true); + } else { + myMsg = new JDlgChangePassword((Dialog) window, true); + } + return myMsg.init(sOldPassword); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel2 = new javax.swing.JPanel(); + jcmdCancel = new javax.swing.JButton(); + jcmdOK = new javax.swing.JButton(); + jPanel1 = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + jtxtPasswordOld = new javax.swing.JPasswordField(); + jLabel2 = new javax.swing.JLabel(); + jtxtPasswordNew = new javax.swing.JPasswordField(); + jtxtPasswordRepeat = new javax.swing.JPasswordField(); + jLabel3 = new javax.swing.JLabel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(AppLocal.getIntString("title.changepassword")); // NOI18N + setResizable(false); + + jPanel2.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT)); + + jcmdCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + jcmdCancel.setText(AppLocal.getIntString("button.cancel")); // NOI18N + jcmdCancel.setPreferredSize(new java.awt.Dimension(110, 45)); + jcmdCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdCancelActionPerformed(evt); + } + }); + jPanel2.add(jcmdCancel); + + jcmdOK.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jcmdOK.setText(AppLocal.getIntString("button.OK")); // NOI18N + jcmdOK.setPreferredSize(new java.awt.Dimension(110, 45)); + jcmdOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdOKActionPerformed(evt); + } + }); + jPanel2.add(jcmdOK); + + getContentPane().add(jPanel2, java.awt.BorderLayout.SOUTH); + + jPanel1.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel1.setFont(new java.awt.Font("Arial", 0, 11)); // NOI18N + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.passwordold")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(150, 30)); + + jtxtPasswordOld.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtPasswordOld.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.passwordnew")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(150, 30)); + + jtxtPasswordNew.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jtxtPasswordNew.setPreferredSize(new java.awt.Dimension(0, 30)); + + jtxtPasswordRepeat.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtPasswordRepeat.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.passwordrepeat")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(150, 30)); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jtxtPasswordOld, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jtxtPasswordNew, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jtxtPasswordRepeat, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(88, 88, 88)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtPasswordOld, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jtxtPasswordNew, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jtxtPasswordRepeat, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + ); + + getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER); + + setSize(new java.awt.Dimension(416, 234)); + setLocationRelativeTo(null); + }// </editor-fold>//GEN-END:initComponents + + private void jcmdCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdCancelActionPerformed + + dispose(); + }//GEN-LAST:event_jcmdCancelActionPerformed + + private void jcmdOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdOKActionPerformed + + if (new String(jtxtPasswordNew.getPassword()).equals(new String(jtxtPasswordRepeat.getPassword()))) { + if (Hashcypher.authenticate(new String(jtxtPasswordOld.getPassword()), m_sOldPassword)) { + m_sNewPassword = Hashcypher.hashString(new String(jtxtPasswordNew.getPassword())); + dispose(); + } else { + JMessageDialog.showMessage(this, new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.BadPassword"))); + } + } else { + JMessageDialog.showMessage(this, new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.changepassworddistinct"))); + } + }//GEN-LAST:event_jcmdOKActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JButton jcmdCancel; + private javax.swing.JButton jcmdOK; + private javax.swing.JPasswordField jtxtPasswordNew; + private javax.swing.JPasswordField jtxtPasswordOld; + private javax.swing.JPasswordField jtxtPasswordRepeat; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/forms/JPanelMenu.form b/src/main/java/com/unicenta/pos/forms/JPanelMenu.form new file mode 100644 index 0000000..b035b3a --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/JPanelMenu.form @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="20" left="20" right="20" top="20"/> + </Border> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_formBundle" type="java.lang.String" value="pos_messages"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,18,0,0,2,35"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="menucontainer"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="1"/> + </Layout> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/forms/JPanelMenu.java b/src/main/java/com/unicenta/pos/forms/JPanelMenu.java new file mode 100644 index 0000000..5d49cc5 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/JPanelMenu.java @@ -0,0 +1,153 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import com.unicenta.basic.BasicException; +import java.awt.Component; +import javax.swing.JComponent; +import javax.swing.JPanel; + +/** + * + * @author adrianromero + */ +public class JPanelMenu extends JPanel implements JPanelView { + + private final MenuDefinition m_menu; + private boolean created = false; + + /** Creates new form JPanelMenu + * @param menu */ + public JPanelMenu(MenuDefinition menu) { + + m_menu = menu; + created = false; + + initComponents(); + + } + + /** + * + * @return + */ + @Override + public JComponent getComponent() { + return this; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return m_menu.getTitle(); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + + if (created == false) { + + for(int i = 0; i < m_menu.countMenuElements(); i++) { + MenuElement menuitem = m_menu.getMenuElement(i); + menuitem.addComponent(this); + } + created = true; + } + } + + /** + * + * @return + */ + @Override + public boolean deactivate() { + return true; + } + + /** + * + * @param title + */ + public void addTitle(Component title) { + + currententrypanel = null; + + JPanel titlepanel = new JPanel(); + titlepanel.setLayout(new java.awt.BorderLayout()); + titlepanel.add(title, java.awt.BorderLayout.CENTER); + titlepanel.applyComponentOrientation(getComponentOrientation()); + + menucontainer.add(titlepanel); + + } + + /** + * + * @param entry + */ + public void addEntry(Component entry) { + + if (currententrypanel == null) { + currententrypanel = new JPanel(); + currententrypanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 0, 20, 0)); + currententrypanel.setLayout(new java.awt.GridLayout(0, 6, 5, 5)); + menucontainer.add(currententrypanel); + + } + + currententrypanel.add(entry); + currententrypanel.applyComponentOrientation(getComponentOrientation()); + + } + + private JPanel currententrypanel = null; + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + menucontainer = new javax.swing.JPanel(); + + setBorder(javax.swing.BorderFactory.createEmptyBorder(20, 20, 20, 20)); + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + setLayout(new java.awt.BorderLayout()); + + menucontainer.setBackground(new java.awt.Color(102, 102, 102)); + menucontainer.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + menucontainer.setLayout(new javax.swing.BoxLayout(menucontainer, javax.swing.BoxLayout.Y_AXIS)); + add(menucontainer, java.awt.BorderLayout.NORTH); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel menucontainer; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/forms/JPanelNull.form b/src/main/java/com/unicenta/pos/forms/JPanelNull.form new file mode 100644 index 0000000..7a5b850 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/JPanelNull.form @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,2,117"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout"> + <Property name="useNullLayout" type="boolean" value="true"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="m_jLabelError"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.LoadError" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="30" y="30" width="490" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Container class="javax.swing.JScrollPane" name="jscrException"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="30" y="70" width="550" height="180"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JTextArea" name="jtxtException"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="lineWrap" type="boolean" value="true"/> + <Property name="wrapStyleWord" type="boolean" value="true"/> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/forms/JPanelNull.java b/src/main/java/com/unicenta/pos/forms/JPanelNull.java new file mode 100644 index 0000000..fefb7f4 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/JPanelNull.java @@ -0,0 +1,115 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import com.unicenta.basic.BasicException; +import javax.swing.JComponent; +import javax.swing.JPanel; + +/** + * + * @author adrianromero + */ +public class JPanelNull extends JPanel implements JPanelView { + + /** Creates new form JPanelNull + * @param oApp + * @param o */ + public JPanelNull(AppView oApp, Object o) { + + initComponents (); + if (o instanceof Exception) { + } + jtxtException.setText(o.toString()); + } + + /** + * + * @return + */ + @Override + public JComponent getComponent() { + return this; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return null; + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + } + + /** + * + * @return + */ + @Override + public boolean deactivate() { + return true; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the FormEditor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jLabelError = new javax.swing.JLabel(); + jscrException = new javax.swing.JScrollPane(); + jtxtException = new javax.swing.JTextArea(); + + setLayout(null); + + m_jLabelError.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jLabelError.setText(AppLocal.getIntString("label.LoadError")); // NOI18N + m_jLabelError.setPreferredSize(new java.awt.Dimension(110, 30)); + add(m_jLabelError); + m_jLabelError.setBounds(30, 30, 490, 30); + + jtxtException.setEditable(false); + jtxtException.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtException.setLineWrap(true); + jtxtException.setWrapStyleWord(true); + jscrException.setViewportView(jtxtException); + + add(jscrException); + jscrException.setBounds(30, 70, 550, 180); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JScrollPane jscrException; + private javax.swing.JTextArea jtxtException; + private javax.swing.JLabel m_jLabelError; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/forms/JPanelView.java b/src/main/java/com/unicenta/pos/forms/JPanelView.java new file mode 100644 index 0000000..c4c34b6 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/JPanelView.java @@ -0,0 +1,54 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import com.unicenta.basic.BasicException; +import javax.swing.JComponent; + +/** + * + * @author adrianromero + */ +public interface JPanelView { + + /** + * + * @return + */ + public abstract String getTitle(); + + /** + * + * @throws BasicException + */ + public abstract void activate() throws BasicException; + + /** + * + * @return + */ + public abstract boolean deactivate(); + + /** + * + * @return + */ + public abstract JComponent getComponent(); +} diff --git a/src/main/java/com/unicenta/pos/forms/JPrincipalApp.form b/src/main/java/com/unicenta/pos/forms/JPrincipalApp.form new file mode 100644 index 0000000..6170ec8 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/JPrincipalApp.form @@ -0,0 +1,202 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,53,0,0,1,-65"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Before"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JScrollPane" name="m_jPanelLeft"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 2]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Before"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + </Container> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[45, 45]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="After"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace min="0" pref="0" max="-2" attributes="0"/> + <Component id="jButton1" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace pref="88" max="32767" attributes="0"/> + <Component id="jButton1" pref="33" max="32767" attributes="0"/> + <EmptySpace pref="188" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="jButton1"> + <Properties> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.menu" replaceFormat="AppLocal.getIntString("tooltip.menu")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="iconTextGap" type="int" value="0"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[10, 2, 10, 2]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[45, 32224661]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 32]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[36, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton1ActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="m_jPanelRight"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 40]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="m_jPanelTitle"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Component class="javax.swing.JLabel" name="m_jTitle"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="1"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="df" green="a8" red="0" type="rgb"/> + </Property> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.MatteColorBorderInfo"> + <MatteColorBorder bottom="1" left="0" right="0" top="0"> + <Color PropertyName="color" blue="40" green="40" id="darkGray" palette="1" red="40" type="palette"/> + </MatteColorBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="10" left="10" right="10" top="10"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 35]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 35]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="m_jPanelContainer"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignCardLayout"/> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/forms/JPrincipalApp.java b/src/main/java/com/unicenta/pos/forms/JPrincipalApp.java new file mode 100644 index 0000000..37495ef --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/JPrincipalApp.java @@ -0,0 +1,650 @@ +// uniCenta oPOS Touch Friendly Point of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com/product +// +// This file is part of uniCenta oPOS. +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Openbravo POS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.JMessageDialog; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.pos.customers.CustomerInfo; +import com.unicenta.pos.scripting.ScriptEngine; +import com.unicenta.pos.scripting.ScriptException; +import com.unicenta.pos.scripting.ScriptFactory; +import com.unicenta.pos.util.Hashcypher; +import com.unicenta.pos.util.StringUtils; +import lombok.extern.slf4j.Slf4j; +import org.jdesktop.swingx.JXTaskPane; +import org.jdesktop.swingx.JXTaskPaneContainer; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +// import java.awt.Color; +// import org.jdesktop.swingx.painter.MattePainter; + +/** + * @author adrianromero + */ +@Slf4j +public class JPrincipalApp extends javax.swing.JPanel implements AppUserView { + + private final JRootApp m_appview; + private final AppUser m_appuser; + + private DataLogicSystem m_dlSystem; + + private JLabel m_principalnotificator; + + private JPanelView m_jLastView; + private Action m_actionfirst; + + private Map<String, JPanelView> m_aPreparedViews; // Prepared views + private Map<String, JPanelView> m_aCreatedViews; + + private Icon menu_open; + private Icon menu_close; + + //HS Updates + private CustomerInfo customerInfo; + + /** + * Creates new form JPrincipalApp + * + * @param appview + * @param appuser + */ + public JPrincipalApp(JRootApp appview, AppUser appuser) { + + m_appview = appview; + m_appuser = appuser; + + m_dlSystem = (DataLogicSystem) m_appview.getBean("com.unicenta.pos.forms.DataLogicSystem"); + + m_appuser.fillPermissions(m_dlSystem); + + m_actionfirst = null; + m_jLastView = null; + + m_aPreparedViews = new HashMap<>(); + m_aCreatedViews = new HashMap<>(); + + initComponents(); + + jPanel2.add(Box.createVerticalStrut(50), 0); + m_jPanelLeft.getVerticalScrollBar().setPreferredSize(new Dimension(35, 35)); + + applyComponentOrientation(appview.getComponentOrientation()); + + m_principalnotificator = new JLabel(); + m_principalnotificator.applyComponentOrientation(getComponentOrientation()); + m_principalnotificator.setText(m_appuser.getName()); + m_principalnotificator.setIcon(m_appuser.getIcon()); + + if (jButton1.getComponentOrientation().isLeftToRight()) { + menu_open = new javax.swing.ImageIcon(getClass().getResource( + "/com/unicenta/images/menu-right.png")); + menu_close = new javax.swing.ImageIcon(getClass().getResource( + "/com/unicenta/images/menu-left.png")); + } else { + menu_open = new javax.swing.ImageIcon(getClass().getResource( + "/com/unicenta/images/menu-left.png")); + menu_close = new javax.swing.ImageIcon(getClass().getResource( + "/com/unicenta/images/menu-right.png")); + } + assignMenuButtonIcon(); + + m_jPanelTitle.setVisible(false); + m_jPanelContainer.add(new JPanel(), "<NULL>"); + + showView("<NULL>"); + + try { + + Component scriptMenu = getScriptMenu(m_dlSystem.getResourceAsText("Menu.Root")); + m_jPanelLeft.setViewportView(scriptMenu); + + } catch (ScriptException e) { + log.error("Cannot read Menu.Root resource. Trying default menu.", e.getMessage()); + try { + m_jPanelLeft.setViewportView(getScriptMenu( + StringUtils.readResource("/com/unicenta/pos/templates/Menu.Root.txt"))); + } catch (IOException | ScriptException ex) { + log.error("Cannot read default menu", ex.getMessage()); + } + } + } + + private Component getScriptMenu(String menutext) throws ScriptException { + + ScriptMenu menu = new ScriptMenu(); + + ScriptEngine eng = ScriptFactory.getScriptEngine(ScriptFactory.BEANSHELL); + eng.put("menu", menu); + eng.eval(menutext); + return menu.getTaskPane(); + } + + private void assignMenuButtonIcon() { + jButton1.setIcon(m_jPanelLeft.isVisible() + ? menu_close + : menu_open); + } + + /** + * + */ + public class ScriptMenu { + private final JXTaskPaneContainer taskPane; + + private ScriptMenu() { + taskPane = new JXTaskPaneContainer(); + taskPane.applyComponentOrientation(getComponentOrientation()); + } + + /** + * @param key + * @return + */ + public ScriptGroup addGroup(String key) { + ScriptGroup group = new ScriptGroup(key); + taskPane.add(group.getTaskGroup()); + return group; + } + + /** + * @return + */ + public JXTaskPaneContainer getTaskPane() { + return taskPane; + } + } + + /** + * + */ + public class ScriptGroup { + + private final JXTaskPane taskGroup; + + private ScriptGroup(String key) { + taskGroup = new JXTaskPane(); + taskGroup.applyComponentOrientation(getComponentOrientation()); + taskGroup.setFocusable(false); + taskGroup.setRequestFocusEnabled(false); + taskGroup.setTitle(AppLocal.getIntString(key)); + taskGroup.setVisible(false); + taskGroup.setFont(new java.awt.Font("Arial", 0, 16)); + + } + + /** + * @param icon + * @param key + * @param classname + */ + public void addPanel(String icon, String key, String classname) { + addAction(new MenuPanelAction(m_appview, icon, key, classname)); + } + + /** + * @param icon + * @param key + * @param classname + */ + public void addExecution(String icon, String key, String classname) { + addAction(new MenuExecAction(m_appview, icon, key, classname)); + } + + /** + * @param icon + * @param key + * @param classname + * @return + */ + public ScriptSubmenu addSubmenu(String icon, String key, String classname) { + ScriptSubmenu submenu = new ScriptSubmenu(key); + m_aPreparedViews.put(classname, new JPanelMenu(submenu.getMenuDefinition())); + MenuPanelAction menuPanelAction = new MenuPanelAction(m_appview, icon, key, classname); + addAction(menuPanelAction); + return submenu; + } + + /** + * + */ + public void addChangePasswordAction() { + addAction(new ChangePasswordAction("/com/unicenta/images/password.png", "Menu.ChangePassword")); + } + + /** + * + */ + public void addExitAction() { + addAction(new ExitAction("/com/unicenta/images/logout.png", "Menu.Exit")); + } + + private void addAction(Action act) { + String permissions = (String) act.getValue(AppUserView.ACTION_TASKNAME); + boolean hasPermission = m_appuser.hasPermission(permissions); + if (hasPermission) { + Component c = taskGroup.add(act); + c.applyComponentOrientation(getComponentOrientation()); + c.setFocusable(false); + + taskGroup.setVisible(true); + + if (m_actionfirst == null) { + m_actionfirst = act; + } + } + } + + + /** + * @return + */ + public JXTaskPane getTaskGroup() { + return taskGroup; + } + } + + /** + * + */ + public class ScriptSubmenu { + private final MenuDefinition menudef; + + private ScriptSubmenu(String key) { + menudef = new MenuDefinition(key); + } + + /** + * @param key + */ + public void addTitle(String key) { + menudef.addMenuTitle(key); + } + + /** + * @param icon + * @param key + * @param classname + */ + public void addPanel(String icon, String key, String classname) { + menudef.addMenuItem(new MenuPanelAction(m_appview, icon, key, classname)); + } + + /** + * @param icon + * @param key + * @param classname + */ + public void addExecution(String icon, String key, String classname) { + menudef.addMenuItem(new MenuExecAction(m_appview, icon, key, classname)); + } + + /** + * @param icon + * @param key + * @param classname + * @return + */ + public ScriptSubmenu addSubmenu(String icon, String key, String classname) { + ScriptSubmenu submenu = new ScriptSubmenu(key); + m_aPreparedViews.put(classname, new JPanelMenu(submenu.getMenuDefinition())); + menudef.addMenuItem(new MenuPanelAction(m_appview, icon, key, classname)); + return submenu; + } + + /** + * + */ + public void addChangePasswordAction() { + menudef.addMenuItem(new ChangePasswordAction("/com/unicenta/images/password.png", "Menu.ChangePassword")); + } + + /** + * + */ + public void addExitAction() { + menudef.addMenuItem(new ExitAction("/com/unicenta/images/logout.png", "Menu.Exit")); + } + + /** + * @return + */ + public MenuDefinition getMenuDefinition() { + return menudef; + } + } + + private void setMenuVisible(boolean value) { + + m_jPanelLeft.setVisible(value); + assignMenuButtonIcon(); + revalidate(); + } + + /** + * @return + */ + public JComponent getNotificator() { + return m_principalnotificator; + } + + /** + * + */ + public void activate() { + + setMenuVisible(getBounds().width > 800); + + if (m_actionfirst != null) { + m_actionfirst.actionPerformed(null); + m_actionfirst = null; + } + } + + /** + * @return + */ + public boolean deactivate() { + if (m_jLastView == null) { + return true; + } else if (m_jLastView.deactivate()) { + m_jLastView = null; + showView("<NULL>"); + return true; + } else { + return false; + } + + } + + private class ExitAction extends AbstractAction { + + public ExitAction(String icon, String keytext) { + putValue(Action.SMALL_ICON, new ImageIcon(JPrincipalApp.class.getResource(icon))); + putValue(Action.NAME, AppLocal.getIntString(keytext)); + putValue(AppUserView.ACTION_TASKNAME, keytext); + } + + @Override + public void actionPerformed(ActionEvent evt) { + m_appview.closeAppView(); + } + } + + /** + * + */ + public void exitToLogin() { + m_appview.closeAppView(); + } + + + private class ChangePasswordAction extends AbstractAction { + public ChangePasswordAction(String icon, String keytext) { + putValue(Action.SMALL_ICON, new ImageIcon(JPrincipalApp.class.getResource(icon))); + putValue(Action.NAME, AppLocal.getIntString(keytext)); + putValue(AppUserView.ACTION_TASKNAME, keytext); + + } + + @Override + public void actionPerformed(ActionEvent evt) { + + String sNewPassword = Hashcypher.changePassword(JPrincipalApp.this, m_appuser.getPassword()); + if (sNewPassword != null) { + try { + + m_dlSystem.execChangePassword(new Object[]{sNewPassword, m_appuser.getId()}); + m_appuser.setPassword(sNewPassword); + } catch (BasicException e) { + JMessageDialog.showMessage(JPrincipalApp.this + , new MessageInf(MessageInf.SGN_WARNING + , AppLocal.getIntString("message.cannotchangepassword"))); + } + } + } + } + + + private void showView(String sView) { + CardLayout cl = (CardLayout) (m_jPanelContainer.getLayout()); + cl.show(m_jPanelContainer, sView); + } + + /** + * @return + */ + @Override + public AppUser getUser() { + return m_appuser; + } + + /** + * @param sTaskClass + */ + @Override + public void showTask(String sTaskClass) { + + customerInfo = new CustomerInfo(""); + customerInfo.setName(""); + + m_appview.waitCursorBegin(); + + if (m_appuser.hasPermission(sTaskClass)) { + + JPanelView m_jMyView = (JPanelView) m_aCreatedViews.get(sTaskClass); + + if (m_jLastView == null|| (m_jMyView != m_jLastView && m_jLastView.deactivate())) { + + if (m_jMyView == null) { + + m_jMyView = m_aPreparedViews.get(sTaskClass); + + if (m_jMyView == null) { + + try { + m_jMyView = (JPanelView) m_appview.getBean(sTaskClass); + } catch (BeanFactoryException e) { + m_jMyView = new JPanelNull(m_appview, e); + } + } + + m_jMyView.getComponent().applyComponentOrientation(getComponentOrientation()); + m_jPanelContainer.add(m_jMyView.getComponent(), sTaskClass); + m_aCreatedViews.put(sTaskClass, m_jMyView); + } + + try { + m_jMyView.activate(); + } catch (BasicException e) { + JMessageDialog.showMessage(this + , new MessageInf(MessageInf.SGN_WARNING + , AppLocal.getIntString("message.notactive"), e)); + } + + m_jLastView = m_jMyView; + + setMenuVisible(getBounds().width > 800); + setMenuVisible(false); + + showView(sTaskClass); + String sTitle = m_jMyView.getTitle(); + m_jPanelTitle.setVisible(sTitle != null); + m_jTitle.setText(sTitle); + } + } else { + + JMessageDialog.showMessage(this + , new MessageInf(MessageInf.SGN_WARNING + , AppLocal.getIntString("message.notpermissions"))); + } + m_appview.waitCursorEnd(); + } + + /** + * @param sTaskClass + */ + @Override + public void executeTask(String sTaskClass) { + + m_appview.waitCursorBegin(); + + if (m_appuser.hasPermission(sTaskClass)) { + try { + ProcessAction myProcess = (ProcessAction) m_appview.getBean(sTaskClass); + + try { + MessageInf m = myProcess.execute(); + if (m != null) { + JMessageDialog.showMessage(JPrincipalApp.this, m); + } + } catch (BasicException eb) { + JMessageDialog.showMessage(JPrincipalApp.this, new MessageInf(eb)); + } + } catch (BeanFactoryException e) { + JMessageDialog.showMessage(JPrincipalApp.this + , new MessageInf(MessageInf.SGN_WARNING + , AppLocal.getIntString("label.LoadError"), e)); + } + } else { + JMessageDialog.showMessage(JPrincipalApp.this + , new MessageInf(MessageInf.SGN_WARNING + , AppLocal.getIntString("message.notpermissions"))); + } + m_appview.waitCursorEnd(); + } + + /** + * This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + m_jPanelLeft = new javax.swing.JScrollPane(); + jPanel2 = new javax.swing.JPanel(); + jButton1 = new javax.swing.JButton(); + m_jPanelRight = new javax.swing.JPanel(); + m_jPanelTitle = new javax.swing.JPanel(); + m_jTitle = new javax.swing.JLabel(); + m_jPanelContainer = new javax.swing.JPanel(); + + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + setLayout(new java.awt.BorderLayout()); + + jPanel1.setLayout(new java.awt.BorderLayout()); + + m_jPanelLeft.setBackground(new java.awt.Color(102, 102, 102)); + m_jPanelLeft.setBorder(null); + m_jPanelLeft.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPanelLeft.setPreferredSize(new java.awt.Dimension(250, 2)); + jPanel1.add(m_jPanelLeft, java.awt.BorderLayout.LINE_START); + + jPanel2.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel2.setPreferredSize(new java.awt.Dimension(45, 45)); + + jButton1.setToolTipText(AppLocal.getIntString("tooltip.menu")); // NOI18N + jButton1.setFocusPainted(false); + jButton1.setFocusable(false); + jButton1.setIconTextGap(0); + jButton1.setMargin(new java.awt.Insets(10, 2, 10, 2)); + jButton1.setMaximumSize(new java.awt.Dimension(45, 32224661)); + jButton1.setMinimumSize(new java.awt.Dimension(32, 32)); + jButton1.setPreferredSize(new java.awt.Dimension(36, 45)); + jButton1.setRequestFocusEnabled(false); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap(88, Short.MAX_VALUE) + .addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, 33, Short.MAX_VALUE) + .addContainerGap(188, Short.MAX_VALUE)) + ); + + jPanel1.add(jPanel2, java.awt.BorderLayout.LINE_END); + + add(jPanel1, java.awt.BorderLayout.LINE_START); + + m_jPanelRight.setPreferredSize(new java.awt.Dimension(200, 40)); + m_jPanelRight.setLayout(new java.awt.BorderLayout()); + + m_jPanelTitle.setLayout(new java.awt.BorderLayout()); + + m_jTitle.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + m_jTitle.setForeground(new java.awt.Color(0, 168, 223)); + m_jTitle.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createMatteBorder(0, 0, 1, 0, java.awt.Color.darkGray), javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10))); + m_jTitle.setMaximumSize(new java.awt.Dimension(100, 35)); + m_jTitle.setMinimumSize(new java.awt.Dimension(30, 25)); + m_jTitle.setPreferredSize(new java.awt.Dimension(100, 35)); + m_jPanelTitle.add(m_jTitle, java.awt.BorderLayout.NORTH); + + m_jPanelRight.add(m_jPanelTitle, java.awt.BorderLayout.NORTH); + + m_jPanelContainer.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPanelContainer.setLayout(new java.awt.CardLayout()); + m_jPanelRight.add(m_jPanelContainer, java.awt.BorderLayout.CENTER); + + add(m_jPanelRight, java.awt.BorderLayout.CENTER); + }// </editor-fold>//GEN-END:initComponents + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + + setMenuVisible(!m_jPanelLeft.isVisible()); + + }//GEN-LAST:event_jButton1ActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel m_jPanelContainer; + private javax.swing.JScrollPane m_jPanelLeft; + private javax.swing.JPanel m_jPanelRight; + private javax.swing.JPanel m_jPanelTitle; + private javax.swing.JLabel m_jTitle; + // End of variables declaration//GEN-END:variables + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/forms/JRootApp.form b/src/main/java/com/unicenta/pos/forms/JRootApp.form new file mode 100644 index 0000000..4a55394 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/JRootApp.form @@ -0,0 +1,443 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[1024, 768]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,3,86,0,0,4,0"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="m_jPanelTitle"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.MatteColorBorderInfo"> + <MatteColorBorder bottom="1" left="0" right="0" top="0"> + <Color PropertyName="color" blue="99" green="8a" id="Button.darkShadow" palette="3" red="7a" type="palette"/> + </MatteColorBorder> + </Border> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[449, 40]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Component class="javax.swing.JLabel" name="m_jLblTitle"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="16" style="1"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="text" type="java.lang.String" value="Window.Title"/> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="JRootApp_m_jLblTitle"/> + </AuxValues> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="poweredby"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/poweredby_uni.png"/> + </Property> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="0" left="5" right="5" top="0"/> + </Border> + </Property> + <Property name="horizontalTextPosition" type="int" value="4"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[180, 34]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[180, 34]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="After"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="16" style="1"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[180, 34]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="generateMnemonicsCode" type="java.lang.Boolean" value="true"/> + </AuxValues> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Before"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="m_jPanelContainer"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignCardLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="m_jPanelLogin"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription"> + <CardConstraints cardName="login"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="1"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/unicenta.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code=""<html><center>uniCenta oPOS - Touch Friendly Point of Sale<br>" + "Copyright \u00A9 2009-2017 uniCenta <br>" + "https://unicenta.com<br>" + "<br>" + "uniCenta oPOS is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.<br>" + "<br>" + "uniCenta oPOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.<br>" + "<br>" + "You should have received a copy of the GNU General Public License along with uniCenta oPOS. If not, see http://www.gnu.org/licenses/<br>" + "</center>"" type="code"/> + </Property> + <Property name="alignmentX" type="float" value="0.5"/> + <Property name="horizontalTextPosition" type="int" value="0"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[800, 1024]"/> + </Property> + <Property name="verticalTextPosition" type="int" value="3"/> + </Properties> + </Component> + <Component class="javax.swing.Box$Filler" name="filler2"> + <Properties> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32767, 0]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 10]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.HorizontalGlue"/> + </AuxValues> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 400]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="jPanel1" max="32767" attributes="1"/> + <Component id="jScrollPane1" max="32767" attributes="1"/> + </Group> + <EmptySpace min="-2" pref="104" max="-2" attributes="0"/> + <Component id="m_jLogonName" min="-2" max="-2" attributes="0"/> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="15" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="m_jLogonName" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="434" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jScrollPane1" max="32767" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jPanel1" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Container class="javax.swing.JPanel" name="m_jLogonName"> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="0" left="5" right="5" top="0"/> + </Border> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 100]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="After"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel8"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> + <Property name="columns" type="int" value="1"/> + <Property name="horizontalGap" type="int" value="5"/> + <Property name="rows" type="int" value="0"/> + <Property name="verticalGap" type="int" value="5"/> + </Layout> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JScrollPane" name="jScrollPane1"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="horizontalScrollBarPolicy" type="int" value="31"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="JRootApp_jScrollPane1"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + </Container> + <Container class="javax.swing.JPanel" name="jPanel1"> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="m_txtKeys" min="-2" max="-2" attributes="0"/> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + </Group> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jClose" pref="267" max="32767" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="m_txtKeys" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jClose" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JTextField" name="m_txtKeys"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 0]"/> + </Property> + </Properties> + <Events> + <EventHandler event="keyTyped" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="m_txtKeysKeyTyped"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jClose"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/exit.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.close" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 50]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jCloseActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="m_jPanelDown"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.MatteColorBorderInfo"> + <MatteColorBorder bottom="0" left="0" right="0" top="1"> + <Color PropertyName="color" blue="99" green="8a" id="Button.darkShadow" palette="3" red="7a" type="palette"/> + </MatteColorBorder> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="panelTask"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Before"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JLabel" name="m_jHost"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="11" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/display.png"/> + </Property> + <Property name="text" type="java.lang.String" value="*Hostname"/> + </Properties> + </Component> + <Component class="com.alee.extended.statusbar.WebMemoryBar" name="webMemoryBar1"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="99" green="99" red="99" type="rgb"/> + </Property> + <Property name="text" type="java.lang.String" value=""/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="11" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="usedBorderColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="cc" green="cc" red="0" type="rgb"/> + </Property> + <Property name="usedFillColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="cc" red="0" type="rgb"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.progressbar.WebProgressBar" name="serverMonitor"> + <Properties> + <Property name="toolTipText" type="java.lang.String" value=""/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 18]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="progressBottomColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ed" green="c5" red="4c" type="rgb"/> + </Property> + <Property name="round" type="int" value="2"/> + <Property name="string" type="java.lang.String" value="Keep Alive"/> + <Property name="stringPainted" type="boolean" value="true"/> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="After"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/forms/JRootApp.java b/src/main/java/com/unicenta/pos/forms/JRootApp.java new file mode 100644 index 0000000..71b653e --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/JRootApp.java @@ -0,0 +1,1217 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/> + +package com.unicenta.pos.forms; + +import com.dalsemi.onewire.OneWireAccessProvider; +import com.dalsemi.onewire.OneWireException; +import com.dalsemi.onewire.adapter.DSPortAdapter; +import com.dalsemi.onewire.application.monitor.DeviceMonitor; +import com.dalsemi.onewire.application.monitor.DeviceMonitorEvent; +import com.dalsemi.onewire.application.monitor.DeviceMonitorEventListener; +import com.dalsemi.onewire.application.monitor.DeviceMonitorException; +import com.dalsemi.onewire.container.OneWireContainer; +import com.dalsemi.onewire.utils.Address; +import com.unicenta.basic.BasicException; +import com.unicenta.beans.JFlowPanel; +import com.unicenta.beans.JPasswordDialog; +import com.unicenta.data.gui.JMessageDialog; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.loader.BatchSentence; +import com.unicenta.data.loader.BatchSentenceResource; +import com.unicenta.data.loader.Session; +import com.unicenta.format.Formats; +import com.unicenta.pos.printer.DeviceTicket; +import com.unicenta.pos.printer.TicketParser; +import com.unicenta.pos.printer.TicketPrinterException; +import com.unicenta.pos.scale.DeviceScale; +import com.unicenta.pos.scanpal2.DeviceScanner; +import com.unicenta.pos.scanpal2.DeviceScannerFactory; +import com.unicenta.pos.util.uOWWatch; +import lombok.extern.slf4j.Slf4j; +import org.joda.time.DateTime; +import org.joda.time.Instant; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.net.*; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.sql.*; +import java.text.DateFormat; +import java.util.Date; +import java.util.*; +import java.util.regex.Matcher; + + +/** + * @author adrianromero + */ +// public class JRootApp extends JPanel implements AppView { +@Slf4j +public class JRootApp extends JPanel implements AppView, DeviceMonitorEventListener { + + private AppProperties m_props; + private Session session; + private DataLogicSystem m_dlSystem; + + private Properties m_propsdb = null; + private String m_sActiveCashIndex; + private int m_iActiveCashSequence; + private Date m_dActiveCashDateStart; + private Date m_dActiveCashDateEnd; + + private Double m_dActiveCashNotes; + private Double m_dActiveCashCoins; + private Double m_dActiveCashCards; + + private String m_sClosedCashIndex; + private int m_iClosedCashSequence; + private Date m_dClosedCashDateStart; + private Date m_dClosedCashDateEnd; + +// private Double m_dClosedCashNotes; +// private Double m_dClosedCashCoins; +// private Double m_dClosedCashCards; + + private String m_sInventoryLocation; + + private StringBuilder inputtext; + + private DeviceScale m_Scale; + private DeviceScanner m_Scanner; + private DeviceTicket m_TP; + private TicketParser m_TTP; + + private final Map<String, BeanFactory> m_aBeanFactories; + + private JPrincipalApp m_principalapp = null; + + private static HashMap<String, String> m_oldclasses; + + private String m_clock; + private String m_date; + private Connection con; + private ResultSet rs; + private Statement stmt; + private String SQL; + private String sJLVersion; + private DatabaseMetaData md; + + private final int m_rate = 0; + + static { + initOldClasses(); + } + + private String sLaunch; + private String sMachine; + + private class PrintTimeAction implements ActionListener { + + @Override + public void actionPerformed(ActionEvent evt) { + m_clock = getLineTimer(); + m_date = getLineDate(); + + DateTime m_datetime = getDateTime(); + + m_jLblTitle.setText(m_dlSystem.getResourceAsText("Window.Title")); + m_jLblTitle.repaint(); + jLabel2.setText(" " + m_date + " " + m_clock); +/* +* JG Note: Arbritary 8 hour cycle for MySQL server ping on chosen port:nnnn +* MySQL default setting is 28800 seconds (8hrs) +* Better than a host ping as need to know if MySQL is alive & kicking +* Be careful though as MySQL could run out of Connections if it's left on default + + + webProgressBar.setValue(0); + + if (getDateTime().getHourOfDay() == 7 + || getDateTime().getHourOfDay() == 15 + || getDateTime().getHourOfDay() == 23) { + + if (getDateTime().getMinuteOfHour() == 59 && + (getDateTime().getSecondOfMinute() == 59)) { + try { + if (pingServer()) { + webProgressBar.setValue(0); + } else { + webProgressBar.setString("Server is down!"); + webProgressBar.setValue(100); + } + } catch (UnknownHostException ex) { + log.error(ex.getMessage()); } + } + } +*/ + } + } + + private DateTime getDateTime() { + DateTime dt = DateTime.now(); + return dt; + } + + private String getLineTimer() { + return Formats.HOURMIN.formatValue(new Date()); + } + + private String getLineDate() { + DateFormat df = DateFormat.getDateInstance(DateFormat.DEFAULT, getDefaultLocale()); + return df.format(new Date()); + } + + + public JRootApp() { + + m_aBeanFactories = new HashMap<>(); + + initComponents(); + jScrollPane1.getVerticalScrollBar().setPreferredSize(new Dimension(30, 30)); + serverMonitor.setVisible(false); + webMemoryBar1.setShowMaximumMemory(true); + } + + private DSPortAdapter m_oneWireAdapter; + private DeviceMonitor m_oneWireMonitor; + + private void initIButtonMonitor() { + + assert m_oneWireMonitor == null; + try { + m_oneWireAdapter = OneWireAccessProvider.getDefaultAdapter(); + m_oneWireAdapter.setSearchAllDevices(); + m_oneWireAdapter.targetFamily(0x01); + m_oneWireAdapter.setSpeed(DSPortAdapter.SPEED_REGULAR); + m_oneWireMonitor = new DeviceMonitor(m_oneWireAdapter); +// Normal state + m_oneWireMonitor.setMaxStateCount(5); +// Use for testing +// m_oneWireMonitor.setMaxStateCount(100); + m_oneWireMonitor.addDeviceMonitorEventListener(this); + new Thread(m_oneWireMonitor).start(); + } catch (OneWireException e) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.ibuttonnotfound"), e)); + } + } + + private void shutdownIButtonMonitor() { + if (m_oneWireMonitor != null) { + m_oneWireMonitor.killMonitor(); + try { + m_oneWireAdapter.freePort(); + } catch (OneWireException e) { +// System.out.println(e); + } + } + } + + public void releaseResources() { + shutdownIButtonMonitor(); + } + + final static int UNIQUE_KEY_FAMILY = 0x01; + + private boolean isDeviceRelevant(OneWireContainer container) { + String iButtonId = container.getAddressAsString(); + try { + if (container.getAdapter().getAdapterAddress().equals(iButtonId)) + return false; + } catch (OneWireException e) { + } + + int familyNumber = Address.toByteArray(iButtonId)[0]; + return (familyNumber == UNIQUE_KEY_FAMILY); + } + + /** + * Called when an iButton is inserted. + * + * @param devt + */ + @Override + public void deviceArrival(DeviceMonitorEvent devt) { + assert m_dlSystem != null; + + for (int i = 0; i < devt.getDeviceCount(); i++) { + OneWireContainer container = devt.getContainerAt(i); + if (!isDeviceRelevant(container)) + continue; + + String iButtonId = devt.getAddressAsStringAt(i); + + AppUser user = null; + try { + user = m_dlSystem.findPeopleByCard(iButtonId); + } catch (BasicException e) { + if (user == null) { + JOptionPane.showMessageDialog(this, + AppLocal.getIntString("message.ibuttonnotassign"), + AppLocal.getIntString("title.editor"), + JOptionPane.INFORMATION_MESSAGE); + } + } + + if (user == null) { + JOptionPane.showMessageDialog(this, + AppLocal.getIntString("message.ibuttonnotassign"), + AppLocal.getIntString("title.editor"), + JOptionPane.INFORMATION_MESSAGE); + + } else { + setVisible(false); + openAppView(user); + setVisible(true); + } + } + } + + /** + * Called when an iButton is removed. + * + * @param devt + */ + @Override + public void deviceDeparture(DeviceMonitorEvent devt) { + + for (int i = 0; i < devt.getDeviceCount(); i++) { + OneWireContainer container = devt.getContainerAt(i); + if (!isDeviceRelevant(container)) + continue; + + String iButtonId = devt.getAddressAsStringAt(i); + + if (m_principalapp != null) { + AppUser currentUser = m_principalapp.getUser(); + if (currentUser != null && currentUser.getCard().equals(iButtonId)) + closeAppView(); + } + } + } + + @Override + public void networkException(DeviceMonitorException dexc) { +// System.out.println("ERROR: " + dexc.toString()); + } + + /** + * @param props + * @return + */ + public boolean initApp(AppProperties props) { + + m_props = props; + m_jPanelDown.setVisible(!(Boolean.valueOf(m_props.getProperty("till.hideinfo")))); + + applyComponentOrientation(ComponentOrientation.getOrientation(Locale.getDefault())); + + try { + session = AppViewConnection.createSession(m_props); + + } catch (BasicException e) { + JMessageDialog.showMessage(this, new MessageInf(MessageInf.SGN_DANGER, e.getMessage(), e)); + return false; + } + + m_dlSystem = (DataLogicSystem) getBean("com.unicenta.pos.forms.DataLogicSystem"); +/** + * CONDITIONS; + * if dbversion is null then new createDatabase + * if dbversion is not null then check the version + * if appversion equals dbversion then check for updates + * IF APP_VERSION = existing db version + * + */ + String sDBVersion = readDataBaseVersion(); + if (!AppLocal.APP_VERSION.equals(sDBVersion)) { + String sScript = sDBVersion == null + ? m_dlSystem.getInitScript() + "-create.sql" + : m_dlSystem.getInitScript() + "-upgrade_master.sql"; + + if (JRootApp.class.getResource(sScript) == null) { + JMessageDialog.showMessage(this, new MessageInf(MessageInf.SGN_DANGER, sDBVersion == null + ? AppLocal.getIntString("message.databasenotsupported", session.DB.getName() + " " + sDBVersion) + : AppLocal.getIntString("message.noupdatescript"))); + session.close(); + return false; + } else { + + String migrationMessage = sDBVersion == null ? "message.createdatabase" : "message.eolupdate"; + if (JOptionPane.showConfirmDialog(this + , AppLocal.getIntString(migrationMessage, session.DB.getName() + " " + sDBVersion) + , AppLocal.getIntString("message.title") + , JOptionPane.OK_OPTION + , JOptionPane.WARNING_MESSAGE) == JOptionPane.OK_OPTION) { + + try { + BatchSentence bsentence = new BatchSentenceResource(session, sScript); + bsentence.putParameter("APP_ID", Matcher.quoteReplacement(AppLocal.APP_ID)); + bsentence.putParameter("APP_NAME", Matcher.quoteReplacement(AppLocal.APP_NAME)); + bsentence.putParameter("APP_VERSION", Matcher.quoteReplacement(AppLocal.APP_VERSION)); + + java.util.List l = bsentence.list(); + + if (l.size() > 0) { + JMessageDialog.showMessage(this, new MessageInf(MessageInf.SGN_WARNING + , AppLocal.getIntString("database.scriptwarning") + , l.toArray(new Throwable[l.size()]))); + } + } catch (BasicException e) { + JMessageDialog.showMessage(this + , new MessageInf(MessageInf.SGN_DANGER + , AppLocal.getIntString("database.scripterror"), e)); + session.close(); + return false; + } + } else { + session.close(); + return false; + } + } + } + + /* + * JG 10 Dec 2018 + * Test rig in prep' to track user install/launch success/fails + * We only need core info' to identify for POC + * For testing; code and declares are deliberately verbose + * + * FUTURE : + * App' error logging + * Also auto-Notify users of available app' updates. + * To be replaced with our REST API + */ + + try { + sMachine = InetAddress.getLocalHost().getHostName(); + } catch (UnknownHostException ex) { + log.error(ex.getMessage()); + } +// create the filename + String sUserPath = System.getProperty("user.home"); + String filePath = sUserPath + "/" + sMachine + ".lau"; + + Instant machineTimestamp = Instant.now(); + String sContent = sUserPath + "," + + machineTimestamp + "," + + AppLocal.APP_ID + "," + + AppLocal.APP_NAME + "," + + AppLocal.APP_VERSION + "\n"; + + try { + Files.write(Paths.get(filePath), sContent.getBytes(), + StandardOpenOption.APPEND, StandardOpenOption.CREATE); + } catch (IOException ex) { + log.error(ex.getMessage()); + } + + try { + filePath = sUserPath + "/open.db"; + Files.write(Paths.get(filePath), sContent.getBytes(), + StandardOpenOption.CREATE); + } catch (IOException ex) { + log.error(ex.getMessage()); + } + + m_propsdb = m_dlSystem.getResourceAsProperties(m_props.getHost() + "/properties"); + + try { + String sActiveCashIndex = m_propsdb.getProperty("activecash"); + + Object[] valcash = sActiveCashIndex == null + ? null + : m_dlSystem.findActiveCash(sActiveCashIndex); + + + if (valcash == null || !m_props.getHost().equals(valcash[0])) { + + setActiveCash(UUID.randomUUID().toString(),m_dlSystem.getSequenceCash(m_props.getHost()) + 1, new Date(), null); + + Object[] cash = new Object[]{ + getActiveCashIndex(), + m_props.getHost(), + getActiveCashSequence(), + getActiveCashDateStart(), + getActiveCashDateEnd() + }; + + m_dlSystem.execInsertCash(cash); + + } else { + setActiveCash(sActiveCashIndex + , (Integer) valcash[1] + , (Date) valcash[2] + , (Date) valcash[3]); + } + } catch (BasicException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE + , AppLocal.getIntString("message.cannotclosecash"), e); + msg.show(this); + session.close(); + return false; + } + + m_sInventoryLocation = m_propsdb.getProperty("location"); + if (m_sInventoryLocation == null) { + m_sInventoryLocation = "0"; + m_propsdb.setProperty("location", m_sInventoryLocation); + m_dlSystem.setResourceAsProperties(m_props.getHost() + "/properties" + , m_propsdb); + } + + m_TP = new DeviceTicket(this, m_props); + + m_TTP = new TicketParser(getDeviceTicket(), m_dlSystem); + printerStart(); + + m_Scale = new DeviceScale(this, m_props); + + m_Scanner = DeviceScannerFactory.createInstance(m_props); + + new javax.swing.Timer(250, new PrintTimeAction()).start(); + + String sWareHouse; + + try { + sWareHouse = m_dlSystem.findLocationName(m_sInventoryLocation); + } catch (BasicException e) { + sWareHouse = null; + } + + String url; + try { + url = session.getURL(); + } catch (SQLException e) { + url = ""; + } + m_jHost.setText("<html>" + m_props.getHost() + " - " + sWareHouse + "<br>" + url); + + + String newLogo = m_props.getProperty("start.logo"); + if (newLogo != null) { + if ("".equals(newLogo)) { + jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/logo.png"))); + } else { + jLabel1.setIcon(new javax.swing.ImageIcon(newLogo)); + } + } + + String newText = m_props.getProperty("start.text"); + if (newText != null) { + if (newText.equals("")) { + jLabel1.setText("<html><center>uniCenta oPOS - Touch Friendly Point of Sale<br>" + + "Copyright \u00A9 uniCenta <br>" + + "https://unicenta.com/<br>" + + "<br>" + + "uniCenta oPOS is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.<br>" + + "<br>" + + "uniCenta oPOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.<br>" + + "<br>" + + "You should have received a copy of the GNU General Public License along with uniCenta oPOS. If not, see http://www.gnu.org/licenses/<br>" + + "</center>"); + + } else { + try { + String newTextCode = new Scanner(new File(newText) + , "UTF-8").useDelimiter("\\A").next(); + jLabel1.setText(newTextCode); + } catch (FileNotFoundException e) { + } + + jLabel1.setAlignmentX(0.5F); + jLabel1.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + jLabel1.setMaximumSize(new java.awt.Dimension(800, 1024)); + jLabel1.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + } + } + + showLogin(); + + String ibutton = m_props.getProperty("machine.iButton"); + if (ibutton.equals("true")) { + initIButtonMonitor(); + uOWWatch.iButtonOn(); + } + return true; + } + + private String readDataBaseVersion() { + try { + return m_dlSystem.findVersion(); + } catch (BasicException ed) { + return null; + } + } + + public void tryToClose() { + + if (closeAppView()) { + m_TP.getDeviceDisplay().clearVisor(); + shutdownIButtonMonitor(); + +// delete the open.db tracking file + String sUserPath = System.getProperty("user.home"); +// String filePath = sUserPath + "\\open.db"; + String filePath = sUserPath + "/open.db"; + try { + Files.deleteIfExists(Paths.get(filePath)); + } catch (IOException ex) { + log.error(ex.getMessage()); + } + + session.close(); + SwingUtilities.getWindowAncestor(this).dispose(); + } + } + + @Override + public DeviceTicket getDeviceTicket() { + return m_TP; + } + + @Override + public DeviceScale getDeviceScale() { + return m_Scale; + } + + @Override + public DeviceScanner getDeviceScanner() { + return m_Scanner; + } + + @Override + public Session getSession() { + return session; + } + + @Override + public String getInventoryLocation() { + return m_sInventoryLocation; + } + + @Override + public String getActiveCashIndex() { + return m_sActiveCashIndex; + } + + @Override + public int getActiveCashSequence() { + return m_iActiveCashSequence; + } + + @Override + public Date getActiveCashDateStart() { + return m_dActiveCashDateStart; + } + + @Override + public Date getActiveCashDateEnd() { + return m_dActiveCashDateEnd; + } + + @Override + public void setActiveCash(String sIndex, int iSeq, Date dStart, Date dEnd) { + m_sActiveCashIndex = sIndex; + m_iActiveCashSequence = iSeq; + m_dActiveCashDateStart = dStart; + m_dActiveCashDateEnd = dEnd; + + m_propsdb.setProperty("activecash", m_sActiveCashIndex); + m_dlSystem.setResourceAsProperties(m_props.getHost() + "/properties", m_propsdb); + } + + @Override + public String getClosedCashIndex() { + return m_sClosedCashIndex; + } + + @Override + public int getClosedCashSequence() { + return m_iClosedCashSequence; + } + + @Override + public Date getClosedCashDateStart() { + return m_dClosedCashDateStart; + } + + @Override + public Date getClosedCashDateEnd() { + return m_dClosedCashDateEnd; + } + + @Override + public void setClosedCash(String sIndex, int iSeq, Date dStart, Date dEnd) { + m_sClosedCashIndex = sIndex; + m_iClosedCashSequence = iSeq; + m_dClosedCashDateStart = dStart; + m_dClosedCashDateEnd = dEnd; + + m_dlSystem.setResourceAsProperties(m_props.getHost() + "/properties", m_propsdb); + } + + @Override + public AppProperties getProperties() { + return m_props; + } + + @Override + public Object getBean(String beanfactory) throws BeanFactoryException { + + beanfactory = mapNewClass(beanfactory); + BeanFactory bf = m_aBeanFactories.get(beanfactory); + + if (bf == null) { + + if (beanfactory.startsWith("/")) { + bf = new BeanFactoryScript(beanfactory); + } else { + try { + Class bfclass = Class.forName(beanfactory); + + if (BeanFactory.class.isAssignableFrom(bfclass)) { + bf = (BeanFactory) bfclass.newInstance(); + } else { + Constructor constMyView = bfclass.getConstructor(new Class[]{AppView.class}); + Object bean = constMyView.newInstance(new Object[]{this}); + bf = new BeanFactoryObj(bean); + } + + } catch (ClassNotFoundException | InstantiationException + | IllegalAccessException | NoSuchMethodException + | SecurityException | IllegalArgumentException | InvocationTargetException e) { + throw new BeanFactoryException(e); + } + } + + m_aBeanFactories.put(beanfactory, bf); + + if (bf instanceof BeanFactoryApp) { + ((BeanFactoryApp) bf).init(this); + } + } + return bf.getBean(); + } + + private static String mapNewClass(String classname) { + String newclass = m_oldclasses.get(classname); + return newclass == null + ? classname + : newclass; + } + + private static void initOldClasses() { + m_oldclasses = new HashMap<>(); + + m_oldclasses.put("com.unicenta.pos.reports.JReportCustomers", "/com/unicenta/reports/customers.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportCustomersB", "/com/unicenta/reports/customersb.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportClosedPos", "/com/unicenta/reports/closedpos.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportClosedProducts", "/com/unicenta/reports/closedproducts.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JChartSales", "/com/unicenta/reports/chartsales.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportInventory", "/com/unicenta/reports/inventory.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportInventory2", "/com/unicenta/reports/inventoryb.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportInventoryBroken", "/com/unicenta/reports/inventorybroken.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportInventoryDiff", "/com/unicenta/reports/inventorydiff.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportPeople", "/com/unicenta/reports/people.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportTaxes", "/com/unicenta/reports/taxes.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportUserSales", "/com/unicenta/reports/usersales.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportProducts", "/com/unicenta/reports/products.bs"); + m_oldclasses.put("com.unicenta.pos.reports.JReportCatalog", "/com/unicenta/reports/productscatalog.bs"); + + m_oldclasses.put("com.unicenta.pos.panels.JPanelTax", "com.unicenta.pos.inventory.TaxPanel"); + + } + + @Override + public void waitCursorBegin() { + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + } + + @Override + public void waitCursorEnd() { + setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + + @Override + public AppUserView getAppUserView() { + return m_principalapp; + } + + private void printerStart() { + + String sresource = m_dlSystem.getResourceAsXML("Printer.Start"); + if (sresource == null) { + m_TP.getDeviceDisplay().writeVisor(AppLocal.APP_NAME, AppLocal.APP_VERSION); + } else { + try { + m_TTP.printTicket(sresource); + } catch (TicketPrinterException eTP) { + m_TP.getDeviceDisplay().writeVisor(AppLocal.APP_NAME, AppLocal.APP_VERSION); + } + } + } + + private void listPeople() { + + try { + + jScrollPane1.getViewport().setView(null); + + JFlowPanel jPeople = new JFlowPanel(); + jPeople.applyComponentOrientation(getComponentOrientation()); + + java.util.List people = m_dlSystem.listPeopleVisible(); + + for (Object people1 : people) { + AppUser user = (AppUser) people1; + JButton btn = new JButton(new AppUserAction(user)); + btn.applyComponentOrientation(getComponentOrientation()); + btn.setFocusPainted(false); + btn.setFocusable(false); + btn.setRequestFocusEnabled(false); + btn.setMaximumSize(new Dimension(110, 60)); + btn.setPreferredSize(new Dimension(110, 60)); + btn.setMinimumSize(new Dimension(110, 60)); + btn.setHorizontalAlignment(SwingConstants.CENTER); + btn.setHorizontalTextPosition(AbstractButton.CENTER); + btn.setVerticalTextPosition(AbstractButton.BOTTOM); + jPeople.add(btn); + } + + jScrollPane1.getViewport().setView(jPeople); + + } catch (BasicException ee) { + } + } + + class AppUserAction extends AbstractAction { + + private final AppUser m_actionuser; + + public AppUserAction(AppUser user) { + m_actionuser = user; + putValue(Action.SMALL_ICON, m_actionuser.getIcon()); + putValue(Action.NAME, m_actionuser.getName()); + } + + public AppUser getUser() { + return m_actionuser; + } + + @Override + public void actionPerformed(ActionEvent evt) { + + if (m_actionuser.authenticate()) { + openAppView(m_actionuser); + } else { + String sPassword = JPasswordDialog.showEditPassword(JRootApp.this, + AppLocal.getIntString("label.Password"), + m_actionuser.getName(), + m_actionuser.getIcon()); + if (sPassword != null) { + + if (m_actionuser.authenticate(sPassword)) { + openAppView(m_actionuser); + } else { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.BadPassword")); + msg.show(JRootApp.this); + } + } + } + } + } + + private void showView(String view) { + CardLayout cl = (CardLayout) (m_jPanelContainer.getLayout()); + cl.show(m_jPanelContainer, view); + } + + private void openAppView(AppUser user) { + + if (closeAppView()) { + + m_principalapp = new JPrincipalApp(this, user); + + jPanel3.add(m_principalapp.getNotificator()); + jPanel3.revalidate(); + + m_jPanelContainer.add(m_principalapp + , "_" + m_principalapp.getUser().getId()); + showView("_" + m_principalapp.getUser().getId()); + + m_principalapp.activate(); + } + } + + public void exitToLogin() { + closeAppView(); + showLogin(); + } + + public boolean closeAppView() { + + if (m_principalapp == null) { + return true; + } else if (!m_principalapp.deactivate()) { + return false; + } else { + jPanel3.remove(m_principalapp.getNotificator()); + jPanel3.revalidate(); + jPanel3.repaint(); + + m_jPanelContainer.remove(m_principalapp); + m_principalapp = null; + + showLogin(); + + return true; + } + } + + private void showLogin() { + + listPeople(); + showView("login"); + + printerStart(); + + inputtext = new StringBuilder(); + m_txtKeys.setText(null); + java.awt.EventQueue.invokeLater(() -> { + m_txtKeys.requestFocus(); + }); + } + + private void processKey(char c) { + + if ((c == '\n') || (c == '?')) { + AppUser user = null; + try { + user = m_dlSystem.findPeopleByCard(inputtext.toString()); + } catch (BasicException e) { + } + + if (user == null) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.nocard")); + msg.show(this); + } else { + openAppView(user); + } + + inputtext = new StringBuilder(); + } else { + inputtext.append(c); + } + } + + private int getProgressBar() { + int rate = serverMonitor.getValue(); + return rate; + } + + private boolean pingServer() throws UnknownHostException { + /* + * This method is for the future. Connects and will include both servers + backup server + * Tested locally on JG machine and unicenta-server + */ + serverMonitor.setString("Checking..."); + + InetAddress addr = InetAddress.getByName(AppLocal.getIntString("db.ip")); + int port = 3306; + + SocketAddress sockaddr = new InetSocketAddress(addr, port); + Socket sock = new Socket(); + try { + sock.connect(sockaddr, 2000); + serverMonitor.setString("Server is alive!"); + serverMonitor.setValue(0); + return true; + } catch (IOException ex) { + log.error(ex.getMessage()); + return false; + } + } + + /** + * This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the FormEditor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jPanelTitle = new javax.swing.JPanel(); + m_jLblTitle = new javax.swing.JLabel(); + poweredby = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + m_jPanelContainer = new javax.swing.JPanel(); + m_jPanelLogin = new javax.swing.JPanel(); + jPanel4 = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 10), new java.awt.Dimension(32767, 0)); + jPanel5 = new javax.swing.JPanel(); + m_jLogonName = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + jPanel8 = new javax.swing.JPanel(); + jScrollPane1 = new javax.swing.JScrollPane(); + jPanel1 = new javax.swing.JPanel(); + m_txtKeys = new javax.swing.JTextField(); + m_jClose = new javax.swing.JButton(); + m_jPanelDown = new javax.swing.JPanel(); + panelTask = new javax.swing.JPanel(); + m_jHost = new javax.swing.JLabel(); + webMemoryBar1 = new com.alee.extended.statusbar.WebMemoryBar(); + serverMonitor = new com.alee.laf.progressbar.WebProgressBar(); + jPanel3 = new javax.swing.JPanel(); + + setEnabled(false); + setPreferredSize(new java.awt.Dimension(1024, 768)); + setLayout(new java.awt.BorderLayout()); + + m_jPanelTitle.setBorder(javax.swing.BorderFactory.createMatteBorder(0, 0, 1, 0, javax.swing.UIManager.getDefaults().getColor("Button.darkShadow"))); + m_jPanelTitle.setPreferredSize(new java.awt.Dimension(449, 40)); + m_jPanelTitle.setLayout(new java.awt.BorderLayout()); + + m_jLblTitle.setFont(new java.awt.Font("Arial", 1, 16)); // NOI18N + m_jLblTitle.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + m_jLblTitle.setText("Window.Title"); + m_jPanelTitle.add(m_jLblTitle, java.awt.BorderLayout.CENTER); + + poweredby.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + poweredby.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/poweredby_uni.png"))); // NOI18N + poweredby.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 5, 0, 5)); + poweredby.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT); + poweredby.setMaximumSize(new java.awt.Dimension(180, 34)); + poweredby.setPreferredSize(new java.awt.Dimension(180, 34)); + m_jPanelTitle.add(poweredby, java.awt.BorderLayout.LINE_END); + + jLabel2.setFont(new java.awt.Font("Arial", 1, 16)); // NOI18N + jLabel2.setForeground(new java.awt.Color(102, 102, 102)); + jLabel2.setPreferredSize(new java.awt.Dimension(180, 34)); + m_jPanelTitle.add(jLabel2, java.awt.BorderLayout.LINE_START); + + add(m_jPanelTitle, java.awt.BorderLayout.NORTH); + + m_jPanelContainer.setLayout(new java.awt.CardLayout()); + + m_jPanelLogin.setLayout(new java.awt.BorderLayout()); + + jPanel4.setLayout(new javax.swing.BoxLayout(jPanel4, javax.swing.BoxLayout.Y_AXIS)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/unicenta.png"))); // NOI18N + jLabel1.setText("<html><center>uniCenta oPOS - Touch Friendly Point of Sale<br>" + + "Copyright \u00A9 2009-2017 uniCenta <br>" + + "https://unicenta.com<br>" + + "<br>" + + "uniCenta oPOS is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.<br>" + + "<br>" + + "uniCenta oPOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.<br>" + + "<br>" + + "You should have received a copy of the GNU General Public License along with uniCenta oPOS. If not, see http://www.gnu.org/licenses/<br>" + + "</center>"); + jLabel1.setAlignmentX(0.5F); + jLabel1.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + jLabel1.setMaximumSize(new java.awt.Dimension(800, 1024)); + jLabel1.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + jPanel4.add(jLabel1); + jPanel4.add(filler2); + + m_jPanelLogin.add(jPanel4, java.awt.BorderLayout.CENTER); + + jPanel5.setPreferredSize(new java.awt.Dimension(300, 400)); + + m_jLogonName.setLayout(new java.awt.BorderLayout()); + + jPanel2.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 5, 0, 5)); + jPanel2.setPreferredSize(new java.awt.Dimension(100, 100)); + jPanel2.setLayout(new java.awt.BorderLayout()); + + jPanel8.setLayout(new java.awt.GridLayout(0, 1, 5, 5)); + jPanel2.add(jPanel8, java.awt.BorderLayout.NORTH); + + m_jLogonName.add(jPanel2, java.awt.BorderLayout.LINE_END); + + jScrollPane1.setBorder(null); + jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + jScrollPane1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + + m_txtKeys.setPreferredSize(new java.awt.Dimension(0, 0)); + m_txtKeys.addKeyListener(new java.awt.event.KeyAdapter() { + public void keyTyped(java.awt.event.KeyEvent evt) { + m_txtKeysKeyTyped(evt); + } + }); + + m_jClose.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jClose.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/exit.png"))); // NOI18N + m_jClose.setText(AppLocal.getIntString("button.close")); // NOI18N + m_jClose.setFocusPainted(false); + m_jClose.setFocusable(false); + m_jClose.setPreferredSize(new java.awt.Dimension(100, 50)); + m_jClose.setRequestFocusEnabled(false); + m_jClose.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jCloseActionPerformed(evt); + } + }); + + org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jPanel1Layout.createSequentialGroup() + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jPanel1Layout.createSequentialGroup() + .add(m_txtKeys, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(0, 0, Short.MAX_VALUE)) + .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1Layout.createSequentialGroup() + .addContainerGap() + .add(m_jClose, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 267, Short.MAX_VALUE))) + .addContainerGap()) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jPanel1Layout.createSequentialGroup() + .add(m_txtKeys, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(m_jClose, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + ); + + org.jdesktop.layout.GroupLayout jPanel5Layout = new org.jdesktop.layout.GroupLayout(jPanel5); + jPanel5.setLayout(jPanel5Layout); + jPanel5Layout.setHorizontalGroup( + jPanel5Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jPanel5Layout.createSequentialGroup() + .addContainerGap() + .add(jPanel5Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false) + .add(jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .add(jScrollPane1)) + .add(104, 104, 104) + .add(m_jLogonName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(0, 0, Short.MAX_VALUE)) + ); + jPanel5Layout.setVerticalGroup( + jPanel5Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jPanel5Layout.createSequentialGroup() + .add(15, 15, 15) + .add(jPanel5Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jPanel5Layout.createSequentialGroup() + .add(m_jLogonName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(434, 434, 434)) + .add(jPanel5Layout.createSequentialGroup() + .add(jScrollPane1) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addContainerGap()))) + ); + + m_jPanelLogin.add(jPanel5, java.awt.BorderLayout.EAST); + + m_jPanelContainer.add(m_jPanelLogin, "login"); + + add(m_jPanelContainer, java.awt.BorderLayout.CENTER); + + m_jPanelDown.setBorder(javax.swing.BorderFactory.createMatteBorder(1, 0, 0, 0, javax.swing.UIManager.getDefaults().getColor("Button.darkShadow"))); + m_jPanelDown.setLayout(new java.awt.BorderLayout()); + + m_jHost.setFont(new java.awt.Font("Arial", 0, 11)); // NOI18N + m_jHost.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/display.png"))); // NOI18N + m_jHost.setText("*Hostname"); + panelTask.add(m_jHost); + + webMemoryBar1.setBackground(new java.awt.Color(153, 153, 153)); + webMemoryBar1.setText(""); + webMemoryBar1.setFont(new java.awt.Font("Arial", 0, 11)); // NOI18N + webMemoryBar1.setPreferredSize(new java.awt.Dimension(150, 30)); + webMemoryBar1.setUsedBorderColor(new java.awt.Color(0, 204, 204)); + webMemoryBar1.setUsedFillColor(new java.awt.Color(0, 204, 255)); + panelTask.add(webMemoryBar1); + + serverMonitor.setToolTipText(""); + serverMonitor.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + serverMonitor.setMaximumSize(new java.awt.Dimension(50, 18)); + serverMonitor.setPreferredSize(new java.awt.Dimension(150, 30)); + serverMonitor.setProgressBottomColor(new java.awt.Color(76, 197, 237)); + serverMonitor.setRound(2); + serverMonitor.setString("Keep Alive"); + serverMonitor.setStringPainted(true); + panelTask.add(serverMonitor); + + m_jPanelDown.add(panelTask, java.awt.BorderLayout.LINE_START); + m_jPanelDown.add(jPanel3, java.awt.BorderLayout.LINE_END); + + add(m_jPanelDown, java.awt.BorderLayout.SOUTH); + }// </editor-fold>//GEN-END:initComponents + + + private void m_txtKeysKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_m_txtKeysKeyTyped + + m_txtKeys.setText("0"); + processKey(evt.getKeyChar()); + + }//GEN-LAST:event_m_txtKeysKeyTyped + + private void m_jCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jCloseActionPerformed + tryToClose(); + }//GEN-LAST:event_m_jCloseActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.Box.Filler filler2; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JPanel jPanel8; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JButton m_jClose; + private javax.swing.JLabel m_jHost; + private javax.swing.JLabel m_jLblTitle; + private javax.swing.JPanel m_jLogonName; + private javax.swing.JPanel m_jPanelContainer; + private javax.swing.JPanel m_jPanelDown; + private javax.swing.JPanel m_jPanelLogin; + private javax.swing.JPanel m_jPanelTitle; + private javax.swing.JTextField m_txtKeys; + private javax.swing.JPanel panelTask; + private javax.swing.JLabel poweredby; + private com.alee.laf.progressbar.WebProgressBar serverMonitor; + private com.alee.extended.statusbar.WebMemoryBar webMemoryBar1; + // End of variables declaration//GEN-END:variables +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/forms/JRootFrame.form b/src/main/java/com/unicenta/pos/forms/JRootFrame.form new file mode 100644 index 0000000..768996a --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/JRootFrame.form @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JFrameFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="0"/> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSizePolicy" type="int" value="2"/> + </SyntheticProperties> + <Events> + <EventHandler event="windowClosed" listener="java.awt.event.WindowListener" parameters="java.awt.event.WindowEvent" handler="formWindowClosed"/> + <EventHandler event="windowClosing" listener="java.awt.event.WindowListener" parameters="java.awt.event.WindowEvent" handler="formWindowClosing"/> + </Events> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> +</Form> diff --git a/src/main/java/com/unicenta/pos/forms/JRootFrame.java b/src/main/java/com/unicenta/pos/forms/JRootFrame.java new file mode 100644 index 0000000..c8fcf10 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/JRootFrame.java @@ -0,0 +1,161 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import com.unicenta.plugins.Application; +import com.unicenta.plugins.metrics.Metrics; +import com.unicenta.pos.config.JFrmConfig; +import com.unicenta.pos.instance.AppMessage; +import com.unicenta.pos.instance.InstanceManager; + +import java.awt.BorderLayout; +import java.io.IOException; +import java.rmi.AlreadyBoundException; +import java.rmi.RemoteException; +import javax.imageio.ImageIO; +import javax.swing.JFrame; + +import com.unicenta.pos.scripting.ScriptEngine; +import com.unicenta.pos.scripting.ScriptException; +import com.unicenta.pos.scripting.ScriptFactory; +import com.unicenta.pos.util.AltEncrypter; +import com.unicenta.pos.util.OSValidator; +import com.unicenta.pos.util.SessionKeepAlive; +import lombok.extern.slf4j.Slf4j; + +/** + * @author adrianromero + */ +@Slf4j +public class JRootFrame extends javax.swing.JFrame implements AppMessage { + + private InstanceManager m_instmanager = null; + + private JRootApp m_rootapp; + private AppProperties m_props; + + private OSValidator m_OS; + + /** + * Creates new form JRootFrame + */ + public JRootFrame() { + + initComponents(); + } + + /** + * @param props + */ + public void initFrame(AppProperties props) { + + m_OS = new OSValidator(); + m_props = props; + + m_rootapp = new JRootApp(); + + if (m_rootapp.initApp(m_props)) { + + if ("true".equals(props.getProperty("machine.uniqueinstance"))) { + // Register the running application + try { + m_instmanager = new InstanceManager(this); + } catch (RemoteException | AlreadyBoundException e) { + } + } + + // Show the application + add(m_rootapp, BorderLayout.CENTER); + + try { + this.setIconImage(ImageIO.read(JRootFrame.class.getResourceAsStream("/com/unicenta/images/favicon.png"))); + } catch (IOException e) { + } + + setTitle(AppLocal.APP_NAME + " - " + AppLocal.APP_VERSION); + pack(); + setLocationRelativeTo(null); + + setVisible(true); + } else { + new JFrmConfig(props).setVisible(true); // Show the configuration window. + } + + } + + /** + * @throws RemoteException + */ + @Override + public void restoreWindow() throws RemoteException { + java.awt.EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + if (getExtendedState() == JFrame.ICONIFIED) { + setExtendedState(JFrame.NORMAL); + } + requestFocus(); + } + }); + } + + private void startSessionKeepAlive(DataLogicSystem dataLogicSystem) { + SessionKeepAlive sessionKeepAlive = new SessionKeepAlive(dataLogicSystem); + sessionKeepAlive.start(); + } + + /** + * This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE); + addWindowListener(new java.awt.event.WindowAdapter() { + public void windowClosed(java.awt.event.WindowEvent evt) { + formWindowClosed(evt); + } + + public void windowClosing(java.awt.event.WindowEvent evt) { + formWindowClosing(evt); + } + }); + }// </editor-fold>//GEN-END:initComponents + + private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing + + m_rootapp.tryToClose(); + + }//GEN-LAST:event_formWindowClosing + + private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed + + m_rootapp.releaseResources(); + System.exit(0); + + }//GEN-LAST:event_formWindowClosed + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/forms/JRootKiosk.form b/src/main/java/com/unicenta/pos/forms/JRootKiosk.form new file mode 100644 index 0000000..9c38533 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/JRootKiosk.form @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JFrameFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="0"/> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSizePolicy" type="int" value="2"/> + </SyntheticProperties> + <Events> + <EventHandler event="windowClosed" listener="java.awt.event.WindowListener" parameters="java.awt.event.WindowEvent" handler="formWindowClosed"/> + <EventHandler event="windowClosing" listener="java.awt.event.WindowListener" parameters="java.awt.event.WindowEvent" handler="formWindowClosing"/> + </Events> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,113,0,0,2,23"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> +</Form> diff --git a/src/main/java/com/unicenta/pos/forms/JRootKiosk.java b/src/main/java/com/unicenta/pos/forms/JRootKiosk.java new file mode 100644 index 0000000..433e262 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/JRootKiosk.java @@ -0,0 +1,175 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import com.unicenta.pos.config.JFrmConfig; +import com.unicenta.pos.instance.AppMessage; +import com.unicenta.pos.instance.InstanceManager; +import com.unicenta.pos.util.OSValidator; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Toolkit; +import java.io.IOException; +import java.rmi.AlreadyBoundException; +import java.rmi.RemoteException; +import javax.swing.JFrame; + +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import javax.swing.JOptionPane; + +/** + * + * @author adrianromero + */ +public class JRootKiosk extends javax.swing.JFrame implements AppMessage { + + private InstanceManager m_instmanager = null; + + private JRootApp m_rootapp; + private AppProperties m_props; + private OSValidator m_OS; + + /** Creates new form JRootKiosk */ + public JRootKiosk() { + + setUndecorated(true); + setResizable(false); + + initComponents(); + } + + /** + * + * @param props + * @throws java.io.IOException + */ + public void initFrame(AppProperties props) throws IOException { + + m_OS = new OSValidator(); + m_props = props; + + m_rootapp = new JRootApp(); + + if (m_rootapp.initApp(m_props)) { + + if ("true".equals(props.getProperty("machine.uniqueinstance"))) { + try { + m_instmanager = new InstanceManager(this); + } catch (RemoteException | AlreadyBoundException e) { + } + } + + add(m_rootapp, BorderLayout.CENTER); + + setTitle(AppLocal.APP_NAME + " - " + AppLocal.APP_VERSION); + + Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); + setBounds(0, 0, d.width, d.height); + +/* + * 4 Sep 17 JG + * 2 Dec 17 - Mod' Thanks Hayk Sokolov! + * Change here for Linux/Ubuntu full screen + * Thanks to Hans Lengerke for solution +*/ + String osName = System.getProperty("os.name").toLowerCase(); + boolean isWindows = osName.startsWith("windows"); + + GraphicsDevice device = GraphicsEnvironment + .getLocalGraphicsEnvironment().getDefaultScreenDevice(); + + if (device.isFullScreenSupported() && !isWindows) { + setResizable(true); + + addFocusListener(new FocusListener() { + @Override + public void focusGained(FocusEvent arg0) { + setAlwaysOnTop(true); + } + @Override + public void focusLost(FocusEvent arg0) { + setAlwaysOnTop(false); + } + }); + device.setFullScreenWindow(this); + } else { + setVisible(true); + } + } else { + JOptionPane.showMessageDialog(this, + AppLocal.getIntString("message.databasechange"), + "Connection", JOptionPane.INFORMATION_MESSAGE); + + new JFrmConfig(props).setVisible(true); // Show the configuration window. + } + } + + @Override + public void restoreWindow() throws RemoteException { + java.awt.EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + if (getExtendedState() == JFrame.ICONIFIED) { + setExtendedState(JFrame.NORMAL); + } + requestFocus(); + } + }); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE); + addWindowListener(new java.awt.event.WindowAdapter() { + public void windowClosed(java.awt.event.WindowEvent evt) { + formWindowClosed(evt); + } + public void windowClosing(java.awt.event.WindowEvent evt) { + formWindowClosing(evt); + } + }); + }// </editor-fold>//GEN-END:initComponents + + private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing + + m_rootapp.tryToClose(); + + }//GEN-LAST:event_formWindowClosing + + private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed + + m_rootapp.releaseResources(); + System.exit(0); + + }//GEN-LAST:event_formWindowClosed + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/forms/MenuDefinition.java b/src/main/java/com/unicenta/pos/forms/MenuDefinition.java new file mode 100644 index 0000000..ad0964e --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/MenuDefinition.java @@ -0,0 +1,94 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import java.util.ArrayList; +import javax.swing.Action; + +/** + * + * @author adrianromero + */ +public class MenuDefinition { + + private final String m_sKey; + + private final ArrayList m_aMenuElements; + + /** Creates a new instance of MenuDefinition + * @param skey */ + public MenuDefinition(String skey) { + m_sKey = skey; + m_aMenuElements = new ArrayList(); + } + + /** + * + * @return + */ + public String getKey() { + return m_sKey; + } + + /** + * + * @return + */ + public String getTitle() { + return AppLocal.getIntString(m_sKey); + } + + /** + * + * @param act + */ + public void addMenuItem(Action act) { + MenuItemDefinition menuitem = new MenuItemDefinition(act); + m_aMenuElements.add(menuitem); + } + + /** + * + * @param keytext + */ + public void addMenuTitle(String keytext) { + MenuTitleDefinition menutitle = new MenuTitleDefinition(); + menutitle.KeyText = keytext; + m_aMenuElements.add(menutitle); + } + + /** + * + * @param i + * @return + */ + public MenuElement getMenuElement(int i) { + return (MenuElement) m_aMenuElements.get(i); + } + + /** + * + * @return + */ + public int countMenuElements() { + return m_aMenuElements.size(); + } + +} diff --git a/src/main/java/com/unicenta/pos/forms/MenuElement.java b/src/main/java/com/unicenta/pos/forms/MenuElement.java new file mode 100644 index 0000000..09cc8b0 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/MenuElement.java @@ -0,0 +1,33 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +/** + * + * @author adrianromero + */ +public interface MenuElement { + + /** + * + * @param menu + */ + public void addComponent(JPanelMenu menu); +} diff --git a/src/main/java/com/unicenta/pos/forms/MenuExecAction.java b/src/main/java/com/unicenta/pos/forms/MenuExecAction.java new file mode 100644 index 0000000..8ef31b4 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/MenuExecAction.java @@ -0,0 +1,52 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import java.awt.event.ActionEvent; +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.ImageIcon; + +/** + * + * @author adrianromero + */ +public class MenuExecAction extends AbstractAction { + + private final AppView m_App; + private final String m_sMyView; + + /** Creates a new instance of MenuExecAction + * @param app + * @param icon + * @param keytext + * @param sMyView */ + public MenuExecAction(AppView app, String icon, String keytext, String sMyView) { + putValue(Action.SMALL_ICON, new ImageIcon(JPrincipalApp.class.getResource(icon))); + putValue(Action.NAME, AppLocal.getIntString(keytext)); + putValue(AppUserView.ACTION_TASKNAME, sMyView); + m_App = app; + m_sMyView = sMyView; + } + @Override + public void actionPerformed(ActionEvent evt) { + m_App.getAppUserView().executeTask(m_sMyView); + } +} diff --git a/src/main/java/com/unicenta/pos/forms/MenuItemDefinition.java b/src/main/java/com/unicenta/pos/forms/MenuItemDefinition.java new file mode 100644 index 0000000..f516bb9 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/MenuItemDefinition.java @@ -0,0 +1,60 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import java.awt.Dimension; +import javax.swing.Action; +import javax.swing.JButton; +import javax.swing.SwingConstants; + +/** + * + * @author adrianromero + */ +public class MenuItemDefinition implements MenuElement { + + private Action act; + + /** + * + * @param act + */ + public MenuItemDefinition(Action act) { + this.act = act; + } + + /** + * + * @param menu + */ + @Override + public void addComponent(JPanelMenu menu) { + + JButton btn = new JButton(act); + + btn.setFocusPainted(false); + btn.setFocusable(false); + btn.setRequestFocusEnabled(false); + btn.setHorizontalAlignment(SwingConstants.LEADING); + btn.setPreferredSize(new Dimension(100, 100)); + + menu.addEntry(btn); + } +} diff --git a/src/main/java/com/unicenta/pos/forms/MenuPanelAction.java b/src/main/java/com/unicenta/pos/forms/MenuPanelAction.java new file mode 100644 index 0000000..2be0eec --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/MenuPanelAction.java @@ -0,0 +1,73 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import com.unicenta.plugins.Application; +import lombok.extern.slf4j.Slf4j; + +import java.awt.*; +import java.awt.event.ActionEvent; +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.ImageIcon; + +/** + * + * @author adrianromero + */ +@Slf4j +public class MenuPanelAction extends AbstractAction { + + private final AppView m_App; + private final String m_sMyView; + + /** Creates a new instance of MenuPanelAction + * @param app + * @param icon + * @param keytext + * @param sMyView */ + public MenuPanelAction(AppView app, String icon, String keytext, String sMyView) { + putValue(Action.SMALL_ICON, new ImageIcon(JPrincipalApp.class.getResource(icon))); + putValue(Action.NAME, AppLocal.getIntString(keytext)); + putValue(AppUserView.ACTION_TASKNAME, sMyView); + m_App = app; + m_sMyView = sMyView; + } + @Override + public void actionPerformed(ActionEvent evt) { + + if (m_sMyView.equals("plugins.configure") ) { + log.debug("Configure plugins"); + new Application().initScreen("Dashboard", getActiveWindow()); + } + else { + m_App.getAppUserView().showTask(m_sMyView); + } + } + + private Window getActiveWindow() { + for (Window window: Window.getWindows()) { + if (window instanceof JRootFrame) { + return window; + } + } + return null; + } +} diff --git a/src/main/java/com/unicenta/pos/forms/MenuTitleDefinition.java b/src/main/java/com/unicenta/pos/forms/MenuTitleDefinition.java new file mode 100644 index 0000000..784f8d1 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/MenuTitleDefinition.java @@ -0,0 +1,51 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import java.awt.Color; +import java.awt.Insets; +import javax.swing.JLabel; +import javax.swing.border.MatteBorder; + +/** + * + * @author adrianromero + */ +public class MenuTitleDefinition implements MenuElement { + + /** + * + */ + public String KeyText; + + /** + * + * @param menu + */ + @Override + public void addComponent(JPanelMenu menu) { + + JLabel lbl = new JLabel(AppLocal.getIntString(KeyText)); + lbl.applyComponentOrientation(menu.getComponentOrientation()); + lbl.setBorder(new MatteBorder(new Insets(0, 0, 1, 0), new Color(0, 0, 0))); + + menu.addTitle(lbl); + } +} diff --git a/src/main/java/com/unicenta/pos/forms/Payments.java b/src/main/java/com/unicenta/pos/forms/Payments.java new file mode 100644 index 0000000..f2f2528 --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/Payments.java @@ -0,0 +1,163 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import java.util.HashMap; + +/** + * + * @author Jack Gerrard + */ +public class Payments { + private Double amount; + private Double tendered; + private final HashMap paymentPaid; + private final HashMap paymentTendered; + private final HashMap rtnMessage; + private String name; + private final HashMap paymentVoucher; + private final HashMap paymentNote; + + /** + * + */ + public Payments() { + paymentPaid = new HashMap(); + paymentTendered = new HashMap(); + rtnMessage = new HashMap(); + paymentVoucher = new HashMap(); + paymentNote = new HashMap(); + } + + /** + * + * @param pName + * @param pAmountPaid + * @param pTendered + * @param rtnMsg + */ + + public void addPayment (String pName, Double pAmountPaid, Double pTendered, String rtnMsg){ + if (paymentPaid.containsKey(pName)){ + paymentPaid.put(pName,Double.parseDouble(paymentPaid.get(pName).toString()) + pAmountPaid); + paymentTendered.put(pName,Double.parseDouble(paymentTendered.get(pName).toString()) + pTendered); + rtnMessage.put(pName, rtnMsg); + }else { + paymentPaid.put(pName, pAmountPaid); + paymentTendered.put(pName,pTendered); + rtnMessage.put(pName, rtnMsg); + } + } + + /** + * + * @param pName + * @param pAmountPaid + * @param pTendered + * @param rtnMsg + * @param pVoucher + */ + public void addPayment (String pName, Double pAmountPaid, Double pTendered, String rtnMsg, String pVoucher, String pNote){ + if (paymentPaid.containsKey(pName)){ + paymentPaid.put(pName,Double.parseDouble(paymentPaid.get(pName).toString()) + pAmountPaid); + paymentTendered.put(pName,Double.parseDouble(paymentTendered.get(pName).toString()) + pTendered); + rtnMessage.put(pName, rtnMsg); + paymentVoucher.put(pName, pVoucher); + paymentNote.put(pName, pNote); + + }else { + paymentPaid.put(pName, pAmountPaid); + paymentTendered.put(pName,pTendered); + rtnMessage.put(pName, rtnMsg); + paymentNote.put(pName, pNote); + if (pVoucher !=null) { + paymentVoucher.put(pName, pVoucher); + } else { + pVoucher = "0"; + paymentVoucher.put(pName, pVoucher); + } + } + } + + + /** + * + * @param pName + * @return + */ + public Double getTendered (String pName){ + return(Double.parseDouble(paymentTendered.get(pName).toString())); + } + + /** + * + * @param pName + * @return + */ + public Double getPaidAmount (String pName){ + return(Double.parseDouble(paymentPaid.get(pName).toString())); + } + + /** + * + * @return + */ + public Integer getSize(){ + return (paymentPaid.size()); + } + + /** + * + * @param pName + * @return + */ + public String getRtnMessage(String pName){ + return (rtnMessage.get(pName).toString()); + } + + public String getVoucher(String pName){ + return (paymentVoucher.get(pName).toString()); + } + + public String getNote(String pName) { + String note = null; + if (paymentNote.get(pName) != null) { + note = paymentNote.get(pName).toString(); + + } + return note ; + } + + public String getFirstElement(){ + String rtnKey= paymentPaid.keySet().iterator().next().toString(); + return(rtnKey); + } + + /** + * + * @param pName + */ + public void removeFirst (String pName){ + paymentPaid.remove(pName); + paymentTendered.remove(pName); + rtnMessage.remove(pName); + } + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/forms/ProcessAction.java b/src/main/java/com/unicenta/pos/forms/ProcessAction.java new file mode 100644 index 0000000..3060daf --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/ProcessAction.java @@ -0,0 +1,37 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.forms; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.MessageInf; + +/** + * + * @author adrianromero + */ +public interface ProcessAction { + + /** + * + * @return + * @throws BasicException + */ + public MessageInf execute() throws BasicException; +} diff --git a/src/main/java/com/unicenta/pos/forms/StartPOS.java b/src/main/java/com/unicenta/pos/forms/StartPOS.java new file mode 100644 index 0000000..9696e3e --- /dev/null +++ b/src/main/java/com/unicenta/pos/forms/StartPOS.java @@ -0,0 +1,138 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/> + +package com.unicenta.pos.forms; + +import com.formdev.flatlaf.FlatDarkLaf; +import com.formdev.flatlaf.FlatLaf; +import com.formdev.flatlaf.FlatLightLaf; +import com.formdev.flatlaf.intellijthemes.FlatCarbonIJTheme; +import com.formdev.flatlaf.intellijthemes.FlatDraculaIJTheme; +import com.formdev.flatlaf.intellijthemes.FlatMaterialDesignDarkIJTheme; +import com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatArcDarkIJTheme; +import com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatAtomOneLightIJTheme; +import com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatGitHubIJTheme; +import com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialLighterIJTheme; +import com.unicenta.format.Formats; +import com.unicenta.plugins.Application; +import com.unicenta.plugins.metrics.Metrics; +import com.unicenta.pos.instance.InstanceQuery; +import com.unicenta.pos.ticket.TicketInfo; +import lombok.extern.slf4j.Slf4j; +import org.pushingpixels.substance.api.SubstanceLookAndFeel; +import org.pushingpixels.substance.api.SubstanceSkin; + +import javax.swing.*; +import javax.swing.plaf.metal.MetalLookAndFeel; +import java.io.IOException; +import java.rmi.NotBoundException; +import java.rmi.RemoteException; +import java.util.Locale; + +@Slf4j +public class StartPOS { + + private StartPOS() { + } + + public static boolean registerApp() { + + InstanceQuery i = null; + try { + i = new InstanceQuery(); + i.getAppMessage().restoreWindow(); + return false; + } catch (RemoteException | NotBoundException e) { + return true; + } + } + + public static void main(final String args[]) { + + SwingUtilities.invokeLater(() -> { + if (!registerApp()) { + System.exit(1); + } + + AppConfig config = new AppConfig(args); + + config.load(); + + String slang = config.getProperty("user.language"); + String scountry = config.getProperty("user.country"); + String svariant = config.getProperty("user.variant"); + if (slang != null + && !slang.equals("") + && scountry != null + && svariant != null) { + Locale.setDefault(new Locale(slang, scountry, svariant)); + } + + Formats.setIntegerPattern(config.getProperty("format.integer")); + Formats.setDoublePattern(config.getProperty("format.double")); + Formats.setCurrencyPattern(config.getProperty("format.currency")); + Formats.setPercentPattern(config.getProperty("format.percent")); + Formats.setDatePattern(config.getProperty("format.date")); + Formats.setTimePattern(config.getProperty("format.time")); + Formats.setDateTimePattern(config.getProperty("format.datetime")); + + // Set the look and feel + try { + Object laf = Class.forName(config.getProperty("swing.defaultlaf")).newInstance(); + if (!(laf instanceof MetalLookAndFeel) && laf instanceof LookAndFeel) { + UIManager.setLookAndFeel((LookAndFeel) laf); + } else { + UIManager.setLookAndFeel("com.formdev.flatlaf.intellijthemes.FlatGrayIJTheme"); + } + } catch (Exception e) { + log.error("Cannot set Look and Feel ${0}", e.getMessage()); + } + + String hostname = config.getProperty("machine.hostname"); + TicketInfo.setHostname(hostname); + applicationStarted(hostname); + + String screenmode = config.getProperty("machine.screenmode"); + + if ("fullscreen".equals(screenmode)) { + JRootKiosk rootkiosk = new JRootKiosk(); + try { + rootkiosk.initFrame(config); + } catch (IOException ex) { + log.error(ex.getMessage()); + } + } else { + JRootFrame rootframe = new JRootFrame(); + try { + rootframe.initFrame(config); + } catch (Exception ex) { + log.error(ex.getMessage()); + } + } + }); + } + private static void applicationStarted(String host) { + new Thread(() -> { + Metrics metrics = new Metrics(); + metrics.setDevice(host); + metrics.setUniCentaVersion(AppLocal.APP_VERSION); + new Application().postMetrics(metrics); + }).start(); + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/imports/CustomerCSVImport.form b/src/main/java/com/unicenta/pos/imports/CustomerCSVImport.form new file mode 100644 index 0000000..2e1c98a --- /dev/null +++ b/src/main/java/com/unicenta/pos/imports/CustomerCSVImport.form @@ -0,0 +1,1302 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="opaque" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[750, 500]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jFileChooserPanel" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel18" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboSeparator" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jCBiso" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="7" max="-2" attributes="0"/> + <Component id="jbtnRead" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="jScrollPane1" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="jPanel2" max="32767" attributes="0"/> + <Component id="webPBar" max="32767" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jFileChooserPanel" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboSeparator" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel18" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jbtnRead" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jCBiso" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="webPBar" min="-2" pref="32" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jPanel2" min="-2" max="-2" attributes="0"/> + <EmptySpace pref="99" max="32767" attributes="0"/> + </Group> + <Component id="jScrollPane1" pref="588" max="32767" attributes="0"/> + </Group> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Container class="javax.swing.JPanel" name="jFileChooserPanel"> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel1" max="32767" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jFileName" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jbtnFileChoose" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="120" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jFileName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + <Component id="jbtnFileChoose" max="32767" attributes="0"/> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvfile" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jFileName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[400, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jFileNameActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jbtnFileChoose"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/fileopen.png"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[64, 32]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[64, 32]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnFileChooseActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JLabel" name="jLabel18"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvdelimit" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jbtnRead"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvread" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnReadActionPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="JPanelCSVSelect_jHeaderRead"/> + </AuxValues> + </Component> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder title="Status"> + <Border PropertyName="innerBorder" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder roundedCorners="true"> + <Color PropertyName="color" blue="99" green="99" red="99" type="rgb"/> + </LineBorder> + </Border> + <ResourceString PropertyName="titleX" bundle="pos_messages.properties" key="title.CSVImport" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + <Font PropertyName="font" name="Arial" size="14" style="1"/> + <Color PropertyName="color" blue="66" green="66" red="66" type="rgb"/> + </TitledBorder> + </Border> + </Property> + </Properties> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jlblRecords" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jtxtRecords" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="1" max="-2" attributes="0"> + <Component id="jlblNotChanged" alignment="0" max="-2" attributes="0"/> + <Component id="jlblInvalid" alignment="0" max="-2" attributes="0"/> + <Component id="jlblUpdates" alignment="0" max="-2" attributes="0"/> + <Component id="jlblMissing" alignment="0" max="-2" attributes="0"/> + <Component id="jlblBad" alignment="0" max="-2" attributes="0"/> + <Component id="jlblNew" alignment="1" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jtxtNew" min="-2" max="-2" attributes="0"/> + <Component id="jtxtInvalid" min="-2" max="-2" attributes="0"/> + <Component id="jtxtUpdate" min="-2" max="-2" attributes="0"/> + <Component id="jtxtMissing" min="-2" max="-2" attributes="0"/> + <Component id="jtxtBad" min="-2" max="-2" attributes="0"/> + <Component id="jtxtNoChange" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="0" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jlblRecords" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jtxtRecords" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jlblNew" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jtxtNew" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jlblInvalid" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jtxtInvalid" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jlblUpdates" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jtxtUpdate" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jlblMissing" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jtxtMissing" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jlblBad" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jtxtBad" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jlblNotChanged" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jtxtNoChange" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jlblRecords"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvrecordsfound" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jlblNew"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvnewcustomers" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[77, 14]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[77, 14]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jlblInvalid"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.invalidcustomers" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jlblUpdates"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.customerupdated" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jlblMissing"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvmissing" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jlblBad"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvbad" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jlblNotChanged"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvnotchanged" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jtxtRecords"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="disabledTextColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="0" green="0" red="0" type="rgb"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jtxtNew"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="disabledTextColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="0" green="0" red="0" type="rgb"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jtxtInvalid"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="disabledTextColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="0" green="0" red="0" type="rgb"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jtxtUpdate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="disabledTextColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="0" green="0" red="0" type="rgb"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jtxtMissing"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="disabledTextColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="0" green="0" red="0" type="rgb"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jtxtBad"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="cc" green="0" red="ff" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="disabledTextColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="0" green="0" red="0" type="rgb"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jtxtNoChange"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="disabledTextColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="0" green="0" red="0" type="rgb"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JComboBox" name="jComboSeparator"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.progressbar.WebProgressBar" name="webPBar"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="13" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[240, 30]"/> + </Property> + </Properties> + </Component> + <Container class="javax.swing.JScrollPane" name="jScrollPane1"> + <Properties> + <Property name="verticalScrollBarPolicy" type="int" value="22"/> + <Property name="autoscrolls" type="boolean" value="true"/> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[430, 650]"/> + </Property> + </Properties> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel8" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jCheckVisible" alignment="0" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="1" attributes="0"> + <Component id="jbtnReset" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="12" max="-2" attributes="0"/> + <Component id="jbtnImport" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="93" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel7" min="-2" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + <Component id="jComboCity" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel4" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboSearchKey" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboAccountID" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel5" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboName" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel10" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboAddress1" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel20" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboAddress2" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel23" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboPhone2" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jLabel22" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboPhone" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jLabel21" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboEmail" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jLabel12" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboLastName" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jLabel9" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboFirstName" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel11" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboRegion" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jLabel6" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboPostal" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jComboSearchKey" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboName" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboAccountID" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboAddress1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel10" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboAddress2" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel20" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboCity" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel7" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboRegion" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel11" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboPostal" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel6" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboFirstName" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel9" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboLastName" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel12" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboEmail" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel21" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboPhone" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel22" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboPhone2" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel23" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" attributes="0"> + <Component id="jLabel8" min="-2" max="-2" attributes="0"/> + <Component id="jCheckVisible" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jbtnImport" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jbtnReset" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace pref="74" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JComboBox" name="jComboSearchKey"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboSearchKeyItemStateChanged"/> + <EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jComboSearchKeyFocusGained"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboNameItemStateChanged"/> + <EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jComboNameFocusGained"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboAccountID"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboAccountIDItemStateChanged"/> + <EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jComboAccountIDFocusGained"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboAddress1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="1"> + <StringItem index="0" value=""/> + </StringArray> + </Property> + <Property name="selectedIndex" type="int" value="-1"/> + <Property name="enabled" type="boolean" value="false"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboAddress1ItemStateChanged"/> + <EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jComboAddress1FocusGained"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboAddress2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboAddress2ItemStateChanged"/> + <EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jComboAddress2FocusGained"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboCity"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboCityItemStateChanged"/> + <EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jComboCityFocusGained"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboRegion"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 25]"/> + </Property> + <Property name="name" type="java.lang.String" value="" noResource="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboRegionItemStateChanged"/> + <EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jComboRegionFocusGained"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboPostal"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 25]"/> + </Property> + <Property name="name" type="java.lang.String" value="" noResource="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboPostalItemStateChanged"/> + <EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jComboPostalFocusGained"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboFirstName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboFirstNameItemStateChanged"/> + <EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jComboFirstNameFocusGained"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboLastName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboLastNameItemStateChanged"/> + <EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jComboLastNameFocusGained"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboEmail"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 25]"/> + </Property> + <Property name="name" type="java.lang.String" value="" noResource="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboEmailItemStateChanged"/> + <EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jComboEmailFocusGained"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboPhone"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboPhoneItemStateChanged"/> + <EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jComboPhoneFocusGained"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboPhone2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboPhone2ItemStateChanged"/> + <EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jComboPhone2FocusGained"/> + </Events> + </Component> + <Component class="javax.swing.JCheckBox" name="jCheckVisible"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="selected" type="boolean" value="true"/> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jbtnReset"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.reset" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnResetActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jbtnImport"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvimpostbtn" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnImportActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.taxid" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.searchkeym" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.namem" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel10"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.address" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel11"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.region" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel7"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.city" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.visible" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel20"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.address2" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.postal" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel21"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.email" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel22"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.phone" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel23"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.phone2" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel9"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.firstname" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel12"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.lastname" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Component class="javax.swing.JComboBox" name="jCBiso"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="13"> + <StringItem index="0" value="ISO-8859-1"/> + <StringItem index="1" value="ISO-8859-2"/> + <StringItem index="2" value="ISO-8859-3"/> + <StringItem index="3" value="ISO-8859-4"/> + <StringItem index="4" value="ISO-8859-5"/> + <StringItem index="5" value="ISO-8859-6"/> + <StringItem index="6" value="ISO-8859-7"/> + <StringItem index="7" value="ISO-8859-8"/> + <StringItem index="8" value="ISO-8859-9"/> + <StringItem index="9" value="ISO-8859-10"/> + <StringItem index="10" value="UTF-8"/> + <StringItem index="11" value="UTF-16"/> + <StringItem index="12" value=" "/> + </StringArray> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.import.cbiso" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[125, 30]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/> + </AuxValues> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/imports/CustomerCSVImport.java b/src/main/java/com/unicenta/pos/imports/CustomerCSVImport.java new file mode 100644 index 0000000..8fe269b --- /dev/null +++ b/src/main/java/com/unicenta/pos/imports/CustomerCSVImport.java @@ -0,0 +1,2005 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + + +package com.unicenta.pos.imports; + +import com.csvreader.CsvReader; +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.Session; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.pos.customers.CustomerInfoExt; +import com.unicenta.pos.customers.DataLogicCustomers; +import com.unicenta.pos.forms.*; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.filechooser.FileNameExtensionFilter; +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + + +/** + * Graphical User Interface and code for importing data from a CSV file allowing + * adding or updating many customers quickly and easily. + */ +@Slf4j +public class CustomerCSVImport extends JPanel implements JPanelView { + + private ArrayList<String> Headers = new ArrayList<>(); + private Session s; + private Connection con; + private String csvFileName; + + private String csvMessage = ""; + private CsvReader customers; + private int currentRecord; + private int rowCount = 0; + private String last_folder; + private File config_file; + + private DataLogicSales m_dlSales; + private DataLogicSystem m_dlSystem; + private DataLogicCustomers m_dlCustomer; + + protected SaveProvider spr; + + private String customerSearchKey; + private String customerAccount; + private String customerName; + private String customerAddress1; + private String customerAddress2; + private String customerPostal; + private String customerCity; + private String customerRegion; + private String customerFirstName; + private String customerLastName; + private String customerEmail; + private String customerPhone; + private String customerPhone2; + + private DocumentListener documentListener; + private CustomerInfoExt custInfo; + private String recordType = null; + + private int newRecords = 0; + private int invalid = 0; + private int updated = 0; + private int missing = 0; + private int noChange = 0; + private int bad = 0; + + private Integer progress = 0; + + private String iso = "ISO-8859-1"; + + /** + * Constructs a new CustomerCSVImport object + * + * @param oApp AppView + */ + public CustomerCSVImport(AppView oApp) { + this(oApp.getProperties()); + } + + /** + * Constructs a new JPanelCSVImport object + * + * @param props AppProperties + */ + @SuppressWarnings("empty-statement") + public CustomerCSVImport(AppProperties props) { + initComponents(); + + try { + s = AppViewConnection.createSession(props); + con = s.getConnection(); + } catch (BasicException | SQLException e) { + ; + } + + m_dlSales = new DataLogicSales(); + m_dlSales.init(s); + + m_dlSystem = new DataLogicSystem(); + m_dlSystem.init(s); + + + spr = new SaveProvider( + m_dlSales.getCustomerUpdate(), + m_dlSales.getCustomerInsert(), + m_dlSales.getCustomerDelete()); + + last_folder = props.getProperty("CSV.last_folder"); + config_file = props.getConfigFile(); + + jFileName.getDocument().addDocumentListener(documentListener); + + documentListener = new DocumentListener() { + @Override + public void changedUpdate(DocumentEvent documentEvent) { + jbtnRead.setEnabled(true); + } + + @Override + public void insertUpdate(DocumentEvent documentEvent) { + if (!"".equals(jFileName.getText().trim())) { + jbtnRead.setEnabled(true); + } + } + + @Override + public void removeUpdate(DocumentEvent documentEvent) { + if (jFileName.getText().trim().equals("")) { + jbtnRead.setEnabled(false); + } + } + }; + jFileName.getDocument().addDocumentListener(documentListener); + + } + + /** + * Reads the headers from the CSV file and initializes subsequent form + * fields. This function first reads the headers from the CSVFileName file, + * then puts them into the header combo boxes and enables the other form + * inputs. + * + * @param CSVFileName Name of the file (including the path) to open and read + * CSV data from + * @throws IOException If there is an issue reading the CSV file + */ + private void GetheadersFromFile(String CSVFileName) throws IOException { + + File f = new File(CSVFileName); + if (f.exists()) { +// customers = new CsvReader(CSVFileName, ',' ,Charset.forName("UTF-8")); + customers = new CsvReader(CSVFileName, ',', Charset.forName(jCBiso.getSelectedItem().toString())); + customers.setDelimiter(((String) jComboSeparator.getSelectedItem()).charAt(0)); + customers.readHeaders(); + + if (customers.getHeaderCount() < 5) { + JOptionPane.showMessageDialog(null, + "Incorrect header in your source file", + "Header Error", + JOptionPane.WARNING_MESSAGE); + customers.close(); + return; + } + rowCount = 0; + int i = 0; + Headers.clear(); + Headers.add(""); + jComboName.addItem(""); + jComboAccountID.addItem(""); + jComboSearchKey.addItem(""); + jComboAddress1.addItem(""); + jComboAddress2.addItem(""); + jComboPostal.addItem(""); + jComboCity.addItem(""); + jComboRegion.addItem(""); + jComboFirstName.addItem(""); + jComboLastName.addItem(""); + jComboEmail.addItem(""); + jComboPhone.addItem(""); + jComboPhone2.addItem(""); + + while (i < customers.getHeaderCount()) { + jComboName.addItem(customers.getHeader(i)); + jComboAccountID.addItem(customers.getHeader(i)); + jComboSearchKey.addItem(customers.getHeader(i)); + jComboAddress1.addItem(customers.getHeader(i)); + jComboAddress2.addItem(customers.getHeader(i)); + jComboPostal.addItem(customers.getHeader(i)); + jComboCity.addItem(customers.getHeader(i)); + jComboRegion.addItem(customers.getHeader(i)); + jComboFirstName.addItem(customers.getHeader(i)); + jComboLastName.addItem(customers.getHeader(i)); + jComboEmail.addItem(customers.getHeader(i)); + jComboPhone.addItem(customers.getHeader(i)); + jComboPhone2.addItem(customers.getHeader(i)); + + Headers.add(customers.getHeader(i)); + ++i; + } + + enableCheckBoxes(); + + while (customers.readRecord()) { + ++rowCount; + } + + jtxtRecords.setText(Long.toString(rowCount)); + + customers.close(); + + } else { + JOptionPane.showMessageDialog(null, "Unable to locate " + + CSVFileName, + "File not found", + JOptionPane.WARNING_MESSAGE); + } + } + + /** + * Enables all the selection options on the for to allow the user to + * interact with the routine. + */ + private void enableCheckBoxes() { + jbtnRead.setEnabled(false); + jbtnImport.setEnabled(false); + jbtnReset.setEnabled(true); + jComboAccountID.setEnabled(true); + jComboName.setEnabled(true); + jComboSearchKey.setEnabled(true); + jComboAddress1.setEnabled(true); + jComboAddress2.setEnabled(true); + jComboPostal.setEnabled(true); + jComboCity.setEnabled(true); + jComboRegion.setEnabled(true); + jComboFirstName.setEnabled(true); + jComboLastName.setEnabled(true); + jComboEmail.setEnabled(true); + jComboPhone.setEnabled(true); + jComboPhone2.setEnabled(true); + + jCheckVisible.setEnabled(true); + + } + + /** + * Pushes the Import process into a new thread so it doesn't interfere with + * the UI responsiveness. + */ + private void setWorker() { + progress = 0; + webPBar.setStringPainted(true); + + final SwingWorker<Integer, Integer> pbWorker; + pbWorker = new SwingWorker<Integer, Integer>() { + + @Override + protected final Integer doInBackground() throws Exception { + while ((progress >= 0) && (progress < 100)) { + Thread.sleep(50); + this.publish(progress); + } + this.publish(100); + this.done(); + return 100; + } + + @Override + protected final void process(final List<Integer> chunks) { + webPBar.setValue(chunks.get(0)); + if (progress > 100) { + progress = 100; + webPBar.setString("Imported 100%"); + } else { + webPBar.setString("Imported " + progress + "%"); + } + } + }; + pbWorker.execute(); + } + + /** + * Runs the setWorker. + */ + private class workProcess implements Runnable { + + @Override + public void run() { + try { + ImportCsvFile(jFileName.getText()); + } catch (IOException | BasicException ex) { + log.error(ex.getMessage()); + } + } + } + + /** + * Imports the CSV File using specifications from the form. + * + * @param CSVFileName Name of the file (including path) to import. + * @throws IOException If there are file reading issues. + */ + private void ImportCsvFile(String CSVFileName) throws IOException, BasicException { + + File f = new File(CSVFileName); + if (f.exists()) { + webPBar.setString("Starting..."); + webPBar.setVisible(true); + jbtnImport.setEnabled(false); + +// Read file +// customers = new CsvReader(CSVFileName, ',' ,Charset.forName("UTF-8")); + customers = new CsvReader(CSVFileName, ',', Charset.forName(jCBiso.getSelectedItem().toString())); + customers.setDelimiter(((String) jComboSeparator.getSelectedItem()).charAt(0)); + customers.readHeaders(); + + currentRecord = 0; + + while (customers.readRecord()) { + customerSearchKey = customers.get((String) jComboSearchKey.getSelectedItem()); + customerAccount = customers.get((String) jComboAccountID.getSelectedItem()); + customerName = customers.get((String) jComboName.getSelectedItem()); + customerAddress1 = customers.get((String) jComboAddress1.getSelectedItem()); + customerAddress2 = customers.get((String) jComboAddress2.getSelectedItem()); + customerPostal = customers.get((String) jComboPostal.getSelectedItem()); + customerCity = customers.get((String) jComboCity.getSelectedItem()); + customerRegion = customers.get((String) jComboRegion.getSelectedItem()); + customerFirstName = customers.get((String) jComboFirstName.getSelectedItem()); + customerLastName = customers.get((String) jComboLastName.getSelectedItem()); + customerEmail = customers.get((String) jComboEmail.getSelectedItem()); + customerPhone = customers.get((String) jComboPhone.getSelectedItem()); + customerPhone2 = customers.get((String) jComboPhone2.getSelectedItem()); + + currentRecord++; + progress = currentRecord; + + if ("".equals(customerSearchKey) + | "".equals(customerName)) { + + createCustomerCSVEntry(csvMessage, null, null); + } else { + + recordType = getRecord(); + switch (recordType) { + case "new": + createCustomer("new"); + newRecords++; + createCustomerCSVEntry("New Customer", null, null); + break; + case "name error": + case "searchkey error": + case "Duplicate searchkey found.": + case "Duplicate name found.": + case "Exception": + invalid++; + createCustomerCSVEntry(recordType, null, null); + break; + default: + updateRecord(recordType); + break; + } + } + } + + } else { + JOptionPane.showMessageDialog(null, + "Unable to locate " + + CSVFileName, "File not found", + JOptionPane.WARNING_MESSAGE); + } + + jtxtNew.setText(Integer.toString(newRecords)); + jtxtUpdate.setText(Integer.toString(updated)); + jtxtInvalid.setText(Integer.toString(invalid)); + jtxtMissing.setText(Integer.toString(missing)); + jtxtNoChange.setText(Integer.toString(noChange)); + jtxtBad.setText(Integer.toString(bad)); + + JOptionPane.showMessageDialog(null, + "Import Complete", + "Imported", + JOptionPane.WARNING_MESSAGE); + +// webPBar.setString("Imported " + progress); + progress = 100; + webPBar.setValue(progress); + webPBar.setString("Imported" + progress); +// } + } + + + /** + * testString for validity as a number + * + * @param testString the string to be checked + * @return True if a real number False if not + */ + private Boolean validateNumber(String testString) { + try { + Double res = Double.parseDouble(testString); + return (true); + } catch (NumberFormatException e) { + return (false); + } + } + + /** + * Updated the record in the database with the new prices and category if + * needed. + * + * @param cID Unique Customer id of the record to be updated It then creates + * an updated record for the Customer, subject to the ???? be different + */ + private void updateRecord(String cID) throws BasicException { +// custInfo = new CustomerInfoExt(); + custInfo = m_dlSales.getCustomerInfo(cID); + createCustomer("update"); + noChange++; + } + + /** + * Gets the title of the current panel + * + * @return The name of the panel + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.CustomerCSVImport"); + } + + /** + * Returns this object + * + * @return + */ + @Override + public JComponent getComponent() { + return this; + } + + /** + * Set CSV field and line separator + * + * @throws com.unicenta.basic.BasicException + */ + @Override + public void activate() throws BasicException { + + jComboSeparator.removeAllItems(); + jComboSeparator.addItem(","); + jComboSeparator.addItem(";"); + jComboSeparator.addItem("~"); + jComboSeparator.addItem("^"); + + } + + /** + * Resets all the form fields + */ + public void resetFields() { + + jComboAccountID.removeAllItems(); + jComboAccountID.setEnabled(false); + + jComboName.removeAllItems(); + jComboName.setEnabled(false); + + jComboSearchKey.removeAllItems(); + jComboSearchKey.setEnabled(false); + + jComboAddress1.removeAllItems(); + jComboAddress1.setEnabled(false); + + jComboAddress2.removeAllItems(); + jComboAddress2.setEnabled(false); + + jComboCity.removeAllItems(); + jComboCity.setEnabled(false); + + jComboRegion.removeAllItems(); + jComboRegion.setEnabled(false); + + jComboPostal.removeAllItems(); + jComboPostal.setEnabled(false); + + jComboFirstName.removeAllItems(); + jComboFirstName.setEnabled(false); + + jComboLastName.removeAllItems(); + jComboLastName.setEnabled(false); + + jComboEmail.removeAllItems(); + jComboEmail.setEnabled(false); + + jComboPhone.removeAllItems(); + jComboPhone.setEnabled(false); + + jComboPhone2.removeAllItems(); + jComboPhone2.setEnabled(false); + + jCheckVisible.setSelected(false); + jCheckVisible.setEnabled(true); + + jbtnImport.setEnabled(false); + jbtnReset.setEnabled(true); + jbtnRead.setEnabled(false); + + jFileName.setText(null); + csvFileName = ""; + +// clear Status area fields + jtxtNew.setText(""); + jtxtUpdate.setText(""); + jtxtInvalid.setText(""); + jtxtMissing.setText(""); + jtxtNoChange.setText(""); + jtxtRecords.setText(""); + jtxtBad.setText(""); + + progress = 0; + + Headers.clear(); + } + + /** + * Checks the field mappings to ensure all compulsory fields have been + * completed to allow import to proceed + */ + public void checkFieldMapping() { + if (jComboSearchKey.getSelectedItem() != "" + & jComboName.getSelectedItem() != "") { + jbtnImport.setEnabled(true); + jbtnReset.setEnabled(true); + } else { + jbtnImport.setEnabled(false); + jbtnReset.setEnabled(false); + } + } + + /** + * Deactivates and resets all form fields. + * + * @return + */ + @Override + public boolean deactivate() { + resetFields(); + return (true); + } + + /** + * @param cType + */ + public void createCustomer(String cType) { + + Object[] mycust = new Object[27]; + if ("new".equals(cType)) { + mycust[0] = UUID.randomUUID().toString(); + } else { + mycust[0] = custInfo.getId(); + } // id string + mycust[1] = customerSearchKey; // searchkey String + mycust[2] = customerAccount; // taxid string + mycust[3] = customerName; // name string + mycust[4] = null; // taxCategory string + mycust[5] = null; // card string + mycust[6] = 0.0; // maxdebt Double + mycust[7] = customerAddress1; // address1 string + mycust[8] = customerAddress2; // address2 string + mycust[9] = customerPostal; // postal string + mycust[10] = customerCity; // city string + mycust[11] = customerRegion; // region string + mycust[12] = null; // country string + mycust[13] = customerFirstName; // firstname string + mycust[14] = customerLastName; // lastname string + mycust[15] = customerEmail; // email string + mycust[16] = customerPhone; // phone string + mycust[17] = customerPhone2; // phone2 string + mycust[18] = null; // fax string + mycust[19] = null; // notes string + mycust[20] = jCheckVisible.isSelected(); // visible flag + mycust[21] = null; // curdate string + mycust[22] = 0.0; // curdate double + mycust[23] = null; // image + mycust[24] = false; // isvip + mycust[25] = 0.0; // discount + mycust[26] = null; // memodate date + + try { + if ("new".equals(cType)) { + spr.insertData(mycust); + webPBar.setString("Adding record " + progress); + } else { + spr.updateData(mycust); + webPBar.setString("Updating record " + progress); + } + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + } + + /** + * Insert file row read and adds to import table log + * + * @param csvError + * @param searchKey + * @param Name + */ + public void createCustomerCSVEntry(String csvError, String searchKey, String Name) { + + Object[] mycust = new Object[5]; + mycust[0] = UUID.randomUUID().toString(); // ID string + mycust[1] = Integer.toString(currentRecord); // Record number + mycust[2] = csvError; // Error description + mycust[3] = customerSearchKey; // SearchKey String + mycust[4] = customerName; // Name string + + try { + m_dlSystem.execCustomerAddCSVEntry(mycust); + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + } + + /** + * @return + */ + public String getRecord() { + // Get record type using using DataLogicSystem + Object[] mycust = new Object[2]; + mycust[0] = customerSearchKey; + mycust[1] = customerName; + + try { + return (m_dlSystem.getCustomerRecordType(mycust)); + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + return "Exception"; + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jFileChooserPanel = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + jFileName = new javax.swing.JTextField(); + jbtnFileChoose = new javax.swing.JButton(); + jLabel18 = new javax.swing.JLabel(); + jbtnRead = new javax.swing.JButton(); + jPanel2 = new javax.swing.JPanel(); + jlblRecords = new javax.swing.JLabel(); + jlblNew = new javax.swing.JLabel(); + jlblInvalid = new javax.swing.JLabel(); + jlblUpdates = new javax.swing.JLabel(); + jlblMissing = new javax.swing.JLabel(); + jlblBad = new javax.swing.JLabel(); + jlblNotChanged = new javax.swing.JLabel(); + jtxtRecords = new javax.swing.JTextField(); + jtxtNew = new javax.swing.JTextField(); + jtxtInvalid = new javax.swing.JTextField(); + jtxtUpdate = new javax.swing.JTextField(); + jtxtMissing = new javax.swing.JTextField(); + jtxtBad = new javax.swing.JTextField(); + jtxtNoChange = new javax.swing.JTextField(); + jComboSeparator = new javax.swing.JComboBox(); + webPBar = new com.alee.laf.progressbar.WebProgressBar(); + jScrollPane1 = new javax.swing.JScrollPane(); + jPanel1 = new javax.swing.JPanel(); + jComboSearchKey = new javax.swing.JComboBox(); + jComboName = new javax.swing.JComboBox(); + jComboAccountID = new javax.swing.JComboBox(); + jComboAddress1 = new javax.swing.JComboBox(); + jComboAddress2 = new javax.swing.JComboBox(); + jComboCity = new javax.swing.JComboBox(); + jComboRegion = new javax.swing.JComboBox(); + jComboPostal = new javax.swing.JComboBox(); + jComboFirstName = new javax.swing.JComboBox(); + jComboLastName = new javax.swing.JComboBox(); + jComboEmail = new javax.swing.JComboBox(); + jComboPhone = new javax.swing.JComboBox(); + jComboPhone2 = new javax.swing.JComboBox(); + jCheckVisible = new javax.swing.JCheckBox(); + jbtnReset = new javax.swing.JButton(); + jbtnImport = new javax.swing.JButton(); + jLabel3 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + jLabel5 = new javax.swing.JLabel(); + jLabel10 = new javax.swing.JLabel(); + jLabel11 = new javax.swing.JLabel(); + jLabel7 = new javax.swing.JLabel(); + jLabel8 = new javax.swing.JLabel(); + jLabel20 = new javax.swing.JLabel(); + jLabel6 = new javax.swing.JLabel(); + jLabel21 = new javax.swing.JLabel(); + jLabel22 = new javax.swing.JLabel(); + jLabel23 = new javax.swing.JLabel(); + jLabel9 = new javax.swing.JLabel(); + jLabel12 = new javax.swing.JLabel(); + jCBiso = new javax.swing.JComboBox<>(); + + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + setOpaque(false); + setPreferredSize(new java.awt.Dimension(750, 500)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jLabel1.setText(bundle.getString("label.csvfile")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(100, 30)); + + jFileName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jFileName.setPreferredSize(new java.awt.Dimension(400, 30)); + jFileName.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jFileNameActionPerformed(evt); + } + }); + + jbtnFileChoose.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/fileopen.png"))); // NOI18N + jbtnFileChoose.setMaximumSize(new java.awt.Dimension(64, 32)); + jbtnFileChoose.setMinimumSize(new java.awt.Dimension(64, 32)); + jbtnFileChoose.setPreferredSize(new java.awt.Dimension(80, 45)); + jbtnFileChoose.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnFileChooseActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jFileChooserPanelLayout = new javax.swing.GroupLayout(jFileChooserPanel); + jFileChooserPanel.setLayout(jFileChooserPanelLayout); + jFileChooserPanelLayout.setHorizontalGroup( + jFileChooserPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jFileChooserPanelLayout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jFileName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jbtnFileChoose, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(120, 120, 120)) + ); + jFileChooserPanelLayout.setVerticalGroup( + jFileChooserPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jFileChooserPanelLayout.createSequentialGroup() + .addGroup(jFileChooserPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jFileName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + .addComponent(jbtnFileChoose, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + ); + + jLabel18.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel18.setText(bundle.getString("label.csvdelimit")); // NOI18N + jLabel18.setPreferredSize(new java.awt.Dimension(100, 30)); + + jbtnRead.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnRead.setText(bundle.getString("label.csvread")); // NOI18N + jbtnRead.setEnabled(false); + jbtnRead.setPreferredSize(new java.awt.Dimension(110, 45)); + jbtnRead.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnReadActionPerformed(evt); + } + }); + + jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(new javax.swing.border.LineBorder(new java.awt.Color(153, 153, 153), 1, true), bundle.getString("title.CSVImport"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Arial", 1, 14), new java.awt.Color(102, 102, 102))); // NOI18N + + jlblRecords.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jlblRecords.setText(bundle.getString("label.csvrecordsfound")); // NOI18N + jlblRecords.setPreferredSize(new java.awt.Dimension(150, 30)); + + jlblNew.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jlblNew.setText(bundle.getString("label.csvnewcustomers")); // NOI18N + jlblNew.setMaximumSize(new java.awt.Dimension(77, 14)); + jlblNew.setMinimumSize(new java.awt.Dimension(77, 14)); + jlblNew.setPreferredSize(new java.awt.Dimension(150, 30)); + + jlblInvalid.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jlblInvalid.setText(bundle.getString("label.invalidcustomers")); // NOI18N + jlblInvalid.setPreferredSize(new java.awt.Dimension(150, 30)); + + jlblUpdates.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jlblUpdates.setText(bundle.getString("label.customerupdated")); // NOI18N + jlblUpdates.setPreferredSize(new java.awt.Dimension(150, 30)); + + jlblMissing.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jlblMissing.setText(bundle.getString("label.csvmissing")); // NOI18N + jlblMissing.setPreferredSize(new java.awt.Dimension(150, 30)); + + jlblBad.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jlblBad.setText(bundle.getString("label.csvbad")); // NOI18N + jlblBad.setPreferredSize(new java.awt.Dimension(150, 30)); + + jlblNotChanged.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jlblNotChanged.setText(bundle.getString("label.csvnotchanged")); // NOI18N + jlblNotChanged.setPreferredSize(new java.awt.Dimension(150, 30)); + + jtxtRecords.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtRecords.setForeground(new java.awt.Color(102, 102, 102)); + jtxtRecords.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + jtxtRecords.setBorder(null); + jtxtRecords.setDisabledTextColor(new java.awt.Color(0, 0, 0)); + jtxtRecords.setEnabled(false); + jtxtRecords.setPreferredSize(new java.awt.Dimension(100, 30)); + + jtxtNew.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtNew.setForeground(new java.awt.Color(102, 102, 102)); + jtxtNew.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + jtxtNew.setBorder(null); + jtxtNew.setDisabledTextColor(new java.awt.Color(0, 0, 0)); + jtxtNew.setEnabled(false); + jtxtNew.setPreferredSize(new java.awt.Dimension(100, 30)); + + jtxtInvalid.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtInvalid.setForeground(new java.awt.Color(102, 102, 102)); + jtxtInvalid.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + jtxtInvalid.setBorder(null); + jtxtInvalid.setDisabledTextColor(new java.awt.Color(0, 0, 0)); + jtxtInvalid.setEnabled(false); + jtxtInvalid.setPreferredSize(new java.awt.Dimension(100, 30)); + + jtxtUpdate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtUpdate.setForeground(new java.awt.Color(102, 102, 102)); + jtxtUpdate.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + jtxtUpdate.setBorder(null); + jtxtUpdate.setDisabledTextColor(new java.awt.Color(0, 0, 0)); + jtxtUpdate.setEnabled(false); + jtxtUpdate.setPreferredSize(new java.awt.Dimension(100, 30)); + + jtxtMissing.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtMissing.setForeground(new java.awt.Color(102, 102, 102)); + jtxtMissing.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + jtxtMissing.setBorder(null); + jtxtMissing.setDisabledTextColor(new java.awt.Color(0, 0, 0)); + jtxtMissing.setEnabled(false); + jtxtMissing.setPreferredSize(new java.awt.Dimension(100, 30)); + + jtxtBad.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtBad.setForeground(new java.awt.Color(255, 0, 204)); + jtxtBad.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + jtxtBad.setBorder(null); + jtxtBad.setDisabledTextColor(new java.awt.Color(0, 0, 0)); + jtxtBad.setEnabled(false); + jtxtBad.setPreferredSize(new java.awt.Dimension(100, 30)); + + jtxtNoChange.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtNoChange.setForeground(new java.awt.Color(102, 102, 102)); + jtxtNoChange.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + jtxtNoChange.setBorder(null); + jtxtNoChange.setDisabledTextColor(new java.awt.Color(0, 0, 0)); + jtxtNoChange.setEnabled(false); + jtxtNoChange.setPreferredSize(new java.awt.Dimension(100, 30)); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(jlblRecords, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jtxtRecords, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(jlblNotChanged, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblInvalid, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblUpdates, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblMissing, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblBad, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblNew, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jtxtNew, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtInvalid, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtMissing, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtBad, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtNoChange, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addContainerGap()) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(0, 0, 0) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jlblRecords, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtRecords, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jlblNew, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtNew, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jlblInvalid, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtInvalid, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jlblUpdates, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jlblMissing, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtMissing, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jlblBad, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtBad, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jlblNotChanged, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtNoChange, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + + jComboSeparator.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboSeparator.setPreferredSize(new java.awt.Dimension(50, 30)); + + webPBar.setFont(new java.awt.Font("Arial", 0, 13)); // NOI18N + webPBar.setPreferredSize(new java.awt.Dimension(240, 30)); + + jScrollPane1.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + jScrollPane1.setAutoscrolls(true); + + jPanel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanel1.setPreferredSize(new java.awt.Dimension(430, 650)); + + jComboSearchKey.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboSearchKey.setEnabled(false); + jComboSearchKey.setMinimumSize(new java.awt.Dimension(32, 25)); + jComboSearchKey.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboSearchKey.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboSearchKeyItemStateChanged(evt); + } + }); + jComboSearchKey.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jComboSearchKeyFocusGained(evt); + } + }); + + jComboName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboName.setEnabled(false); + jComboName.setMinimumSize(new java.awt.Dimension(32, 25)); + jComboName.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboName.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboNameItemStateChanged(evt); + } + }); + jComboName.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jComboNameFocusGained(evt); + } + }); + + jComboAccountID.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboAccountID.setEnabled(false); + jComboAccountID.setMinimumSize(new java.awt.Dimension(32, 25)); + jComboAccountID.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboAccountID.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboAccountIDItemStateChanged(evt); + } + }); + jComboAccountID.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jComboAccountIDFocusGained(evt); + } + }); + + jComboAddress1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboAddress1.setModel(new javax.swing.DefaultComboBoxModel(new String[]{""})); + jComboAddress1.setSelectedIndex(-1); + jComboAddress1.setEnabled(false); + jComboAddress1.setMinimumSize(new java.awt.Dimension(32, 25)); + jComboAddress1.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboAddress1.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboAddress1ItemStateChanged(evt); + } + }); + jComboAddress1.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jComboAddress1FocusGained(evt); + } + }); + + jComboAddress2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboAddress2.setEnabled(false); + jComboAddress2.setMinimumSize(new java.awt.Dimension(32, 25)); + jComboAddress2.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboAddress2.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboAddress2ItemStateChanged(evt); + } + }); + jComboAddress2.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jComboAddress2FocusGained(evt); + } + }); + + jComboCity.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboCity.setEnabled(false); + jComboCity.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboCity.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboCityItemStateChanged(evt); + } + }); + jComboCity.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jComboCityFocusGained(evt); + } + }); + + jComboRegion.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboRegion.setEnabled(false); + jComboRegion.setMinimumSize(new java.awt.Dimension(32, 25)); + jComboRegion.setName(""); // NOI18N + jComboRegion.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboRegion.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboRegionItemStateChanged(evt); + } + }); + jComboRegion.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jComboRegionFocusGained(evt); + } + }); + + jComboPostal.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboPostal.setEnabled(false); + jComboPostal.setMinimumSize(new java.awt.Dimension(32, 25)); + jComboPostal.setName(""); // NOI18N + jComboPostal.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboPostal.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboPostalItemStateChanged(evt); + } + }); + jComboPostal.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jComboPostalFocusGained(evt); + } + }); + + jComboFirstName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboFirstName.setEnabled(false); + jComboFirstName.setMinimumSize(new java.awt.Dimension(32, 25)); + jComboFirstName.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboFirstName.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboFirstNameItemStateChanged(evt); + } + }); + jComboFirstName.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jComboFirstNameFocusGained(evt); + } + }); + + jComboLastName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboLastName.setEnabled(false); + jComboLastName.setMinimumSize(new java.awt.Dimension(32, 25)); + jComboLastName.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboLastName.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboLastNameItemStateChanged(evt); + } + }); + jComboLastName.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jComboLastNameFocusGained(evt); + } + }); + + jComboEmail.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboEmail.setEnabled(false); + jComboEmail.setMinimumSize(new java.awt.Dimension(32, 25)); + jComboEmail.setName(""); // NOI18N + jComboEmail.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboEmail.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboEmailItemStateChanged(evt); + } + }); + jComboEmail.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jComboEmailFocusGained(evt); + } + }); + + jComboPhone.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboPhone.setEnabled(false); + jComboPhone.setMinimumSize(new java.awt.Dimension(32, 25)); + jComboPhone.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboPhone.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboPhoneItemStateChanged(evt); + } + }); + jComboPhone.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jComboPhoneFocusGained(evt); + } + }); + + jComboPhone2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboPhone2.setEnabled(false); + jComboPhone2.setMinimumSize(new java.awt.Dimension(32, 25)); + jComboPhone2.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboPhone2.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboPhone2ItemStateChanged(evt); + } + }); + jComboPhone2.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jComboPhone2FocusGained(evt); + } + }); + + jCheckVisible.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jCheckVisible.setSelected(true); + jCheckVisible.setEnabled(false); + jCheckVisible.setPreferredSize(new java.awt.Dimension(30, 30)); + + jbtnReset.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jbtnReset.setText(bundle.getString("button.reset")); // NOI18N + jbtnReset.setPreferredSize(new java.awt.Dimension(110, 45)); + jbtnReset.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnResetActionPerformed(evt); + } + }); + + jbtnImport.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jbtnImport.setText(bundle.getString("label.csvimpostbtn")); // NOI18N + jbtnImport.setEnabled(false); + jbtnImport.setPreferredSize(new java.awt.Dimension(110, 45)); + jbtnImport.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnImportActionPerformed(evt); + } + }); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(bundle.getString("label.taxid")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(bundle.getString("label.searchkeym")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(bundle.getString("label.namem")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel10.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel10.setText(bundle.getString("label.address")); // NOI18N + jLabel10.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel11.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel11.setText(bundle.getString("label.region")); // NOI18N + jLabel11.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel7.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel7.setText(bundle.getString("label.city")); // NOI18N + jLabel7.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel8.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel8.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jLabel8.setText(bundle.getString("label.visible")); // NOI18N + jLabel8.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel20.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel20.setText(bundle.getString("label.address2")); // NOI18N + jLabel20.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setText(bundle.getString("label.postal")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel21.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel21.setText(bundle.getString("label.email")); // NOI18N + jLabel21.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel22.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel22.setText(bundle.getString("label.phone")); // NOI18N + jLabel22.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel23.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel23.setText(bundle.getString("label.phone2")); // NOI18N + jLabel23.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel9.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel9.setText(bundle.getString("label.firstname")); // NOI18N + jLabel9.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel12.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel12.setText(bundle.getString("label.lastname")); // NOI18N + jLabel12.setPreferredSize(new java.awt.Dimension(100, 30)); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jCheckVisible, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addComponent(jbtnReset, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(12, 12, 12) + .addComponent(jbtnImport, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(93, 93, 93)))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jComboCity, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboSearchKey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboAccountID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboAddress1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboAddress2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel23, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboPhone2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel22, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboPhone, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboEmail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboLastName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboFirstName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboRegion, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboPostal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))) + .addContainerGap()) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jComboSearchKey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboAccountID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboAddress1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboAddress2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboCity, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboRegion, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboPostal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboFirstName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboLastName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboEmail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboPhone, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel22, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboPhone2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel23, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jCheckVisible, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jbtnImport, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jbtnReset, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(74, Short.MAX_VALUE)) + ); + + jScrollPane1.setViewportView(jPanel1); + + jCBiso.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jCBiso.setModel(new javax.swing.DefaultComboBoxModel<>(new String[]{"ISO-8859-1", "ISO-8859-2", "ISO-8859-3", "ISO-8859-4", "ISO-8859-5", "ISO-8859-6", "ISO-8859-7", "ISO-8859-8", "ISO-8859-9", "ISO-8859-10", "UTF-8", "UTF-16", " "})); + jCBiso.setToolTipText(bundle.getString("tooltip.import.cbiso")); // NOI18N + jCBiso.setPreferredSize(new java.awt.Dimension(125, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jFileChooserPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel18, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jCBiso, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(7, 7, 7) + .addComponent(jbtnRead, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(webPBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jFileChooserPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel18, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jbtnRead, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jCBiso, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(webPBar, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(99, Short.MAX_VALUE)) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 588, Short.MAX_VALUE))) + ); + }// </editor-fold>//GEN-END:initComponents + + private void jbtnReadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnReadActionPerformed + try { + GetheadersFromFile(jFileName.getText()); + webPBar.setString("Source file Header OK"); + } catch (IOException ex) { + log.error(ex.getMessage()); + webPBar.setString("Source file Header error!"); + } + }//GEN-LAST:event_jbtnReadActionPerformed + + private void jFileNameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jFileNameActionPerformed + jbtnImport.setEnabled(false); + jbtnRead.setEnabled(true); + }//GEN-LAST:event_jFileNameActionPerformed + + private void jbtnFileChooseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnFileChooseActionPerformed + resetFields(); + setWorker(); + + JFileChooser chooser = new JFileChooser(last_folder == null ? "C:\\" : last_folder); + FileNameExtensionFilter filter = new FileNameExtensionFilter("csv files", "csv"); + chooser.setFileFilter(filter); + chooser.showOpenDialog(null); + File csvFile = chooser.getSelectedFile(); + + if (csvFile == null) { + return; + } + + File current_folder = chooser.getCurrentDirectory(); + + if (last_folder == null + || !last_folder.equals(current_folder.getAbsolutePath())) { + AppConfig CSVConfig = new AppConfig(config_file); + CSVConfig.load(); + CSVConfig.setProperty("CSV.last_folder" + , current_folder.getAbsolutePath()); + last_folder = current_folder.getAbsolutePath(); + try { + CSVConfig.save(); + } catch (IOException ex) { + log.error(ex.getMessage()); + } + } + + String csv = csvFile.getName(); + if (!(csv.trim().equals(""))) { + csvFileName = csvFile.getAbsolutePath(); + jFileName.setText(csvFileName); + } + }//GEN-LAST:event_jbtnFileChooseActionPerformed + + private void jComboPostalFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jComboPostalFocusGained + jComboPostal.removeAllItems(); + int i = 1; + jComboPostal.addItem(""); + + while (i < Headers.size()) { + if ((Headers.get(i) + != jComboSearchKey.getSelectedItem()) + & (Headers.get(i) != jComboAccountID.getSelectedItem()) + & (Headers.get(i) != jComboName.getSelectedItem()) + & (Headers.get(i) != jComboAddress1.getSelectedItem()) + & (Headers.get(i) != jComboAddress2.getSelectedItem()) +// & (Headers.get(i) != jComboPostal.getSelectedItem()) + & (Headers.get(i) != jComboCity.getSelectedItem()) + & (Headers.get(i) != jComboRegion.getSelectedItem()) + & (Headers.get(i) != jComboFirstName.getSelectedItem()) + & (Headers.get(i) != jComboLastName.getSelectedItem()) + & (Headers.get(i) != jComboEmail.getSelectedItem()) + & (Headers.get(i) != jComboPhone.getSelectedItem()) + & (Headers.get(i) != jComboPhone2.getSelectedItem()) + ) { + + jComboPostal.addItem(Headers.get(i)); + } + ++i; + } + }//GEN-LAST:event_jComboPostalFocusGained + + private void jComboPostalItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboPostalItemStateChanged + + checkFieldMapping(); + + }//GEN-LAST:event_jComboPostalItemStateChanged + + private void jComboLastNameItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboLastNameItemStateChanged + + checkFieldMapping(); + + }//GEN-LAST:event_jComboLastNameItemStateChanged + + private void jComboFirstNameItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboFirstNameItemStateChanged + + checkFieldMapping(); + + }//GEN-LAST:event_jComboFirstNameItemStateChanged + + private void jComboPhone2ItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboPhone2ItemStateChanged + + checkFieldMapping(); + + }//GEN-LAST:event_jComboPhone2ItemStateChanged + + private void jComboPhoneItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboPhoneItemStateChanged + + checkFieldMapping(); + + }//GEN-LAST:event_jComboPhoneItemStateChanged + + private void jComboEmailFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jComboEmailFocusGained + jComboEmail.removeAllItems(); + int i = 1; + jComboEmail.addItem(""); + + while (i < Headers.size()) { + if ((Headers.get(i) + != jComboSearchKey.getSelectedItem()) + & (Headers.get(i) != jComboAccountID.getSelectedItem()) + & (Headers.get(i) != jComboName.getSelectedItem()) + & (Headers.get(i) != jComboAddress1.getSelectedItem()) + & (Headers.get(i) != jComboAddress2.getSelectedItem()) + & (Headers.get(i) != jComboPostal.getSelectedItem()) + & (Headers.get(i) != jComboCity.getSelectedItem()) + & (Headers.get(i) != jComboRegion.getSelectedItem()) + & (Headers.get(i) != jComboFirstName.getSelectedItem()) + & (Headers.get(i) != jComboLastName.getSelectedItem()) +// & (Headers.get(i) != jComboEmail.getSelectedItem()) + & (Headers.get(i) != jComboPhone.getSelectedItem()) + & (Headers.get(i) != jComboPhone2.getSelectedItem()) + ) { + + jComboEmail.addItem(Headers.get(i)); + } + ++i; + } + }//GEN-LAST:event_jComboEmailFocusGained + + private void jComboEmailItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboEmailItemStateChanged + + checkFieldMapping(); + + }//GEN-LAST:event_jComboEmailItemStateChanged + + private void jbtnResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnResetActionPerformed + resetFields(); + progress = -1; + webPBar.setString("Waiting..."); + }//GEN-LAST:event_jbtnResetActionPerformed + + private void jbtnImportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnImportActionPerformed + + jbtnImport.setEnabled(false); + + workProcess work = new workProcess(); + Thread thread2 = new Thread(work); + thread2.start(); + }//GEN-LAST:event_jbtnImportActionPerformed + + private void jComboRegionFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jComboRegionFocusGained + jComboRegion.removeAllItems(); + int i = 1; + jComboRegion.addItem(""); + + while (i < Headers.size()) { + if ((Headers.get(i) + != jComboSearchKey.getSelectedItem()) + & (Headers.get(i) != jComboAccountID.getSelectedItem()) + & (Headers.get(i) != jComboName.getSelectedItem()) + & (Headers.get(i) != jComboAddress1.getSelectedItem()) + & (Headers.get(i) != jComboAddress2.getSelectedItem()) + & (Headers.get(i) != jComboPostal.getSelectedItem()) + & (Headers.get(i) != jComboCity.getSelectedItem()) +// & (Headers.get(i) != jComboRegion.getSelectedItem()) + & (Headers.get(i) != jComboFirstName.getSelectedItem()) + & (Headers.get(i) != jComboLastName.getSelectedItem()) + & (Headers.get(i) != jComboEmail.getSelectedItem()) + & (Headers.get(i) != jComboPhone.getSelectedItem()) + & (Headers.get(i) != jComboPhone2.getSelectedItem()) + ) { + + jComboRegion.addItem(Headers.get(i)); + } + ++i; + } + }//GEN-LAST:event_jComboRegionFocusGained + + private void jComboRegionItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboRegionItemStateChanged + + checkFieldMapping(); + + }//GEN-LAST:event_jComboRegionItemStateChanged + + private void jComboCityFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jComboCityFocusGained + jComboCity.removeAllItems(); + int i = 1; + jComboCity.addItem(""); + + while (i < Headers.size()) { + if ((Headers.get(i) + != jComboSearchKey.getSelectedItem()) + & (Headers.get(i) != jComboAccountID.getSelectedItem()) + & (Headers.get(i) != jComboName.getSelectedItem()) + & (Headers.get(i) != jComboAddress1.getSelectedItem()) + & (Headers.get(i) != jComboAddress2.getSelectedItem()) + & (Headers.get(i) != jComboPostal.getSelectedItem()) +// & (Headers.get(i) != jComboCity.getSelectedItem()) + & (Headers.get(i) != jComboRegion.getSelectedItem()) + & (Headers.get(i) != jComboFirstName.getSelectedItem()) + & (Headers.get(i) != jComboLastName.getSelectedItem()) + & (Headers.get(i) != jComboEmail.getSelectedItem()) + & (Headers.get(i) != jComboPhone.getSelectedItem()) + & (Headers.get(i) != jComboPhone2.getSelectedItem()) + ) { + + jComboCity.addItem(Headers.get(i)); + } + ++i; + } + }//GEN-LAST:event_jComboCityFocusGained + + private void jComboCityItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboCityItemStateChanged + + checkFieldMapping(); + + }//GEN-LAST:event_jComboCityItemStateChanged + + private void jComboAddress2FocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jComboAddress2FocusGained + jComboAddress2.removeAllItems(); + int i = 1; + jComboAddress2.addItem(""); + + while (i < Headers.size()) { + if ((Headers.get(i) + != jComboSearchKey.getSelectedItem()) + & (Headers.get(i) != jComboAccountID.getSelectedItem()) + & (Headers.get(i) != jComboName.getSelectedItem()) + & (Headers.get(i) != jComboAddress1.getSelectedItem()) +// & (Headers.get(i) != jComboAddress2.getSelectedItem()) + & (Headers.get(i) != jComboPostal.getSelectedItem()) + & (Headers.get(i) != jComboCity.getSelectedItem()) + & (Headers.get(i) != jComboRegion.getSelectedItem()) + & (Headers.get(i) != jComboFirstName.getSelectedItem()) + & (Headers.get(i) != jComboLastName.getSelectedItem()) + & (Headers.get(i) != jComboEmail.getSelectedItem()) + & (Headers.get(i) != jComboPhone.getSelectedItem()) + & (Headers.get(i) != jComboPhone2.getSelectedItem()) + ) { + + jComboAddress2.addItem(Headers.get(i)); + } + ++i; + } + }//GEN-LAST:event_jComboAddress2FocusGained + + private void jComboAddress2ItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboAddress2ItemStateChanged + + checkFieldMapping(); + + }//GEN-LAST:event_jComboAddress2ItemStateChanged + + private void jComboAddress1FocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jComboAddress1FocusGained + jComboAddress1.removeAllItems(); + int i = 1; + jComboAddress1.addItem(""); + + while (i < Headers.size()) { + if ((Headers.get(i) + != jComboSearchKey.getSelectedItem()) + & (Headers.get(i) != jComboAccountID.getSelectedItem()) + & (Headers.get(i) != jComboName.getSelectedItem()) +// & (Headers.get(i) != jComboAddress1.getSelectedItem()) + & (Headers.get(i) != jComboAddress2.getSelectedItem()) + & (Headers.get(i) != jComboPostal.getSelectedItem()) + & (Headers.get(i) != jComboCity.getSelectedItem()) + & (Headers.get(i) != jComboRegion.getSelectedItem()) + & (Headers.get(i) != jComboFirstName.getSelectedItem()) + & (Headers.get(i) != jComboLastName.getSelectedItem()) + & (Headers.get(i) != jComboEmail.getSelectedItem()) + & (Headers.get(i) != jComboPhone.getSelectedItem()) + & (Headers.get(i) != jComboPhone2.getSelectedItem()) + ) { + + jComboAddress1.addItem(Headers.get(i)); + } + ++i; + } + }//GEN-LAST:event_jComboAddress1FocusGained + + private void jComboAddress1ItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboAddress1ItemStateChanged + + checkFieldMapping(); + + }//GEN-LAST:event_jComboAddress1ItemStateChanged + + private void jComboNameFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jComboNameFocusGained + jComboName.removeAllItems(); + int i = 1; + jComboName.addItem(""); + + while (i < Headers.size()) { + if ((Headers.get(i) + != jComboSearchKey.getSelectedItem()) + & (Headers.get(i) != jComboAccountID.getSelectedItem()) +// & (Headers.get(i) != jComboName.getSelectedItem()) + & (Headers.get(i) != jComboAddress1.getSelectedItem()) + & (Headers.get(i) != jComboAddress2.getSelectedItem()) + & (Headers.get(i) != jComboPostal.getSelectedItem()) + & (Headers.get(i) != jComboCity.getSelectedItem()) + & (Headers.get(i) != jComboRegion.getSelectedItem()) + & (Headers.get(i) != jComboFirstName.getSelectedItem()) + & (Headers.get(i) != jComboLastName.getSelectedItem()) + & (Headers.get(i) != jComboEmail.getSelectedItem()) + & (Headers.get(i) != jComboPhone.getSelectedItem()) + & (Headers.get(i) != jComboPhone2.getSelectedItem()) + ) { + + jComboName.addItem(Headers.get(i)); + } + ++i; + } + }//GEN-LAST:event_jComboNameFocusGained + + private void jComboNameItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboNameItemStateChanged + + checkFieldMapping(); + + }//GEN-LAST:event_jComboNameItemStateChanged + + private void jComboSearchKeyFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jComboSearchKeyFocusGained + jComboName.removeAllItems(); + int i = 1; + jComboName.addItem(""); + + while (i < Headers.size()) { + if ((Headers.get(i) +// != jComboSearchKey.getSelectedItem()) + != jComboAccountID.getSelectedItem()) + & (Headers.get(i) != jComboName.getSelectedItem()) + & (Headers.get(i) != jComboAddress1.getSelectedItem()) + & (Headers.get(i) != jComboAddress2.getSelectedItem()) + & (Headers.get(i) != jComboPostal.getSelectedItem()) + & (Headers.get(i) != jComboCity.getSelectedItem()) + & (Headers.get(i) != jComboRegion.getSelectedItem()) + & (Headers.get(i) != jComboFirstName.getSelectedItem()) + & (Headers.get(i) != jComboLastName.getSelectedItem()) + & (Headers.get(i) != jComboEmail.getSelectedItem()) + & (Headers.get(i) != jComboPhone.getSelectedItem()) + & (Headers.get(i) != jComboPhone2.getSelectedItem()) + ) { + + jComboSearchKey.addItem(Headers.get(i)); + } + ++i; + } + }//GEN-LAST:event_jComboSearchKeyFocusGained + + private void jComboSearchKeyItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboSearchKeyItemStateChanged + + checkFieldMapping(); + + }//GEN-LAST:event_jComboSearchKeyItemStateChanged + + private void jComboAccountIDFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jComboAccountIDFocusGained + jComboAccountID.removeAllItems(); + int i = 1; + jComboAccountID.addItem(""); + + while (i < Headers.size()) { + if ((Headers.get(i) + != jComboSearchKey.getSelectedItem()) +// & (Headers.get(i) != jComboAccountID.getSelectedItem()) + & (Headers.get(i) != jComboName.getSelectedItem()) + & (Headers.get(i) != jComboAddress1.getSelectedItem()) + & (Headers.get(i) != jComboAddress2.getSelectedItem()) + & (Headers.get(i) != jComboPostal.getSelectedItem()) + & (Headers.get(i) != jComboCity.getSelectedItem()) + & (Headers.get(i) != jComboRegion.getSelectedItem()) + & (Headers.get(i) != jComboFirstName.getSelectedItem()) + & (Headers.get(i) != jComboLastName.getSelectedItem()) + & (Headers.get(i) != jComboEmail.getSelectedItem()) + & (Headers.get(i) != jComboPhone.getSelectedItem()) + & (Headers.get(i) != jComboPhone2.getSelectedItem()) + ) { + + jComboAccountID.addItem(Headers.get(i)); + } + ++i; + } + }//GEN-LAST:event_jComboAccountIDFocusGained + + private void jComboAccountIDItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboAccountIDItemStateChanged + + checkFieldMapping(); + + }//GEN-LAST:event_jComboAccountIDItemStateChanged + + private void jComboFirstNameFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jComboFirstNameFocusGained + jComboFirstName.removeAllItems(); + int i = 1; + jComboFirstName.addItem(""); + + while (i < Headers.size()) { + if ((Headers.get(i) + != jComboSearchKey.getSelectedItem()) + & (Headers.get(i) != jComboAccountID.getSelectedItem()) + & (Headers.get(i) != jComboName.getSelectedItem()) + & (Headers.get(i) != jComboAddress1.getSelectedItem()) + & (Headers.get(i) != jComboAddress2.getSelectedItem()) + & (Headers.get(i) != jComboPostal.getSelectedItem()) + & (Headers.get(i) != jComboCity.getSelectedItem()) + & (Headers.get(i) != jComboRegion.getSelectedItem()) +// & (Headers.get(i) != jComboFirstName.getSelectedItem()) + & (Headers.get(i) != jComboLastName.getSelectedItem()) + & (Headers.get(i) != jComboEmail.getSelectedItem()) + & (Headers.get(i) != jComboPhone.getSelectedItem()) + & (Headers.get(i) != jComboPhone2.getSelectedItem()) + ) { + + jComboFirstName.addItem(Headers.get(i)); + } + ++i; + } + }//GEN-LAST:event_jComboFirstNameFocusGained + + private void jComboLastNameFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jComboLastNameFocusGained + jComboLastName.removeAllItems(); + int i = 1; + jComboLastName.addItem(""); + + while (i < Headers.size()) { + if ((Headers.get(i) + != jComboSearchKey.getSelectedItem()) + & (Headers.get(i) != jComboAccountID.getSelectedItem()) + & (Headers.get(i) != jComboName.getSelectedItem()) + & (Headers.get(i) != jComboAddress1.getSelectedItem()) + & (Headers.get(i) != jComboAddress2.getSelectedItem()) + & (Headers.get(i) != jComboPostal.getSelectedItem()) + & (Headers.get(i) != jComboCity.getSelectedItem()) + & (Headers.get(i) != jComboRegion.getSelectedItem()) + & (Headers.get(i) != jComboFirstName.getSelectedItem()) +// & (Headers.get(i) != jComboLastName.getSelectedItem()) + & (Headers.get(i) != jComboEmail.getSelectedItem()) + & (Headers.get(i) != jComboPhone.getSelectedItem()) + & (Headers.get(i) != jComboPhone2.getSelectedItem()) + ) { + + jComboLastName.addItem(Headers.get(i)); + } + ++i; + } + }//GEN-LAST:event_jComboLastNameFocusGained + + private void jComboPhoneFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jComboPhoneFocusGained + jComboPhone.removeAllItems(); + int i = 1; + jComboPhone.addItem(""); + + while (i < Headers.size()) { + if ((Headers.get(i) + != jComboSearchKey.getSelectedItem()) + & (Headers.get(i) != jComboAccountID.getSelectedItem()) + & (Headers.get(i) != jComboName.getSelectedItem()) + & (Headers.get(i) != jComboAddress1.getSelectedItem()) + & (Headers.get(i) != jComboAddress2.getSelectedItem()) + & (Headers.get(i) != jComboPostal.getSelectedItem()) + & (Headers.get(i) != jComboCity.getSelectedItem()) + & (Headers.get(i) != jComboRegion.getSelectedItem()) + & (Headers.get(i) != jComboFirstName.getSelectedItem()) + & (Headers.get(i) != jComboLastName.getSelectedItem()) + & (Headers.get(i) != jComboEmail.getSelectedItem()) +// & (Headers.get(i) != jComboPhone.getSelectedItem()) + & (Headers.get(i) != jComboPhone2.getSelectedItem()) + ) { + + jComboPhone.addItem(Headers.get(i)); + } + ++i; + } + }//GEN-LAST:event_jComboPhoneFocusGained + + private void jComboPhone2FocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jComboPhone2FocusGained + jComboPhone2.removeAllItems(); + int i = 1; + jComboPhone2.addItem(""); + + while (i < Headers.size()) { + if ((Headers.get(i) + != jComboSearchKey.getSelectedItem()) + & (Headers.get(i) != jComboAccountID.getSelectedItem()) + & (Headers.get(i) != jComboName.getSelectedItem()) + & (Headers.get(i) != jComboAddress1.getSelectedItem()) + & (Headers.get(i) != jComboAddress2.getSelectedItem()) + & (Headers.get(i) != jComboPostal.getSelectedItem()) + & (Headers.get(i) != jComboCity.getSelectedItem()) + & (Headers.get(i) != jComboRegion.getSelectedItem()) + & (Headers.get(i) != jComboFirstName.getSelectedItem()) + & (Headers.get(i) != jComboLastName.getSelectedItem()) + & (Headers.get(i) != jComboEmail.getSelectedItem()) + & (Headers.get(i) != jComboPhone.getSelectedItem()) +// & (Headers.get(i) != jComboPhone2.getSelectedItem()) + ) { + + jComboPhone2.addItem(Headers.get(i)); + } + ++i; + } + }//GEN-LAST:event_jComboPhone2FocusGained + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JComboBox<String> jCBiso; + private javax.swing.JCheckBox jCheckVisible; + private javax.swing.JComboBox jComboAccountID; + private javax.swing.JComboBox jComboAddress1; + private javax.swing.JComboBox jComboAddress2; + private javax.swing.JComboBox jComboCity; + private javax.swing.JComboBox jComboEmail; + private javax.swing.JComboBox jComboFirstName; + private javax.swing.JComboBox jComboLastName; + private javax.swing.JComboBox jComboName; + private javax.swing.JComboBox jComboPhone; + private javax.swing.JComboBox jComboPhone2; + private javax.swing.JComboBox jComboPostal; + private javax.swing.JComboBox jComboRegion; + private javax.swing.JComboBox jComboSearchKey; + private javax.swing.JComboBox jComboSeparator; + private javax.swing.JPanel jFileChooserPanel; + private javax.swing.JTextField jFileName; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel10; + private javax.swing.JLabel jLabel11; + private javax.swing.JLabel jLabel12; + private javax.swing.JLabel jLabel18; + private javax.swing.JLabel jLabel20; + private javax.swing.JLabel jLabel21; + private javax.swing.JLabel jLabel22; + private javax.swing.JLabel jLabel23; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JLabel jLabel9; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JButton jbtnFileChoose; + private javax.swing.JButton jbtnImport; + private javax.swing.JButton jbtnRead; + private javax.swing.JButton jbtnReset; + private javax.swing.JLabel jlblBad; + private javax.swing.JLabel jlblInvalid; + private javax.swing.JLabel jlblMissing; + private javax.swing.JLabel jlblNew; + private javax.swing.JLabel jlblNotChanged; + private javax.swing.JLabel jlblRecords; + private javax.swing.JLabel jlblUpdates; + private javax.swing.JTextField jtxtBad; + private javax.swing.JTextField jtxtInvalid; + private javax.swing.JTextField jtxtMissing; + private javax.swing.JTextField jtxtNew; + private javax.swing.JTextField jtxtNoChange; + private javax.swing.JTextField jtxtRecords; + private javax.swing.JTextField jtxtUpdate; + private com.alee.laf.progressbar.WebProgressBar webPBar; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/imports/JPanelCSV.form b/src/main/java/com/unicenta/pos/imports/JPanelCSV.form new file mode 100644 index 0000000..1a0bd58 --- /dev/null +++ b/src/main/java/com/unicenta/pos/imports/JPanelCSV.form @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <EmptySpace min="0" pref="750" max="32767" attributes="0"/> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <EmptySpace min="0" pref="500" max="32767" attributes="0"/> + </Group> + </DimensionLayout> + </Layout> +</Form> diff --git a/src/main/java/com/unicenta/pos/imports/JPanelCSV.java b/src/main/java/com/unicenta/pos/imports/JPanelCSV.java new file mode 100644 index 0000000..5d1f09d --- /dev/null +++ b/src/main/java/com/unicenta/pos/imports/JPanelCSV.java @@ -0,0 +1,53 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +// CSV Import Panel added by JDL - February 2013 +// Additonal library required - javacsv + +package com.unicenta.pos.imports; + +public class JPanelCSV extends javax.swing.JPanel { + + + public JPanelCSV() { + initComponents(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 750, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 500, Short.MAX_VALUE) + ); + }// </editor-fold>//GEN-END:initComponents + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/imports/JPanelCSVCleardb.form b/src/main/java/com/unicenta/pos/imports/JPanelCSVCleardb.form new file mode 100644 index 0000000..caf82ea --- /dev/null +++ b/src/main/java/com/unicenta/pos/imports/JPanelCSVCleardb.form @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[450, 240]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="16" max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" max="-2" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jEnableButton" pref="0" max="32767" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jBtnCleardb" min="-2" pref="218" max="-2" attributes="0"/> + </Group> + <Component id="jScrollPane1" min="-2" pref="400" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jScrollPane1" min="-2" pref="127" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jBtnCleardb" min="-2" max="-2" attributes="0"/> + <Component id="jEnableButton" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvresetimport" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + </Component> + <Container class="javax.swing.JScrollPane" name="jScrollPane1"> + <AuxValues> + <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JTextPane" name="jMessageBox"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JCheckBox" name="jEnableButton"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvenableclear" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="jEnableButtonStateChanged"/> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jEnableButtonActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jBtnCleardb"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/sale_delete.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.clearimport" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="actionCommand" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvclearlog" replaceFormat="AppLocal.getIntString("button.exit")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnCleardbActionPerformed"/> + </Events> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/imports/JPanelCSVCleardb.java b/src/main/java/com/unicenta/pos/imports/JPanelCSVCleardb.java new file mode 100644 index 0000000..7f5a673 --- /dev/null +++ b/src/main/java/com/unicenta/pos/imports/JPanelCSVCleardb.java @@ -0,0 +1,238 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +// CSV Import Panel added by JDL - February 2013 +// Additonal library required - javacsv + + +package com.unicenta.pos.imports; + +import com.unicenta.basic.BasicException; +import com.unicenta.pos.forms.*; +import com.unicenta.pos.util.AltEncrypter; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.Statement; +import javax.swing.*; + +public class JPanelCSVCleardb extends JPanel implements JPanelView { + + private Connection con; + private Statement stmt; + private String SQL; + private AppConfig config; + + /** + * + * @param oApp + */ + public JPanelCSVCleardb(AppView oApp) { + this(oApp.getProperties()); + + } + + /** + * + * @param props + */ + public JPanelCSVCleardb(AppProperties props) { + + initComponents(); + + config = new AppConfig(props.getConfigFile()); + config.load(); + + jMessageBox.setText("Performing this action, will clear all " + + "data in the CSVImport table. \n\n" + + "It is recommended that this is performed before " + + "running a new import. \n"); + + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.CSVReset"); + } + + /** + * + * @return + */ + @Override + public JComponent getComponent() { + return this; + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + + String db_user =(config.getProperty("db.user")); + String db_url = (config.getProperty("db.URL")); + String db_password = (config.getProperty("db.password")); + + if (db_user != null && db_password != null && db_password.startsWith("crypt:")) { + AltEncrypter cypher = new AltEncrypter("cypherkey" + db_user); + db_password = cypher.decrypt(db_password.substring(6)); + } + try{ + con = DriverManager.getConnection(db_url,db_user,db_password); + stmt = (Statement) con.createStatement(); + + } catch (Exception e) { + } + + } + + /** + * + * @return + */ + @Override + public boolean deactivate() { + try{ + stmt.close(); + con.close(); + }catch (Exception e){} + + return (true); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel1 = new javax.swing.JLabel(); + jScrollPane1 = new javax.swing.JScrollPane(); + jMessageBox = new javax.swing.JTextPane(); + jEnableButton = new javax.swing.JCheckBox(); + jBtnCleardb = new javax.swing.JButton(); + + setPreferredSize(new java.awt.Dimension(450, 240)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jLabel1.setText(bundle.getString("label.csvresetimport")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(250, 30)); + + jMessageBox.setEditable(false); + jMessageBox.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jScrollPane1.setViewportView(jMessageBox); + + jEnableButton.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jEnableButton.setText(bundle.getString("label.csvenableclear")); // NOI18N + jEnableButton.setPreferredSize(new java.awt.Dimension(250, 30)); + jEnableButton.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + jEnableButtonStateChanged(evt); + } + }); + jEnableButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jEnableButtonActionPerformed(evt); + } + }); + + jBtnCleardb.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jBtnCleardb.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/sale_delete.png"))); // NOI18N + jBtnCleardb.setText(bundle.getString("label.clearimport")); // NOI18N + jBtnCleardb.setActionCommand(AppLocal.getIntString("button.exit")); // NOI18N + jBtnCleardb.setEnabled(false); + jBtnCleardb.setPreferredSize(new java.awt.Dimension(160, 45)); + jBtnCleardb.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnCleardbActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createSequentialGroup() + .addGap(16, 16, 16) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addGroup(layout.createSequentialGroup() + .addComponent(jEnableButton, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jBtnCleardb, javax.swing.GroupLayout.PREFERRED_SIZE, 218, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 400, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 127, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jBtnCleardb, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jEnableButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + private void jEnableButtonStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jEnableButtonStateChanged + if (jEnableButton.isSelected()){ + jBtnCleardb.setEnabled(true); + }else { + jBtnCleardb.setEnabled(false); + } + }//GEN-LAST:event_jEnableButtonStateChanged + + private void jBtnCleardbActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnCleardbActionPerformed + SQL="DELETE FROM csvimport"; + try{ + stmt.executeUpdate(SQL); + }catch (Exception e){ + } + }//GEN-LAST:event_jBtnCleardbActionPerformed + + private void jEnableButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jEnableButtonActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jEnableButtonActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jBtnCleardb; + private javax.swing.JCheckBox jEnableButton; + private javax.swing.JLabel jLabel1; + private javax.swing.JTextPane jMessageBox; + private javax.swing.JScrollPane jScrollPane1; + // End of variables declaration//GEN-END:variables + + + +} diff --git a/src/main/java/com/unicenta/pos/imports/JPanelCSVImport.form b/src/main/java/com/unicenta/pos/imports/JPanelCSVImport.form new file mode 100644 index 0000000..c8f1d54 --- /dev/null +++ b/src/main/java/com/unicenta/pos/imports/JPanelCSVImport.form @@ -0,0 +1,1268 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="opaque" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[750, 500]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + <Component id="jLabel17" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="jFileChooserPanel" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jPanel1" alignment="0" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel18" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboSeparator" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jCBiso" min="-2" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="jHeaderRead" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="jPanel2" max="32767" attributes="0"/> + <Component id="webPBar" max="32767" attributes="0"/> + <Component id="jLblImportNotice" max="32767" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel17" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jFileChooserPanel" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboSeparator" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel18" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jHeaderRead" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jCBiso" alignment="1" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="webPBar" min="-2" pref="32" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jPanel2" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jLblImportNotice" min="-2" pref="70" max="-2" attributes="0"/> + </Group> + <Component id="jPanel1" min="-2" pref="469" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Container class="javax.swing.JPanel" name="jFileChooserPanel"> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel1" max="32767" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jFileName" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jbtnFileChoose" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="120" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jFileName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + <Component id="jbtnFileChoose" max="32767" attributes="0"/> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvfile" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jFileName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[400, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jFileNameActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jbtnFileChoose"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/fileopen.png"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[64, 32]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[64, 32]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnFileChooseActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[430, 400]"/> + </Property> + </Properties> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel8" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jCheckInCatalogue" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="59" max="-2" attributes="0"/> + <Component id="jCheckSellIncTax" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel12" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="1" attributes="0"> + <Component id="jbtnReset" min="-2" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + <Component id="jImport" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="93" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <Group type="103" alignment="0" groupAlignment="1" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel7" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboTax" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel4" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboBarcode" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboReference" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel5" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboName" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel10" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboBuy" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel20" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboSell" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel6" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboDefaultCategory" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel11" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboCategory" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jLabel21" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboSupplier" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jLabel22" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboDefaultSupplier" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="2" pref="2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboReference" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jComboBarcode" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboName" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboBuy" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel10" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboSell" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel20" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboTax" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel7" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel11" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="jComboCategory" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboDefaultCategory" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel6" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel21" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="jComboSupplier" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboDefaultSupplier" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel22" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel12" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="jCheckSellIncTax" alignment="0" min="-2" max="-2" attributes="0"/> + <Group type="103" alignment="0" groupAlignment="1" attributes="0"> + <Component id="jLabel8" min="-2" max="-2" attributes="0"/> + <Component id="jCheckInCatalogue" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jImport" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jbtnReset" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace pref="16" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JComboBox" name="jComboReference"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboReferenceItemStateChanged"/> + <EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jComboReferenceFocusGained"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboBarcode"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboBarcodeItemStateChanged"/> + <EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jComboBarcodeFocusGained"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboNameItemStateChanged"/> + <EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jComboNameFocusGained"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboBuy"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="1"> + <StringItem index="0" value=""/> + </StringArray> + </Property> + <Property name="selectedIndex" type="int" value="-1"/> + <Property name="enabled" type="boolean" value="false"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboBuyItemStateChanged"/> + <EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jComboBuyFocusGained"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboSell"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboSellItemStateChanged"/> + <EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jComboSellFocusGained"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboDefaultCategory"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboDefaultCategoryItemStateChanged"/> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jComboDefaultCategoryActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboTax"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboTaxItemStateChanged"/> + <EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jComboTaxFocusGained"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodref" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodbarcode" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodname" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel10"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodpricebuy" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel11"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodcategory" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel7"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodtaxcode" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="jCheckInCatalogue"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodincatalog" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="jCheckSellIncTax"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel12"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvsellingintax" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="jComboCategory"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 25]"/> + </Property> + <Property name="name" type="java.lang.String" value="" noResource="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboCategoryItemStateChanged"/> + <EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jComboCategoryFocusGained"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel20"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodpricesell" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jImport"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvimpostbtn" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jImportActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.proddefaultcategory" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jbtnReset"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.reset" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnResetActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboSupplier"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 25]"/> + </Property> + <Property name="name" type="java.lang.String" value="" noResource="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboSupplierItemStateChanged"/> + <EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="jComboSupplierFocusGained"/> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jComboSupplierActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel21"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.suppliername" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel22"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.proddefaultsupplier" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="jComboDefaultSupplier"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="jComboDefaultSupplierItemStateChanged"/> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jComboDefaultSupplierActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JLabel" name="jLabel17"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="10" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="Import version 4.5"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel18"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvdelimit" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jHeaderRead"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvread" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jHeaderReadActionPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="JPanelCSVSelect_jHeaderRead"/> + </AuxValues> + </Component> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder title="Status"> + <Border PropertyName="innerBorder" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder roundedCorners="true"> + <Color PropertyName="color" blue="99" green="99" red="99" type="rgb"/> + </LineBorder> + </Border> + <ResourceString PropertyName="titleX" bundle="pos_messages.properties" key="title.CSVImport" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + <Font PropertyName="font" name="Arial" size="14" style="1"/> + <Color PropertyName="color" blue="66" green="66" red="66" type="rgb"/> + </TitledBorder> + </Border> + </Property> + </Properties> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel9" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jTextRecords" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="1" max="-2" attributes="0"> + <Component id="jLabel19" max="-2" attributes="0"/> + <Component id="jLabel13" alignment="0" max="-2" attributes="0"/> + <Component id="jLabel16" alignment="0" max="-2" attributes="0"/> + <Component id="jTextUpdates" alignment="0" max="-2" attributes="0"/> + <Component id="jLabel2" alignment="0" max="-2" attributes="0"/> + <Component id="jLabel15" alignment="0" max="-2" attributes="0"/> + <Component id="jLabel14" alignment="1" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jTextBadCats" min="-2" max="-2" attributes="0"/> + <Component id="jTextNew" min="-2" max="-2" attributes="0"/> + <Component id="jTextInvalid" min="-2" max="-2" attributes="0"/> + <Component id="jTextUpdate" min="-2" max="-2" attributes="0"/> + <Component id="jTextMissing" min="-2" max="-2" attributes="0"/> + <Component id="jTextBadPrice" min="-2" max="-2" attributes="0"/> + <Component id="jTextNoChange" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="0" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel9" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jTextRecords" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel14" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jTextNew" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel16" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jTextInvalid" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jTextUpdates" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jTextUpdate" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jTextMissing" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel15" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jTextBadPrice" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel13" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jTextNoChange" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel19" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jTextBadCats" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel9"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvrecordsfound" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel14"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvnewproducts" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[77, 14]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[77, 14]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel16"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvchanged" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jTextUpdates"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvpriceupdated" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvmissing" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel15"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvbad" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel13"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvnotchanged" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTextRecords"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="disabledTextColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="0" green="0" red="0" type="rgb"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTextNew"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="disabledTextColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="0" green="0" red="0" type="rgb"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTextInvalid"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="disabledTextColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="0" green="0" red="0" type="rgb"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTextUpdate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="disabledTextColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="0" green="0" red="0" type="rgb"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTextMissing"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="disabledTextColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="0" green="0" red="0" type="rgb"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTextBadPrice"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="cc" green="0" red="ff" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="disabledTextColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="0" green="0" red="0" type="rgb"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTextNoChange"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="disabledTextColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="0" green="0" red="0" type="rgb"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel19"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvbadcats" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTextBadCats"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="cc" green="0" red="ff" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="disabledTextColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="0" green="0" red="0" type="rgb"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JComboBox" name="jComboSeparator"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.progressbar.WebProgressBar" name="webPBar"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="13" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[240, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblImportNotice"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" red="ff" type="rgb"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/refundit.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.importnotice" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 37]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="jCBiso"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="13"> + <StringItem index="0" value="ISO-8859-1"/> + <StringItem index="1" value="ISO-8859-2"/> + <StringItem index="2" value="ISO-8859-3"/> + <StringItem index="3" value="ISO-8859-4"/> + <StringItem index="4" value="ISO-8859-5"/> + <StringItem index="5" value="ISO-8859-6"/> + <StringItem index="6" value="ISO-8859-7"/> + <StringItem index="7" value="ISO-8859-8"/> + <StringItem index="8" value="ISO-8859-9"/> + <StringItem index="9" value="ISO-8859-10"/> + <StringItem index="10" value="UTF-8"/> + <StringItem index="11" value="UTF-16"/> + <StringItem index="12" value=" "/> + </StringArray> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.import.cbiso" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[125, 30]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/> + </AuxValues> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/imports/JPanelCSVImport.java b/src/main/java/com/unicenta/pos/imports/JPanelCSVImport.java new file mode 100644 index 0000000..348cc65 --- /dev/null +++ b/src/main/java/com/unicenta/pos/imports/JPanelCSVImport.java @@ -0,0 +1,2076 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + + +package com.unicenta.pos.imports; + +import com.csvreader.CsvReader; +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.loader.*; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.pos.forms.*; +import com.unicenta.pos.sales.TaxesLogic; +import com.unicenta.pos.ticket.ProductInfoExt; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.filechooser.FileNameExtensionFilter; +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.UUID; + + +/** + * Graphical User Interface and code for importing data from a CSV file allowing + * adding or updating many products quickly and easily. + * + */ +@Slf4j +public class JPanelCSVImport extends JPanel implements JPanelView { + + private ArrayList<String> Headers = new ArrayList<>(); + private Session s; + private Connection con; + private String csvFileName; + private Double dOriginalRate = 0.0; + private String dCategory; + private String dSupplier; + private String csvMessage = ""; + private CsvReader products; + private double oldSellPrice = 0; + private double oldBuyPrice = 0; + private int currentRecord; + private int rowCount = 0; + private String last_folder; + private File config_file; + + private static String category_default = "[ USE DEFAULT CATEGORY ]"; + private static String reject_bad_category = "[ REJECT ITEMS WITH BAD CATEGORIES ]"; + private static String supplier_default = "[ USE DEFAULT SUPPLIER ]"; + private static String reject_bad_supplier = "[ REJECT ITEMS WITH BAD SUPPLIER ]"; + + private DataLogicSales m_dlSales; + private DataLogicSystem m_dlSystem; + + protected SaveProvider spr; + + private String Category; + private String categoryName; + private String categoryParentid; + private Integer categoryCatorder; + private SentenceList m_sentcat; + private ComboBoxValModel m_CategoryModel; + private HashMap cat_list = new HashMap(); + private ArrayList badCategories = new ArrayList(); + + private String productReference; + private String productBarcode; + private String productBarcodetype; + private String productName; + private Double productBuyPrice; + private Double productSellPrice; + private String productTax; + + private String Supplier; + private String supplierName; + private SentenceList m_sentsupp; + private ComboBoxValModel m_SupplierModel; + private HashMap supp_list = new HashMap(); + private ArrayList badSuppliers = new ArrayList(); + + private SentenceList taxcatsent; + private ComboBoxValModel taxcatmodel; + private SentenceList taxsent; + private TaxesLogic taxeslogic; + + private DocumentListener documentListener; + private ProductInfoExt prodInfo; + private String recordType = null; + + private int newRecords = 0; + private int invalidRecords = 0; + private int priceUpdates = 0; + private int missingData = 0; + private int noChanges = 0; + private int badPrice = 0; + + private double dTaxRate; + + private Integer progress = 0; + + private String iso="ISO-8859-1"; + + /** + * Constructs a new JPanelCSVImport object + * + * @param oApp AppView + */ + public JPanelCSVImport(AppView oApp) { + this(oApp.getProperties()); + } + + /** + * Constructs a new JPanelCSVImport object + * + * @param props AppProperties + */ + @SuppressWarnings("empty-statement") + public JPanelCSVImport(AppProperties props) { + initComponents(); + + try { + s = AppViewConnection.createSession(props); + con = s.getConnection(); + } catch (BasicException | SQLException e) {; + } + + m_dlSales = new DataLogicSales(); + m_dlSales.init(s); + + m_dlSystem = new DataLogicSystem(); + m_dlSystem.init(s); + + spr = new SaveProvider( + m_dlSales.getProductCatUpdate(), + m_dlSales.getProductCatInsert(), + m_dlSales.getProductCatDelete()); + + last_folder = props.getProperty("CSV.last_folder"); + config_file = props.getConfigFile(); + + jFileName.getDocument().addDocumentListener(documentListener); + + documentListener = new DocumentListener() { + @Override + public void changedUpdate(DocumentEvent documentEvent) { + jHeaderRead.setEnabled(true); + } + + @Override + public void insertUpdate(DocumentEvent documentEvent) { + if (!"".equals(jFileName.getText().trim())) { + jHeaderRead.setEnabled(true); + } + } + + @Override + public void removeUpdate(DocumentEvent documentEvent) { + if (jFileName.getText().trim().equals("")) { + jHeaderRead.setEnabled(false); + } + } + }; + jFileName.getDocument().addDocumentListener(documentListener); + + } + + /** + * Reads the headers from the CSV file and initializes subsequent form + * fields. This function first reads the headers from the CSVFileName file, + * then puts them into the header combo boxes and enables the other form + * inputs. + * + * @param CSVFileName Name of the file (including the path) to open and read + * CSV data from + * @throws IOException If there is an issue reading the CSV file + */ + private void GetheadersFromFile(String CSVFileName) throws IOException { + + File f = new File(CSVFileName); + if (f.exists()) { +// products = new CsvReader(CSVFileName, ',' ,Charset.forName("UTF-8")); + products = new CsvReader(CSVFileName, ',' ,Charset.forName(jCBiso.getSelectedItem().toString())); + products.setDelimiter(((String) jComboSeparator.getSelectedItem()).charAt(0)); + products.readHeaders(); + + if (products.getHeaderCount() < 5) { + JOptionPane.showMessageDialog(null, + "Incorrect header in your source file", + "Header Error", + JOptionPane.WARNING_MESSAGE); + products.close(); + return; + } + rowCount = 0; + int i = 0; + Headers.clear(); + Headers.add(""); + jComboName.addItem(""); + jComboReference.addItem(""); + jComboBarcode.addItem(""); + jComboBuy.addItem(""); + jComboSell.addItem(""); + jComboTax.addItem(""); + jComboCategory.addItem(""); + jComboSupplier.addItem(""); + + while (i < products.getHeaderCount()) { + jComboName.addItem(products.getHeader(i)); + jComboReference.addItem(products.getHeader(i)); + jComboBarcode.addItem(products.getHeader(i)); + jComboBuy.addItem(products.getHeader(i)); + jComboSell.addItem(products.getHeader(i)); + jComboTax.addItem(products.getHeader(i)); + jComboCategory.addItem(products.getHeader(i)); + jComboSupplier.addItem(products.getHeader(i)); + + Headers.add(products.getHeader(i)); + ++i; + } + + enableCheckBoxes(); + + while (products.readRecord()) { + System.out.println(products.getRawRecord()); + ++rowCount; + } + + jTextRecords.setText(Long.toString(rowCount)); + + products.close(); + + } else { + JOptionPane.showMessageDialog(null, "Unable to locate " + + CSVFileName, + "File not found", + JOptionPane.WARNING_MESSAGE); + } + } + + /** + * Enables all the selection options on the for to allow the user to + * interact with the routine. + * + */ + private void enableCheckBoxes() { + jHeaderRead.setEnabled(false); + jImport.setEnabled(false); + jbtnReset.setEnabled(true); + jComboReference.setEnabled(true); + jComboName.setEnabled(true); + jComboBarcode.setEnabled(true); + jComboBuy.setEnabled(true); + jComboSell.setEnabled(true); + jComboTax.setEnabled(true); + jComboCategory.setEnabled(true); + jComboDefaultCategory.setEnabled(true); + jComboSupplier.setEnabled(true); + jComboDefaultSupplier.setEnabled(true); + + jCheckInCatalogue.setEnabled(true); + jCheckSellIncTax.setEnabled(true); + } + + /** + * Pushes the Import process into a new thread so it doesn't interfere with + * the UI responsiveness. + */ + private void setWorker() { + progress = 0; + webPBar.setStringPainted(true); + + final SwingWorker<Integer, Integer> pbWorker; + pbWorker = new SwingWorker<Integer, Integer>() { + + @Override + protected final Integer doInBackground() throws Exception { + while ((progress >= 0) && (progress < 100)) { + Thread.sleep(50); + this.publish(progress); + } + this.publish(100); + this.done(); + return 100; + } + + @Override + protected final void process(final List<Integer> chunks) { + webPBar.setValue(chunks.get(0)); + if (progress > 100) { + progress = 100; + webPBar.setString("Imported 100%"); + } else { + webPBar.setString("Imported " + progress + "%"); + } + } + }; + pbWorker.execute(); + } + + /** + * Runs the setWorker. + * + */ + private class workProcess implements Runnable { + + @Override + public void run() { + try { + ImportCsvFile(jFileName.getText()); + } catch (IOException ex) { + log.error(ex.getMessage()); + } + } + } + + /** + * Imports the CSV File using specifications from the form. + * + * @param CSVFileName Name of the file (including path) to import. + * @throws IOException If there are file reading issues. + */ + private void ImportCsvFile(String CSVFileName) throws IOException { + + File f = new File(CSVFileName); + if (f.exists()) { + webPBar.setString ( "Starting..." ); + webPBar.setVisible(true); + jImport.setEnabled(false); + +// Read file +// products = new CsvReader(CSVFileName, ',' ,Charset.forName("UTF-8")); + products = new CsvReader(CSVFileName, ',' ,Charset.forName(jCBiso.getSelectedItem().toString())); + + products.setDelimiter(((String) jComboSeparator.getSelectedItem()).charAt(0)); + products.readHeaders(); + + currentRecord = 0; + + while (products.readRecord()) { + productReference = products.get((String) jComboReference.getSelectedItem()); + productName = products.get((String) jComboName.getSelectedItem()); + productBarcode = products.get((String) jComboBarcode.getSelectedItem()); + String BuyPrice = products.get((String) jComboBuy.getSelectedItem()); + String SellPrice = products.get((String) jComboSell.getSelectedItem()); + productTax = products.get((String) jComboTax.getSelectedItem()); + + Category = products.get((String) jComboCategory.getSelectedItem()); + Supplier = products.get((String) jComboSupplier.getSelectedItem()); + + currentRecord++; + progress = currentRecord; + +// Strip Currencies Dollar GBP, euro + BuyPrice = StringUtils.replaceChars(BuyPrice, "$", ""); + SellPrice = StringUtils.replaceChars(SellPrice, "$", ""); + + BuyPrice = StringUtils.replaceChars(BuyPrice, "£", ""); + SellPrice = StringUtils.replaceChars(SellPrice, "£", ""); + + BuyPrice = StringUtils.replaceChars(BuyPrice, "€", ""); + SellPrice = StringUtils.replaceChars(SellPrice, "€", ""); + + dCategory = getCategory(); + if ("Bad Category".equals(dCategory)) { + csvMessage = "Bad category details"; + } else { + csvMessage = "Missing data or Invalid number"; + } + + dSupplier = getSupplier(); + if ("Bad Supplier".equals(dSupplier)) { + csvMessage = "Bad Supplier details"; + } else { + csvMessage = "Missing data or Invalid number"; + } + + if (validateNumber(BuyPrice)) { + productBuyPrice = Double.parseDouble(BuyPrice); + } else { + productBuyPrice = null; + } + + if (validateNumber(SellPrice)) { + productSellPrice = getSellPrice(SellPrice); + } else { + productSellPrice = null; + } + + if ("".equals(productReference) +// | "".equals(productName) + | "".equals(productBarcode) + | "".equals(BuyPrice) + | "".equals(SellPrice) + | "".equals(productTax) + | productBuyPrice == null + | productSellPrice == null + | "Bad Category".equals(dCategory)) { + + if (productBuyPrice == null + | productSellPrice == null) { + badPrice++; + } else { + missingData++; + } + createCSVEntry(csvMessage, null, null); + } else { + + recordType = getRecord(); + switch (recordType) { + case "new": + createProduct("new"); + newRecords++; + createCSVEntry("New product", null, null); + break; + case "Name change": + case "Barcode change": + case "Reference change": + case "Duplicate Reference found.": + case "Duplicate Barcode found.": + case "Duplicate Description found.": + createProduct("new"); + newRecords++; + createCSVEntry("New product", null, null); + break; + case "Tax change": + case "Exception": + invalidRecords++; + createCSVEntry(recordType, null, null); + break; + default: + updateRecord(recordType); + break; + } + } + } + products.close(); + } else { + JOptionPane.showMessageDialog(null, + "Unable to locate " + + CSVFileName, + "File not found", + JOptionPane.WARNING_MESSAGE); + } + + jTextNew.setText(Integer.toString(newRecords)); + jTextUpdate.setText(Integer.toString(priceUpdates)); + jTextInvalid.setText(Integer.toString(invalidRecords)); + jTextMissing.setText(Integer.toString(missingData)); + jTextNoChange.setText(Integer.toString(noChanges)); + jTextBadPrice.setText(Integer.toString(badPrice)); + if (badCategories.size() == 1 && badCategories.get(0) == "") { + jTextBadCats.setText("0"); + } else { + jTextBadCats.setText(Integer.toString(badCategories.size())); + } + + JOptionPane.showMessageDialog(null, + "Import Complete", + "Imported", + JOptionPane.WARNING_MESSAGE); + + progress = 100; + webPBar.setValue(progress); + webPBar.setString("Imported : " + progress + " records"); +// } + } + + /** + * Tests + * <code>testString</code> for validity as a number + * + * @param testString the string to be checked + * @return True if a real number False if not + */ + private Boolean validateNumber(String testString) { + try { + Double res = Double.parseDouble(testString); + return (true); + } catch (NumberFormatException e) { + return (false); + } + } + + /** + * Lookup for an existing Product's Category + * CategoryID as string. + */ + private String getCategory() { + + if (jComboCategory.getSelectedItem() != category_default) { + String cat = (String) cat_list.get(Category); + + if (cat != null) { + return (cat); + } + } + + if (!Category.equals("")) { + Object[] newcat = new Object[3]; + newcat[0] = UUID.randomUUID().toString(); + newcat[1] = Category; + newcat[2] = true; + + try { + m_dlSales.createCategory(newcat); + + cat_list = new HashMap<>(); + for (Object category : m_sentcat.list()) { + m_CategoryModel.setSelectedItem(category); + cat_list.put(category.toString(), m_CategoryModel.getSelectedKey().toString()); + } + String cat = (String) cat_list.get(Category); + return (cat); + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + } + + if (!badCategories.contains(Category)) { + badCategories.add(Category.trim()); // Save a list of the bad categories + } + return ((jComboDefaultCategory.getSelectedItem() + == reject_bad_category) + ? "Bad Category" + : (String) cat_list.get(m_CategoryModel.getSelectedText())); + } + + /** + * Grab Supplier from Import file. + * + */ + private String getSupplier() { + + if (jComboSupplier.getSelectedItem() != supplier_default) { + String supp = (String) supp_list.get(Supplier); + + if (supp != null) { + return (supp); + } + } + + if (!Supplier.equals("")) { + Object[] newsupp = new Object[4]; + newsupp[0] = UUID.randomUUID().toString(); + newsupp[1] = Supplier; + newsupp[2] = Supplier; + newsupp[3] = true; + + try { + m_dlSales.createSupplier(newsupp); + + supp_list = new HashMap<>(); + for (Object supplier : m_sentsupp.list()) { + m_SupplierModel.setSelectedItem(supplier); + supp_list.put(supplier.toString(), m_SupplierModel.getSelectedKey().toString()); + } + String supp = (String) supp_list.get(Supplier); + return (supp); + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + } + + if (!badSuppliers.contains(Supplier)) { + badSuppliers.add(Supplier.trim()); + } + return ((jComboDefaultSupplier.getSelectedItem() + == reject_bad_supplier) + ? "Bad Supplier" + : (String) supp_list.get(m_SupplierModel.getSelectedText())); + } + + /** + * Adjusts the sell price for included taxes + * + * @param pSellPrice sell price to be converted + * @return sell price after adjustment for included taxes and converted to double + */ + private Double getSellPrice(String pSellPrice) { + + // Get the Tax Rate from the Import file + dTaxRate = taxeslogic.getTaxRate(productTax); + + if (jCheckSellIncTax.isSelected()) { + productSellPrice = ((Double.parseDouble(pSellPrice)) / (1 + dTaxRate)); + return productSellPrice; + } else { + return (Double.parseDouble(pSellPrice)); + } + } + + /** + * Updated the record in the database with the new prices and category if + * needed. + * + * @param pID Unique product id of the record to be updated It then creates + * an updated record for the product, subject to the prices being different + * + */ + private void updateRecord(String pID) { + prodInfo = new ProductInfoExt(); + try { + prodInfo = m_dlSales.getProductInfo(pID); + dOriginalRate = taxeslogic.getTaxRate(prodInfo.getTaxCategoryID()); + dCategory = ((String) cat_list.get(prodInfo.getCategoryID()) + == null) ? prodInfo.getCategoryID() + : (String) cat_list.get(prodInfo.getCategoryID()); + oldBuyPrice = prodInfo.getPriceBuy(); + oldSellPrice = prodInfo.getPriceSell(); +// productSellPrice *= (1 + dOriginalRate); + + dSupplier = ((String) supp_list.get(prodInfo.getSupplierID()) + == null) ? prodInfo.getSupplierID() + : (String) supp_list.get(prodInfo.getSupplierID()); + + if ((oldBuyPrice != productBuyPrice) + || (oldSellPrice != productSellPrice)) { + createCSVEntry("Updated Price Details", oldBuyPrice, + (jCheckSellIncTax.isSelected()) + ? oldSellPrice * (1 + dOriginalRate) + : oldSellPrice); + createProduct("update"); + priceUpdates++; + } else { + noChanges++; + } + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + } + + /** + * Gets the title of the current panel + * + * @return The name of the panel + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.CSVImport"); + } + + /** + * Returns this object + * @return + */ + @Override + public JComponent getComponent() { + return this; + } + + /** + * Loads Tax and Category data into their combo boxes. + * @throws com.unicenta.basic.BasicException + */ + @Override + public void activate() throws BasicException { + // Get tax details and logic + taxsent = m_dlSales.getTaxList(); + taxeslogic = new TaxesLogic(taxsent.list()); + taxcatsent = m_dlSales.getTaxCategoriesList(); + taxcatmodel = new ComboBoxValModel(taxcatsent.list()); + + // Get categories list + m_sentcat = m_dlSales.getCategoriesList(); + m_CategoryModel = new ComboBoxValModel(m_sentcat.list()); + m_CategoryModel.add(reject_bad_category); + jComboDefaultCategory.setModel(m_CategoryModel); + + // Build the cat_list for later use + cat_list = new HashMap<>(); + for (Object category : m_sentcat.list()) { + m_CategoryModel.setSelectedItem(category); + cat_list.put(category.toString(), m_CategoryModel.getSelectedKey().toString()); + } + + // Get suppliers list + m_sentsupp = m_dlSales.getSuppList(); + m_SupplierModel = new ComboBoxValModel(m_sentsupp.list()); + m_SupplierModel.add(reject_bad_supplier); + jComboDefaultSupplier.setModel(m_SupplierModel); + + // Build the supp_list for later + supp_list = new HashMap<>(); + for (Object supplier : m_sentsupp.list()) { + m_SupplierModel.setSelectedItem(supplier); + supp_list.put(supplier.toString(), m_SupplierModel.getSelectedKey().toString()); + } + + // reset the selected to the first in the list + m_CategoryModel.setSelectedItem(null); + m_SupplierModel.setSelectedItem(null); + + // Set the column delimiter + jComboSeparator.removeAllItems(); + jComboSeparator.addItem(","); + jComboSeparator.addItem(";"); + jComboSeparator.addItem("~"); + jComboSeparator.addItem("^"); + + } + + /** + * Resets all the form fields + */ + public void resetFields() { + // Clear the form + jComboReference.removeAllItems(); + jComboReference.setEnabled(false); + + jComboName.removeAllItems(); + jComboName.setEnabled(false); + + jComboBarcode.removeAllItems(); + jComboBarcode.setEnabled(false); + + jComboBuy.removeAllItems(); + jComboBuy.setEnabled(false); + + jComboSell.removeAllItems(); + jComboSell.setEnabled(false); + + jComboTax.removeAllItems(); + jComboTax.setEnabled(false); + + jComboCategory.removeAllItems(); + jComboCategory.setEnabled(false); + jComboDefaultCategory.setEnabled(false); + + jComboSupplier.removeAllItems(); + jComboSupplier.setEnabled(false); + jComboDefaultSupplier.setEnabled(false); + + jImport.setEnabled(false); + jbtnReset.setEnabled(true); + jHeaderRead.setEnabled(false); + jCheckInCatalogue.setSelected(true); + jCheckInCatalogue.setEnabled(true); + jCheckSellIncTax.setSelected(true); + jCheckSellIncTax.setEnabled(true); + jFileName.setText(null); + csvFileName = ""; + jTextNew.setText(""); + jTextUpdate.setText(""); + jTextInvalid.setText(""); + jTextMissing.setText(""); + jTextNoChange.setText(""); + jTextRecords.setText(""); + jTextBadPrice.setText(""); + jTextBadCats.setText(""); + + progress = 0; + + Headers.clear(); + newRecords = 0; + invalidRecords = 0; + priceUpdates = 0; + missingData = 0; + noChanges = 0; + badPrice = 0; +// badCategories = 0; + + } + + /** + * Checks the field mappings to ensure all compulsory fields have been + * completed to allow import to proceed + */ + public void checkFieldMapping() { + if (jComboReference.getSelectedItem() != "" + & jComboName.getSelectedItem() != "" + & jComboBarcode.getSelectedItem() != "" + & jComboBuy.getSelectedItem() != "" + & jComboSell.getSelectedItem() != "" + & jComboTax.getSelectedItem() != "" + & jComboCategory.getSelectedItem() != "" + & m_CategoryModel.getSelectedText() != null) { + jImport.setEnabled(true); + jbtnReset.setEnabled(true); + } else { + jImport.setEnabled(false); + jbtnReset.setEnabled(false); + } + } + + /** + * Deactivates and resets all form fields. + * + * @return + */ + @Override + public boolean deactivate() { + resetFields(); + return (true); + } + + /** + * Creates a new Category if it doesn't exist + * @param cType + */ + public void createCategory(String cType) { + + Object[] mycat = new Object[7]; + mycat[0] = UUID.randomUUID().toString(); // ID string + mycat[1] = categoryName; // Name string + mycat[2] = categoryParentid; // Parent String + mycat[3] = null; // Image + mycat[4] = "<html><center><h4>" + categoryName; // Text tip string + mycat[5] = true; // Show + mycat[6] = categoryCatorder; // Order + + try { + if ("new".equals(cType)) { + spr.insertData(mycat); + } else { + spr.updateData(mycat); + } + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + } + + /** + * + * @param sType + */ + public void createSupplier(String sType) { + + Object[] mysupp = new Object[4]; + mysupp[0] = UUID.randomUUID().toString(); // ID string + mysupp[1] = supplierName; // SearchKey + mysupp[2] = supplierName; // Name string + mysupp[3] = true; // Visible + + try { + if ("new".equals(sType)) { + spr.insertData(mysupp); + } else { + spr.updateData(mysupp); + } + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + } + + + /** + * + * @param pType + */ + public void createProduct(String pType) { + + Object[] myprod = new Object[32]; + if("new".equals(pType)) { + myprod[0] = UUID.randomUUID().toString(); + } else { + myprod[0] = prodInfo.getID(); + } // ID string + myprod[1] = productReference; // Reference string + myprod[2] = productBarcode; // Barcode String + myprod[3] = null; // Barcode Type + myprod[4] = productName; // Name string + myprod[5] = productBuyPrice; // Buy price double + myprod[6] = productSellPrice; // Sell price double + myprod[7] = dCategory; // Category string + myprod[8] = productTax; // User Tax string + myprod[9] = null; // Attributeset string + myprod[10] = 0.0; // Stock cost double + myprod[11] = 0.0; // Stock volume double + myprod[12] = null; // Image + myprod[13] = false; // IScomment flag (Attribute modifier) + myprod[14] = false; // ISscale flag + myprod[15] = false; // IsConstant flag + myprod[16] = false; // PrintKB flag + myprod[17] = false; // SendStatus flag + myprod[18] = false; // isService flag + myprod[19] = null; // Attributes + myprod[20] = "<html><center>" + productName; // Setup Display button + myprod[21] = false; // isVariable price flag + myprod[22] = false; // Compulsory Att flag + myprod[23] = "<html><center><h4>" + productName; // Text tip string + myprod[24] = false; // Warranty flag + myprod[25] = 0.0; // Stock Units + myprod[26] = "1"; // Printer + myprod[27] = dSupplier; // Supplier + myprod[28] = "0"; // UOM + myprod[29]= null; // memodate + myprod[30] = jCheckInCatalogue.isSelected(); // In catalog flag + myprod[31] = null; // catalog order + + try { + if ("new".equals(pType)) { + spr.insertData(myprod); + addStockCurrent("0", myprod[0].toString(), 0.0); + webPBar.setString("Adding record " + progress); + } else { + spr.updateData(myprod); + webPBar.setString("Updating record " + progress); + } + + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + } + + public void addStockCurrent(String LocationID, String ProductID, Double Units) throws BasicException { + + Object[] values = new Object[3]; + values[0] = "0"; + values[1] = ProductID; + values[2] = (double) Units; + + PreparedSentence sentence = new PreparedSentence(s, + "INSERT INTO stockcurrent ( " + + "LOCATION, PRODUCT, UNITS) VALUES (?, ?, ?)" + , new SerializerWriteBasicExt((new Datas[]{ + Datas.STRING, Datas.STRING, Datas.DOUBLE}), + new int[]{0, 1, 2})); + + sentence.exec(values); + } + + /** + * + * @param csvError + * @param previousBuy + * @param previousSell + */ + public void createCSVEntry(String csvError, Double previousBuy, Double previousSell) { + + Object[] myprod = new Object[13]; + myprod[0] = UUID.randomUUID().toString(); // ID string + myprod[1] = Integer.toString(currentRecord); // Record number + myprod[2] = csvError; // Error description + myprod[3] = productReference; // Reference string + myprod[4] = productBarcode; // Barcode String + myprod[5] = productName; // Name string + myprod[6] = productBuyPrice; // Buy price + myprod[7] = productSellPrice; // Sell price + myprod[8] = previousBuy; // Previous Buy price double + myprod[9] = previousSell; // Previous Sell price double + myprod[10] = Category; // Category + myprod[11] = productTax; // Tax + myprod[12] = Supplier; // Supplier + try { + m_dlSystem.execAddCSVEntry(myprod); + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + } + + /** + * + * @return + */ + public String getRecord() { + // Get record type using using DataLogicSystem + Object[] myprod = new Object[3]; + myprod[0] = productReference; + myprod[1] = productBarcode; + myprod[2] = productName; + try { + return (m_dlSystem.getProductRecordType(myprod)); + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + return "Exception"; + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jFileChooserPanel = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + jFileName = new javax.swing.JTextField(); + jbtnFileChoose = new javax.swing.JButton(); + jPanel1 = new javax.swing.JPanel(); + jComboReference = new javax.swing.JComboBox(); + jComboBarcode = new javax.swing.JComboBox(); + jComboName = new javax.swing.JComboBox(); + jComboBuy = new javax.swing.JComboBox(); + jComboSell = new javax.swing.JComboBox(); + jComboDefaultCategory = new javax.swing.JComboBox(); + jComboTax = new javax.swing.JComboBox(); + jLabel3 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + jLabel5 = new javax.swing.JLabel(); + jLabel10 = new javax.swing.JLabel(); + jLabel11 = new javax.swing.JLabel(); + jLabel7 = new javax.swing.JLabel(); + jCheckInCatalogue = new javax.swing.JCheckBox(); + jLabel8 = new javax.swing.JLabel(); + jCheckSellIncTax = new javax.swing.JCheckBox(); + jLabel12 = new javax.swing.JLabel(); + jComboCategory = new javax.swing.JComboBox(); + jLabel20 = new javax.swing.JLabel(); + jImport = new javax.swing.JButton(); + jLabel6 = new javax.swing.JLabel(); + jbtnReset = new javax.swing.JButton(); + jComboSupplier = new javax.swing.JComboBox(); + jLabel21 = new javax.swing.JLabel(); + jLabel22 = new javax.swing.JLabel(); + jComboDefaultSupplier = new javax.swing.JComboBox(); + jLabel17 = new javax.swing.JLabel(); + jLabel18 = new javax.swing.JLabel(); + jHeaderRead = new javax.swing.JButton(); + jPanel2 = new javax.swing.JPanel(); + jLabel9 = new javax.swing.JLabel(); + jLabel14 = new javax.swing.JLabel(); + jLabel16 = new javax.swing.JLabel(); + jTextUpdates = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + jLabel15 = new javax.swing.JLabel(); + jLabel13 = new javax.swing.JLabel(); + jTextRecords = new javax.swing.JTextField(); + jTextNew = new javax.swing.JTextField(); + jTextInvalid = new javax.swing.JTextField(); + jTextUpdate = new javax.swing.JTextField(); + jTextMissing = new javax.swing.JTextField(); + jTextBadPrice = new javax.swing.JTextField(); + jTextNoChange = new javax.swing.JTextField(); + jLabel19 = new javax.swing.JLabel(); + jTextBadCats = new javax.swing.JTextField(); + jComboSeparator = new javax.swing.JComboBox(); + webPBar = new com.alee.laf.progressbar.WebProgressBar(); + jLblImportNotice = new javax.swing.JLabel(); + jCBiso = new javax.swing.JComboBox<>(); + + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + setOpaque(false); + setPreferredSize(new java.awt.Dimension(750, 500)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jLabel1.setText(bundle.getString("label.csvfile")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(100, 30)); + + jFileName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jFileName.setPreferredSize(new java.awt.Dimension(400, 30)); + jFileName.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jFileNameActionPerformed(evt); + } + }); + + jbtnFileChoose.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/fileopen.png"))); // NOI18N + jbtnFileChoose.setMaximumSize(new java.awt.Dimension(64, 32)); + jbtnFileChoose.setMinimumSize(new java.awt.Dimension(64, 32)); + jbtnFileChoose.setPreferredSize(new java.awt.Dimension(80, 45)); + jbtnFileChoose.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnFileChooseActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jFileChooserPanelLayout = new javax.swing.GroupLayout(jFileChooserPanel); + jFileChooserPanel.setLayout(jFileChooserPanelLayout); + jFileChooserPanelLayout.setHorizontalGroup( + jFileChooserPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jFileChooserPanelLayout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jFileName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jbtnFileChoose, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(120, 120, 120)) + ); + jFileChooserPanelLayout.setVerticalGroup( + jFileChooserPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jFileChooserPanelLayout.createSequentialGroup() + .addGroup(jFileChooserPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jFileName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + .addComponent(jbtnFileChoose, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + ); + + jPanel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanel1.setPreferredSize(new java.awt.Dimension(430, 400)); + + jComboReference.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboReference.setEnabled(false); + jComboReference.setMinimumSize(new java.awt.Dimension(32, 25)); + jComboReference.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboReference.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboReferenceItemStateChanged(evt); + } + }); + jComboReference.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jComboReferenceFocusGained(evt); + } + }); + + jComboBarcode.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboBarcode.setEnabled(false); + jComboBarcode.setMinimumSize(new java.awt.Dimension(32, 25)); + jComboBarcode.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboBarcode.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboBarcodeItemStateChanged(evt); + } + }); + jComboBarcode.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jComboBarcodeFocusGained(evt); + } + }); + + jComboName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboName.setEnabled(false); + jComboName.setMinimumSize(new java.awt.Dimension(32, 25)); + jComboName.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboName.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboNameItemStateChanged(evt); + } + }); + jComboName.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jComboNameFocusGained(evt); + } + }); + + jComboBuy.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboBuy.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "" })); + jComboBuy.setSelectedIndex(-1); + jComboBuy.setEnabled(false); + jComboBuy.setMinimumSize(new java.awt.Dimension(32, 25)); + jComboBuy.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboBuy.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboBuyItemStateChanged(evt); + } + }); + jComboBuy.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jComboBuyFocusGained(evt); + } + }); + + jComboSell.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboSell.setEnabled(false); + jComboSell.setMinimumSize(new java.awt.Dimension(32, 25)); + jComboSell.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboSell.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboSellItemStateChanged(evt); + } + }); + jComboSell.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jComboSellFocusGained(evt); + } + }); + + jComboDefaultCategory.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboDefaultCategory.setEnabled(false); + jComboDefaultCategory.setMinimumSize(new java.awt.Dimension(32, 25)); + jComboDefaultCategory.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboDefaultCategory.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboDefaultCategoryItemStateChanged(evt); + } + }); + jComboDefaultCategory.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jComboDefaultCategoryActionPerformed(evt); + } + }); + + jComboTax.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboTax.setEnabled(false); + jComboTax.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboTax.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboTaxItemStateChanged(evt); + } + }); + jComboTax.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jComboTaxFocusGained(evt); + } + }); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(bundle.getString("label.prodref")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(bundle.getString("label.prodbarcode")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(bundle.getString("label.prodname")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel10.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel10.setText(bundle.getString("label.prodpricebuy")); // NOI18N + jLabel10.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel11.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel11.setText(bundle.getString("label.prodcategory")); // NOI18N + jLabel11.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel7.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel7.setText(bundle.getString("label.prodtaxcode")); // NOI18N + jLabel7.setPreferredSize(new java.awt.Dimension(100, 30)); + + jCheckInCatalogue.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jCheckInCatalogue.setEnabled(false); + jCheckInCatalogue.setPreferredSize(new java.awt.Dimension(30, 30)); + + jLabel8.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel8.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jLabel8.setText(bundle.getString("label.prodincatalog")); // NOI18N + jLabel8.setPreferredSize(new java.awt.Dimension(100, 30)); + + jCheckSellIncTax.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jCheckSellIncTax.setEnabled(false); + jCheckSellIncTax.setPreferredSize(new java.awt.Dimension(30, 30)); + + jLabel12.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel12.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jLabel12.setText(bundle.getString("label.csvsellingintax")); // NOI18N + jLabel12.setPreferredSize(new java.awt.Dimension(200, 30)); + + jComboCategory.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboCategory.setEnabled(false); + jComboCategory.setMinimumSize(new java.awt.Dimension(32, 25)); + jComboCategory.setName(""); // NOI18N + jComboCategory.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboCategory.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboCategoryItemStateChanged(evt); + } + }); + jComboCategory.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jComboCategoryFocusGained(evt); + } + }); + + jLabel20.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel20.setText(bundle.getString("label.prodpricesell")); // NOI18N + jLabel20.setPreferredSize(new java.awt.Dimension(100, 30)); + + jImport.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jImport.setText(bundle.getString("label.csvimpostbtn")); // NOI18N + jImport.setEnabled(false); + jImport.setPreferredSize(new java.awt.Dimension(110, 45)); + jImport.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jImportActionPerformed(evt); + } + }); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setText(bundle.getString("label.proddefaultcategory")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(100, 30)); + + jbtnReset.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jbtnReset.setText(bundle.getString("button.reset")); // NOI18N + jbtnReset.setPreferredSize(new java.awt.Dimension(110, 45)); + jbtnReset.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnResetActionPerformed(evt); + } + }); + + jComboSupplier.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboSupplier.setEnabled(false); + jComboSupplier.setMinimumSize(new java.awt.Dimension(32, 25)); + jComboSupplier.setName(""); // NOI18N + jComboSupplier.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboSupplier.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboSupplierItemStateChanged(evt); + } + }); + jComboSupplier.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusGained(java.awt.event.FocusEvent evt) { + jComboSupplierFocusGained(evt); + } + }); + jComboSupplier.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jComboSupplierActionPerformed(evt); + } + }); + + jLabel21.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel21.setText(bundle.getString("label.suppliername")); // NOI18N + jLabel21.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel22.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel22.setText(bundle.getString("label.proddefaultsupplier")); // NOI18N + jLabel22.setPreferredSize(new java.awt.Dimension(100, 30)); + + jComboDefaultSupplier.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboDefaultSupplier.setEnabled(false); + jComboDefaultSupplier.setMinimumSize(new java.awt.Dimension(32, 25)); + jComboDefaultSupplier.setPreferredSize(new java.awt.Dimension(300, 30)); + jComboDefaultSupplier.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + jComboDefaultSupplierItemStateChanged(evt); + } + }); + jComboDefaultSupplier.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jComboDefaultSupplierActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jCheckInCatalogue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(59, 59, 59) + .addComponent(jCheckSellIncTax, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addComponent(jbtnReset, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jImport, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(93, 93, 93)))) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboTax, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboBarcode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboReference, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboBuy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboSell, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboDefaultCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboSupplier, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel22, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboDefaultSupplier, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(2, 2, 2) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboReference, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jComboBarcode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboBuy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboSell, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboTax, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel11, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jComboCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboDefaultCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel21, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jComboSupplier, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboDefaultSupplier, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel22, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jCheckSellIncTax, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jCheckInCatalogue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jImport, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jbtnReset, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(16, Short.MAX_VALUE)) + ); + + jLabel17.setFont(new java.awt.Font("Arial", 0, 10)); // NOI18N + jLabel17.setText("Import version 4.5"); + + jLabel18.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel18.setText(bundle.getString("label.csvdelimit")); // NOI18N + jLabel18.setPreferredSize(new java.awt.Dimension(100, 30)); + + jHeaderRead.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jHeaderRead.setText(bundle.getString("label.csvread")); // NOI18N + jHeaderRead.setEnabled(false); + jHeaderRead.setPreferredSize(new java.awt.Dimension(110, 45)); + jHeaderRead.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jHeaderReadActionPerformed(evt); + } + }); + + jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(new javax.swing.border.LineBorder(new java.awt.Color(153, 153, 153), 1, true), bundle.getString("title.CSVImport"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Arial", 1, 14), new java.awt.Color(102, 102, 102))); // NOI18N + + jLabel9.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel9.setText(bundle.getString("label.csvrecordsfound")); // NOI18N + jLabel9.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel14.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel14.setText(bundle.getString("label.csvnewproducts")); // NOI18N + jLabel14.setMaximumSize(new java.awt.Dimension(77, 14)); + jLabel14.setMinimumSize(new java.awt.Dimension(77, 14)); + jLabel14.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel16.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel16.setText(bundle.getString("label.csvchanged")); // NOI18N + jLabel16.setPreferredSize(new java.awt.Dimension(150, 30)); + + jTextUpdates.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTextUpdates.setText(bundle.getString("label.csvpriceupdated")); // NOI18N + jTextUpdates.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(bundle.getString("label.csvmissing")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel15.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel15.setText(bundle.getString("label.csvbad")); // NOI18N + jLabel15.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel13.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel13.setText(bundle.getString("label.csvnotchanged")); // NOI18N + jLabel13.setPreferredSize(new java.awt.Dimension(150, 30)); + + jTextRecords.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTextRecords.setForeground(new java.awt.Color(102, 102, 102)); + jTextRecords.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + jTextRecords.setBorder(null); + jTextRecords.setDisabledTextColor(new java.awt.Color(0, 0, 0)); + jTextRecords.setEnabled(false); + jTextRecords.setPreferredSize(new java.awt.Dimension(100, 30)); + + jTextNew.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTextNew.setForeground(new java.awt.Color(102, 102, 102)); + jTextNew.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + jTextNew.setBorder(null); + jTextNew.setDisabledTextColor(new java.awt.Color(0, 0, 0)); + jTextNew.setEnabled(false); + jTextNew.setPreferredSize(new java.awt.Dimension(100, 30)); + + jTextInvalid.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTextInvalid.setForeground(new java.awt.Color(102, 102, 102)); + jTextInvalid.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + jTextInvalid.setBorder(null); + jTextInvalid.setDisabledTextColor(new java.awt.Color(0, 0, 0)); + jTextInvalid.setEnabled(false); + jTextInvalid.setPreferredSize(new java.awt.Dimension(100, 30)); + + jTextUpdate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTextUpdate.setForeground(new java.awt.Color(102, 102, 102)); + jTextUpdate.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + jTextUpdate.setBorder(null); + jTextUpdate.setDisabledTextColor(new java.awt.Color(0, 0, 0)); + jTextUpdate.setEnabled(false); + jTextUpdate.setPreferredSize(new java.awt.Dimension(100, 30)); + + jTextMissing.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTextMissing.setForeground(new java.awt.Color(102, 102, 102)); + jTextMissing.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + jTextMissing.setBorder(null); + jTextMissing.setDisabledTextColor(new java.awt.Color(0, 0, 0)); + jTextMissing.setEnabled(false); + jTextMissing.setPreferredSize(new java.awt.Dimension(100, 30)); + + jTextBadPrice.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTextBadPrice.setForeground(new java.awt.Color(255, 0, 204)); + jTextBadPrice.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + jTextBadPrice.setBorder(null); + jTextBadPrice.setDisabledTextColor(new java.awt.Color(0, 0, 0)); + jTextBadPrice.setEnabled(false); + jTextBadPrice.setPreferredSize(new java.awt.Dimension(100, 30)); + + jTextNoChange.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTextNoChange.setForeground(new java.awt.Color(102, 102, 102)); + jTextNoChange.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + jTextNoChange.setBorder(null); + jTextNoChange.setDisabledTextColor(new java.awt.Color(0, 0, 0)); + jTextNoChange.setEnabled(false); + jTextNoChange.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel19.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel19.setText(bundle.getString("label.csvbadcats")); // NOI18N + jLabel19.setPreferredSize(new java.awt.Dimension(150, 30)); + + jTextBadCats.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTextBadCats.setForeground(new java.awt.Color(255, 0, 204)); + jTextBadCats.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + jTextBadCats.setBorder(null); + jTextBadCats.setDisabledTextColor(new java.awt.Color(0, 0, 0)); + jTextBadCats.setEnabled(false); + jTextBadCats.setPreferredSize(new java.awt.Dimension(100, 30)); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jTextRecords, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(jLabel19, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel13, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel16, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextUpdates, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel15, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel14, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jTextBadCats, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextNew, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextInvalid, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextMissing, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextBadPrice, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextNoChange, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addContainerGap()) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(0, 0, 0) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextRecords, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel14, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextNew, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel16, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextInvalid, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextUpdates, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextMissing, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel15, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextBadPrice, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextNoChange, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel19, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextBadCats, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + + jComboSeparator.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboSeparator.setPreferredSize(new java.awt.Dimension(50, 30)); + + webPBar.setFont(new java.awt.Font("Arial", 0, 13)); // NOI18N + webPBar.setPreferredSize(new java.awt.Dimension(240, 30)); + + jLblImportNotice.setBackground(new java.awt.Color(255, 255, 255)); + jLblImportNotice.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblImportNotice.setForeground(new java.awt.Color(102, 102, 102)); + jLblImportNotice.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLblImportNotice.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/refundit.png"))); // NOI18N + jLblImportNotice.setText(bundle.getString("label.importnotice")); // NOI18N + jLblImportNotice.setOpaque(true); + jLblImportNotice.setPreferredSize(new java.awt.Dimension(150, 37)); + + jCBiso.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jCBiso.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "ISO-8859-1", "ISO-8859-2", "ISO-8859-3", "ISO-8859-4", "ISO-8859-5", "ISO-8859-6", "ISO-8859-7", "ISO-8859-8", "ISO-8859-9", "ISO-8859-10", "UTF-8", "UTF-16", " " })); + jCBiso.setToolTipText(bundle.getString("tooltip.import.cbiso")); // NOI18N + jCBiso.setPreferredSize(new java.awt.Dimension(125, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(jLabel17)) + .addComponent(jFileChooserPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel18, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jCBiso, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(jHeaderRead, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(webPBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLblImportNotice, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel17) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jFileChooserPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel18, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jHeaderRead, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jCBiso, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(webPBar, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLblImportNotice, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 469, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + private void jHeaderReadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jHeaderReadActionPerformed + try { + GetheadersFromFile(jFileName.getText()); + webPBar.setString("Source file Header OK"); + } catch (IOException ex) { + log.error(ex.getMessage()); + webPBar.setString("Source file Header error!"); + } + }//GEN-LAST:event_jHeaderReadActionPerformed + + private void jImportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jImportActionPerformed + + jImport.setEnabled(false); + + workProcess work = new workProcess(); + Thread thread2 = new Thread(work); + thread2.start(); + + }//GEN-LAST:event_jImportActionPerformed + + private void jFileNameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jFileNameActionPerformed + jImport.setEnabled(false); + jHeaderRead.setEnabled(true); + }//GEN-LAST:event_jFileNameActionPerformed + + private void jbtnFileChooseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnFileChooseActionPerformed + resetFields(); + setWorker(); + + JFileChooser chooser = new JFileChooser(last_folder == null ? "C:\\" : last_folder); + FileNameExtensionFilter filter = new FileNameExtensionFilter("csv files", "csv"); + chooser.setFileFilter(filter); + chooser.showOpenDialog(null); + File csvFile = chooser.getSelectedFile(); + + if (csvFile == null) { + return; + } + + File current_folder = chooser.getCurrentDirectory(); + + if (last_folder == null || !last_folder.equals(current_folder.getAbsolutePath())) { + AppConfig CSVConfig = new AppConfig(config_file); + CSVConfig.load(); + CSVConfig.setProperty("CSV.last_folder", current_folder.getAbsolutePath()); + last_folder = current_folder.getAbsolutePath(); + try { + CSVConfig.save(); + } catch (IOException ex) { + log.error(ex.getMessage()); + } + } + + String csv = csvFile.getName(); + if (!(csv.trim().equals(""))) { + csvFileName = csvFile.getAbsolutePath(); + jFileName.setText(csvFileName); + } + }//GEN-LAST:event_jbtnFileChooseActionPerformed + + private void jComboCategoryFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jComboCategoryFocusGained + jComboCategory.removeAllItems(); + int i = 1; + jComboCategory.addItem(""); + while (i < Headers.size()) { + if ((Headers.get(i) != jComboBarcode.getSelectedItem()) + & (Headers.get(i) != jComboReference.getSelectedItem()) + & (Headers.get(i) != jComboName.getSelectedItem()) + & (Headers.get(i) != jComboBuy.getSelectedItem()) + & (Headers.get(i) != jComboSell.getSelectedItem()) + & (Headers.get(i) != jComboTax.getSelectedItem()) + & (Headers.get(i) != jComboSupplier.getSelectedItem())) { + jComboCategory.addItem(Headers.get(i)); + } + ++i; + } + jComboCategory.addItem(category_default); + }//GEN-LAST:event_jComboCategoryFocusGained + + private void jComboCategoryItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboCategoryItemStateChanged + + try { + if (jComboCategory.getSelectedItem() == "[ USE DEFAULT CATEGORY ]") { + m_CategoryModel = new ComboBoxValModel(m_sentcat.list()); + jComboDefaultCategory.setModel(m_CategoryModel); + } else { + m_CategoryModel = new ComboBoxValModel(m_sentcat.list()); + m_CategoryModel.add(reject_bad_category); + jComboDefaultCategory.setModel(m_CategoryModel); + } + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + checkFieldMapping(); + }//GEN-LAST:event_jComboCategoryItemStateChanged + + private void jComboDefaultCategoryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jComboDefaultCategoryActionPerformed + checkFieldMapping(); + }//GEN-LAST:event_jComboDefaultCategoryActionPerformed + + private void jComboDefaultCategoryItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboDefaultCategoryItemStateChanged + // TODO add your handling code here: + }//GEN-LAST:event_jComboDefaultCategoryItemStateChanged + + private void jComboSellFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jComboSellFocusGained + jComboSell.removeAllItems(); + int i = 1; + jComboSell.addItem(""); + while (i < Headers.size()) { + if ((Headers.get(i) != jComboCategory.getSelectedItem()) + & (Headers.get(i) != jComboReference.getSelectedItem()) + & (Headers.get(i) != jComboName.getSelectedItem()) + & (Headers.get(i) != jComboBarcode.getSelectedItem()) + & (Headers.get(i) != jComboBuy.getSelectedItem()) + & (Headers.get(i) != jComboTax.getSelectedItem()) + & (Headers.get(i) != jComboSupplier.getSelectedItem())) { + + jComboSell.addItem(Headers.get(i)); + } + ++i; + } + }//GEN-LAST:event_jComboSellFocusGained + + private void jComboSellItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboSellItemStateChanged + checkFieldMapping(); + }//GEN-LAST:event_jComboSellItemStateChanged + + private void jComboBuyFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jComboBuyFocusGained + jComboBuy.removeAllItems(); + int i = 1; + jComboBuy.addItem(""); + while (i < Headers.size()) { + if ((Headers.get(i) != jComboCategory.getSelectedItem()) + & (Headers.get(i) != jComboReference.getSelectedItem()) + & (Headers.get(i) != jComboName.getSelectedItem()) + & (Headers.get(i) != jComboBarcode.getSelectedItem()) + & (Headers.get(i) != jComboSell.getSelectedItem()) + & (Headers.get(i) != jComboTax.getSelectedItem()) + & (Headers.get(i) != jComboSupplier.getSelectedItem())) { + jComboBuy.addItem(Headers.get(i)); + } + ++i; + } + }//GEN-LAST:event_jComboBuyFocusGained + + private void jComboBuyItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboBuyItemStateChanged + checkFieldMapping(); + }//GEN-LAST:event_jComboBuyItemStateChanged + + private void jComboNameFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jComboNameFocusGained + jComboName.removeAllItems(); + int i = 1; + jComboName.addItem(""); + while (i < Headers.size()) { + if ((Headers.get(i) != jComboCategory.getSelectedItem()) + & (Headers.get(i) != jComboReference.getSelectedItem()) + & (Headers.get(i) != jComboBarcode.getSelectedItem()) + & (Headers.get(i) != jComboBuy.getSelectedItem()) + & (Headers.get(i) != jComboSell.getSelectedItem()) + & (Headers.get(i) != jComboTax.getSelectedItem()) + & (Headers.get(i) != jComboSupplier.getSelectedItem())) { + jComboName.addItem(Headers.get(i)); + } + ++i; + } + }//GEN-LAST:event_jComboNameFocusGained + + private void jComboNameItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboNameItemStateChanged + checkFieldMapping(); + }//GEN-LAST:event_jComboNameItemStateChanged + + private void jComboBarcodeFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jComboBarcodeFocusGained + jComboBarcode.removeAllItems(); + int i = 1; + jComboBarcode.addItem(""); + while (i < Headers.size()) { + if ((Headers.get(i) != jComboCategory.getSelectedItem()) + & (Headers.get(i) != jComboReference.getSelectedItem()) + & (Headers.get(i) != jComboName.getSelectedItem()) + & (Headers.get(i) != jComboBuy.getSelectedItem()) + & (Headers.get(i) != jComboSell.getSelectedItem()) + & (Headers.get(i) != jComboTax.getSelectedItem()) + & (Headers.get(i) != jComboSupplier.getSelectedItem())) { + jComboBarcode.addItem(Headers.get(i)); + } + ++i; + } + }//GEN-LAST:event_jComboBarcodeFocusGained + + private void jComboBarcodeItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboBarcodeItemStateChanged + checkFieldMapping(); + }//GEN-LAST:event_jComboBarcodeItemStateChanged + + private void jComboReferenceFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jComboReferenceFocusGained + jComboReference.removeAllItems(); + int i = 1; + jComboReference.addItem(""); + while (i < Headers.size()) { + if ((Headers.get(i) != jComboCategory.getSelectedItem()) + & (Headers.get(i) != jComboBarcode.getSelectedItem()) + & (Headers.get(i) != jComboName.getSelectedItem()) + & (Headers.get(i) != jComboBuy.getSelectedItem()) + & (Headers.get(i) != jComboSell.getSelectedItem()) + & (Headers.get(i) != jComboTax.getSelectedItem()) + & (Headers.get(i) != jComboSupplier.getSelectedItem())) { + jComboReference.addItem(Headers.get(i)); + } + ++i; + } + }//GEN-LAST:event_jComboReferenceFocusGained + + private void jComboReferenceItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboReferenceItemStateChanged + checkFieldMapping(); + }//GEN-LAST:event_jComboReferenceItemStateChanged + + private void jbtnResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnResetActionPerformed + resetFields(); + progress = -1; + webPBar.setString("Waiting..."); + }//GEN-LAST:event_jbtnResetActionPerformed + + private void jComboTaxFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jComboTaxFocusGained + jComboTax.removeAllItems(); + int i = 1; + jComboTax.addItem(""); + while (i < Headers.size()) { + if ((Headers.get(i) != jComboCategory.getSelectedItem()) + & (Headers.get(i) != jComboReference.getSelectedItem()) + & (Headers.get(i) != jComboBarcode.getSelectedItem()) + & (Headers.get(i) != jComboName.getSelectedItem()) + & (Headers.get(i) != jComboBuy.getSelectedItem()) + & (Headers.get(i) != jComboSell.getSelectedItem()) + & (Headers.get(i) != jComboSupplier.getSelectedItem())) { + jComboTax.addItem(Headers.get(i)); + } + ++i; + } + }//GEN-LAST:event_jComboTaxFocusGained + + private void jComboTaxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboTaxItemStateChanged + checkFieldMapping(); + }//GEN-LAST:event_jComboTaxItemStateChanged + + private void jComboSupplierItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboSupplierItemStateChanged + + try { + if (jComboSupplier.getSelectedItem() == "[ USE DEFAULT SUPPLIER ]") { + m_SupplierModel = new ComboBoxValModel(m_sentsupp.list()); + jComboDefaultSupplier.setModel(m_SupplierModel); + } else { + m_SupplierModel = new ComboBoxValModel(m_sentsupp.list()); + m_SupplierModel.add(reject_bad_supplier); + jComboDefaultSupplier.setModel(m_SupplierModel); + } + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + checkFieldMapping(); + }//GEN-LAST:event_jComboSupplierItemStateChanged + + private void jComboSupplierFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jComboSupplierFocusGained + jComboSupplier.removeAllItems(); + int i = 1; + jComboSupplier.addItem(""); + while (i < Headers.size()) { + if ((Headers.get(i) != jComboCategory.getSelectedItem()) + & (Headers.get(i) != jComboReference.getSelectedItem()) + & (Headers.get(i) != jComboBarcode.getSelectedItem()) + & (Headers.get(i) != jComboName.getSelectedItem()) + & (Headers.get(i) != jComboBuy.getSelectedItem()) + & (Headers.get(i) != jComboSell.getSelectedItem()) + & (Headers.get(i) != jComboTax.getSelectedItem())) { + + jComboSupplier.addItem(Headers.get(i)); + } + ++i; + } + }//GEN-LAST:event_jComboSupplierFocusGained + + private void jComboDefaultSupplierItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jComboDefaultSupplierItemStateChanged + // TODO add your handling code here: + }//GEN-LAST:event_jComboDefaultSupplierItemStateChanged + + private void jComboDefaultSupplierActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jComboDefaultSupplierActionPerformed + checkFieldMapping(); + }//GEN-LAST:event_jComboDefaultSupplierActionPerformed + + private void jComboSupplierActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jComboSupplierActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jComboSupplierActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JComboBox<String> jCBiso; + private javax.swing.JCheckBox jCheckInCatalogue; + private javax.swing.JCheckBox jCheckSellIncTax; + private javax.swing.JComboBox jComboBarcode; + private javax.swing.JComboBox jComboBuy; + private javax.swing.JComboBox jComboCategory; + private javax.swing.JComboBox jComboDefaultCategory; + private javax.swing.JComboBox jComboDefaultSupplier; + private javax.swing.JComboBox jComboName; + private javax.swing.JComboBox jComboReference; + private javax.swing.JComboBox jComboSell; + private javax.swing.JComboBox jComboSeparator; + private javax.swing.JComboBox jComboSupplier; + private javax.swing.JComboBox jComboTax; + private javax.swing.JPanel jFileChooserPanel; + private javax.swing.JTextField jFileName; + private javax.swing.JButton jHeaderRead; + private javax.swing.JButton jImport; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel10; + private javax.swing.JLabel jLabel11; + private javax.swing.JLabel jLabel12; + private javax.swing.JLabel jLabel13; + private javax.swing.JLabel jLabel14; + private javax.swing.JLabel jLabel15; + private javax.swing.JLabel jLabel16; + private javax.swing.JLabel jLabel17; + private javax.swing.JLabel jLabel18; + private javax.swing.JLabel jLabel19; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel20; + private javax.swing.JLabel jLabel21; + private javax.swing.JLabel jLabel22; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JLabel jLabel9; + private javax.swing.JLabel jLblImportNotice; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JTextField jTextBadCats; + private javax.swing.JTextField jTextBadPrice; + private javax.swing.JTextField jTextInvalid; + private javax.swing.JTextField jTextMissing; + private javax.swing.JTextField jTextNew; + private javax.swing.JTextField jTextNoChange; + private javax.swing.JTextField jTextRecords; + private javax.swing.JTextField jTextUpdate; + private javax.swing.JLabel jTextUpdates; + private javax.swing.JButton jbtnFileChoose; + private javax.swing.JButton jbtnReset; + private com.alee.laf.progressbar.WebProgressBar webPBar; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/imports/StockQtyImport.form b/src/main/java/com/unicenta/pos/imports/StockQtyImport.form new file mode 100644 index 0000000..da2c9dc --- /dev/null +++ b/src/main/java/com/unicenta/pos/imports/StockQtyImport.form @@ -0,0 +1,443 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="opaque" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[700, 350]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="10" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jFileChooserPanel" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace min="0" pref="0" max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" attributes="0"> + <Component id="m_jLocation" min="-2" pref="295" max="-2" attributes="0"/> + <Group type="102" attributes="0"> + <Component id="jFileRead" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jImport" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jbtnReset" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="webPBar" min="-2" pref="284" max="-2" attributes="0"/> + <Component id="jPanel2" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="19" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jFileChooserPanel" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jLocation" min="-2" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Group type="103" groupAlignment="2" attributes="0"> + <Component id="jFileRead" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="jImport" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="jbtnReset" alignment="2" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="webPBar" min="-2" pref="32" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jPanel2" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace min="-2" pref="10" max="-2" attributes="0"/> + <Component id="jLabel2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Container class="javax.swing.JPanel" name="jFileChooserPanel"> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel1" max="32767" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jFileName" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jLabel18" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboSeparator" min="-2" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + <Component id="jbtnFileChoose" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jFileName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="2" attributes="0"> + <Component id="jLabel18" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="jComboSeparator" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="jbtnFileChoose" alignment="2" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvfile" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jFileName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jFileNameActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel18"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvdelimit" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jbtnFileChoose"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/fileopen.png"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[64, 32]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[64, 32]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnFileChooseActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboSeparator"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JButton" name="jFileRead"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvread" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[85, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jFileReadActionPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="JPanelCSVSelect_jHeaderRead"/> + </AuxValues> + </Component> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder title="Status"> + <Border PropertyName="innerBorder" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder roundedCorners="true"> + <Color PropertyName="color" blue="99" green="99" red="99" type="rgb"/> + </LineBorder> + </Border> + <ResourceString PropertyName="titleX" bundle="pos_messages.properties" key="title.CSVImport" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + <Font PropertyName="font" name="Arial" size="14" style="1"/> + <Color PropertyName="color" blue="66" green="66" red="66" type="rgb"/> + </TitledBorder> + </Border> + </Property> + </Properties> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel9" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jTextRecords" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jTextUpdates" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jTextUpdate" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="0" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel9" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jTextRecords" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jTextUpdates" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jTextUpdate" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" pref="47" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel9"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvrecordsfound" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jTextUpdates"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvchanged" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTextRecords"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="disabledTextColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="0" green="0" red="0" type="rgb"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTextUpdate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="disabledTextColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="0" green="0" red="0" type="rgb"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="com.alee.laf.progressbar.WebProgressBar" name="webPBar"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="13" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[240, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jLocation"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.location" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jImport"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvimpostbtn" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[85, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jImportActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jbtnReset"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.reset" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[85, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnResetActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" red="ff" type="rgb"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.csvnotice" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="verticalAlignment" type="int" value="1"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="99" green="99" red="99" type="rgb"/> + </LineBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[710, 110]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/imports/StockQtyImport.java b/src/main/java/com/unicenta/pos/imports/StockQtyImport.java new file mode 100644 index 0000000..9eb914b --- /dev/null +++ b/src/main/java/com/unicenta/pos/imports/StockQtyImport.java @@ -0,0 +1,897 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + + +package com.unicenta.pos.imports; + +import com.csvreader.CsvReader; +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.loader.PreparedSentence; +import com.unicenta.data.loader.SerializerWriteBasicExt; +import com.unicenta.data.loader.Session; +import com.unicenta.pos.forms.*; +import com.unicenta.pos.inventory.ProductStock; +import com.unicenta.pos.ticket.ProductInfoExt; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.filechooser.FileNameExtensionFilter; +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.List; +import java.util.Properties; +import java.util.UUID; + + +/** + * User Interface and code for CSV type data import to update Products + * Current Stock quantity levels in table: stockcurrent + */ +@Slf4j +public class StockQtyImport extends JPanel implements JPanelView { + // the workspace + private AppProperties m_props; + private Properties m_propsdb = null; + private CsvReader products; + private DocumentListener documentListener; + + // the db connection session + private Session s; + private Connection con; + private DataLogicSales m_dlSales; + private DataLogicSystem m_dlSystem; + private ProductInfoExt prodInfo; + private ProductStock prodStock; + + // Location + private String Location = "0"; + private String m_sInventoryLocation; + + // Product properties + private String productBarcode; + private Double productQty; + private double oldQty = 0; + private double newQty = 0; + private String recordType = null; + + // the csv filename + private String last_folder; + private File config_file; + private String csvFileName; + + //Status area messages + private Integer progress = 0; + private int currentRecord; + private int rowCount = 0; + private int qtyUpdates = 0; + + /** + * Constructs a new StockQtyImport object + * + * @param oApp AppView + */ + public StockQtyImport(AppView oApp) { + this(oApp.getProperties()); + } + + /** + * Constructs a new StockQtyImport object + * + * @param props AppProperties + */ + @SuppressWarnings("empty-statement") + public StockQtyImport(AppProperties props) { + + initComponents(); + +// Get current db session connection + AppProperties m_props = props; + + try { + s = AppViewConnection.createSession(props); + con = s.getConnection(); + } catch (BasicException | SQLException e) { + ; + } + +// Set db tables + m_dlSales = new DataLogicSales(); + m_dlSales.init(s); + m_dlSystem = new DataLogicSystem(); + m_dlSystem.init(s); + +// Get terminal's current resource property settings + Properties m_propsdb = m_dlSystem.getResourceAsProperties(m_props.getHost() + "/properties"); + +// Get terminal's set Location property <entry key="location">0</entry> + m_sInventoryLocation = m_propsdb.getProperty("location"); + try { + Location = m_dlSystem.findLocationName(m_sInventoryLocation); + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + +// last used folder stored in unicentaopos.properties + last_folder = props.getProperty("CSV.last_folder"); + config_file = props.getConfigFile(); + + jFileName.getDocument().addDocumentListener(documentListener); + documentListener = new DocumentListener() { + @Override + public void changedUpdate(DocumentEvent documentEvent) { + jFileRead.setEnabled(true); + } + + @Override + public void insertUpdate(DocumentEvent documentEvent) { + if (!"".equals(jFileName.getText().trim())) { + jFileRead.setEnabled(true); + } + } + + @Override + public void removeUpdate(DocumentEvent documentEvent) { + if (jFileName.getText().trim().equals("")) { + jFileRead.setEnabled(false); + } + } + }; + } + + /** + * Enables form components + */ + private void enableForm() { + jFileRead.setEnabled(true); + jImport.setEnabled(true); + jbtnReset.setEnabled(true); + m_jLocation.setEnabled(true); + } + + /** + * This forms Title + * + * @return The name of the panel + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.CSVImport"); + } + + /** + * Returns this object + * + * @return + */ + @Override + public JComponent getComponent() { + return this; + } + + /** + * Get this form object ready + * + * @throws com.unicenta.basic.BasicException + */ + @Override + public void activate() throws BasicException { + // Current Location + m_jLocation.setText("Current Location : " + Location); + + // Set the column delimiter + jComboSeparator.removeAllItems(); + jComboSeparator.addItem(","); + jComboSeparator.addItem(";"); + jComboSeparator.addItem("~"); + jComboSeparator.addItem("^"); + } + + /** + * Resets all the form fields + */ + public void resetForm() { + + m_jLocation.setEnabled(false); + jImport.setEnabled(false); + jbtnReset.setEnabled(true); + jFileRead.setEnabled(false); + jFileName.setText(null); + csvFileName = ""; + +// Status area + progress = 0; + webPBar.setValue(progress); + jTextUpdate.setText(""); + jTextRecords.setText(""); + qtyUpdates = 0; + } + + /** + * Deactivates and resets all form fields. + * + * @return + */ + @Override + public boolean deactivate() { + resetForm(); + return (true); + } + + /** + * Check file can be opened, read and closed + * No Headers in the CSVFileName are required, + * + * @param CSVFileName Name of the file (including the path) to open and read + * @throws IOException If there is an issue reading the CSV file + */ + private void checkFile(String CSVFileName) throws IOException { + + File f = new File(CSVFileName); + if (f.exists()) { + products = new CsvReader(CSVFileName, ',', Charset.forName("UTF-8")); + products.setDelimiter(((String) jComboSeparator.getSelectedItem()).charAt(0)); + + rowCount = 0; + int i = 0; + + while (products.readRecord()) { + ++rowCount; + } + jTextRecords.setText(Long.toString(rowCount)); + products.close(); + + JOptionPane.showMessageDialog(null, "File Check " + + CSVFileName, + "File read OK", + JOptionPane.WARNING_MESSAGE); + + enableForm(); + + } else { + JOptionPane.showMessageDialog(null, "Unable to locate " + + CSVFileName, + "File not found", + JOptionPane.WARNING_MESSAGE); + } + } + + /** + * Imports the external file + * + * @param CSVFileName Name of the file (including path) to import. + * @throws IOException If there are file reading issues. + */ + private void ImportCsvFile(String CSVFileName) throws IOException { + + File f = new File(CSVFileName); + if (f.exists()) { + webPBar.setString("Starting..."); + webPBar.setVisible(true); + jImport.setEnabled(true); + +// Read file + products = new CsvReader(CSVFileName, ',', Charset.forName("UTF-8")); + products.setDelimiter(((String) jComboSeparator.getSelectedItem()).charAt(0)); + currentRecord = 0; + +// Prime: read the csv record and update to zero matching stockcurrent values + while (products.readRecord()) { + recordType = "delete"; + deleteRecord(recordType); + } + products.close(); + +// Work: read the file again and update stockcurrent values + products = new CsvReader(CSVFileName, ',', Charset.forName("UTF-8")); + products.setDelimiter(((String) jComboSeparator.getSelectedItem()).charAt(0)); + currentRecord = 0; + + while (products.readRecord()) { + currentRecord++; + progress = currentRecord; + recordType = "update"; + updateRecord(recordType); + } + products.close(); + + } else { + JOptionPane.showMessageDialog(null, + "Unable to locate " + + CSVFileName, + "File not found", + JOptionPane.WARNING_MESSAGE); + } + + jTextUpdate.setText(Integer.toString(qtyUpdates)); + + JOptionPane.showMessageDialog(null, + "Import Complete", + "Imported", + JOptionPane.WARNING_MESSAGE); + + progress = 100; + webPBar.setValue(progress); + webPBar.setString("Imported" + progress); + } + + /** + * Update the record in the database with the new Quantities + * + * @param pId Unique product id of the record to be updated + */ + private void updateRecord(String pId) throws IOException { + prodInfo = new ProductInfoExt(); + prodStock = new ProductStock(); + try { + + String sCode = products.get(0); + + prodInfo = m_dlSales.getProductInfoByCode(sCode); + + if (prodInfo != null) { + prodStock = m_dlSales.getProductStockState(prodInfo.getID(), m_sInventoryLocation); + productBarcode = products.get(0); + oldQty = prodStock.getUnits(); + newQty = Double.valueOf(products.get(1)); + productQty = oldQty + newQty; + updateStockCurrent(m_sInventoryLocation, prodInfo.getID(), productQty); + CSVStockUpdate(Location, productBarcode, newQty); + qtyUpdates++; + } + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + } + + /** + * Delete the record in the database with the new Quantities + * + * @param pId Unique product id of the record to be updated + */ + private void deleteRecord(String pId) throws IOException { + prodInfo = new ProductInfoExt(); + prodStock = new ProductStock(); + try { + + String sCode = products.get(0); + + prodInfo = m_dlSales.getProductInfoByCode(sCode); + + if (prodInfo != null) { + prodStock = m_dlSales.getProductStockState(prodInfo.getID(), m_sInventoryLocation); + productQty = 0.; + + deleteStockCurrent(m_sInventoryLocation, prodInfo.getID(), productQty); + } + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + } + + /** + * FUTURE - Add non existing minimal Products + * + * @param LocationID + * @param ProductID + * @param Units + * @throws com.unicenta.basic.BasicException + */ + public void addStockCurrent(String LocationID, String ProductID, Double Units) throws BasicException { + + Object[] values = new Object[3]; + values[0] = LocationID; + values[1] = ProductID; + values[2] = (double) Units; + + PreparedSentence sentence = new PreparedSentence(s, + "INSERT INTO stockcurrent ( " + + "LOCATION, PRODUCT, UNITS) VALUES (?, ?, ?)" + , new SerializerWriteBasicExt((new Datas[]{ + Datas.STRING, + Datas.STRING, + Datas.DOUBLE + }), + new int[]{0, 1, 2 + })); + + sentence.exec(values); + } + + /** + * Update existing Product Current Quantity + * + * @param LocationID + * @param ProductID + * @param Units + * @throws com.unicenta.basic.BasicException + */ + public void updateStockCurrent(String LocationID, String ProductID, Double Units) throws BasicException { + + Object[] newValues = new Object[3]; + newValues[0] = (double) Units; + newValues[1] = LocationID; + newValues[2] = ProductID; + + PreparedSentence sentence = new PreparedSentence(s, + "UPDATE stockcurrent SET " + + "UNITS = ? " + + "WHERE LOCATION = ? " + + "AND PRODUCT = ?" + , new SerializerWriteBasicExt((new Datas[]{ + Datas.DOUBLE, + Datas.STRING, + Datas.STRING + }), + new int[]{ + 0, 1, 2} + )); + + sentence.exec(newValues); + } + + /** + * Reset existing Product Current Quantity to Zero + * + * @param LocationID + * @param ProductID + * @param Units + * @throws com.unicenta.basic.BasicException + */ + public void deleteStockCurrent(String LocationID, String ProductID, Double Units) throws BasicException { + + Object[] oldValues = new Object[3]; + oldValues[0] = (double) Units; + oldValues[1] = LocationID; + oldValues[2] = ProductID; + + PreparedSentence sentence = new PreparedSentence(s, + "UPDATE stockcurrent SET " + + "UNITS = ? " + + "WHERE LOCATION = ? " + + "AND PRODUCT = ?" + , new SerializerWriteBasicExt((new Datas[]{ + Datas.DOUBLE, + Datas.STRING, + Datas.STRING + }), + new int[]{ + 0, 1, 2} + )); + + sentence.exec(oldValues); + } + + /** + * Add Product Update log entry - Updates only + * + * @param LocationID + * @param Units + */ + public void CSVStockUpdate(String LocationID, String Code, Double Units) { + + Object[] myprod = new Object[6]; + myprod[0] = UUID.randomUUID().toString(); // ID string + myprod[1] = Integer.toString(currentRecord); // Record number + myprod[2] = "Qty update"; // Error description + myprod[3] = Location; // Location ID + myprod[4] = productBarcode; // Product Barcode + myprod[5] = newQty; // Product Quantity + + try { + m_dlSystem.execCSVStockUpdate(myprod); + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + } + + /** + * Pushes the Import process into a new thread so it doesn't interfere with + * the UI responsiveness. + */ + private void setWorker() { + progress = 0; + webPBar.setStringPainted(true); + + final SwingWorker<Integer, Integer> pbWorker; + pbWorker = new SwingWorker<Integer, Integer>() { + + @Override + protected final Integer doInBackground() throws Exception { + while ((progress >= 0) && (progress < 100)) { + Thread.sleep(50); + this.publish(progress); + } + this.publish(100); + this.done(); + return 100; + } + + @Override + protected final void process(final List<Integer> chunks) { + webPBar.setValue(chunks.get(0)); + if (progress > 100) { + progress = 100; + webPBar.setString("Imported 100%"); + } else { + webPBar.setString("Imported " + progress + "%"); + } + } + }; + pbWorker.execute(); + } + + /** + * Runs the setWorker. + */ + private class workProcess implements Runnable { + + @Override + public void run() { + try { + ImportCsvFile(jFileName.getText()); + } catch (IOException ex) { + log.error(ex.getMessage()); + } + } + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jFileChooserPanel = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + jFileName = new javax.swing.JTextField(); + jLabel18 = new javax.swing.JLabel(); + jbtnFileChoose = new javax.swing.JButton(); + jComboSeparator = new javax.swing.JComboBox(); + jFileRead = new javax.swing.JButton(); + jPanel2 = new javax.swing.JPanel(); + jLabel9 = new javax.swing.JLabel(); + jTextUpdates = new javax.swing.JLabel(); + jTextRecords = new javax.swing.JTextField(); + jTextUpdate = new javax.swing.JTextField(); + webPBar = new com.alee.laf.progressbar.WebProgressBar(); + m_jLocation = new javax.swing.JLabel(); + jImport = new javax.swing.JButton(); + jbtnReset = new javax.swing.JButton(); + jLabel2 = new javax.swing.JLabel(); + + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + setOpaque(false); + setPreferredSize(new java.awt.Dimension(700, 350)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jLabel1.setText(bundle.getString("label.csvfile")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(100, 30)); + + jFileName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jFileName.setPreferredSize(new java.awt.Dimension(300, 30)); + jFileName.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jFileNameActionPerformed(evt); + } + }); + + jLabel18.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel18.setText(bundle.getString("label.csvdelimit")); // NOI18N + jLabel18.setPreferredSize(new java.awt.Dimension(100, 30)); + + jbtnFileChoose.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/fileopen.png"))); // NOI18N + jbtnFileChoose.setMaximumSize(new java.awt.Dimension(64, 32)); + jbtnFileChoose.setMinimumSize(new java.awt.Dimension(64, 32)); + jbtnFileChoose.setPreferredSize(new java.awt.Dimension(80, 45)); + jbtnFileChoose.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnFileChooseActionPerformed(evt); + } + }); + + jComboSeparator.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jComboSeparator.setPreferredSize(new java.awt.Dimension(50, 30)); + + javax.swing.GroupLayout jFileChooserPanelLayout = new javax.swing.GroupLayout(jFileChooserPanel); + jFileChooserPanel.setLayout(jFileChooserPanelLayout); + jFileChooserPanelLayout.setHorizontalGroup( + jFileChooserPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jFileChooserPanelLayout.createSequentialGroup() + .addGroup(jFileChooserPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jFileChooserPanelLayout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jFileName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jFileChooserPanelLayout.createSequentialGroup() + .addComponent(jLabel18, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jbtnFileChoose, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) + ); + jFileChooserPanelLayout.setVerticalGroup( + jFileChooserPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jFileChooserPanelLayout.createSequentialGroup() + .addGroup(jFileChooserPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jFileName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jFileChooserPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel18, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jComboSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jbtnFileChoose, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + + jFileRead.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jFileRead.setText(bundle.getString("label.csvread")); // NOI18N + jFileRead.setEnabled(false); + jFileRead.setPreferredSize(new java.awt.Dimension(85, 45)); + jFileRead.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jFileReadActionPerformed(evt); + } + }); + + jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(new javax.swing.border.LineBorder(new java.awt.Color(153, 153, 153), 1, true), bundle.getString("title.CSVImport"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Arial", 1, 14), new java.awt.Color(102, 102, 102))); // NOI18N + + jLabel9.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel9.setText(bundle.getString("label.csvrecordsfound")); // NOI18N + jLabel9.setPreferredSize(new java.awt.Dimension(150, 30)); + + jTextUpdates.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTextUpdates.setText(bundle.getString("label.csvchanged")); // NOI18N + jTextUpdates.setPreferredSize(new java.awt.Dimension(150, 30)); + + jTextRecords.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTextRecords.setForeground(new java.awt.Color(102, 102, 102)); + jTextRecords.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + jTextRecords.setBorder(null); + jTextRecords.setDisabledTextColor(new java.awt.Color(0, 0, 0)); + jTextRecords.setEnabled(false); + jTextRecords.setPreferredSize(new java.awt.Dimension(100, 30)); + + jTextUpdate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTextUpdate.setForeground(new java.awt.Color(102, 102, 102)); + jTextUpdate.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + jTextUpdate.setBorder(null); + jTextUpdate.setDisabledTextColor(new java.awt.Color(0, 0, 0)); + jTextUpdate.setEnabled(false); + jTextUpdate.setPreferredSize(new java.awt.Dimension(100, 30)); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jTextRecords, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(jTextUpdates, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jTextUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(0, 0, 0) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextRecords, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextUpdates, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(47, 47, 47)) + ); + + webPBar.setFont(new java.awt.Font("Arial", 0, 13)); // NOI18N + webPBar.setPreferredSize(new java.awt.Dimension(240, 30)); + + m_jLocation.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jLocation.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + m_jLocation.setText(bundle.getString("label.location")); // NOI18N + m_jLocation.setPreferredSize(new java.awt.Dimension(100, 30)); + + jImport.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jImport.setText(bundle.getString("label.csvimpostbtn")); // NOI18N + jImport.setEnabled(false); + jImport.setPreferredSize(new java.awt.Dimension(85, 45)); + jImport.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jImportActionPerformed(evt); + } + }); + + jbtnReset.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnReset.setText(bundle.getString("button.reset")); // NOI18N + jbtnReset.setPreferredSize(new java.awt.Dimension(85, 45)); + jbtnReset.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnResetActionPerformed(evt); + } + }); + + jLabel2.setBackground(new java.awt.Color(255, 255, 255)); + jLabel2.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel2.setText(bundle.getString("label.csvnotice")); // NOI18N + jLabel2.setVerticalAlignment(javax.swing.SwingConstants.TOP); + jLabel2.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(153, 153, 153))); + jLabel2.setOpaque(true); + jLabel2.setPreferredSize(new java.awt.Dimension(710, 110)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(10, 10, 10) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jFileChooserPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 0, 0) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(m_jLocation, javax.swing.GroupLayout.PREFERRED_SIZE, 295, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createSequentialGroup() + .addComponent(jFileRead, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jImport, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jbtnReset, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED))) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(webPBar, javax.swing.GroupLayout.PREFERRED_SIZE, 284, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(19, 19, 19) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jFileChooserPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jLocation, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jFileRead, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jImport, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jbtnReset, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(layout.createSequentialGroup() + .addComponent(webPBar, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(10, 10, 10) + .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + private void jFileReadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jFileReadActionPerformed + try { + checkFile(jFileName.getText()); + webPBar.setString("Source file OK"); + m_jLocation.setEnabled(true); + } catch (IOException ex) { + log.error(ex.getMessage()); + webPBar.setString("Source file error!"); + m_jLocation.setEnabled(false); + } + }//GEN-LAST:event_jFileReadActionPerformed + + private void jFileNameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jFileNameActionPerformed + jImport.setEnabled(false); + jFileRead.setEnabled(true); + }//GEN-LAST:event_jFileNameActionPerformed + + private void jbtnFileChooseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnFileChooseActionPerformed + resetForm(); + setWorker(); + + JFileChooser chooser = new JFileChooser(last_folder == null ? "C:\\" : last_folder); + FileNameExtensionFilter filter = new FileNameExtensionFilter("csv files", "csv"); + chooser.setFileFilter(filter); + chooser.showOpenDialog(null); + File csvFile = chooser.getSelectedFile(); + + if (csvFile == null) { + return; + } + + File current_folder = chooser.getCurrentDirectory(); + + if (last_folder == null || !last_folder.equals(current_folder.getAbsolutePath())) { + AppConfig CSVConfig = new AppConfig(config_file); + CSVConfig.load(); + CSVConfig.setProperty("CSV.last_folder", current_folder.getAbsolutePath()); + last_folder = current_folder.getAbsolutePath(); + try { + CSVConfig.save(); + } catch (IOException ex) { + log.error(ex.getMessage()); + } + } + + String csv = csvFile.getName(); + if (!(csv.trim().equals(""))) { + csvFileName = csvFile.getAbsolutePath(); + jFileName.setText(csvFileName); + jFileRead.setEnabled(true); + } + }//GEN-LAST:event_jbtnFileChooseActionPerformed + + private void jbtnResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnResetActionPerformed + resetForm(); + progress = 0; + webPBar.setString("Waiting..."); + }//GEN-LAST:event_jbtnResetActionPerformed + + private void jImportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jImportActionPerformed + + jFileRead.setEnabled(false); + jImport.setEnabled(false); + + workProcess work = new workProcess(); + Thread thread2 = new Thread(work); + thread2.start(); + }//GEN-LAST:event_jImportActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JComboBox jComboSeparator; + private javax.swing.JPanel jFileChooserPanel; + private javax.swing.JTextField jFileName; + private javax.swing.JButton jFileRead; + private javax.swing.JButton jImport; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel18; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel9; + private javax.swing.JPanel jPanel2; + private javax.swing.JTextField jTextRecords; + private javax.swing.JTextField jTextUpdate; + private javax.swing.JLabel jTextUpdates; + private javax.swing.JButton jbtnFileChoose; + private javax.swing.JButton jbtnReset; + private javax.swing.JLabel m_jLocation; + private com.alee.laf.progressbar.WebProgressBar webPBar; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/instance/AppMessage.java b/src/main/java/com/unicenta/pos/instance/AppMessage.java new file mode 100644 index 0000000..194e0a5 --- /dev/null +++ b/src/main/java/com/unicenta/pos/instance/AppMessage.java @@ -0,0 +1,36 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.instance; + +import java.rmi.Remote; +import java.rmi.RemoteException; + +/** + * + * @author adrianromero + */ +public interface AppMessage extends Remote { + + /** + * + * @throws RemoteException + */ + public void restoreWindow() throws RemoteException; +} diff --git a/src/main/java/com/unicenta/pos/instance/InstanceManager.java b/src/main/java/com/unicenta/pos/instance/InstanceManager.java new file mode 100644 index 0000000..b43a9c4 --- /dev/null +++ b/src/main/java/com/unicenta/pos/instance/InstanceManager.java @@ -0,0 +1,52 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.instance; + +import java.rmi.AlreadyBoundException; +import java.rmi.RemoteException; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; +import java.rmi.server.UnicastRemoteObject; + +/** + * + * @author adrianromero + */ +public class InstanceManager { + + private final Registry m_registry; + private final AppMessage m_message; + + /** Creates a new instance of InstanceManager + * @param message + * @throws java.rmi.RemoteException + * @throws java.rmi.AlreadyBoundException */ + public InstanceManager(AppMessage message) throws RemoteException, AlreadyBoundException { + + m_registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT); + + m_message = message; + + AppMessage stub = (AppMessage) UnicastRemoteObject.exportObject(m_message, 0); + m_registry.bind("AppMessage", stub); + + // jLabel1.setText("Server ready"); + } +} diff --git a/src/main/java/com/unicenta/pos/instance/InstanceQuery.java b/src/main/java/com/unicenta/pos/instance/InstanceQuery.java new file mode 100644 index 0000000..9fbf002 --- /dev/null +++ b/src/main/java/com/unicenta/pos/instance/InstanceQuery.java @@ -0,0 +1,51 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.instance; + +import java.rmi.NotBoundException; +import java.rmi.RemoteException; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; + +/** + * + * @author adrianromero + */ +public class InstanceQuery { + + private final AppMessage m_appstub; + + /** Creates a new instance of InstanceQuery + * @throws java.rmi.RemoteException + * @throws java.rmi.NotBoundException */ + public InstanceQuery() throws RemoteException, NotBoundException { + + Registry registry = LocateRegistry.getRegistry(); + m_appstub = (AppMessage) registry.lookup("AppMessage"); + } + + /** + * + * @return + */ + public AppMessage getAppMessage() { + return m_appstub; + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/AttributeFilter.form b/src/main/java/com/unicenta/pos/inventory/AttributeFilter.form new file mode 100644 index 0000000..5f9f639 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/AttributeFilter.form @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel8" min="-2" pref="110" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jAttr" min="-2" pref="220" max="-2" attributes="0"/> + <EmptySpace min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="jAttr" max="32767" attributes="0"/> + <Component id="jLabel8" max="32767" attributes="0"/> + </Group> + <EmptySpace pref="17" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.attribute" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="jAttr"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[220, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jAttrActionPerformed"/> + </Events> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/AttributeFilter.java b/src/main/java/com/unicenta/pos/inventory/AttributeFilter.java new file mode 100644 index 0000000..069bd9f --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/AttributeFilter.java @@ -0,0 +1,177 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.loader.*; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.reports.ReportEditorCreator; +import java.awt.Component; +import java.awt.event.ActionListener; +import java.util.List; + +/** + * + * @author adrianromero + */ +public class AttributeFilter extends javax.swing.JPanel implements ReportEditorCreator { + + private SentenceList attsent; + private ComboBoxValModel attmodel; + + /** Creates new form AttributeUseFilter */ + public AttributeFilter() { + initComponents(); + } + + /** + * + * @param app + */ + @Override + public void init(AppView app) { + + attsent = new StaticSentence(app.getSession() + , "SELECT ID, NAME FROM attribute ORDER BY NAME" + , null + , new SerializerRead() {@Override + public Object readValues(DataRead dr) throws BasicException { + return new AttributeInfo(dr.getString(1), dr.getString(2)); + }}); + attmodel = new ComboBoxValModel(); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + List a = attsent.list(); + attmodel = new ComboBoxValModel(a); + attmodel.setSelectedFirst(); + jAttr.setModel(attmodel); + } + + /** + * + * @return + */ + @Override + public SerializerWrite getSerializerWrite() { + return SerializerWriteString.INSTANCE; + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @param l + */ + public void addActionListener(ActionListener l) { + jAttr.addActionListener(l); + } + + /** + * + * @param l + */ + public void removeActionListener(ActionListener l) { + jAttr.removeActionListener(l); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + AttributeInfo att = (AttributeInfo) attmodel.getSelectedItem(); + + return att == null ? null : att.getId(); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel8 = new javax.swing.JLabel(); + jAttr = new javax.swing.JComboBox(); + + jLabel8.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel8.setText(AppLocal.getIntString("label.attribute")); // NOI18N + jLabel8.setPreferredSize(new java.awt.Dimension(110, 30)); + + jAttr.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jAttr.setPreferredSize(new java.awt.Dimension(220, 30)); + jAttr.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jAttrActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jAttr, javax.swing.GroupLayout.PREFERRED_SIZE, 220, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jAttr, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel8, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(17, Short.MAX_VALUE)) + ); + }// </editor-fold>//GEN-END:initComponents + + private void jAttrActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jAttrActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jAttrActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JComboBox jAttr; + private javax.swing.JLabel jLabel8; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/inventory/AttributeInfo.java b/src/main/java/com/unicenta/pos/inventory/AttributeInfo.java new file mode 100644 index 0000000..4bee510 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/AttributeInfo.java @@ -0,0 +1,62 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.data.loader.IKeyed; + +/** + * + * @author adrianromero + */ +public class AttributeInfo implements IKeyed { + + private String id; + private String name; + + /** Creates new CategoryInfo + * @param id + * @param name */ + public AttributeInfo(String id, String name) { + this.id = id; + this.name = name; + } + + /** + * + * @return + */ + @Override + public Object getKey() { + return id; + } + + /** + * + * @return + */ + public String getId() { + return id; + } + + @Override + public String toString() { + return name; + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/AttributeSetFilter.form b/src/main/java/com/unicenta/pos/inventory/AttributeSetFilter.form new file mode 100644 index 0000000..9a66a1a --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/AttributeSetFilter.form @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[354, 61]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel8" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jAttrSet" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel8" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jAttrSet" alignment="3" max="32767" attributes="0"/> + </Group> + <EmptySpace pref="20" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.attributeset" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="jAttrSet"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[220, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/AttributeSetFilter.java b/src/main/java/com/unicenta/pos/inventory/AttributeSetFilter.java new file mode 100644 index 0000000..a71e4b7 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/AttributeSetFilter.java @@ -0,0 +1,170 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.loader.*; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.reports.ReportEditorCreator; +import java.awt.Component; +import java.awt.event.ActionListener; +import java.util.List; + +/** + * + * @author adrianromero + */ +public class AttributeSetFilter extends javax.swing.JPanel implements ReportEditorCreator { + + private SentenceList attusesent; + private ComboBoxValModel attusemodel; + + /** Creates new form AttributeUseFilter */ + public AttributeSetFilter() { + initComponents(); + } + + /** + * + * @param app + */ + @Override + public void init(AppView app) { + + attusesent = new StaticSentence(app.getSession() + , "SELECT ID, NAME FROM attributeset ORDER BY NAME" + , null + , new SerializerRead() {@Override + public Object readValues(DataRead dr) throws BasicException { + return new AttributeSetInfo(dr.getString(1), dr.getString(2)); + }}); + attusemodel = new ComboBoxValModel(); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + List a = attusesent.list(); + attusemodel = new ComboBoxValModel(a); + attusemodel.setSelectedFirst(); + jAttrSet.setModel(attusemodel); + } + + /** + * + * @return + */ + @Override + public SerializerWrite getSerializerWrite() { + return SerializerWriteString.INSTANCE; + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @param l + */ + public void addActionListener(ActionListener l) { + jAttrSet.addActionListener(l); + } + + /** + * + * @param l + */ + public void removeActionListener(ActionListener l) { + jAttrSet.removeActionListener(l); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + AttributeSetInfo attset = (AttributeSetInfo) attusemodel.getSelectedItem(); + + return attset == null ? null : attset.getId(); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel8 = new javax.swing.JLabel(); + jAttrSet = new javax.swing.JComboBox(); + + setPreferredSize(new java.awt.Dimension(354, 61)); + + jLabel8.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel8.setText(AppLocal.getIntString("label.attributeset")); // NOI18N + jLabel8.setPreferredSize(new java.awt.Dimension(110, 30)); + + jAttrSet.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jAttrSet.setPreferredSize(new java.awt.Dimension(220, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jAttrSet, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jAttrSet, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(20, Short.MAX_VALUE)) + ); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JComboBox jAttrSet; + private javax.swing.JLabel jLabel8; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/inventory/AttributeSetInfo.java b/src/main/java/com/unicenta/pos/inventory/AttributeSetInfo.java new file mode 100644 index 0000000..0f8973f --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/AttributeSetInfo.java @@ -0,0 +1,72 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.data.loader.IKeyed; + +/** + * + * @author adrianromero + */ +public class AttributeSetInfo implements IKeyed { + + private String id; + private String name; + + /** + * + * @param id + * @param name + */ + public AttributeSetInfo(String id, String name) { + this.id = id; + this.name = name; + } + + /** + * + * @return + */ + @Override + public Object getKey() { + return id; + } + + /** + * + * @return + */ + public String getId() { + return id; + } + + /** + * + * @return + */ + public String getName() { + return name; + } + + @Override + public String toString() { + return name; + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/AttributeSetsEditor.form b/src/main/java/com/unicenta/pos/inventory/AttributeSetsEditor.form new file mode 100644 index 0000000..b774be8 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/AttributeSetsEditor.form @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jName" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.namem" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[220, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/AttributeSetsEditor.java b/src/main/java/com/unicenta/pos/inventory/AttributeSetsEditor.java new file mode 100644 index 0000000..bf00912 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/AttributeSetsEditor.java @@ -0,0 +1,179 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import java.awt.Component; +import java.util.UUID; +import javax.swing.JOptionPane; + +/** + * + * @author adrianromero + */ +public final class AttributeSetsEditor extends javax.swing.JPanel implements EditorRecord { + + private Object id; + + /** Creates new form AttributesEditor + * @param dirty */ + public AttributeSetsEditor(DirtyManager dirty) { + initComponents(); + + m_jName.getDocument().addDocumentListener(dirty); + + writeValueEOF(); + } + + /** + * + */ + @Override + public void writeValueEOF() { + id = null; + m_jName.setText(null); + m_jName.setEnabled(false); + } + + /** + * + */ + @Override + public void writeValueInsert() { + id = UUID.randomUUID().toString(); + m_jName.setText(null); + m_jName.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueDelete(Object value) { + + Object[] attrset = (Object[]) value; + id = attrset[0]; + m_jName.setText(Formats.STRING.formatValue(attrset[1])); + m_jName.setEnabled(false); + } + + /** + * + * @param value + */ + @Override + public void writeValueEdit(Object value) { + + Object[] attrset = (Object[]) value; + id = attrset[0]; + m_jName.setText(Formats.STRING.formatValue(attrset[1])); + m_jName.setEnabled(true); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + Object[] attrset = new Object[2]; + + attrset[0] = id; + attrset[1] = m_jName.getText(); + + if (m_jName.getText().contains("&")) { + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.ampersand")); + } + + return attrset; + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + */ + @Override + public void refresh() { + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel2 = new javax.swing.JLabel(); + m_jName = new javax.swing.JTextField(); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.namem")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(220, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel2; + private javax.swing.JTextField m_jName; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/inventory/AttributeSetsPanel.java b/src/main/java/com/unicenta/pos/inventory/AttributeSetsPanel.java new file mode 100644 index 0000000..859662f --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/AttributeSetsPanel.java @@ -0,0 +1,80 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.data.loader.Datas; +import com.unicenta.data.model.*; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.panels.JPanelTable2; + +/** + * + * @author adrianromero + */ +public class AttributeSetsPanel extends JPanelTable2 { + + private EditorRecord editor; + + /** Creates a new instance of JPanelCategories */ + public AttributeSetsPanel() { + } + + /** + * + */ + @Override + protected void init() { + + row = new Row( + new Field("ID", Datas.STRING, Formats.STRING), + new Field(AppLocal.getIntString("label.name"), Datas.STRING, Formats.STRING, true, true, true) + ); + + Table table = new Table( + "attributeset", + new PrimaryKey("ID"), + new Column("NAME")); + + lpr = row.getListProvider(app.getSession(), table); + spr = row.getSaveProvider(app.getSession(), table); + + editor = new AttributeSetsEditor(dirty); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return editor; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.AttributeSets"); + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/AttributeUseEditor.form b/src/main/java/com/unicenta/pos/inventory/AttributeUseEditor.form new file mode 100644 index 0000000..1b9ae99 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/AttributeUseEditor.form @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jLineno" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel4" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jAttribute" min="-2" pref="170" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel3" alignment="3" min="-2" pref="25" max="-2" attributes="0"/> + <Component id="jLineno" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jAttribute" alignment="3" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.order" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jLineno"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.attribute" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="jAttribute"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/AttributeUseEditor.java b/src/main/java/com/unicenta/pos/inventory/AttributeUseEditor.java new file mode 100644 index 0000000..8e0db9c --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/AttributeUseEditor.java @@ -0,0 +1,261 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.loader.SerializerRead; +import com.unicenta.data.loader.StaticSentence; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import java.awt.Component; +import java.util.UUID; + +/** + * + * @author adrianromero + */ +public class AttributeUseEditor extends javax.swing.JPanel implements EditorRecord { + + private SentenceList attributesent; + private ComboBoxValModel attributemodel; + + private Object id; + private Object attuseid; + + private Object insertid; + + /** Creates new form AttributeSetEditor + * @param app + * @param dirty */ + public AttributeUseEditor(AppView app, DirtyManager dirty) { + + attributesent = new StaticSentence(app.getSession() + , "SELECT ID, NAME FROM attribute ORDER BY NAME" + , null + , new SerializerRead() {@Override + public Object readValues(DataRead dr) throws BasicException { + return new AttributeInfo(dr.getString(1), dr.getString(2)); + }} + ); + attributemodel = new ComboBoxValModel(); + + initComponents(); + + jLineno.getDocument().addDocumentListener(dirty); + jAttribute.addActionListener(dirty); + } + + /** + * + * @param insertid + */ + public void setInsertId(String insertid) { + + this.insertid = insertid; + } + + /** + * + * @throws BasicException + */ + public void activate() throws BasicException { + + attributemodel = new ComboBoxValModel(attributesent.list()); + jAttribute.setModel(attributemodel); + } + + /** + * + */ + @Override + public void refresh() { + } + + /** + * + */ + @Override + public void writeValueEOF() { + + id = null; + attuseid = null; + attributemodel.setSelectedKey(null); + jLineno.setText(null); + + jAttribute.setEnabled(false); + jLineno.setEnabled(false); + } + + /** + * + */ + @Override + public void writeValueInsert() { + + id = UUID.randomUUID().toString(); + attuseid = insertid; + attributemodel.setSelectedKey(null); + jLineno.setText(null); + + jAttribute.setEnabled(true); + jLineno.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueEdit(Object value) { + + Object[] obj = (Object[]) value; + + id = obj[0]; + attuseid = obj[1]; + attributemodel.setSelectedKey(obj[2]); + jLineno.setText(Formats.INT.formatValue(obj[3])); + + jAttribute.setEnabled(true); + jLineno.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueDelete(Object value) { + + Object[] obj = (Object[]) value; + + id = obj[0]; + attuseid = obj[1]; + attributemodel.setSelectedKey(obj[2]); + jLineno.setText(Formats.INT.formatValue(obj[3])); + + jAttribute.setEnabled(false); + jLineno.setEnabled(false); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + Object[] value = new Object[5]; + + value[0] = id; + value[1] = attuseid; + value[2] = attributemodel.getSelectedKey(); + value[3] = Formats.INT.parseValue(jLineno.getText()); + value[4] = attributemodel.getSelectedText(); + + return value; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel3 = new javax.swing.JLabel(); + jLineno = new javax.swing.JTextField(); + jLabel4 = new javax.swing.JLabel(); + jAttribute = new javax.swing.JComboBox(); + + setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.order")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLineno.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLineno.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.attribute")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(110, 30)); + + jAttribute.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jAttribute.setPreferredSize(new java.awt.Dimension(0, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLineno, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jAttribute, javax.swing.GroupLayout.PREFERRED_SIZE, 170, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLineno, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jAttribute, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JComboBox jAttribute; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JTextField jLineno; + // End of variables declaration//GEN-END:variables + + +} diff --git a/src/main/java/com/unicenta/pos/inventory/AttributeUsePanel.java b/src/main/java/com/unicenta/pos/inventory/AttributeUsePanel.java new file mode 100644 index 0000000..7fd6f81 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/AttributeUsePanel.java @@ -0,0 +1,134 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.model.*; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.panels.JPanelTable2; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * + * @author adrianromero + */ +public class AttributeUsePanel extends JPanelTable2 { + + private AttributeUseEditor editor; + private AttributeSetFilter filter; + + /** + * + */ + @Override + protected void init() { + + filter = new AttributeSetFilter(); + filter.init(app); + filter.addActionListener(new ReloadActionListener()); + + row = new Row( + new Field("ID", Datas.STRING, Formats.STRING), + new Field("ATRIBUTESET_ID", Datas.STRING, Formats.STRING), + new Field("ATTRIBUTE_ID", Datas.STRING, Formats.STRING), + new Field(AppLocal.getIntString("label.order"), Datas.INT, Formats.INT, false, true, true), + new Field(AppLocal.getIntString("label.name"), Datas.STRING, Formats.STRING, true, true, true) + ); + + Table table = new Table( + "attributeuse", + new PrimaryKey("ID"), + new Column("attributeset_ID"), + new Column("ATTRIBUTE_ID"), + new Column("LINENO")); + + lpr = row.getListProvider(app.getSession(), + "SELECT ATTUSE.ID, ATTUSE.attributeset_ID, ATTUSE.ATTRIBUTE_ID, ATTUSE.LINENO, ATT.NAME " + + "FROM attributeuse ATTUSE, attribute ATT " + + "WHERE ATTUSE.ATTRIBUTE_ID = ATT.ID AND ATTUSE.attributeset_ID = ? ORDER BY LINENO", filter); + spr = row.getSaveProvider(app.getSession(), table); + + editor = new AttributeUseEditor(app, dirty); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + filter.activate(); + editor.activate(); + + //super.activate(); + startNavigation(); + reload(); + } + + /** + * + * @return + */ + @Override + public Component getFilter(){ + return filter.getComponent(); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return editor; + } + + private void reload() throws BasicException { + + String attsetid = (String) filter.createValue(); + editor.setInsertId(attsetid); // must be set before load + bd.setEditable(attsetid != null); + bd.actionLoad(); + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.AttributeUse"); + } + + private class ReloadActionListener implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + try { + reload(); + } catch (BasicException w) { + } + } + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/AttributeValuesEditor.form b/src/main/java/com/unicenta/pos/inventory/AttributeValuesEditor.form new file mode 100644 index 0000000..2d3ec9d --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/AttributeValuesEditor.form @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel2" min="-2" pref="80" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jValue" min="-2" pref="200" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jValue" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.value" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jValue"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[220, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/AttributeValuesEditor.java b/src/main/java/com/unicenta/pos/inventory/AttributeValuesEditor.java new file mode 100644 index 0000000..e968e5e --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/AttributeValuesEditor.java @@ -0,0 +1,196 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import java.awt.Component; +import java.util.UUID; + +/** + * + * @author adrian + */ +public class AttributeValuesEditor extends javax.swing.JPanel implements EditorRecord { + + private Object id; + private Object attid; + + private Object insertid; + + /** Creates new form AttributesValuesEditor + * @param dirty */ + public AttributeValuesEditor(DirtyManager dirty) { + + initComponents(); + + jValue.getDocument().addDocumentListener(dirty); + } + + /** + * + * @param insertid + */ + public void setInsertId(String insertid) { + + this.insertid = insertid; + } + + /** + * + */ + @Override + public void refresh() { + } + + /** + * + */ + @Override + public void writeValueEOF() { + + id = null; + attid = null; + jValue.setText(null); + + jValue.setEnabled(false); + } + + /** + * + */ + @Override + public void writeValueInsert() { + + id = UUID.randomUUID().toString(); + attid = insertid; + jValue.setText(null); + + jValue.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueEdit(Object value) { + + Object[] obj = (Object[]) value; + + id = obj[0]; + attid = obj[1]; + jValue.setText(Formats.STRING.formatValue(obj[2])); + + jValue.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueDelete(Object value) { + + Object[] obj = (Object[]) value; + + id = obj[0]; + attid = obj[1]; + jValue.setText(Formats.STRING.formatValue(obj[2])); + + jValue.setEnabled(false); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + return new Object[] { + id, + attid, + Formats.STRING.formatValue(jValue.getText()) + }; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel2 = new javax.swing.JLabel(); + jValue = new javax.swing.JTextField(); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.value")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(110, 30)); + + jValue.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jValue.setPreferredSize(new java.awt.Dimension(220, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jValue, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel2; + private javax.swing.JTextField jValue; + // End of variables declaration//GEN-END:variables + + +} diff --git a/src/main/java/com/unicenta/pos/inventory/AttributeValuesPanel.java b/src/main/java/com/unicenta/pos/inventory/AttributeValuesPanel.java new file mode 100644 index 0000000..27c61d7 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/AttributeValuesPanel.java @@ -0,0 +1,128 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.model.*; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.panels.JPanelTable2; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * + * @author adrianromero + */ +public class AttributeValuesPanel extends JPanelTable2 { + + private AttributeValuesEditor editor; + private AttributeFilter filter; + + /** + * + */ + @Override + protected void init() { + + filter = new AttributeFilter(); + filter.init(app); + filter.addActionListener(new ReloadActionListener()); + + row = new Row( + new Field("ID", Datas.STRING, Formats.STRING), + new Field("ATTRIBUTE_ID", Datas.STRING, Formats.STRING), + new Field(AppLocal.getIntString("label.value"), Datas.STRING, Formats.STRING, true, true, true) + ); + + Table table = new Table( + "attributevalue", + new PrimaryKey("ID"), + new Column("ATTRIBUTE_ID"), + new Column("VALUE")); + + lpr = row.getListProvider(app.getSession(), + "SELECT ID, ATTRIBUTE_ID, VALUE FROM attributevalue WHERE ATTRIBUTE_ID = ? ORDER BY VALUE ", filter); + spr = row.getSaveProvider(app.getSession(), table); + + editor = new AttributeValuesEditor(dirty); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + filter.activate(); + + //super.activate(); + startNavigation(); + reload(); + } + + /** + * + * @return + */ + @Override + public Component getFilter(){ + return filter.getComponent(); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return editor; + } + + private void reload() throws BasicException { + + String attid = (String) filter.createValue(); + editor.setInsertId(attid); // must be set before load + bd.setEditable(attid != null); + bd.actionLoad(); + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.AttributeValues"); + } + + private class ReloadActionListener implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + try { + reload(); + } catch (BasicException w) { + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/inventory/AttributesEditor.form b/src/main/java/com/unicenta/pos/inventory/AttributesEditor.form new file mode 100644 index 0000000..da093ec --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/AttributesEditor.form @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.6" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jName" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.name" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[220, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/AttributesEditor.java b/src/main/java/com/unicenta/pos/inventory/AttributesEditor.java new file mode 100644 index 0000000..fe7ea25 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/AttributesEditor.java @@ -0,0 +1,179 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import java.awt.Component; +import java.util.UUID; +import javax.swing.JOptionPane; + +/** + * + * @author adrian + */ +public final class AttributesEditor extends javax.swing.JPanel implements EditorRecord { + + private Object id; + + /** Creates new form AttributesEditor + * @param dirty */ + public AttributesEditor(DirtyManager dirty) { + initComponents(); + + m_jName.getDocument().addDocumentListener(dirty); + + writeValueEOF(); + } + + /** + * + */ + @Override + public void writeValueEOF() { + id = null; + m_jName.setText(null); + m_jName.setEnabled(false); + } + + /** + * + */ + @Override + public void writeValueInsert() { + id = UUID.randomUUID().toString(); + m_jName.setText(null); + m_jName.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueDelete(Object value) { + + Object[] attr = (Object[]) value; + id = attr[0]; + m_jName.setText(Formats.STRING.formatValue(attr[1])); + m_jName.setEnabled(false); + } + + /** + * + * @param value + */ + @Override + public void writeValueEdit(Object value) { + + Object[] attr = (Object[]) value; + id = attr[0]; + m_jName.setText(Formats.STRING.formatValue(attr[1])); + m_jName.setEnabled(true); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + Object[] attr = new Object[2]; + + attr[0] = id; + attr[1] = m_jName.getText(); + + if (m_jName.getText().contains("&")) { + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.ampersand")); + } + + return attr; + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + */ + @Override + public void refresh() { + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel2 = new javax.swing.JLabel(); + m_jName = new javax.swing.JTextField(); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.name")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(220, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel2; + private javax.swing.JTextField m_jName; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/inventory/AttributesPanel.java b/src/main/java/com/unicenta/pos/inventory/AttributesPanel.java new file mode 100644 index 0000000..11b7afa --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/AttributesPanel.java @@ -0,0 +1,80 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.data.loader.Datas; +import com.unicenta.data.model.*; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.panels.JPanelTable2; + +/** + * + * @author adrian + */ +public class AttributesPanel extends JPanelTable2 { + + private EditorRecord editor; + + /** Creates a new instance of JPanelCategories */ + public AttributesPanel() { + } + + /** + * + */ + @Override + protected void init() { + + row = new Row( + new Field("ID", Datas.STRING, Formats.STRING), + new Field(AppLocal.getIntString("label.name"), Datas.STRING, Formats.STRING, true, true, true) + ); + + Table table = new Table( + "attribute", + new PrimaryKey("ID"), + new Column("NAME")); + + lpr = row.getListProvider(app.getSession(), table); + spr = row.getSaveProvider(app.getSession(), table); + + editor = new AttributesEditor(dirty); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return editor; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.Attributes"); + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/AuxiliarEditor.form b/src/main/java/com/unicenta/pos/inventory/AuxiliarEditor.form new file mode 100644 index 0000000..9773a4b --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/AuxiliarEditor.form @@ -0,0 +1,206 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.5" maxVersion="1.6" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[700, 100]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel4" min="-2" max="-2" attributes="0"/> + <Component id="jLabel3" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="jLabel5" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="m_jProduct" min="-2" pref="264" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jSearch" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="m_jBarcode" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jEnter2" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="m_jReference" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jEnter1" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jReference" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jEnter1" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jEnter2" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jBarcode" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jSearch" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="m_jProduct" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodref" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jReference"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jReferenceActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jEnter1"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" value=" "/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jEnter1ActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jEnter2"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/barcode.png"/> + </Property> + <Property name="text" type="java.lang.String" value=" "/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jEnter2ActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jSearch"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/search24.png"/> + </Property> + <Property name="text" type="java.lang.String" value=" "/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jSearchActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JTextField" name="m_jProduct"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jProductActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JTextField" name="m_jBarcode"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jBarcodeActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodbarcode" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodname" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/AuxiliarEditor.java b/src/main/java/com/unicenta/pos/inventory/AuxiliarEditor.java new file mode 100644 index 0000000..51e66f8 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/AuxiliarEditor.java @@ -0,0 +1,427 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.panels.JProductFinder; +import com.unicenta.pos.ticket.ProductInfoExt; +import java.awt.Component; +import java.awt.Toolkit; +import java.util.UUID; + +/** + * + * @author jaroslawwozniak + */ +public class AuxiliarEditor extends javax.swing.JPanel implements EditorRecord { + + private DataLogicSales m_dlSales; + + private Object id; + private Object product; + private Object product2; + private Object name; + + private Object insertproduct; + + /** Creates new form AuxiliarEditor + * @param app + * @param dirty */ + public AuxiliarEditor(AppView app, DirtyManager dirty) { + + m_dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + + initComponents(); + + m_jProduct.getDocument().addDocumentListener(dirty); + } + + /** + * + * @param prod + */ + public void setInsertProduct(ProductInfoExt prod) { + + if (prod == null) { + insertproduct = null; + } else { + insertproduct = prod.getID(); + } + } + + /** + * + */ + @Override + public void refresh() { + } + + /** + * + */ + @Override + public void writeValueEOF() { + + id = null; + product = null; + product2 = null; + name = null; + m_jReference.setText(null); + m_jBarcode.setText(null); + m_jProduct.setText(null); + + m_jReference.setEnabled(false); + m_jBarcode.setEnabled(false); + m_jProduct.setEnabled(false); + m_jEnter1.setEnabled(false); + m_jEnter2.setEnabled(false); + m_jSearch.setEnabled(false); + } + + /** + * + */ + @Override + public void writeValueInsert() { + + id = UUID.randomUUID().toString(); + product = insertproduct; + product2 = null; + name = null; + m_jReference.setText(null); + m_jBarcode.setText(null); + m_jProduct.setText(null); + + m_jReference.setEnabled(true); + m_jBarcode.setEnabled(true); + m_jProduct.setEnabled(true); + m_jEnter1.setEnabled(true); + m_jEnter2.setEnabled(true); + m_jSearch.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueEdit(Object value) { + Object[] obj = (Object[]) value; + + id = obj[0]; + product = obj[1]; + product2 = obj[2]; + name = obj[5]; + m_jReference.setText(Formats.STRING.formatValue(obj[3])); + m_jBarcode.setText(Formats.STRING.formatValue(obj[4])); + m_jProduct.setText(Formats.STRING.formatValue(obj[3]) + " - " + Formats.STRING.formatValue(obj[5])); + + m_jReference.setEnabled(true); + m_jBarcode.setEnabled(true); + m_jProduct.setEnabled(true); + m_jEnter1.setEnabled(true); + m_jEnter2.setEnabled(true); + m_jSearch.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueDelete(Object value) { + Object[] obj = (Object[]) value; + + id = obj[0]; + product = obj[1]; + product2 = obj[2]; + name = obj[5]; + m_jReference.setText(Formats.STRING.formatValue(obj[3])); + m_jBarcode.setText(Formats.STRING.formatValue(obj[4])); + m_jProduct.setText(Formats.STRING.formatValue(obj[3]) + " - " + Formats.STRING.formatValue(obj[5])); + + + m_jReference.setEnabled(false); + m_jBarcode.setEnabled(false); + m_jProduct.setEnabled(false); + m_jEnter1.setEnabled(false); + m_jEnter2.setEnabled(false); + m_jSearch.setEnabled(false); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + return new Object[] { + id, + product, + product2, + m_jReference.getText(), + m_jBarcode.getText(), + name, + }; + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + private void assignProduct(ProductInfoExt prod) { + + if (m_jSearch.isEnabled()) { + if (prod == null) { + product2 = null; + m_jReference.setText(null); + m_jBarcode.setText(null); + m_jProduct.setText(null); + name = null; + } else { + product2 = prod.getID(); + m_jReference.setText(prod.getReference()); + m_jBarcode.setText(prod.getCode()); + m_jProduct.setText(prod.getReference() + " - " + prod.getName()); + name = prod.getName(); + } + } + + } + + private void assignProductByCode() { + try { + ProductInfoExt prod = m_dlSales.getProductInfoByCode(m_jBarcode.getText()); + assignProduct(prod); + if (prod == null) { + Toolkit.getDefaultToolkit().beep(); + } + } catch (BasicException eData) { + assignProduct(null); + MessageInf msg = new MessageInf(eData); + msg.show(this); + } + } + + + private void assignProductByReference() { + try { + ProductInfoExt prod = m_dlSales.getProductInfoByReference(m_jReference.getText()); + assignProduct(prod); + if (prod == null) { + Toolkit.getDefaultToolkit().beep(); + } + } catch (BasicException eData) { + assignProduct(null); + MessageInf msg = new MessageInf(eData); + msg.show(this); + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel3 = new javax.swing.JLabel(); + m_jReference = new javax.swing.JTextField(); + m_jEnter1 = new javax.swing.JButton(); + m_jEnter2 = new javax.swing.JButton(); + m_jSearch = new javax.swing.JButton(); + m_jProduct = new javax.swing.JTextField(); + m_jBarcode = new javax.swing.JTextField(); + jLabel4 = new javax.swing.JLabel(); + jLabel5 = new javax.swing.JLabel(); + + setPreferredSize(new java.awt.Dimension(700, 100)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.prodref")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jReference.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jReference.setPreferredSize(new java.awt.Dimension(150, 30)); + m_jReference.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jReferenceActionPerformed(evt); + } + }); + + m_jEnter1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + m_jEnter1.setText(" "); + m_jEnter1.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jEnter1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jEnter1ActionPerformed(evt); + } + }); + + m_jEnter2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/barcode.png"))); // NOI18N + m_jEnter2.setText(" "); + m_jEnter2.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jEnter2.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jEnter2ActionPerformed(evt); + } + }); + + m_jSearch.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/search24.png"))); // NOI18N + m_jSearch.setText(" "); + m_jSearch.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jSearch.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jSearchActionPerformed(evt); + } + }); + + m_jProduct.setEditable(false); + m_jProduct.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jProduct.setPreferredSize(new java.awt.Dimension(150, 30)); + m_jProduct.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jProductActionPerformed(evt); + } + }); + + m_jBarcode.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jBarcode.setPreferredSize(new java.awt.Dimension(150, 30)); + m_jBarcode.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jBarcodeActionPerformed(evt); + } + }); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.prodbarcode")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.prodname")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(110, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(m_jProduct, javax.swing.GroupLayout.PREFERRED_SIZE, 264, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addComponent(m_jBarcode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jEnter2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addComponent(m_jReference, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jEnter1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jReference, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jEnter1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jEnter2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jBarcode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(m_jProduct, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + private void m_jSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jSearchActionPerformed + + assignProduct(JProductFinder.showMessage(this, m_dlSales, JProductFinder.PRODUCT_AUXILIAR)); + +}//GEN-LAST:event_m_jSearchActionPerformed + + private void m_jReferenceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jReferenceActionPerformed + this.assignProductByReference(); + }//GEN-LAST:event_m_jReferenceActionPerformed + + private void m_jEnter2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jEnter2ActionPerformed + this.assignProductByCode(); + }//GEN-LAST:event_m_jEnter2ActionPerformed + + private void m_jEnter1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jEnter1ActionPerformed + this.assignProductByReference(); + }//GEN-LAST:event_m_jEnter1ActionPerformed + + private void m_jBarcodeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jBarcodeActionPerformed + this.assignProductByCode(); + }//GEN-LAST:event_m_jBarcodeActionPerformed + + private void m_jProductActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jProductActionPerformed + + }//GEN-LAST:event_m_jProductActionPerformed + + + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JTextField m_jBarcode; + private javax.swing.JButton m_jEnter1; + private javax.swing.JButton m_jEnter2; + private javax.swing.JTextField m_jProduct; + private javax.swing.JTextField m_jReference; + private javax.swing.JButton m_jSearch; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/inventory/AuxiliarPanel.java b/src/main/java/com/unicenta/pos/inventory/AuxiliarPanel.java new file mode 100644 index 0000000..6f65f4b --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/AuxiliarPanel.java @@ -0,0 +1,134 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.model.*; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.panels.AuxiliarFilter; +import com.unicenta.pos.panels.JPanelTable2; +import com.unicenta.pos.ticket.ProductInfoExt; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * + * @author jaroslawwozniak + * @author adrianromero + */ +public class AuxiliarPanel extends JPanelTable2 { + + private AuxiliarEditor editor; + private AuxiliarFilter filter; + + /** + * + */ + @Override + protected void init() { + + filter = new AuxiliarFilter(); + filter.init(app); + filter.addActionListener(new ReloadActionListener()); + + row = new Row( + new Field("ID", Datas.STRING, Formats.STRING), + new Field("PRODUCT1", Datas.STRING, Formats.STRING), + new Field("PRODUCT2", Datas.STRING, Formats.STRING), + new Field(AppLocal.getIntString("label.prodref"), Datas.STRING, Formats.STRING, true, true, true), + new Field(AppLocal.getIntString("label.prodbarcode"), Datas.STRING, Formats.STRING, false, true, true), + new Field(AppLocal.getIntString("label.prodname"), Datas.STRING, Formats.STRING, true, true, true) + ); + Table table = new Table( + "products_com", + new PrimaryKey("ID"), + new Column("PRODUCT"), + new Column("PRODUCT2")); + + lpr = row.getListProvider(app.getSession(), + "SELECT COM.ID, COM.PRODUCT, COM.PRODUCT2, P.REFERENCE, P.CODE, P.NAME " + + "FROM products_com COM, products P " + + "WHERE COM.PRODUCT2 = P.ID AND COM.PRODUCT = ?", filter); + spr = row.getSaveProvider(app.getSession(), table); + + editor = new AuxiliarEditor(app, dirty); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + filter.activate(); + + //super.activate(); + startNavigation(); + reload(filter); + } + + /** + * + * @return + */ + @Override + public Component getFilter(){ + return filter.getComponent(); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return editor; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.Auxiliar"); + } + + private void reload(AuxiliarFilter filter) throws BasicException { + ProductInfoExt prod = filter.getProductInfoExt(); + editor.setInsertProduct(prod); // must be set before load + bd.setEditable(prod != null); + bd.actionLoad(); + } + + private class ReloadActionListener implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + try { + reload((AuxiliarFilter) e.getSource()); + } catch (BasicException w) { + } + } + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/BundleEditor.form b/src/main/java/com/unicenta/pos/inventory/BundleEditor.form new file mode 100644 index 0000000..a954ec1 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/BundleEditor.form @@ -0,0 +1,207 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.5" maxVersion="1.6" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[700, 120]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel4" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jBarcode" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jReference" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace min="-2" pref="10" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="m_jEnter1" max="32767" attributes="0"/> + <Component id="m_jEnter2" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Group type="102" attributes="0"> + <Component id="m_jQuantity" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jLabel1" pref="0" max="32767" attributes="0"/> + </Group> + <Component id="m_jProduct" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/> + <Component id="m_jSearch" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="2" attributes="0"> + <Component id="jLabel3" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="m_jReference" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="m_jEnter1" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="m_jProduct" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="m_jSearch" alignment="2" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="2" attributes="0"> + <Component id="m_jBarcode" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="jLabel4" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="m_jEnter2" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="m_jQuantity" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="jLabel1" alignment="2" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodref" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jReference"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jReferenceActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jEnter1"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jEnter1ActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jEnter2"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/barcode.png"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jEnter2ActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jSearch"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/search24.png"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jSearchActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JTextField" name="m_jProduct"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jProductActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JTextField" name="m_jBarcode"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jBarcodeActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodbarcode" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="Quantity"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jQuantity"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/BundleEditor.java b/src/main/java/com/unicenta/pos/inventory/BundleEditor.java new file mode 100644 index 0000000..e29481f --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/BundleEditor.java @@ -0,0 +1,412 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2013 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.panels.JProductFinder; +import com.unicenta.pos.ticket.ProductInfoExt; +import java.awt.Component; +import java.awt.Toolkit; +import java.util.UUID; + +/** + * + * @author jaroslawwozniak + */ +public class BundleEditor extends javax.swing.JPanel implements EditorRecord { + + private DataLogicSales m_dlSales; + + private Object id; + private Object product; + private Object productBundle; + private Object name; + private Object quantity; + + private Object insertproduct; + + /** Creates new form BundleEditor */ + public BundleEditor(AppView app, DirtyManager dirty) { + + m_dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + + initComponents(); + + m_jProduct.getDocument().addDocumentListener(dirty); + m_jQuantity.getDocument().addDocumentListener(dirty); + } + + public void setInsertProduct(ProductInfoExt prod) { + + if (prod == null) { + insertproduct = null; + } else { + insertproduct = prod.getID(); + } + } + + @Override + public void refresh() { + } + + @Override + public void writeValueEOF() { + + id = null; + product = null; + productBundle = null; + quantity = null; + name = null; + m_jReference.setText(null); + m_jBarcode.setText(null); + m_jProduct.setText(null); + m_jQuantity.setText(null); + + m_jReference.setEnabled(false); + m_jBarcode.setEnabled(false); + m_jProduct.setEnabled(false); + m_jQuantity.setEnabled(false); + m_jEnter1.setEnabled(false); + m_jEnter2.setEnabled(false); + m_jSearch.setEnabled(false); + } + + @Override + public void writeValueInsert() { + + id = UUID.randomUUID().toString(); + product = insertproduct; + productBundle = null; + name = null; + quantity = null; + m_jReference.setText(null); + m_jBarcode.setText(null); + m_jProduct.setText(null); + m_jQuantity.setText(null); + + m_jReference.setEnabled(true); + m_jBarcode.setEnabled(true); + m_jProduct.setEnabled(true); + m_jQuantity.setEnabled(true); + m_jEnter1.setEnabled(true); + m_jEnter2.setEnabled(true); + m_jSearch.setEnabled(true); + } + + @Override + public void writeValueEdit(Object value) { + Object[] obj = (Object[]) value; + + id = obj[0]; + product = obj[1]; + productBundle = obj[2]; + quantity = obj[3]; + name = obj[6]; + m_jReference.setText(Formats.STRING.formatValue(obj[4])); + m_jBarcode.setText(Formats.STRING.formatValue(obj[5])); + m_jProduct.setText(Formats.STRING.formatValue(obj[4]) + " - " + Formats.STRING.formatValue(obj[6])); + m_jQuantity.setText(Formats.DOUBLE.formatValue(obj[3])); + + m_jReference.setEnabled(true); + m_jBarcode.setEnabled(true); + m_jProduct.setEnabled(true); + m_jQuantity.setEnabled(true); + m_jEnter1.setEnabled(true); + m_jEnter2.setEnabled(true); + m_jSearch.setEnabled(true); + } + + @Override + public void writeValueDelete(Object value) { + Object[] obj = (Object[]) value; + + id = obj[0]; + product = obj[1]; + productBundle = obj[2]; + quantity = obj[3]; + name = obj[6]; + m_jReference.setText(Formats.STRING.formatValue(obj[4])); + m_jBarcode.setText(Formats.STRING.formatValue(obj[5])); + m_jProduct.setText(Formats.STRING.formatValue(obj[4]) + " - " + Formats.STRING.formatValue(obj[6])); + m_jQuantity.setText(Formats.DOUBLE.formatValue(obj[3])); + + m_jReference.setEnabled(false); + m_jBarcode.setEnabled(false); + m_jProduct.setEnabled(false); + m_jEnter1.setEnabled(false); + m_jEnter2.setEnabled(false); + m_jSearch.setEnabled(false); + } + + @Override + public Object createValue() throws BasicException { + return new Object[] { + id, + product, + productBundle, + Formats.DOUBLE.parseValue(m_jQuantity.getText()), + m_jReference.getText(), + m_jBarcode.getText(), + name, + }; + } + + @Override + public Component getComponent() { + return this; + } + + private void assignProduct(ProductInfoExt prod) { + + if (m_jSearch.isEnabled()) { + if (prod == null) { + productBundle = null; + quantity = null; + m_jReference.setText(null); + m_jBarcode.setText(null); + m_jProduct.setText(null); + name = null; + } else { + productBundle = prod.getID(); + quantity = null; + m_jReference.setText(prod.getReference()); + m_jBarcode.setText(prod.getCode()); + m_jProduct.setText(prod.getReference() + " - " + prod.getName()); + name = prod.getName(); + } + } + + } + + private void assignProductByCode() { + try { + ProductInfoExt prod = m_dlSales.getProductInfoByCode(m_jBarcode.getText()); + assignProduct(prod); + if (prod == null) { + Toolkit.getDefaultToolkit().beep(); + } + } catch (BasicException eData) { + assignProduct(null); + MessageInf msg = new MessageInf(eData); + msg.show(this); + } + } + + + private void assignProductByReference() { + try { + ProductInfoExt prod = m_dlSales.getProductInfoByReference(m_jReference.getText()); + assignProduct(prod); + if (prod == null) { + Toolkit.getDefaultToolkit().beep(); + } + } catch (BasicException eData) { + assignProduct(null); + MessageInf msg = new MessageInf(eData); + msg.show(this); + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel3 = new javax.swing.JLabel(); + m_jReference = new javax.swing.JTextField(); + m_jEnter1 = new javax.swing.JButton(); + m_jEnter2 = new javax.swing.JButton(); + m_jSearch = new javax.swing.JButton(); + m_jProduct = new javax.swing.JTextField(); + m_jBarcode = new javax.swing.JTextField(); + jLabel4 = new javax.swing.JLabel(); + jLabel1 = new javax.swing.JLabel(); + m_jQuantity = new javax.swing.JTextField(); + + setPreferredSize(new java.awt.Dimension(700, 120)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.prodref")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jReference.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jReference.setPreferredSize(new java.awt.Dimension(150, 30)); + m_jReference.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jReferenceActionPerformed(evt); + } + }); + + m_jEnter1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + m_jEnter1.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jEnter1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jEnter1ActionPerformed(evt); + } + }); + + m_jEnter2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/barcode.png"))); // NOI18N + m_jEnter2.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jEnter2.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jEnter2ActionPerformed(evt); + } + }); + + m_jSearch.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/search24.png"))); // NOI18N + m_jSearch.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jSearch.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jSearchActionPerformed(evt); + } + }); + + m_jProduct.setEditable(false); + m_jProduct.setPreferredSize(new java.awt.Dimension(200, 30)); + m_jProduct.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jProductActionPerformed(evt); + } + }); + + m_jBarcode.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jBarcode.setPreferredSize(new java.awt.Dimension(150, 30)); + m_jBarcode.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jBarcodeActionPerformed(evt); + } + }); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.prodbarcode")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText("Quantity"); + jLabel1.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jQuantity.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jQuantity.setPreferredSize(new java.awt.Dimension(100, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jBarcode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jReference, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(10, 10, 10) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(m_jEnter1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(m_jEnter2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(layout.createSequentialGroup() + .addComponent(m_jQuantity, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) + .addComponent(m_jProduct, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jReference, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jEnter1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jProduct, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(m_jBarcode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jEnter2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jQuantity, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + private void m_jSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jSearchActionPerformed + + assignProduct(JProductFinder.showMessage(this, m_dlSales, JProductFinder.PRODUCT_BUNDLE)); + +}//GEN-LAST:event_m_jSearchActionPerformed + + private void m_jReferenceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jReferenceActionPerformed + this.assignProductByReference(); + }//GEN-LAST:event_m_jReferenceActionPerformed + + private void m_jEnter2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jEnter2ActionPerformed + this.assignProductByCode(); + }//GEN-LAST:event_m_jEnter2ActionPerformed + + private void m_jEnter1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jEnter1ActionPerformed + this.assignProductByReference(); + }//GEN-LAST:event_m_jEnter1ActionPerformed + + private void m_jBarcodeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jBarcodeActionPerformed + this.assignProductByCode(); + }//GEN-LAST:event_m_jBarcodeActionPerformed + + private void m_jProductActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jProductActionPerformed + + }//GEN-LAST:event_m_jProductActionPerformed + + + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JTextField m_jBarcode; + private javax.swing.JButton m_jEnter1; + private javax.swing.JButton m_jEnter2; + private javax.swing.JTextField m_jProduct; + private javax.swing.JTextField m_jQuantity; + private javax.swing.JTextField m_jReference; + private javax.swing.JButton m_jSearch; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/inventory/BundlePanel.java b/src/main/java/com/unicenta/pos/inventory/BundlePanel.java new file mode 100644 index 0000000..2237db7 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/BundlePanel.java @@ -0,0 +1,118 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.model.*; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.panels.BundleFilter; +import com.unicenta.pos.panels.JPanelTable2; +import com.unicenta.pos.ticket.ProductInfoExt; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * + * @author Jack + */ +public class BundlePanel extends JPanelTable2 { + + private BundleEditor editor; + private BundleFilter filter; + + @Override + protected void init() { + + filter = new BundleFilter(); + filter.init(app); + filter.addActionListener(new ReloadActionListener()); + + row = new Row( + new Field("ID", Datas.STRING, Formats.STRING), + new Field("PRODUCT", Datas.STRING, Formats.STRING), + new Field("PRODUCT_BUNDLE", Datas.STRING, Formats.STRING), + new Field("QUANTITY", Datas.DOUBLE, Formats.DOUBLE), + new Field(AppLocal.getIntString("label.prodref"), Datas.STRING, Formats.STRING, true, true, true), + new Field(AppLocal.getIntString("label.prodbarcode"), Datas.STRING, Formats.STRING, false, true, true), + new Field(AppLocal.getIntString("label.prodname"), Datas.STRING, Formats.STRING, true, true, true) + ); + Table table = new Table( + "products_bundle", + new PrimaryKey("ID"), + new Column("PRODUCT"), + new Column("PRODUCT_BUNDLE"), + new Column("QUANTITY")); + + lpr = row.getListProvider(app.getSession(), + "SELECT " + + "B.ID, B.PRODUCT, " + + "B.PRODUCT_BUNDLE, B.QUANTITY, " + + "P.REFERENCE, P.CODE, P.NAME " + + "FROM products_bundle B, products P " + + "WHERE B.PRODUCT_BUNDLE = P.ID AND B.PRODUCT = ?", filter); + spr = row.getSaveProvider(app.getSession(), table); + + editor = new BundleEditor(app, dirty); + } + + @Override + public void activate() throws BasicException { + filter.activate(); + + startNavigation(); + reload(filter); + } + + @Override + public Component getFilter(){ + return filter.getComponent(); + } + + @Override + public EditorRecord getEditor() { + return editor; + } + + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.Bundle"); + } + + private void reload(BundleFilter filter) throws BasicException { + ProductInfoExt prod = filter.getProductInfoExt(); + editor.setInsertProduct(prod); + bd.setEditable(prod != null); + bd.actionLoad(); + } + + private class ReloadActionListener implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + try { + reload((BundleFilter) e.getSource()); + } catch (BasicException w) { + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/inventory/CategoriesEditor.form b/src/main/java/com/unicenta/pos/inventory/CategoriesEditor.form new file mode 100644 index 0000000..53a9df2 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/CategoriesEditor.form @@ -0,0 +1,383 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <NonVisualComponents> + <Container class="javax.swing.JInternalFrame" name="jInternalFrame1"> + <Properties> + <Property name="visible" type="boolean" value="true"/> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + </Container> + </NonVisualComponents> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[750, 500]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jScrollPane2" min="-2" pref="657" max="-2" attributes="0"/> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLblInCat" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="webSwtch_InCatalog" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="1" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLblName" min="-2" max="-2" attributes="0"/> + <Component id="jLblCategory" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="jLblTextTip" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jName" min="-2" max="-2" attributes="0"/> + <Component id="m_jTextTip" min="-2" max="-2" attributes="0"/> + <Component id="m_jCategory" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLblCatShowName" min="-2" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="m_jCatNameShow" min="-2" pref="30" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jLblCatOrder" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCatOrder" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jBtnShowTrans" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jLblProdCount" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jImage" min="-2" pref="270" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace min="-2" pref="26" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jName" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLblName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jCategory" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLblCategory" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jTextTip" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLblTextTip" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLblInCat" min="-2" max="-2" attributes="0"/> + <Component id="webSwtch_InCatalog" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLblCatShowName" min="-2" max="-2" attributes="0"/> + <Component id="m_jCatNameShow" min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLblCatOrder" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCatOrder" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="jLblProdCount" max="32767" attributes="0"/> + <Component id="jBtnShowTrans" alignment="0" pref="32" max="32767" attributes="0"/> + </Group> + </Group> + <Component id="m_jImage" max="32767" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jScrollPane2" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLblName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/info.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.namem" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[125, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="jLblNameMouseClicked"/> + </Events> + </Component> + <Component class="javax.swing.JTextField" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblCategory"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodcategory" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[125, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCategory"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblTextTip"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.texttip" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[125, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jTextTip"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblCatShowName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.subcategorytitle" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="m_jCatNameShow"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="selected" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblCatOrder"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.ccatorder" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jCatOrder"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblInCat"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.CatalogueStatusYes" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="horizontalTextPosition" type="int" value="2"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[125, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.extended.button.WebSwitch" name="webSwtch_InCatalog"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="webSwtch_InCatalogActionPerformed"/> + </Events> + </Component> + <Component class="com.unicenta.data.gui.JImageEditor" name="m_jImage"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[270, 200]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jBtnShowTrans"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.CatProds" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value=""/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnShowTransActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLblProdCount"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[237, 30]"/> + </Property> + </Properties> + </Component> + <Container class="javax.swing.JScrollPane" name="jScrollPane2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[650, 300]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="com.alee.laf.table.WebTable" name="jTableCategoryStock"> + <Properties> + <Property name="autoCreateRowSorter" type="boolean" value="true"/> + <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor"> + <Table columnCount="2" rowCount="20"> + <Column editable="true" title="Name" type="java.lang.Object"/> + <Column editable="true" title="Barcode" type="java.lang.Object"/> + </Table> + </Property> + <Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor"> + <TableColumnModel selectionModel="0"> + <Column maxWidth="-1" minWidth="-1" prefWidth="250" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + </TableColumnModel> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="gridColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="cc" red="66" type="rgb"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[310, 500]"/> + </Property> + <Property name="rowHeight" type="int" value="25"/> + <Property name="selectionBackground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="d7" green="78" red="0" type="rgb"/> + </Property> + <Property name="showVerticalLines" type="boolean" value="false"/> + <Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor"> + <TableHeader reorderingAllowed="true" resizingAllowed="true"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/CategoriesEditor.java b/src/main/java/com/unicenta/pos/inventory/CategoriesEditor.java new file mode 100644 index 0000000..b7670ec --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/CategoriesEditor.java @@ -0,0 +1,675 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.alee.extended.time.ClockType; +import com.alee.extended.time.WebClock; +import com.alee.managers.notification.NotificationIcon; +import com.alee.managers.notification.NotificationManager; +import com.alee.managers.notification.WebNotification; +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.gui.JMessageDialog; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.loader.SentenceExec; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.catalog.CategoryStock; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.JTableHeader; +import java.awt.*; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * @author adrianromero + */ +@Slf4j +public final class CategoriesEditor extends JPanel implements EditorRecord { + + private Object m_oId; + private Object m_id; + public String cId; + + private final SentenceList m_sentcat; + private ComboBoxValModel m_CategoryModel; + + private final SentenceExec m_sentadd; + private final SentenceExec m_sentdel; + + private List<CategoryStock> categoryStockList; + private CategoriesEditor.StockTableModel stockModel; + + private final DataLogicSales dlSales; + + /** + * Creates new form JPanelCategories + * + * @param app + * @param dirty + */ + public CategoriesEditor(AppView app, DirtyManager dirty) { + +// DataLogicSales dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + + initComponents(); + + // El modelo de categorias + m_sentcat = dlSales.getCategoriesList(); + m_CategoryModel = new ComboBoxValModel(); + + m_sentadd = dlSales.getCatalogCategoryAdd(); + m_sentdel = dlSales.getCatalogCategoryDel(); + + m_jName.getDocument().addDocumentListener(dirty); + m_jCategory.addActionListener(dirty); + m_jImage.addPropertyChangeListener("image", dirty); + m_jCatNameShow.addActionListener(dirty); + m_jTextTip.getDocument().addDocumentListener(dirty); + m_jCatOrder.getDocument().addDocumentListener(dirty); + webSwtch_InCatalog.addActionListener(dirty); + + writeValueEOF(); + } + + /** + * + */ + @Override + public void refresh() { + + List a; + + try { + a = m_sentcat.list(); + } catch (BasicException eD) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, AppLocal.getIntString("message.cannotloadlists"), eD); + msg.show(this); + a = new ArrayList(); + } + + a.add(0, null); + m_CategoryModel = new ComboBoxValModel(a); + m_jCategory.setModel(m_CategoryModel); + + jLblProdCount.setText(null); + } + + /** + * + */ + @Override + public void writeValueEOF() { + m_id = null; + m_jName.setText(null); + m_CategoryModel.setSelectedKey(null); + m_jImage.setImage(null); + m_jName.setEnabled(false); + m_jCategory.setEnabled(false); + m_jImage.setEnabled(false); + webSwtch_InCatalog.isSelected(); + m_jTextTip.setText(null); + m_jTextTip.setEnabled(false); + m_jCatNameShow.setSelected(false); + m_jCatNameShow.setEnabled(false); +// Added JG Feb 2017 + m_jCatOrder.setText(null); + m_jCatOrder.setEnabled(false); + + } + + /** + * + */ + @Override + public void writeValueInsert() { + m_id = UUID.randomUUID().toString(); + m_jName.setText(null); + m_CategoryModel.setSelectedKey(null); + m_jImage.setImage(null); + m_jName.setEnabled(true); + m_jCategory.setEnabled(true); + m_jImage.setEnabled(true); + webSwtch_InCatalog.setEnabled(false); + m_jTextTip.setText(null); + m_jTextTip.setEnabled(true); + m_jCatNameShow.setSelected(true); + m_jCatNameShow.setEnabled(true); +// Added JG Feb 2017 + m_jCatOrder.setText(null); + m_jCatOrder.setEnabled(true); + + } + + /** + * @param value + */ + @Override + public void writeValueDelete(Object value) { + Object[] cat = (Object[]) value; + m_id = cat[0]; + m_jName.setText(Formats.STRING.formatValue(cat[1])); + m_CategoryModel.setSelectedKey(cat[2]); + m_jImage.setImage((BufferedImage) cat[3]); + m_jTextTip.setText(Formats.STRING.formatValue(cat[4])); + m_jCatNameShow.setSelected(((Boolean) cat[5]).booleanValue()); + m_jCatOrder.setText(Formats.STRING.formatValue(cat[6])); + + m_jName.setEnabled(false); + m_jCategory.setEnabled(false); + m_jImage.setEnabled(false); + webSwtch_InCatalog.setEnabled(false); + m_jTextTip.setEnabled(false); + m_jCatNameShow.setEnabled(false); + m_jCatOrder.setEnabled(false); + + stockModel = new CategoriesEditor.StockTableModel(getProductOfName((String) m_oId)); + + } + + /** + * @param value + */ + @Override + public void writeValueEdit(Object value) { + Object[] cat = (Object[]) value; + m_id = cat[0]; + m_jName.setText(Formats.STRING.formatValue(cat[1])); + m_CategoryModel.setSelectedKey(cat[2]); + m_jImage.setImage((BufferedImage) cat[3]); + m_jTextTip.setText(Formats.STRING.formatValue(cat[4])); + m_jCatNameShow.setSelected(((Boolean) cat[5])); + + if (m_jCatOrder.getText().length() == 0) { + m_jCatOrder.setText(null); + } + m_jCatOrder.setText(Formats.STRING.formatValue(cat[6])); + + m_jName.setEnabled(true); + m_jCategory.setEnabled(true); + m_jImage.setEnabled(true); + webSwtch_InCatalog.setEnabled(true); + m_jTextTip.setEnabled(true); + m_jCatNameShow.setEnabled(true); +// Added JG Feb 2017 + m_jCatOrder.setEnabled(true); + + resetTranxTable(); + } + + /** + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + Object[] cat = new Object[8]; + + cat[0] = m_id; + cat[1] = m_jName.getText(); + cat[2] = m_CategoryModel.getSelectedKey(); + cat[3] = m_jImage.getImage(); + cat[4] = m_jTextTip.getText(); + cat[5] = m_jCatNameShow.isSelected(); + if (m_jCatOrder.getText().length() == 0) { + m_jCatOrder.setText(null); + } + cat[6] = m_jCatOrder.getText(); + + if (m_jName.getText().contains("&")) { + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.ampersand")); + } + + return cat; + } + + /** + * @return + */ + @Override + public Component getComponent() { + return this; + } + + public void resetTranxTable() { + + jTableCategoryStock.getColumnModel().getColumn(0).setPreferredWidth(250); + + // set font for headers + Font f = new Font("Arial", Font.BOLD, 14); + JTableHeader header = jTableCategoryStock.getTableHeader(); + header.setFont(f); + + jTableCategoryStock.getTableHeader().setReorderingAllowed(true); + jTableCategoryStock.setAutoCreateRowSorter(true); + jTableCategoryStock.repaint(); + } + + private List<CategoryStock> getProductOfName(String pId) { + + try { + categoryStockList = dlSales.getCategorysProductList(pId); + + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + + List<CategoryStock> categoryList = new ArrayList<>(); + + for (CategoryStock categoryStock : categoryStockList) { + String categoryId = categoryStock.getCategoryId(); + if (categoryId.equals(pId)) { + categoryList.add(categoryStock); + } + } + + repaint(); + refresh(); + + return categoryList; + } + + class StockTableModel extends AbstractTableModel { + String nam = AppLocal.getIntString("label.prodname"); + String cod = AppLocal.getIntString("label.prodbarcode"); + + List<CategoryStock> stockList; + String[] columnNames = {nam, cod}; + + public StockTableModel(List<CategoryStock> list) { + stockList = list; + } + + @Override + public int getColumnCount() { + return 2; + } + + @Override + public int getRowCount() { + return stockList.size(); + } + + @Override + public Object getValueAt(int row, int column) { + CategoryStock categoryStock = stockList.get(row); + + switch (column) { + case 0: + return categoryStock.getProductName(); + case 1: + return categoryStock.getProductCode(); + case 2: + return categoryStock.getProductId(); + default: + return ""; + } + } + + @Override + public String getColumnName(int col) { + return columnNames[col]; + } + } + + + public void Notify(String msg) { + final WebNotification notification = new WebNotification(); + notification.setIcon(NotificationIcon.information); + notification.setDisplayTime(4000); + + final WebClock clock = new WebClock(); + clock.setClockType(ClockType.timer); + clock.setTimeLeft(5000); + clock.setTimePattern(msg); + notification.setContent(clock); + + NotificationManager.showNotification(notification); + clock.start(); + } + + /** + * This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jInternalFrame1 = new javax.swing.JInternalFrame(); + jLblName = new javax.swing.JLabel(); + m_jName = new javax.swing.JTextField(); + jLblCategory = new javax.swing.JLabel(); + m_jCategory = new javax.swing.JComboBox(); + jLblTextTip = new javax.swing.JLabel(); + m_jTextTip = new javax.swing.JTextField(); + jLblCatShowName = new javax.swing.JLabel(); + m_jCatNameShow = new javax.swing.JCheckBox(); + jLblCatOrder = new javax.swing.JLabel(); + m_jCatOrder = new javax.swing.JTextField(); + jLblInCat = new javax.swing.JLabel(); + webSwtch_InCatalog = new com.alee.extended.button.WebSwitch(); + m_jImage = new com.unicenta.data.gui.JImageEditor(); + jBtnShowTrans = new javax.swing.JButton(); + jLblProdCount = new javax.swing.JLabel(); + jScrollPane2 = new javax.swing.JScrollPane(); + jTableCategoryStock = new com.alee.laf.table.WebTable(); + + jInternalFrame1.setVisible(true); + + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + setPreferredSize(new java.awt.Dimension(750, 500)); + + jLblName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblName.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/info.png"))); // NOI18N + jLblName.setText(AppLocal.getIntString("label.namem")); // NOI18N + jLblName.setPreferredSize(new java.awt.Dimension(125, 30)); + jLblName.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + jLblNameMouseClicked(evt); + } + }); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(250, 30)); + + jLblCategory.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblCategory.setText(AppLocal.getIntString("label.prodcategory")); // NOI18N + jLblCategory.setPreferredSize(new java.awt.Dimension(125, 30)); + + m_jCategory.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCategory.setPreferredSize(new java.awt.Dimension(250, 30)); + + jLblTextTip.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jLblTextTip.setText(bundle.getString("label.texttip")); // NOI18N + jLblTextTip.setPreferredSize(new java.awt.Dimension(125, 30)); + + m_jTextTip.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jTextTip.setPreferredSize(new java.awt.Dimension(250, 30)); + + jLblCatShowName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblCatShowName.setText(bundle.getString("label.subcategorytitle")); // NOI18N + jLblCatShowName.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jCatNameShow.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCatNameShow.setSelected(true); + m_jCatNameShow.setPreferredSize(new java.awt.Dimension(30, 30)); + + jLblCatOrder.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblCatOrder.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLblCatOrder.setText(bundle.getString("label.ccatorder")); // NOI18N + jLblCatOrder.setPreferredSize(new java.awt.Dimension(60, 30)); + + m_jCatOrder.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCatOrder.setHorizontalAlignment(javax.swing.JTextField.CENTER); + m_jCatOrder.setPreferredSize(new java.awt.Dimension(60, 30)); + + jLblInCat.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblInCat.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jLblInCat.setText(bundle.getString("label.CatalogueStatusYes")); // NOI18N + jLblInCat.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT); + jLblInCat.setPreferredSize(new java.awt.Dimension(125, 30)); + + webSwtch_InCatalog.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + webSwtch_InCatalog.setPreferredSize(new java.awt.Dimension(80, 30)); + webSwtch_InCatalog.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + webSwtch_InCatalogActionPerformed(evt); + } + }); + + m_jImage.setPreferredSize(new java.awt.Dimension(270, 200)); + + jBtnShowTrans.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jBtnShowTrans.setText(bundle.getString("button.CatProds")); // NOI18N + jBtnShowTrans.setToolTipText(""); + jBtnShowTrans.setPreferredSize(new java.awt.Dimension(140, 30)); + jBtnShowTrans.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnShowTransActionPerformed(evt); + } + }); + + jLblProdCount.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblProdCount.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLblProdCount.setOpaque(true); + jLblProdCount.setPreferredSize(new java.awt.Dimension(237, 30)); + + jScrollPane2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jScrollPane2.setPreferredSize(new java.awt.Dimension(650, 300)); + + jTableCategoryStock.setAutoCreateRowSorter(true); + jTableCategoryStock.setModel(new javax.swing.table.DefaultTableModel( + new Object[][]{ + {null, null}, + {null, null}, + {null, null}, + {null, null}, + {null, null}, + {null, null}, + {null, null}, + {null, null}, + {null, null}, + {null, null}, + {null, null}, + {null, null}, + {null, null}, + {null, null}, + {null, null}, + {null, null}, + {null, null}, + {null, null}, + {null, null}, + {null, null} + }, + new String[]{ + "Name", "Barcode" + } + )); + jTableCategoryStock.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTableCategoryStock.setGridColor(new java.awt.Color(102, 204, 255)); + jTableCategoryStock.setPreferredSize(new java.awt.Dimension(310, 500)); + jTableCategoryStock.setRowHeight(25); + jTableCategoryStock.setSelectionBackground(new java.awt.Color(0, 120, 215)); + jTableCategoryStock.setShowVerticalLines(false); + jScrollPane2.setViewportView(jTableCategoryStock); + if (jTableCategoryStock.getColumnModel().getColumnCount() > 0) { + jTableCategoryStock.getColumnModel().getColumn(0).setPreferredWidth(250); + } + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 657, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLblInCat, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(webSwtch_InCatalog, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLblName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jLblTextTip, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jTextTip, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(layout.createSequentialGroup() + .addComponent(jLblCatShowName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(m_jCatNameShow, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLblCatOrder, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCatOrder, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jBtnShowTrans, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLblProdCount, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED))) + .addComponent(m_jImage, javax.swing.GroupLayout.PREFERRED_SIZE, 270, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(26, 26, 26)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jTextTip, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblTextTip, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLblInCat, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(webSwtch_InCatalog, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLblCatShowName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCatNameShow, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLblCatOrder, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCatOrder, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jLblProdCount, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jBtnShowTrans, javax.swing.GroupLayout.DEFAULT_SIZE, 32, Short.MAX_VALUE))) + .addComponent(m_jImage, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + private void webSwtch_InCatalogActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_webSwtch_InCatalogActionPerformed + if (webSwtch_InCatalog.isSelected()) { + + try { + Object param = m_id; + m_sentdel.exec(param); + m_sentadd.exec(param); + jLblInCat.setText(AppLocal.getIntString("label.CatalogueStatusYes")); + Notify(AppLocal.getIntString("notify.added")); + } catch (BasicException e) { + JMessageDialog.showMessage(this, new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotexecute"), e)); + } + } else { + + try { + m_sentdel.exec(m_id); + jLblInCat.setText(AppLocal.getIntString("label.CatalogueStatusNo")); + Notify(AppLocal.getIntString("notify.removed")); + } catch (BasicException e) { + JMessageDialog.showMessage(this, new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotexecute"), e)); + } + } + }//GEN-LAST:event_webSwtch_InCatalogActionPerformed + + private void jLblNameMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLblNameMouseClicked + + if (evt.getClickCount() == 2) { + String uuidString = m_id.toString(); + StringSelection stringSelection = new StringSelection(uuidString); + Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard(); + clpbrd.setContents(stringSelection, null); + + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.uuidcopy")); + } + }//GEN-LAST:event_jLblNameMouseClicked + + private void jBtnShowTransActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnShowTransActionPerformed + String pId = m_id.toString(); + if (pId != null) { + stockModel = new CategoriesEditor.StockTableModel(getProductOfName(pId)); + jTableCategoryStock.setModel(stockModel); + + if (stockModel.getRowCount() > 0) { + jTableCategoryStock.setVisible(true); + String ProdCount = String.valueOf(stockModel.getRowCount()); + jLblProdCount.setText(ProdCount + " for " + m_jName.getText()); + } else { + jTableCategoryStock.setVisible(false); + JOptionPane.showMessageDialog(null, + "No Products for this Category", "Products", JOptionPane.INFORMATION_MESSAGE); + } + resetTranxTable(); + } + }//GEN-LAST:event_jBtnShowTransActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jBtnShowTrans; + private javax.swing.JInternalFrame jInternalFrame1; + private javax.swing.JLabel jLblCatOrder; + private javax.swing.JLabel jLblCatShowName; + private javax.swing.JLabel jLblCategory; + private javax.swing.JLabel jLblInCat; + private javax.swing.JLabel jLblName; + private javax.swing.JLabel jLblProdCount; + private javax.swing.JLabel jLblTextTip; + private javax.swing.JScrollPane jScrollPane2; + private com.alee.laf.table.WebTable jTableCategoryStock; + private javax.swing.JCheckBox m_jCatNameShow; + private javax.swing.JTextField m_jCatOrder; + private javax.swing.JComboBox m_jCategory; + private com.unicenta.data.gui.JImageEditor m_jImage; + private javax.swing.JTextField m_jName; + private javax.swing.JTextField m_jTextTip; + private com.alee.extended.button.WebSwitch webSwtch_InCatalog; + // End of variables declaration//GEN-END:variables + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/inventory/CategoriesPanel.java b/src/main/java/com/unicenta/pos/inventory/CategoriesPanel.java new file mode 100644 index 0000000..f44cbf0 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/CategoriesPanel.java @@ -0,0 +1,120 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.data.gui.ListCellRendererBasic; +import com.unicenta.data.loader.ComparatorCreator; +import com.unicenta.data.loader.TableDefinition; +import com.unicenta.data.loader.Vectorer; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.panels.JPanelTable; +import javax.swing.ListCellRenderer; + +/** + * + * @author adrianromero + */ +public class CategoriesPanel extends JPanelTable { + + private TableDefinition tcategories; + private CategoriesEditor jeditor; + + /** Creates a new instance of JPanelCategories */ + public CategoriesPanel() { + } + + /** + * + */ + @Override + protected void init() { + DataLogicSales dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + tcategories = dlSales.getTableCategories(); + jeditor = new CategoriesEditor(app, dirty); + } + + /** + * + * @return + */ + @Override + public ListProvider getListProvider() { + return new ListProviderCreator(tcategories); + } + + /** + * + * @return + */ + @Override + public SaveProvider getSaveProvider() { + return new SaveProvider(tcategories); + } + + /** + * + * @return + */ + @Override + public Vectorer getVectorer() { + return tcategories.getVectorerBasic(new int[]{1}); + } + + /** + * + * @return + */ + @Override + public ComparatorCreator getComparatorCreator() { + return tcategories.getComparatorCreator(new int[]{1}); + } + + /** + * + * @return + */ + @Override + public ListCellRenderer getListCellRenderer() { + return new ListCellRendererBasic(tcategories.getRenderStringBasic(new int[]{1})); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return jeditor; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.Categories"); + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/CodeType.java b/src/main/java/com/unicenta/pos/inventory/CodeType.java new file mode 100644 index 0000000..118c7e6 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/CodeType.java @@ -0,0 +1,75 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.data.loader.IKeyed; + +/** + * + * @author adrianromero + */ +public class CodeType implements IKeyed { + + /** + * + */ + public static final CodeType EAN13 = new CodeType("EAN13", "EAN13"); + + /** + * + */ + public static final CodeType CODE128 = new CodeType("CODE128", "CODE128"); + + /** + * + */ + protected String m_sKey; + + /** + * + */ + protected String m_sValue; + + private CodeType(String key, String value) { + m_sKey = key; + m_sValue = value; + } + + /** + * + * @return + */ + @Override + public Object getKey() { + return m_sKey; + } + + /** + * + * @return + */ + public String getValue() { + return m_sValue; + } + @Override + public String toString() { + return m_sValue; + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/inventory/InvEditLine.form b/src/main/java/com/unicenta/pos/inventory/InvEditLine.form new file mode 100644 index 0000000..90744c8 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/InvEditLine.form @@ -0,0 +1,112 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSizePolicy" type="int" value="1"/> + <SyntheticProperty name="generateCenter" type="boolean" value="false"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="25" max="-2" attributes="0"/> + <Component id="webLabel1" min="-2" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Group type="102" attributes="0"> + <Component id="webButtonCancel" min="-2" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + <Component id="webButtonOK" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="webTxtPriceBuy" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace pref="27" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="27" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="webLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="webTxtPriceBuy" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="webButtonOK" min="-2" pref="45" max="-2" attributes="0"/> + <Component id="webButtonCancel" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace pref="19" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="com.alee.laf.label.WebLabel" name="webLabel1"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.invline" replaceFormat="AppLocal.getIntString("button.exit")"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[130, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.text.WebTextField" name="webTxtPriceBuy"> + <Properties> + <Property name="text" type="java.lang.String" value="webTextField1"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.button.WebButton" name="webButtonOK"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="webButtonOKActionPerformed"/> + </Events> + </Component> + <Component class="com.alee.laf.button.WebButton" name="webButtonCancel"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="webButtonCancelActionPerformed"/> + </Events> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/InvEditLine.java b/src/main/java/com/unicenta/pos/inventory/InvEditLine.java new file mode 100644 index 0000000..1e3ecf6 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/InvEditLine.java @@ -0,0 +1,137 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.pos.forms.AppLocal; +import com.alee.laf.*; + + +/** + * + * @author jack + */ +public class InvEditLine extends javax.swing.JDialog { + private boolean ok; + + /** + * Creates new form InvEditLine + * @param parent + * @param modal + */ + public InvEditLine(java.awt.Frame parent, boolean modal) { + super(parent, modal); + initComponents(); + } + public boolean isOK() { + boolean ok = false; + return ok; + } + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + webLabel1 = new com.alee.laf.label.WebLabel(); + webTxtPriceBuy = new com.alee.laf.text.WebTextField(); + webButtonOK = new com.alee.laf.button.WebButton(); + webButtonCancel = new com.alee.laf.button.WebButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + + webLabel1.setText(AppLocal.getIntString("button.exit")); // NOI18N + webLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + webLabel1.setPreferredSize(new java.awt.Dimension(130, 30)); + + webTxtPriceBuy.setText("webTextField1"); + webTxtPriceBuy.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + webTxtPriceBuy.setPreferredSize(new java.awt.Dimension(200, 30)); + + webButtonOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + webButtonOK.setPreferredSize(new java.awt.Dimension(80, 45)); + webButtonOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + webButtonOKActionPerformed(evt); + } + }); + + webButtonCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + webButtonCancel.setPreferredSize(new java.awt.Dimension(80, 45)); + webButtonCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + webButtonCancelActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(25, 25, 25) + .addComponent(webLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(layout.createSequentialGroup() + .addComponent(webButtonCancel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(webButtonOK, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(webTxtPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(27, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(27, 27, 27) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(webLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(webTxtPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(webButtonOK, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(webButtonCancel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(19, Short.MAX_VALUE)) + ); + + pack(); + }// </editor-fold>//GEN-END:initComponents + + private void webButtonOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_webButtonOKActionPerformed + ok = true; + String invlinevalue = (String)webTxtPriceBuy.getText(); + dispose(); + }//GEN-LAST:event_webButtonOKActionPerformed + + private void webButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_webButtonCancelActionPerformed + dispose(); + }//GEN-LAST:event_webButtonCancelActionPerformed + + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private com.alee.laf.button.WebButton webButtonCancel; + private com.alee.laf.button.WebButton webButtonOK; + private com.alee.laf.label.WebLabel webLabel1; + private com.alee.laf.text.WebTextField webTxtPriceBuy; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/inventory/InventoryLine.java b/src/main/java/com/unicenta/pos/inventory/InventoryLine.java new file mode 100644 index 0000000..181784e --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/InventoryLine.java @@ -0,0 +1,212 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.format.Formats; +import com.unicenta.pos.ticket.ProductInfoExt; +import com.unicenta.pos.util.StringUtils; + +/** + * + * @author adrianromero + */ +public class InventoryLine { + + private double m_dMultiply; + private double m_dPrice; + + private String m_sProdID; + private String m_sProdName; + + private String attsetid; + private String attsetinstid; + private String attsetinstdesc; + + /** Creates a new instance of InventoryLine + * @param oProduct */ + public InventoryLine(ProductInfoExt oProduct) { + m_sProdID = oProduct.getID(); + m_sProdName = oProduct.getName(); + m_dMultiply = 1.0; + m_dPrice = oProduct.getPriceBuy(); + + attsetid = oProduct.getAttributeSetID(); + attsetinstid = null; + attsetinstdesc = null; + } + + /** + * + * @param oProduct + * @param dpor + * @param dprice + */ + public InventoryLine(ProductInfoExt oProduct, double dpor, double dprice) { + m_sProdID = oProduct.getID(); + m_sProdName = oProduct.getName(); + m_dMultiply = dpor; + m_dPrice = dprice; + attsetid = oProduct.getAttributeSetID(); + attsetinstid = null; + attsetinstdesc = null; + } + + /** + * + * @return + */ + public String getProductID() { + return m_sProdID; + } + + /** + * + * @return + */ + public String getProductName() { + return m_sProdName; + } + + /** + * + * @param sValue + */ + public void setProductName(String sValue) { + if (m_sProdID == null) { + m_sProdName = sValue; + } + } + + /** + * + * @return + */ + public double getMultiply() { + return m_dMultiply; + } + + /** + * + * @param dValue + */ + public void setMultiply(double dValue) { + m_dMultiply = dValue; + } + + /** + * + * @return + */ + public double getPrice() { + return m_dPrice; + } + + /** + * + * @param dValue + */ + public void setPrice(double dValue) { + m_dPrice = dValue; + } + + /** + * + * @return + */ + public double getSubValue() { + return m_dMultiply * m_dPrice; + } + + /** + * + * @return + */ + public String getProductAttSetInstId() { + return attsetinstid; + } + + /** + * + * @param value + */ + public void setProductAttSetInstId(String value) { + attsetinstid = value; + } + + /** + * + * @return + */ + public String getProductAttSetId() { + return attsetid; + } + + /** + * + * @return + */ + public String getProductAttSetInstDesc() { + return attsetinstdesc; + } + + /** + * + * @param value + */ + public void setProductAttSetInstDesc(String value) { + attsetinstdesc = value; + } + + /** + * + * @return + */ + public String printName() { + return StringUtils.encodeXML(m_sProdName); + } + + /** + * + * @return + */ + public String printPrice() { + if (m_dMultiply == 1.0) { + return ""; + } else { + return Formats.CURRENCY.formatValue(new Double(getPrice())); + } + } + + /** + * + * @return + */ + public String printMultiply() { + return Formats.DOUBLE.formatValue(new Double(m_dMultiply)); + } + + /** + * + * @return + */ + public String printSubValue() { + return Formats.CURRENCY.formatValue(new Double(getSubValue())); + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/InventoryRecord.java b/src/main/java/com/unicenta/pos/inventory/InventoryRecord.java new file mode 100644 index 0000000..3ec2598 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/InventoryRecord.java @@ -0,0 +1,204 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.format.Formats; +import com.unicenta.pos.suppliers.SupplierInfo; +import com.unicenta.pos.util.StringUtils; +import java.util.Date; +import java.util.Iterator; +import java.util.List; + + +/** + * + * @author adrianromero + */ +public class InventoryRecord { + + private final Date m_dDate; + private final MovementReason m_reason; + private final LocationInfo m_locationOri; + private final List<InventoryLine> m_invlines; + private final String user; + private final SupplierInfo m_Supplier; + private final String m_SupplierDoc; + + /** Creates a new instance of InventoryRecord + * @param d + * @param reason + * @param location + * @param invlines + * @param currentUser + * @param supplier + * @param supplierdoc + */ + public InventoryRecord(Date d, MovementReason reason, + LocationInfo location, String currentUser, + SupplierInfo supplier, + List<InventoryLine> invlines, String supplierdoc) { + + m_dDate = d; + m_reason = reason; + m_locationOri = location; + m_invlines = invlines; + user = currentUser; + m_Supplier = supplier; + m_SupplierDoc = supplierdoc; + + } + + + /** + * + * @return + */ + public Date getDate() { + return m_dDate; + } + /** + * + * @return + */ + public String printDate() { + return Formats.TIMESTAMP.formatValue(m_dDate); + } + + /** + * + * @return + */ + public MovementReason getReason() { + return m_reason; + } + /** + * + * @return + */ + public String printReason() { + return StringUtils.encodeXML(m_reason.toString()); + } + + /** + * + * @return + */ + public String getUser() { + return user; + } + public String printUser() { + return StringUtils.encodeXML(user.toString()); + } + + /** + * + * @return + */ + public LocationInfo getLocation() { + return m_locationOri; + } + /** + * + * @return + */ + public String printLocation() { + return StringUtils.encodeXML(m_locationOri.toString()); + } + + /** + * + * @return + */ + public SupplierInfo getSupplier() { + return m_Supplier; + } + public String printSupplier() { + return StringUtils.encodeXML(m_Supplier.toString()); + } + + /** + * + * @return + */ + public String getSupplierDoc() { + return m_SupplierDoc; + } + public String printSupplierDoc() { + return StringUtils.encodeXML(m_SupplierDoc.toString()); + } + + /** + * + * @return + */ + public List<InventoryLine> getLines() { + return m_invlines; + } + + /** + * + * @return + */ + public boolean isInput() { + return m_reason.isInput(); + } + + /** + * + * @return + */ + public double getSubTotal() { + double dSuma = 0.0; + InventoryLine oLine; + for (Iterator<InventoryLine> i = m_invlines.iterator(); i.hasNext();) { + oLine = i.next(); + dSuma += oLine.getSubValue(); + } + return dSuma; + } + /** + * + * @return + */ + public String printSubTotal() { + return Formats.CURRENCY.formatValue(getSubTotal()); + } + + /** + * + * @return + */ + public double getTotalArticles() { + double dSum = 0.0; + InventoryLine oLine; + for (Iterator<InventoryLine> i = m_invlines.iterator(); i.hasNext();) { + oLine = i.next(); + dSum += oLine.getMultiply(); + } + return dSum; + } + /** + * + * @return + */ + public String printTotalArticles() { + return Formats.DOUBLE.formatValue(getTotalArticles()); + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/JDlgUploadProducts.form b/src/main/java/com/unicenta/pos/inventory/JDlgUploadProducts.form new file mode 100644 index 0000000..dc68ecd --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/JDlgUploadProducts.form @@ -0,0 +1,114 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="caption.upload" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="resizable" type="boolean" value="false"/> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-95,0,0,1,-38"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="2"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="jcmdCancel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.cancel" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jcmdCancelActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jcmdOK"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.OK" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jcmdOKActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout"> + <Property name="useNullLayout" type="boolean" value="true"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="message.preparescanner" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[450, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="0" y="20" width="460" height="-1"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/JDlgUploadProducts.java b/src/main/java/com/unicenta/pos/inventory/JDlgUploadProducts.java new file mode 100644 index 0000000..f16a7c1 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/JDlgUploadProducts.java @@ -0,0 +1,212 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.user.BrowsableEditableData; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.scanpal2.DeviceScanner; +import com.unicenta.pos.scanpal2.DeviceScannerException; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.Window; +import javax.swing.JFrame; +import javax.swing.ListModel; + +/** + * + * @author adrianromero + */ +public class JDlgUploadProducts extends javax.swing.JDialog { + + // private AppView m_App; + private DeviceScanner m_scanner; + private BrowsableEditableData m_bd; + + /** Creates new form JDlgUploadProducts */ + private JDlgUploadProducts(java.awt.Frame parent, boolean modal) { + super(parent, modal); + } + /** Creates new form JDlgUploadProducts */ + private JDlgUploadProducts(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + } + + private void init(DeviceScanner scanner, BrowsableEditableData bd) { + + initComponents(); + + getRootPane().setDefaultButton(jcmdOK); + + m_scanner = scanner; + m_bd = bd; + + //show(); + setVisible(true); + + // return; + } + + private static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window)parent; + } else { + return getWindow(parent.getParent()); + } + } + + /** + * + * @param parent + * @param scanner + * @param bd + */ + public static void showMessage(Component parent, DeviceScanner scanner, BrowsableEditableData bd) { + + Window window = getWindow(parent); + + JDlgUploadProducts myMsg; + if (window instanceof Frame) { + myMsg = new JDlgUploadProducts((Frame) window, true); + } else { + myMsg = new JDlgUploadProducts((Dialog) window, true); + } + + myMsg.init(scanner, bd); + } + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel2 = new javax.swing.JPanel(); + jcmdCancel = new javax.swing.JButton(); + jcmdOK = new javax.swing.JButton(); + jPanel1 = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(AppLocal.getIntString("caption.upload")); // NOI18N + setResizable(false); + + jPanel2.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT)); + + jcmdCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + jcmdCancel.setText(AppLocal.getIntString("button.cancel")); // NOI18N + jcmdCancel.setPreferredSize(new java.awt.Dimension(110, 45)); + jcmdCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdCancelActionPerformed(evt); + } + }); + jPanel2.add(jcmdCancel); + + jcmdOK.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jcmdOK.setText(AppLocal.getIntString("button.OK")); // NOI18N + jcmdOK.setPreferredSize(new java.awt.Dimension(110, 45)); + jcmdOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdOKActionPerformed(evt); + } + }); + jPanel2.add(jcmdOK); + + getContentPane().add(jPanel2, java.awt.BorderLayout.SOUTH); + + jPanel1.setLayout(null); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLabel1.setText(AppLocal.getIntString("message.preparescanner")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(450, 30)); + jPanel1.add(jLabel1); + jLabel1.setBounds(0, 20, 460, 30); + + getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER); + + setSize(new java.awt.Dimension(474, 161)); + setLocationRelativeTo(null); + }// </editor-fold>//GEN-END:initComponents + + private void jcmdCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdCancelActionPerformed + + dispose(); + }//GEN-LAST:event_jcmdCancelActionPerformed + + private void jcmdOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdOKActionPerformed + + + // Ponemos el estado de leyendo productos + String stext = jLabel1.getText(); + jLabel1.setText(AppLocal.getIntString("label.uploadingproducts")); + jcmdOK.setEnabled(false); + jcmdCancel.setEnabled(false); + + // Ejecutamos la descarga... + try { + m_scanner.connectDevice(); + m_scanner.startUploadProduct(); + + ListModel l = m_bd.getListModel(); + for (int i = 0; i < l.getSize(); i++) { + Object[] myprod = (Object[]) l.getElementAt(i); + m_scanner.sendProduct( + (String) myprod[3], // name + (String) myprod[2], // barcode + (Double) myprod[6] // buy price + ); + } + m_scanner.stopUploadProduct(); + MessageInf msg = new MessageInf(MessageInf.SGN_SUCCESS, AppLocal.getIntString("message.scannerok")); + msg.show(this); + } catch (DeviceScannerException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.scannerfail"), e); + msg.show(this); + } finally { + m_scanner.disconnectDevice(); + } + + // Deshacemos el estado de leyendo productos + jLabel1.setText(stext); + jcmdOK.setEnabled(true); + jcmdCancel.setEnabled(true); + + dispose(); + + }//GEN-LAST:event_jcmdOKActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JButton jcmdCancel; + private javax.swing.JButton jcmdOK; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/inventory/JInventoryLines.form b/src/main/java/com/unicenta/pos/inventory/JInventoryLines.form new file mode 100644 index 0000000..9fa95ed --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/JInventoryLines.form @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JScrollPane" name="jScrollPane1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[455, 402]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JTable" name="m_tableinventory"> + <Properties> + <Property name="autoCreateColumnsFromModel" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="autoResizeMode" type="int" value="0"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + <Property name="selectionBackground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="cc" green="99" red="0" type="rgb"/> + </Property> + <Property name="showVerticalLines" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="mousePressed" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="m_tableinventoryMousePressed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/JInventoryLines.java b/src/main/java/com/unicenta/pos/inventory/JInventoryLines.java new file mode 100644 index 0000000..bdd02f9 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/JInventoryLines.java @@ -0,0 +1,362 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import java.awt.Component; +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.List; +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.DefaultTableColumnModel; +import javax.swing.table.TableColumn; +import javax.swing.table.TableModel; + +/** + * + * @author adrianromero + */ +public class JInventoryLines extends javax.swing.JPanel { + + private InventoryTableModel m_inventorylines; + + /** Creates new form JInventoryLines */ + public JInventoryLines() { + + initComponents(); + + DefaultTableColumnModel columns = new DefaultTableColumnModel(); + TableColumn c; + + c = new TableColumn(0, 150 + , new DataCellRenderer(javax.swing.SwingConstants.LEFT) + , new DefaultCellEditor(new JTextField())); + c.setHeaderValue(AppLocal.getIntString("label.item")); + columns.addColumn(c); + c = new TableColumn(1, 75 + , new DataCellRenderer(javax.swing.SwingConstants.RIGHT) + , new DefaultCellEditor(new JTextField())); + c.setHeaderValue(AppLocal.getIntString("label.units2")); + columns.addColumn(c); + c = new TableColumn(2, 100 + , new DataCellRenderer(javax.swing.SwingConstants.RIGHT) + , new DefaultCellEditor(new JTextField())); + c.setHeaderValue(AppLocal.getIntString("label.price")); + columns.addColumn(c); + c = new TableColumn(3, 100 + , new DataCellRenderer(javax.swing.SwingConstants.RIGHT) + , new DefaultCellEditor(new JTextField())); + c.setHeaderValue(AppLocal.getIntString("label.prodvaluebuy")); + columns.addColumn(c); + + m_tableinventory.setColumnModel(columns); + + m_tableinventory.getTableHeader().setReorderingAllowed(false); + m_tableinventory.setRowHeight(30); + m_tableinventory.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + m_tableinventory.setIntercellSpacing(new java.awt.Dimension(0, 1)); + + m_inventorylines = new InventoryTableModel(); + m_tableinventory.setModel(m_inventorylines); + + + } + + /** + * + */ + public void clear() { + m_inventorylines.clear(); + } + + /** + * + * @param i + */ + public void addLine(InventoryLine i) { + m_inventorylines.addRow(i); + setSelectedIndex(m_inventorylines.getRowCount() - 1); + } + + /** + * + * @param index + */ + public void deleteLine(int index) { + m_inventorylines.removeRow(index); + + // Escojo una a seleccionar + if (index >= m_inventorylines.getRowCount()) { + index = m_inventorylines.getRowCount() - 1; + } + + if ((index >= 0) && (index < m_inventorylines.getRowCount())) { + // Solo seleccionamos si podemos. + setSelectedIndex(index); + } + } + + /** + * + * @param index + * @param i + */ + public void setLine(int index, InventoryLine i) { + m_inventorylines.setRow(index, i); + setSelectedIndex(index); + } + + /** + * + * @param index + * @return + */ + public InventoryLine getLine(int index) { + return m_inventorylines.getRow(index); + } + + /** + * + * @return + */ + public List<InventoryLine> getLines() { + return m_inventorylines.getLines(); + } + + /** + * + * @return + */ + public int getCount() { + return m_inventorylines.getRowCount(); + } + + /** + * + * @return + */ + public int getSelectedRow() { + return m_tableinventory.getSelectedRow(); + } + + /** + * + * @param i + */ + public void setSelectedIndex(int i){ + + // Seleccionamos + m_tableinventory.getSelectionModel().setSelectionInterval(i, i); + + // Hacemos visible la seleccion. + Rectangle oRect = m_tableinventory.getCellRect(i, 0, true); + m_tableinventory.scrollRectToVisible(oRect); + } + + /** + * + */ + public void goDown() { + + int i = m_tableinventory.getSelectionModel().getMaxSelectionIndex(); + if (i < 0){ + i = 0; // No hay ninguna seleccionada + } else { + i ++; + if (i >= m_inventorylines.getRowCount()) { + i = m_inventorylines.getRowCount() - 1; + } + } + + if ((i >= 0) && (i < m_inventorylines.getRowCount())) { + // Solo seleccionamos si podemos. + + setSelectedIndex(i); + } + } + + /** + * + */ + public void goUp() { + int i = m_tableinventory.getSelectionModel().getMinSelectionIndex(); + if (i < 0){ + i = m_inventorylines.getRowCount() - 1; // No hay ninguna seleccionada + } else { + i --; + if (i < 0) { + i = 0; + } + } + + if ((i >= 0) && (i < m_inventorylines.getRowCount())) { + // Solo seleccionamos si podemos. + setSelectedIndex(i); + } + } + + private static class InventoryTableModel extends AbstractTableModel { +// JG 16 May 2013 use diamond inference + private final ArrayList<InventoryLine> m_rows = new ArrayList<>(); + + @Override + public int getRowCount() { + return m_rows.size(); + } + @Override + public int getColumnCount() { + return 4; + } + @Override + public String getColumnName(int column) { + //return AppLocal.getIntString(m_acolumns[column].name); + return "a"; + } + @Override + public Object getValueAt(int row, int column) { + + InventoryLine i = m_rows.get(row); + switch (column) { + case 0: return "<html>" + i.getProductName() + ( + i.getProductAttSetInstDesc() == null + ? "" + : "<br>" + i.getProductAttSetInstDesc()); + case 1: return "x" + Formats.DOUBLE.formatValue(i.getMultiply()); + case 2: return Formats.CURRENCY.formatValue(i.getPrice()); + case 3: return Formats.CURRENCY.formatValue(i.getSubValue()); + default: return null; + } + + } + + @Override + public boolean isCellEditable(int row, int column) { + return false; + } + + public void clear() { + int old = getRowCount(); + if (old > 0) { + m_rows.clear(); + fireTableRowsDeleted(0, old - 1); + } + } + + public List<InventoryLine> getLines() { + return m_rows; + } + + public InventoryLine getRow(int index) { + return m_rows.get(index); + } + + public void setRow(int index, InventoryLine oLine){ + + m_rows.set(index, oLine); + fireTableRowsUpdated(index, index); + } + + public void addRow(InventoryLine oLine) { + + insertRow(m_rows.size(), oLine); + } + + public void insertRow(int index, InventoryLine oLine) { + + m_rows.add(index, oLine); + fireTableRowsInserted(index, index); + } + + public void removeRow(int row) { + m_rows.remove(row); + fireTableRowsDeleted(row, row); + } + } + private static class DataCellRenderer extends DefaultTableCellRenderer { + + private int m_iAlignment; + + public DataCellRenderer(int align) { + m_iAlignment = align; + } + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column){ + + JLabel aux = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + aux.setVerticalAlignment(javax.swing.SwingConstants.TOP); + aux.setHorizontalAlignment(m_iAlignment); + if (!isSelected) { + aux.setBackground(javax.swing.UIManager.getDefaults().getColor("TextField.disabledBackground")); + } + return aux; + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jScrollPane1 = new javax.swing.JScrollPane(); + m_tableinventory = new javax.swing.JTable(); + + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + setLayout(new java.awt.BorderLayout()); + + jScrollPane1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jScrollPane1.setPreferredSize(new java.awt.Dimension(455, 402)); + + m_tableinventory.setAutoCreateColumnsFromModel(false); + m_tableinventory.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_tableinventory.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF); + m_tableinventory.setFocusable(false); + m_tableinventory.setRequestFocusEnabled(false); + m_tableinventory.setSelectionBackground(new java.awt.Color(0, 153, 204)); + m_tableinventory.setShowVerticalLines(false); + m_tableinventory.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + m_tableinventoryMousePressed(evt); + } + }); + jScrollPane1.setViewportView(m_tableinventory); + + add(jScrollPane1, java.awt.BorderLayout.CENTER); + }// </editor-fold>//GEN-END:initComponents + + private void m_tableinventoryMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_m_tableinventoryMousePressed + + }//GEN-LAST:event_m_tableinventoryMousePressed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JTable m_tableinventory; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/inventory/LocationInfo.java b/src/main/java/com/unicenta/pos/inventory/LocationInfo.java new file mode 100644 index 0000000..fde67ed --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/LocationInfo.java @@ -0,0 +1,117 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.IKeyed; +import com.unicenta.data.loader.SerializableRead; + +/** + * + * @author adrianromero + * Created on February 13, 2007, 10:13 AM + * + */ +public class LocationInfo implements SerializableRead, IKeyed { + + private static final long serialVersionUID = 9032683595230L; + private String m_sID; + private String m_sName; + private String m_sAddress; + + /** Creates a new instance of LocationInfo */ + public LocationInfo() { + m_sID = null; + m_sName = null; + m_sAddress = null; + } + + /** + * + * @return + */ + public Object getKey() { + return m_sID; + } + + /** + * + * @param dr + * @throws BasicException + */ + public void readValues(DataRead dr) throws BasicException { + m_sID = dr.getString(1); + m_sName = dr.getString(2); + m_sAddress = dr.getString(3); + } + + /** + * + * @param sID + */ + public void setID(String sID) { + m_sID = sID; + } + + /** + * + * @return + */ + public String getID() { + return m_sID; + } + + /** + * + * @return + */ + public String getName() { + return m_sName; + } + + /** + * + * @param sName + */ + public void setName(String sName) { + m_sName = sName; + } + + /** + * + * @return + */ + public String getAddress() { + return m_sAddress; + } + + /** + * + * @param sAddress + */ + public void setAddress(String sAddress) { + m_sAddress = sAddress; + } + + public String toString(){ + return m_sName; + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/LocationsPanel.java b/src/main/java/com/unicenta/pos/inventory/LocationsPanel.java new file mode 100644 index 0000000..627e71d --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/LocationsPanel.java @@ -0,0 +1,120 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.data.gui.ListCellRendererBasic; +import com.unicenta.data.loader.ComparatorCreator; +import com.unicenta.data.loader.TableDefinition; +import com.unicenta.data.loader.Vectorer; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.panels.JPanelTable; +import javax.swing.ListCellRenderer; + +/** + * + * @author adrianromero + */ +public class LocationsPanel extends JPanelTable { + + private TableDefinition tlocations; + private LocationsView jeditor; + + /** Creates a new instance of LocationsPanel */ + public LocationsPanel() { + } + + /** + * + */ + @Override + protected void init() { + DataLogicSales dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + tlocations = dlSales.getTableLocations(); + jeditor = new LocationsView(dirty); + } + + /** + * + * @return + */ + @Override + public ListProvider getListProvider() { + return new ListProviderCreator(tlocations); + } + + /** + * + * @return + */ + @Override + public SaveProvider getSaveProvider() { + return new SaveProvider(tlocations); + } + + /** + * + * @return + */ + @Override + public Vectorer getVectorer() { + return tlocations.getVectorerBasic(new int[]{1, 2}); + } + + /** + * + * @return + */ + @Override + public ComparatorCreator getComparatorCreator() { + return tlocations.getComparatorCreator(new int[] {1, 2}); + } + + /** + * + * @return + */ + @Override + public ListCellRenderer getListCellRenderer() { + return new ListCellRendererBasic(tlocations.getRenderStringBasic(new int[]{1})); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return jeditor; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.Locations"); + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/LocationsView.form b/src/main/java/com/unicenta/pos/inventory/LocationsView.form new file mode 100644 index 0000000..3db3357 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/LocationsView.form @@ -0,0 +1,105 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jAddress" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="m_jName" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jName" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jAddress" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/info.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.locationname" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="jLabel2MouseClicked"/> + </Events> + </Component> + <Component class="javax.swing.JTextField" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[220, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.locationaddress" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jAddress"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[220, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/LocationsView.java b/src/main/java/com/unicenta/pos/inventory/LocationsView.java new file mode 100644 index 0000000..4d052fe --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/LocationsView.java @@ -0,0 +1,227 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import java.awt.Component; +import java.awt.datatransfer.StringSelection; +import java.util.UUID; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import javax.swing.JOptionPane; + +/** + * + * @author adrianromero + */ +public final class LocationsView extends javax.swing.JPanel implements EditorRecord { + + // private DirtyManager m_Dirty = new DirtyManager(); + private String m_sID; + + /** Creates new form LocationsEditor + * @param dirty */ + public LocationsView(DirtyManager dirty) { + initComponents(); + + m_jName.getDocument().addDocumentListener(dirty); + m_jAddress.getDocument().addDocumentListener(dirty); + + writeValueEOF(); + } + + /** + * + */ + @Override + public void writeValueEOF() { + + m_sID = null; + m_jName.setText(null); + m_jAddress.setText(null); + + m_jName.setEnabled(false); + m_jAddress.setEnabled(false); + } + + /** + * + */ + @Override + public void writeValueInsert() { + + m_sID = UUID.randomUUID().toString(); + m_jName.setText(null); + m_jAddress.setText(null); + + m_jName.setEnabled(true); + m_jAddress.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueDelete(Object value) { + + Object[] location = (Object[]) value; + m_sID = Formats.STRING.formatValue(location[0]); + m_jName.setText(Formats.STRING.formatValue(location[1])); + m_jAddress.setText(Formats.STRING.formatValue(location[2])); + + m_jName.setEnabled(false); + m_jAddress.setEnabled(false); + } + + /** + * + * @param value + */ + @Override + public void writeValueEdit(Object value) { + + Object[] location = (Object[]) value; + m_sID = Formats.STRING.formatValue(location[0]); + m_jName.setText(Formats.STRING.formatValue(location[1])); + m_jAddress.setText(Formats.STRING.formatValue(location[2])); + + m_jName.setEnabled(true); + m_jAddress.setEnabled(true); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + Object[] location = new Object[3]; + location[0] = m_sID; + location[1] = m_jName.getText(); + location[2] = m_jAddress.getText(); + return location; + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + */ + @Override + public void refresh() { + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel2 = new javax.swing.JLabel(); + m_jName = new javax.swing.JTextField(); + jLabel3 = new javax.swing.JLabel(); + m_jAddress = new javax.swing.JTextField(); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/info.png"))); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.locationname")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(110, 30)); + jLabel2.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + jLabel2MouseClicked(evt); + } + }); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(220, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.locationaddress")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jAddress.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jAddress.setPreferredSize(new java.awt.Dimension(220, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jAddress, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jAddress, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + ); + }// </editor-fold>//GEN-END:initComponents + + private void jLabel2MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabel2MouseClicked + + if (evt.getClickCount() == 2) { + String uuidString = m_sID; + StringSelection stringSelection = new StringSelection(uuidString); + Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard(); + clpbrd.setContents(stringSelection, null); + + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.uuidcopy")); + } + }//GEN-LAST:event_jLabel2MouseClicked + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JTextField m_jAddress; + private javax.swing.JTextField m_jName; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/inventory/MaterialFilter.form b/src/main/java/com/unicenta/pos/inventory/MaterialFilter.form new file mode 100644 index 0000000..60c0ba6 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/MaterialFilter.form @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32767, 160]"/> + </Property> + <Property name="opaque" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[500, 160]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,123,0,0,2,101"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="1"/> + </Layout> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder title="By Form"> + <ResourceString PropertyName="titleX" bundle="pos_messages.properties" key="label.byform" replaceFormat="AppLocal.getIntString("{key}")"/> + </TitledBorder> + </Border> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32767, 140]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[500, 140]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout"> + <Property name="useNullLayout" type="boolean" value="true"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodpricebuy" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="20" y="50" width="130" height="25"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCboName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="150" y="20" width="150" height="25"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="310" y="20" width="180" height="25"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="m_jPriceBuy"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="310" y="50" width="60" height="25"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCboPriceBuy"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="150" y="50" width="150" height="25"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodname" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="20" y="20" width="130" height="25"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.stockproduct" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="20" y="80" width="130" height="25"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCboProduct"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="150" y="80" width="220" height="25"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/MaterialFilter.java b/src/main/java/com/unicenta/pos/inventory/MaterialFilter.java new file mode 100644 index 0000000..1e0bdf2 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/MaterialFilter.java @@ -0,0 +1,164 @@ +// Opentpv is a point of sales application designed for touch screens. +// Copyright (c) 2009-20162008 Open Sistemas de Información Internet, S.L. +// Copyright (c) 2009-20162007-2008 Openbravo, S.L. +// http://www.opensistemas.com +// e-mail: imasd@opensistemas.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.gui.ListQBFModelNumber; +import com.unicenta.data.loader.QBFCompareEnum; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.user.EditorCreator; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSales; + +/** + * + * @author Luis Ig. Bacas Riveiro lbacas@opensistemas.com + * @author Pablo J. Urbano Santos purbano@opensistemas.com + */ +public class MaterialFilter extends javax.swing.JPanel implements EditorCreator { + + private SentenceList m_sentprods; + private ComboBoxValModel m_ProdsModel; + + /** Creates new form JQBFProduct + * @param dlSales */ + public MaterialFilter(DataLogicSales dlSales) { + initComponents(); + + //El modelo de productos + m_sentprods = dlSales.getProductList(); + m_ProdsModel = new ComboBoxValModel(); + + m_jCboName.setModel(new ListQBFModelNumber()); + m_jCboPriceBuy.setModel(new ListQBFModelNumber()); + } + + /** + * + * @throws BasicException + */ + public void activate() throws BasicException { + java.util.List prodlist = m_sentprods.list(); + prodlist.add(0, null); + m_ProdsModel.refresh(prodlist); + m_jCboProduct.setModel(m_ProdsModel); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + return new Object[] { + m_jCboName.getSelectedItem(), m_jName.getText(), + m_jCboPriceBuy.getSelectedItem(), Formats.CURRENCY.parseValue(m_jPriceBuy.getText()), + m_ProdsModel.getSelectedKey() == null ? QBFCompareEnum.COMP_NONE : QBFCompareEnum.COMP_EQUALS, m_ProdsModel.getSelectedKey() + }; + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jLabel4 = new javax.swing.JLabel(); + m_jCboName = new javax.swing.JComboBox(); + m_jName = new javax.swing.JTextField(); + m_jPriceBuy = new javax.swing.JTextField(); + m_jCboPriceBuy = new javax.swing.JComboBox(); + jLabel2 = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + m_jCboProduct = new javax.swing.JComboBox(); + + setMaximumSize(new java.awt.Dimension(32767, 160)); + setOpaque(false); + setPreferredSize(new java.awt.Dimension(500, 160)); + setRequestFocusEnabled(false); + setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.Y_AXIS)); + + jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(AppLocal.getIntString("label.byform"))); // NOI18N + jPanel1.setMaximumSize(new java.awt.Dimension(32767, 140)); + jPanel1.setPreferredSize(new java.awt.Dimension(500, 140)); + jPanel1.setRequestFocusEnabled(false); + jPanel1.setLayout(null); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.prodpricebuy")); // NOI18N + jPanel1.add(jLabel4); + jLabel4.setBounds(20, 50, 130, 25); + + m_jCboName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanel1.add(m_jCboName); + m_jCboName.setBounds(150, 20, 150, 25); + + m_jName.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel1.add(m_jName); + m_jName.setBounds(310, 20, 180, 25); + + m_jPriceBuy.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel1.add(m_jPriceBuy); + m_jPriceBuy.setBounds(310, 50, 60, 25); + + m_jCboPriceBuy.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanel1.add(m_jCboPriceBuy); + m_jCboPriceBuy.setBounds(150, 50, 150, 25); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.prodname")); // NOI18N + jPanel1.add(jLabel2); + jLabel2.setBounds(20, 20, 130, 25); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.stockproduct")); // NOI18N + jPanel1.add(jLabel3); + jLabel3.setBounds(20, 80, 130, 25); + + m_jCboProduct.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanel1.add(m_jCboProduct); + m_jCboProduct.setBounds(150, 80, 220, 25); + + add(jPanel1); + }// </editor-fold>//GEN-END:initComponents + + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JPanel jPanel1; + private javax.swing.JComboBox m_jCboName; + private javax.swing.JComboBox m_jCboPriceBuy; + private javax.swing.JComboBox m_jCboProduct; + private javax.swing.JTextField m_jName; + private javax.swing.JTextField m_jPriceBuy; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/inventory/MaterialProdInfo.java b/src/main/java/com/unicenta/pos/inventory/MaterialProdInfo.java new file mode 100644 index 0000000..85716f0 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/MaterialProdInfo.java @@ -0,0 +1,169 @@ +// Openbravo POS is a point of sales application designed for touch screens. +// Copyright (c) 2009-20162008 Open Sistemas de Información Internet, S.L. +// http://www.opensistemas.com +// http://sourceforge.net/projects/openbravopos +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.IKeyed; +import com.unicenta.data.loader.SerializableRead; +import com.unicenta.pos.ticket.ProductInfoExt; + +/** + * Clase para la gestion de los materiales de un producto (escandallo) + * @author Luis Ig. Bacas Riveiro lbacas@opensistemas.com + * @author Pablo J. Urbano Santos purbano@opensistemas.com + */ +public class MaterialProdInfo implements SerializableRead, IKeyed { + private String m_sID; + private String m_sName; + private double m_dPriceBuy; + private double m_dAmount; + private String m_sUnit; + + /** + * + */ + public MaterialProdInfo() { + m_sID = null; + m_sName = null; + m_dPriceBuy = 0.0; + m_dAmount = 0.0; + m_sUnit = null; + } + + /** + * + * @param p + */ + public MaterialProdInfo(ProductInfoExt p) { + m_sID = p.getID(); + m_sName = p.getName(); + m_dPriceBuy = p.getPriceBuy(); + m_dAmount = 1.0; + } + + /** + * + * @param dr + * @throws BasicException + */ + @Override + public void readValues(DataRead dr) throws BasicException { + m_sID = dr.getString(1); + m_sName = dr.getString(2); + m_dPriceBuy = dr.getDouble(3).doubleValue(); + m_dAmount = (dr.getDouble(4) == null) ? 1.0 : dr.getDouble(4).doubleValue(); + m_sUnit = dr.getString(5); + } + + /** + * + * @param id + */ + public void setID (String id) { + m_sID = id; + } + + /** + * + * @return + */ + public String getID() { + return m_sID; + } + + /** + * + * @param name + */ + public void setName (String name) { + m_sName = name; + } + + /** + * + * @return + */ + public String getName() { + return m_sName; + } + + /** + * + * @param price + */ + public void setPriceBuy (double price) { + m_dPriceBuy = price; + } + + /** + * + * @return + */ + public double getPriceBuy() { + return m_dPriceBuy; + } + + /** + * + * @param amount + */ + public void setAmount (double amount) { + m_dAmount = amount; + } + + /** + * + * @return + */ + public double getAmount() { + return m_dAmount; + } + + /** + * + * @param unit + */ + public void setUnit (String unit) { + m_sUnit = unit; + } + + /** + * + * @return + */ + public String getUnit() { + return m_sUnit; + } + + /** + * + * @return + */ + @Override + public Object getKey() { + return m_sID; + } + + @Override + public final String toString() { + return (m_sName +" - "+m_dAmount+" "+m_sUnit); + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/MovementReason.java b/src/main/java/com/unicenta/pos/inventory/MovementReason.java new file mode 100644 index 0000000..c3478ca --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/MovementReason.java @@ -0,0 +1,85 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.pos.panels.ComboItemLocal; + +/** + * + * @author adrianromero + */ +public class MovementReason extends ComboItemLocal { + +// IN values + public static final MovementReason IN_PURCHASE = new MovementReason(+1, "stock.in.purchase"); + public static final MovementReason IN_REFUND = new MovementReason(+2, "stock.in.refund"); + public static final MovementReason IN_MOVEMENT = new MovementReason(+4, "stock.in.movement"); + +// OUT values + public static final MovementReason OUT_SALE = new MovementReason(-1, "stock.out.sale"); + public static final MovementReason OUT_REFUND = new MovementReason(-2, "stock.out.refund"); + public static final MovementReason OUT_BREAK = new MovementReason(-3, "stock.out.break"); + public static final MovementReason OUT_MOVEMENT = new MovementReason(-4, "stock.out.movement"); + + public static final MovementReason OUT_SAMPLE = new MovementReason(-5, "stock.out.sample"); + public static final MovementReason OUT_FREE = new MovementReason(-6, "stock.out.free"); + public static final MovementReason OUT_USED = new MovementReason(-7, "stock.out.used"); + public static final MovementReason OUT_SUBTRACT = new MovementReason(-8, "stock.out.subtract"); + +// TRANSFER + public static final MovementReason OUT_CROSSING = new MovementReason(1000, "stock.out.crossing"); + + private MovementReason(Integer iKey, String sKeyValue) { + super(iKey, sKeyValue); + } + + public boolean isInput() { + return m_iKey.intValue() > 0; + } + + public Double samesignum(Double d) { + + if (d == null || m_iKey == null) { + return d; + } else if ((m_iKey.intValue() > 0 && d.doubleValue() < 0.0) || + (m_iKey.intValue() < 0 && d.doubleValue() > 0.0)) { + return -d.doubleValue(); + } else { + return d; + } + } + + /** + * + * @param dBuyPrice + * @param dSellPrice + * @return + */ + public Double getPrice(Double dBuyPrice, Double dSellPrice) { + + if (this == IN_PURCHASE || this == OUT_REFUND || this == OUT_BREAK) { + return dBuyPrice; + } else if (this == OUT_SALE || this == IN_REFUND) { + return dSellPrice; + } else { + return null; + } + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/PriceImportPanel.java b/src/main/java/com/unicenta/pos/inventory/PriceImportPanel.java new file mode 100644 index 0000000..0c2e058 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/PriceImportPanel.java @@ -0,0 +1,148 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// Portions Contributed by: John D L 2013 +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.user.EditorListener; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.panels.JPanelTable2; +import com.unicenta.pos.ticket.ProductFilter; +import java.awt.Component; +import javax.swing.JButton; + +/** + * + * @author adrianromero + * Created on 1 de marzo de 2007, 22:15 + * + */ +public class PriceImportPanel extends JPanelTable2 implements EditorListener { + + private ProductsEditor jeditor; + private ProductFilter jproductfilter; + + private DataLogicSales m_dlSales = null; + + /** Creates a new instance of ProductsPanel2 */ + public PriceImportPanel() { + } + + /** + * + */ + @Override + protected void init() { + m_dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + + // el panel del filtro + jproductfilter = new ProductFilter(); + jproductfilter.init(app); + + row = m_dlSales.getProductsRow(); + + lpr = new ListProviderCreator(m_dlSales.getProductCatQBF(), jproductfilter); + + spr = new SaveProvider( + m_dlSales.getProductCatUpdate(), + m_dlSales.getProductCatInsert(), + m_dlSales.getProductCatDelete()); + + // el panel del editor + jeditor = new ProductsEditor(app, dirty); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return jeditor; + } + + /** + * + * @return + */ + @Override + public Component getFilter() { + return jproductfilter.getComponent(); + } + + /** + * + * @return + */ + @Override + public Component getToolbarExtras() { + + JButton btnScanPal = new JButton(); + btnScanPal.setText("ScanPal"); + btnScanPal.setVisible(app.getDeviceScanner() != null); + btnScanPal.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnScanPalActionPerformed(evt); + } + }); + + return btnScanPal; + } + + private void btnScanPalActionPerformed(java.awt.event.ActionEvent evt) { + + JDlgUploadProducts.showMessage(this, app.getDeviceScanner(), bd); + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.StockImport"); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + + jeditor.activate(); + jproductfilter.activate(); + + super.activate(); + } + + /** + * + * @param value + */ + @Override + public void updateValue(Object value) { + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/ProductStock.java b/src/main/java/com/unicenta/pos/inventory/ProductStock.java new file mode 100644 index 0000000..826f54c --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/ProductStock.java @@ -0,0 +1,186 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.SerializerRead; +import java.util.Date; + +/** + * + * @author JG uniCenta May 15 + * Used in Product stock tab to display all this Product's + * location values + */ +public class ProductStock { + + String pId; + String location; + Double units; + Double minimum; + Double maximum; + Double pricebuy; + Double pricesell; + Date memodate; + + /** + * Main method to return a product's "live" stock position + */ + public ProductStock() { + } + + /** + * + * @param pId + * @param location + * @param units + * @param minimum + * @param maximum + * @param pricebuy + * @param pricesell + * @param memodate + */ + public ProductStock(String pId, String location, Double units, Double minimum, + Double maximum, Double pricebuy, Double pricesell, Date memodate) { + + this.pId = pId; + this.location = location; + this.units = units; + this.minimum = minimum; + this.maximum = maximum; + this.pricebuy = pricebuy; + this.pricesell = pricesell; + this.memodate = memodate; + } + + /** + * + * @return product id string + */ + public String getProductId() { + return pId; + } + public void setProductId(String pId) { + this.pId = pId; + } + + /** + * + * @return product's location string + */ + public String getLocation() { + return location; + } + public void setLocation(String location) { + this.location = location; + } + + /** + * + * @return product's quantity string value + */ + public Double getUnits() { + return units; + } + public void setUnits(Double units) { + this.units = units; + } + + /** + * + * @return + */ + public Double getMinimum() { + return minimum; + } + public void setMinimum(Double minimum) { + this.minimum = minimum; + } + + /** + * + * @return maximum value + */ + public Double getMaximum() { + return maximum; + } + public void setMaximum(Double maximum) { + this.maximum = maximum; + } + + /** + * + * @return price buy + */ + public Double getPriceBuy() { + return pricebuy; + } + public void setPriceBuy(Double pricebuy) { + this.pricebuy = pricebuy; + } + + /** + * + * @return price sell + */ + public Double getPriceSell() { + return pricesell; + } + public void setPriceSell(Double pricesell) { + this.pricesell = pricesell; + } + /** + * + * @return memodate Date value + */ + public Date getMemoDate() { + return memodate; + } + public void setMemoDate(Date memodate) { + this.memodate = memodate; + } + + + /** + * + * @return stock for this product + */ + public static SerializerRead getSerializerRead() { + return new SerializerRead() { + + @Override + public Object readValues(DataRead dr) throws BasicException { + + String pId = dr.getString(1); + String location = dr.getString(2); + Double units = dr.getDouble(3); + Double minimum = dr.getDouble(4); + Double maximum = dr.getDouble(5); + Double pricebuy = dr.getDouble(6); + Double pricesell = dr.getDouble(7); + Date memodate = dr.getTimestamp(8); + + return + new ProductStock(pId, location, units, minimum, maximum, pricebuy, pricesell, memodate); + } + }; + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/inventory/ProductsBundleInfo.java b/src/main/java/com/unicenta/pos/inventory/ProductsBundleInfo.java new file mode 100644 index 0000000..0601a02 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/ProductsBundleInfo.java @@ -0,0 +1,92 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.SerializerRead; + +/** + * + * @author Jack G + */ +public class ProductsBundleInfo { + private static final long serialVersionUID = 7587646873036L; + + protected String id; + protected String productId; + protected String productBundleId; + protected Double quantity; + + /** + * + * @param id + * @param productId + * @param productBundleId + * @param quantity + */ + public ProductsBundleInfo(String id, String productId, String productBundleId, Double quantity) { + this.id = id; + this.productId = productId; + this.productBundleId = productBundleId; + this.quantity = quantity; + } + + + public void setM_ID(String id) { + this.id = id; + } + + public void setM_sProduct(String productId) { + this.productId = productId; + } + + public void setM_sProductBundle(String productBundleId) { + this.productBundleId = productBundleId; + } + + public void setM_dQuantity(Double m_dQuantity) { + this.quantity = quantity; + } + + public String getId() { + return id; + } + + public String getProductId() { + return productId; + } + + public String getProductBundleId() { + return productBundleId; + } + + public Double getQuantity() { + return quantity; + } + + + public static SerializerRead getSerializerRead() { + return (DataRead dr) -> new ProductsBundleInfo(dr.getString(1) + , dr.getString(2) + , dr.getString(3) + , dr.getDouble(4)); + } + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/inventory/ProductsEditor.form b/src/main/java/com/unicenta/pos/inventory/ProductsEditor.form new file mode 100644 index 0000000..1f16c9c --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/ProductsEditor.form @@ -0,0 +1,1823 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.5" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-76,0,0,2,-122"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout"> + <Property name="useNullLayout" type="boolean" value="true"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="m_jTitle"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" red="ff" type="rgb"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="verticalAlignment" type="int" value="3"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="horizontalTextPosition" type="int" value="4"/> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[260, 25]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="365" y="5" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Container class="javax.swing.JTabbedPane" name="jTabbedPane1"> + <Properties> + <Property name="toolTipText" type="java.lang.String" value=""/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[680, 420]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="10" y="10" width="630" height="-1"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.product.general.tab" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 0]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription"> + <JTabbedPaneConstraints tabName="General"> + <Property name="tabTitle" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodgeneral" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </JTabbedPaneConstraints> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="jLabel2" max="32767" attributes="0"/> + <Component id="jLabel5" max="32767" attributes="0"/> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="10" pref="10" max="-2" attributes="0"/> + <Component id="jLabel13" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel7" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel16" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel4" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="m_jPriceSell" min="-2" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jGrossProfit" alignment="0" min="-2" max="-2" attributes="0"/> + <Group type="103" alignment="0" groupAlignment="1" attributes="0"> + <Component id="m_jUom" min="-2" max="-2" attributes="0"/> + <Group type="102" attributes="0"> + <Component id="jLabel22" min="-2" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="m_jmargin" max="32767" attributes="0"/> + <Component id="jLabel19" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </Group> + <EmptySpace min="-2" pref="115" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jName" alignment="0" max="-2" attributes="0"/> + <Group type="102" attributes="0"> + <Component id="m_jAtt" min="-2" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="m_jVerpatrib" min="-2" pref="120" max="-2" attributes="0"/> + </Group> + <Component id="m_jTax" alignment="0" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Component id="m_jPriceSellTax" min="-2" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="jLabel26" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="m_jCategory" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + </Group> + </Group> + <EmptySpace min="-2" pref="50" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jRef" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel6" min="-2" pref="78" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCode" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCodetype" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jPriceBuy" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel17" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jSupplier" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jBtnSupplier" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jRef" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel6" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCode" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCodetype" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jName" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jCategory" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel13" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jAtt" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jVerpatrib" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jTax" min="-2" max="-2" attributes="0"/> + <Component id="jLabel7" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel16" min="-2" max="-2" attributes="0"/> + <Component id="m_jPriceSellTax" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel26" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jUom" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jPriceSell" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + <Component id="m_jPriceBuy" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel22" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel19" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jGrossProfit" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jmargin" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel17" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jSupplier" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jBtnSupplier" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" pref="14" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/info.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodrefm" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="jLabel1MouseClicked"/> + </Events> + </Component> + <Component class="javax.swing.JTextField" name="m_jRef"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value=""/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="m_jRefFocusLost"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodbarcodem" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jCode"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[125, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="m_jCodeFocusLost"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCodetype"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="5"> + <StringItem index="0" value="EAN-13"/> + <StringItem index="1" value="EAN-8"/> + <StringItem index="2" value="CODE128"/> + <StringItem index="3" value="Upc-A"/> + <StringItem index="4" value="Upc-E"/> + </StringArray> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodnamem" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[450, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="m_jNameFocusLost"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodcategorym" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCategory"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[450, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel13"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.attributes" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jAtt"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel7"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.taxcategorym" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jTax"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel16"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodpriceselltaxm" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jPriceSellTax"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodpricesell" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jPriceSell"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel19"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.margin" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jmargin"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor"> + <Color id="Text Cursor"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodpricebuym" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jPriceBuy"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="0"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="m_jVerpatrib"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.mandatory" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="horizontalTextPosition" type="int" value="10"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[49, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="none"/> + </Events> + </Component> + <Component class="javax.swing.JTextField" name="m_jGrossProfit"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="disabledTextColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="0" green="0" red="0" type="rgb"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel22"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.grossprofit" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="horizontalTextPosition" type="int" value="0"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel26"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.UOM" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jUom"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel17"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodsupplier" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jSupplier"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jBtnSupplier"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/customer_add_sml.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.supplier" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnSupplierActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Properties> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.product.stock.tab" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 0]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription"> + <JTabbedPaneConstraints tabName="Stock"> + <Property name="tabTitle" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodstock" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </JTabbedPaneConstraints> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="1" attributes="0"> + <Component id="jLabel18" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="jLabel8" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jCatalogOrder" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="m_jInCatalog" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="webLabel1" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jPrintTo" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="1" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel14" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jConstant" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel9" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="jLabel10" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="m_jstockvolume" max="-2" attributes="0"/> + <Component id="m_jstockcost" max="-2" attributes="0"/> + </Group> + </Group> + <Component id="jLabel23" pref="0" max="32767" attributes="0"/> + </Group> + </Group> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel15" alignment="0" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel33" min="-2" max="-2" attributes="0"/> + <Component id="jLabel11" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="jLabel12" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="jLabel20" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="m_jService" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="m_jCheckWarrantyReceipt" min="-2" max="-2" attributes="0"/> + <Component id="m_jComment" min="-2" max="-2" attributes="0"/> + <Component id="m_jScale" min="-2" max="-2" attributes="0"/> + <Component id="m_jVprice" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" attributes="0"> + <Component id="m_jPrintKB" min="-2" pref="30" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jSendStatus" min="-2" pref="30" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jStockUnits" min="-2" pref="24" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="jScrollPane2" min="-2" pref="372" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="1" attributes="0"> + <Component id="jLblDate" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jbtndate" min="-2" pref="40" max="-2" attributes="0"/> + <EmptySpace min="0" pref="0" max="-2" attributes="0"/> + <Component id="m_jdate" min="-2" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + <Component id="jBtnShowTrans" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jstockcost" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel9" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel14" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="m_jConstant" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jstockvolume" alignment="0" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + <Component id="jLabel10" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel23" min="-2" pref="30" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel8" min="-2" max="-2" attributes="0"/> + <Component id="m_jInCatalog" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jCatalogOrder" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel18" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="webLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jPrintTo" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jBtnShowTrans" min="-2" pref="30" max="-2" attributes="0"/> + <Component id="m_jbtndate" min="-2" pref="30" max="-2" attributes="0"/> + <Component id="m_jdate" min="-2" max="-2" attributes="0"/> + <Component id="jLblDate" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jScrollPane2" min="-2" pref="206" max="-2" attributes="0"/> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel15" min="-2" max="-2" attributes="0"/> + <Component id="m_jService" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel33" min="-2" max="-2" attributes="0"/> + <Component id="m_jCheckWarrantyReceipt" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel11" min="-2" max="-2" attributes="0"/> + <Component id="m_jComment" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel12" min="-2" max="-2" attributes="0"/> + <Component id="m_jScale" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel20" min="-2" max="-2" attributes="0"/> + <Component id="m_jVprice" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" alignment="0" groupAlignment="1" attributes="0"> + <Component id="m_jPrintKB" min="-2" pref="25" max="-2" attributes="0"/> + <Component id="m_jSendStatus" min="-2" pref="25" max="-2" attributes="0"/> + </Group> + <Component id="m_jStockUnits" alignment="1" min="-2" pref="25" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace min="-2" pref="42" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel9"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodstockcost" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jstockcost"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[85, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel10"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodstockvol" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jstockvolume"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[85, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodincatalog" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[130, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="m_jInCatalog"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + <Property name="selected" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jInCatalogActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel18"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodorder" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[130, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jCatalogOrder"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel15"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.service" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[130, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="m_jService"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="A Service Item will not be deducted from the Inventory"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 30]"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" value="null"/> + </AccessibilityProperties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel11"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodaux" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[130, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="m_jComment"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel12"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodscale" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[130, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="m_jScale"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="m_jConstant"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel14"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodconstant" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[130, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel20"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.variableprice" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[130, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="m_jVprice"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel33"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.warranty" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.warranty" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[130, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="m_jCheckWarrantyReceipt"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.productreceipt" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel23"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodminmax" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="verticalAlignment" type="int" value="1"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[531, 20]"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.label.WebLabel" name="webLabel1"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.printto" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.printto" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[130, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jPrintTo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="7"> + <StringItem index="0" value="0"/> + <StringItem index="1" value="1"/> + <StringItem index="2" value="2"/> + <StringItem index="3" value="3"/> + <StringItem index="4" value="4"/> + <StringItem index="5" value="5"/> + <StringItem index="6" value="6"/> + </StringArray> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jBtnShowTrans"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.ProductStock" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value=""/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 25]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnShowTransActionPerformed"/> + </Events> + </Component> + <Container class="javax.swing.JScrollPane" name="jScrollPane2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="com.alee.laf.table.WebTable" name="jTableProductStock"> + <Properties> + <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor"> + <Table columnCount="4" rowCount="8"> + <Column editable="true" title="Location" type="java.lang.Object"/> + <Column editable="true" title="Current" type="java.lang.Object"/> + <Column editable="true" title="Minimum" type="java.lang.Object"/> + <Column editable="true" title="Maximum" type="java.lang.Object"/> + </Table> + </Property> + <Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor"> + <TableColumnModel selectionModel="0"> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + </TableColumnModel> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="rowHeight" type="int" value="25"/> + <Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor"> + <TableHeader reorderingAllowed="true" resizingAllowed="true"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JCheckBox" name="m_jPrintKB"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="m_jSendStatus"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jStockUnits"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="0"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblDate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.proddate" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[130, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="m_jbtndate"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/date.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Open Calendar"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jbtndateActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JTextField" name="m_jdate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.product.properties.tab" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 0]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription"> + <JTabbedPaneConstraints tabName="Properties"> + <Property name="tabTitle" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.properties" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </JTabbedPaneConstraints> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JScrollPane" name="jScrollPane1"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[680, 400]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JTextArea" name="txtAttributes"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Monospaced" size="14" style="0"/> + </Property> + <Property name="lineWrap" type="boolean" value="true"/> + <Property name="wrapStyleWord" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[580, 300]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JButton" name="jBtnXml"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.injectxml" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.xmlheader" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnXmlActionPerformed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="First"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel6"> + <Properties> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.product.image.tab" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 0]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription"> + <JTabbedPaneConstraints tabName="Image"> + <Property name="tabTitle" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.image" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + </JTabbedPaneConstraints> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel34" min="-2" max="-2" attributes="0"/> + <EmptySpace pref="115" max="32767" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="m_jImage" max="32767" attributes="0"/> + <EmptySpace min="-2" pref="243" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jImage" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel34" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel34"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.imagesize" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[500, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.data.gui.JImageEditor" name="m_jImage"> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Properties> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.product.button.tab" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 0]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription"> + <JTabbedPaneConstraints tabName="Button"> + <Property name="tabTitle" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.button" replaceFormat="AppLocal.getIntString("label.button")"/> + </Property> + </JTabbedPaneConstraints> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel28" min="-2" pref="230" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="272" max="-2" attributes="0"/> + <Component id="jBtnReset" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="103" groupAlignment="1" max="-2" attributes="0"> + <Component id="jScrollPane3" alignment="0" max="32767" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel21" min="-2" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="m_jTextTip" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jBtnStyle" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jBtnBreak" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jBtnColour" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jBtnLarge" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jBtnSmall" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="13" max="-2" attributes="0"/> + <Component id="colourChooser" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="49" max="-2" attributes="0"/> + <Component id="jButtonHTML" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Component id="jBtnBold" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jBtnItalic" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Component id="jBtnImage" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </Group> + <EmptySpace min="63" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel28" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jBtnReset" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Component id="jScrollPane3" min="-2" pref="100" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jBtnSmall" alignment="0" min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jBtnColour" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jBtnLarge" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jBtnBold" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jBtnItalic" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jBtnImage" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jBtnStyle" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="jBtnBreak" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jButtonHTML" min="-2" max="-2" attributes="0"/> + <Component id="colourChooser" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel21" min="-2" max="-2" attributes="0"/> + <Component id="m_jTextTip" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace pref="58" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel28"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodbuttonhtml" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="ProductsEditor_jLabel17"/> + </AuxValues> + </Component> + <Component class="javax.swing.JButton" name="jButtonHTML"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.htmltest" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[1, 1, 1, 1]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[96, 72]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[96, 72]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[96, 72]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonHTMLActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel21"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.texttip" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jTextTip"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[400, 30]"/> + </Property> + </Properties> + </Component> + <Container class="javax.swing.JScrollPane" name="jScrollPane3"> + <AuxValues> + <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="com.alee.laf.text.WebTextArea" name="m_jDisplay"> + <Properties> + <Property name="columns" type="int" value="20"/> + <Property name="lineWrap" type="boolean" value="true"/> + <Property name="rows" type="int" value="4"/> + <Property name="wrapStyleWord" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 100]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JButton" name="jBtnBreak"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.prodhtmldisplayBreak" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="<html><center><h4>Inserts a Line Break<br> (a new line) for the button text"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 35]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnBreakActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jBtnColour"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="cc" red="0" type="rgb"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.prodhtmldisplayColour" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="<html><center><h4>Set the colour <br>for the button text"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 35]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnColourActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jBtnLarge"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.prodhtmldisplayLarge" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="<html><center><h4>Set the button<br> text to Large"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 35]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnLargeActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jBtnSmall"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.prodhtmldisplaySmall" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="<html><center><h4>Set the button<br>text to Small"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 35]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnSmallActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jBtnBold"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.prodhtmldisplayBold" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="<html><center><h4>Set the button<br> text to Italic"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 35]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnBoldActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jBtnItalic"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.prodhtmldisplayItalic" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="<html><center><h4>Set the button<br> text to Italic"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 35]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnItalicActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jBtnImage"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.prodhtmldisplayImage" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="<html><center><h4>Insert image from<br>local disk or internet URL"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 35]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnImageActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jBtnReset"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/reload.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.prodhtmldisplayReset" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 35]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnResetActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jBtnStyle"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.prodhtmldisplayStyle" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="<html><center><h4>Insert <style> tag to change<br>button background colour"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 35]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnStyleActionPerformed"/> + </Events> + </Component> + <Container class="com.alee.extended.colorchooser.WebColorPicker" name="colourChooser"> + <Properties> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.prodhtmldisplayColourChooser" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="colourChooserActionPerformed"/> + </Events> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout"> + <Property name="useNullLayout" type="boolean" value="true"/> + </Layout> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/ProductsEditor.java b/src/main/java/com/unicenta/pos/inventory/ProductsEditor.java new file mode 100644 index 0000000..416cb63 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/ProductsEditor.java @@ -0,0 +1,2371 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.beans.JCalendarDialog; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.loader.SentenceFind; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.loader.Session; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.*; +import com.unicenta.pos.sales.TaxesLogic; +import com.unicenta.pos.suppliers.DataLogicSuppliers; +import com.unicenta.pos.suppliers.JDialogNewSupplier; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.filechooser.FileFilter; +import javax.swing.filechooser.FileNameExtensionFilter; +import javax.swing.table.AbstractTableModel; +import java.awt.*; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.image.BufferedImage; +import java.io.File; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +/** + * @author Jack Gerrard + */ +@Slf4j +public final class ProductsEditor extends javax.swing.JPanel implements EditorRecord { + + private AppProperties m_props; + + private static final long serialVersionUID = 1L; + private Object m_oId; + + private final SentenceList m_sentcat; + private ComboBoxValModel m_CategoryModel; + + private final SentenceList taxcatsent; + private ComboBoxValModel taxcatmodel; + + private final SentenceList attsent; + private ComboBoxValModel attmodel; + + private final SentenceList m_sentsuppliers; + private ComboBoxValModel m_SuppliersModel; + + private final SentenceList taxsent; + private TaxesLogic taxeslogic; + + private Object pricesell; + private boolean priceselllock = false; + + private boolean reportlock = false; + private int btn; + + private List<ProductStock> productStockList; + private ProductsEditor.StockTableModel stockModel; + + private SentenceList m_sentuom; + private ComboBoxValModel m_UomModel; + + private DirtyManager m_Dirty; + private DataLogicSales dlSales; + private DataLogicSystem m_dlSystem; + private DataLogicSuppliers m_dlSuppliers; + + private AppView appView; + + private final SentenceFind loadimage; // JG 3 feb 16 speedup + + private Session s; + private Connection con; + private Statement stmt; + private PreparedStatement pstmt; + private String SQL; + private ResultSet rs; + private AppView m_App; + + protected DataLogicSystem dlSystem; + + + /** + * Creates new form JEditProduct + * + * @param app + * @param dirty + */ + public ProductsEditor(AppView app, DirtyManager dirty) { + + setAppView(app); + dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + m_dlSystem = (DataLogicSystem) app.getBean("com.unicenta.pos.forms.DataLogicSystem"); + m_dlSuppliers = (DataLogicSuppliers) app.getBean("com.unicenta.pos.suppliers.DataLogicSuppliers"); + + initComponents(); + + loadimage = dlSales.getProductImage(); // JG 3 feb 16 speedup + + taxsent = dlSales.getTaxList(); + + m_sentcat = dlSales.getCategoriesList(); + m_CategoryModel = new ComboBoxValModel(); + + taxcatsent = dlSales.getTaxCategoriesList(); + taxcatmodel = new ComboBoxValModel(); + + attsent = dlSales.getAttributeSetList(); + attmodel = new ComboBoxValModel(); + + m_sentsuppliers = m_dlSuppliers.getSupplierList(); + m_SuppliersModel = new ComboBoxValModel(); + + m_sentuom = dlSales.getUomList(); + m_UomModel = new ComboBoxValModel(); + +// Tab General + m_jRef.getDocument().addDocumentListener(dirty); + m_jCode.getDocument().addDocumentListener(dirty); + m_jCodetype.addActionListener(dirty); + m_jName.getDocument().addDocumentListener(dirty); + m_jCategory.addActionListener(dirty); + m_jAtt.addActionListener(dirty); + m_jVerpatrib.addActionListener(dirty); + m_jTax.addActionListener(dirty); + m_jUom.addActionListener(dirty); + m_jPriceBuy.getDocument().addDocumentListener(dirty); + m_jPriceSell.getDocument().addDocumentListener(dirty); + m_jPrintTo.addActionListener(dirty); + +// Tab Stock + m_jInCatalog.addActionListener(dirty); + m_jConstant.addActionListener(dirty); + m_jCatalogOrder.getDocument().addDocumentListener(dirty); + m_jSupplier.addActionListener(dirty); + + m_jService.addActionListener(dirty); + m_jCheckWarrantyReceipt.addActionListener(dirty); + m_jComment.addActionListener(dirty); + m_jScale.addActionListener(dirty); + m_jVprice.addActionListener(dirty); + m_jstockcost.getDocument().addDocumentListener(dirty); + m_jstockvolume.getDocument().addDocumentListener(dirty); + m_jPrintKB.addActionListener(dirty); + m_jSendStatus.addActionListener(dirty); + +// Tab Image + m_jImage.addPropertyChangeListener("image", dirty); + +// Tab Button + m_jDisplay.getDocument().addDocumentListener(dirty); + m_jTextTip.getDocument().addDocumentListener(dirty); + colourChooser.addActionListener(dirty); + m_jDisplay.addCaretListener(null); + +// Tab Properties + txtAttributes.getDocument().addDocumentListener(dirty); + + FieldsManager fm = new FieldsManager(); + m_jPriceBuy.getDocument().addDocumentListener(fm); + m_jPriceSell.getDocument().addDocumentListener(new PriceSellManager()); + m_jTax.addActionListener(fm); + m_jPriceSellTax.getDocument().addDocumentListener(new PriceTaxManager()); + m_jmargin.getDocument().addDocumentListener(new MarginManager()); + m_jGrossProfit.getDocument().addDocumentListener(new MarginManager()); + + m_jdate.getDocument().addDocumentListener(dirty); + + init(); + } + + private void init() { + writeValueEOF(); + } + + /** + * Instantiate object + * + * @throws BasicException + */ + @SuppressWarnings("unchecked") + public void activate() throws BasicException { + + taxeslogic = new TaxesLogic(taxsent.list()); + + m_CategoryModel = new ComboBoxValModel(m_sentcat.list()); + m_jCategory.setModel(m_CategoryModel); + + taxcatmodel = new ComboBoxValModel(taxcatsent.list()); + m_jTax.setModel(taxcatmodel); + + attmodel = new ComboBoxValModel(attsent.list()); + attmodel.add(0, null); + m_jAtt.setModel(attmodel); + + m_SuppliersModel = new ComboBoxValModel(m_sentsuppliers.list()); + m_jSupplier.setModel(m_SuppliersModel); + + m_UomModel = new ComboBoxValModel(m_sentuom.list()); + m_jUom.setModel(m_UomModel); + + String pId = null; + } + + /** + * + */ + @Override + public void refresh() { + } + + /** + * + */ + @Override + public void writeValueEOF() { + + reportlock = true; + + m_jTitle.setText(AppLocal.getIntString("label.recordeof")); + +// Tab General + m_oId = null; + m_jRef.setText(null); + m_jCode.setText(null); + m_jCodetype.setSelectedIndex(0); + m_jName.setText(null); + m_CategoryModel.setSelectedKey(null); + taxcatmodel.setSelectedKey(null); + attmodel.setSelectedKey(null); + m_jVerpatrib.setSelected(false); + m_UomModel.setSelectedKey(0); + m_jPriceBuy.setText("0"); + setPriceSell(null); + m_SuppliersModel.setSelectedKey(0); + +// Tab Stock + m_jInCatalog.setSelected(false); + m_jConstant.setSelected(false); + m_jCatalogOrder.setText(null); + m_jPrintTo.setSelectedIndex(1); + m_jService.setSelected(false); + m_jCheckWarrantyReceipt.setSelected(false); + m_jComment.setSelected(false); + m_jScale.setSelected(false); + m_jVprice.setSelected(false); + m_jstockcost.setText("0"); + m_jstockvolume.setText("0"); + m_jPrintKB.setVisible(false); + m_jSendStatus.setVisible(false); + m_jStockUnits.setVisible(false); + m_jdate.setText(null); + +// Tab Image + m_jImage.setImage(null); + +// Tab Button + m_jDisplay.setText(null); + m_jTextTip.setText(null); +// colourChooser.setText("#000000"); + +// Tab Properties + txtAttributes.setText(null); + + reportlock = false; + +// Tab General + m_jRef.setEnabled(false); + m_jCode.setEnabled(false); + m_jCodetype.setEnabled(false); + m_jName.setEnabled(false); + m_jCategory.setEnabled(false); + m_jAtt.setEnabled(false); + m_jVerpatrib.setEnabled(false); + m_jTax.setEnabled(false); + m_jUom.setEnabled(false); + m_jPriceBuy.setEnabled(false); + m_jPriceSell.setEnabled(false); + m_jPriceSellTax.setEnabled(false); + m_jmargin.setEnabled(false); + m_jSupplier.setEnabled(false); + +// Tab Stock + m_jInCatalog.setEnabled(false); + m_jConstant.setEnabled(false); + m_jCatalogOrder.setEnabled(false); + m_jPrintTo.setEnabled(false); + m_jService.setEnabled(false); + m_jCheckWarrantyReceipt.setEnabled(false); + m_jComment.setEnabled(false); + m_jScale.setEnabled(false); + m_jVprice.setEnabled(false); + m_jstockcost.setEnabled(false); + m_jstockvolume.setEnabled(false); + jTableProductStock.setEnabled(false); + m_jdate.setEnabled(false); + +// Tab Image + m_jImage.setEnabled(false); + +// Tab Button + m_jDisplay.setEnabled(false); + m_jTextTip.setEnabled(false); + colourChooser.setEnabled(false); + +// Tab Properties + txtAttributes.setEnabled(false); + + calculateMargin(); + calculatePriceSellTax(); + calculateGP(); + + } + + @Override + public void writeValueInsert() { + + final int selectedIndex = 0; + + reportlock = true; + + m_jTitle.setText(AppLocal.getIntString("label.recordnew")); + +// Tab General + m_oId = UUID.randomUUID().toString(); + m_jRef.setText(null); + m_jCode.setText(null); + m_jCodetype.setSelectedIndex(0); + m_jName.setText(null); + m_CategoryModel.setSelectedKey("000"); + attmodel.setSelectedKey(null); + m_jVerpatrib.setSelected(false); + taxcatmodel.setSelectedKey("001"); + m_UomModel.setSelectedKey("0"); + m_jPriceBuy.setText("0"); + setPriceSell(null); +// m_SuppliersModel.setSelectedKey(0); + m_jSupplier.setSelectedIndex(selectedIndex); + +// Tab Stock + m_jInCatalog.setSelected(true); + m_jConstant.setSelected(false); + m_jCatalogOrder.setText(null); + m_jPrintTo.setSelectedIndex(1); + m_jService.setSelected(false); + m_jCheckWarrantyReceipt.setSelected(false); + m_jComment.setSelected(false); + m_jScale.setSelected(false); + m_jVprice.setSelected(false); + m_jstockcost.setText("0"); + m_jstockvolume.setText("0"); + m_jdate.setText(null); + +// Tab Image + m_jImage.setImage(null); + +// Tab Button + m_jDisplay.setText(null); + m_jTextTip.setText(null); + colourChooser.setEnabled(false); + +// Tab Properties + txtAttributes.setText(null); + + reportlock = false; + +// Tab General + m_jRef.setEnabled(true); + m_jCode.setEnabled(true); + m_jCodetype.setEnabled(true); + m_jName.setEnabled(true); + m_jCategory.setEnabled(true); + m_jTax.setEnabled(true); + m_jAtt.setEnabled(true); + m_jVerpatrib.setEnabled(true); + m_jUom.setEnabled(true); + m_jPriceBuy.setEnabled(true); + m_jPriceSell.setEnabled(true); + m_jPriceSellTax.setEnabled(true); + m_jmargin.setEnabled(true); + m_jSupplier.setEnabled(true); + +// Tab Stock + m_jInCatalog.setEnabled(true); + m_jConstant.setEnabled(true); + m_jCatalogOrder.setEnabled(false); + m_jPrintTo.setEnabled(true); + m_jService.setEnabled(true); + m_jCheckWarrantyReceipt.setEnabled(true); + m_jComment.setEnabled(true); + m_jScale.setEnabled(true); + m_jVprice.setEnabled(true); + m_jstockcost.setEnabled(true); + m_jstockvolume.setEnabled(true); + jTableProductStock.setEnabled(false); + m_jdate.setEnabled(true); + +// Tab Image + m_jImage.setEnabled(true); + +// Tab Button + m_jDisplay.setEnabled(true); + m_jTextTip.setEnabled(true); + colourChooser.setEnabled(true); + +// Tab Properties + txtAttributes.setEnabled(true); + + calculateMargin(); + calculatePriceSellTax(); + calculateGP(); + + } + + /** + * @return myprod + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + Object[] myprod = new Object[32]; + + myprod[0] = m_oId == null ? UUID.randomUUID().toString() : m_oId; + myprod[1] = m_jRef.getText(); + myprod[2] = m_jCode.getText(); + myprod[3] = m_jCodetype.getSelectedItem(); + myprod[4] = m_jName.getText(); + myprod[5] = Formats.CURRENCY.parseValue(m_jPriceBuy.getText()); + myprod[6] = pricesell; + myprod[7] = m_CategoryModel.getSelectedKey(); + myprod[8] = taxcatmodel.getSelectedKey(); + myprod[9] = attmodel.getSelectedKey(); + myprod[10] = Formats.CURRENCY.parseValue(m_jstockcost.getText()); + myprod[11] = Formats.DOUBLE.parseValue(m_jstockvolume.getText()); + myprod[12] = m_jImage.getImage(); + myprod[13] = m_jComment.isSelected(); + myprod[14] = m_jScale.isSelected(); + myprod[15] = m_jConstant.isSelected(); + myprod[16] = m_jPrintKB.isSelected(); + myprod[17] = m_jSendStatus.isSelected(); + myprod[18] = m_jService.isSelected(); + myprod[19] = Formats.BYTEA.parseValue(txtAttributes.getText()); + myprod[20] = m_jDisplay.getText(); + myprod[21] = m_jVprice.isSelected(); + myprod[22] = m_jVerpatrib.isSelected(); + myprod[23] = m_jTextTip.getText(); + myprod[24] = m_jCheckWarrantyReceipt.isSelected(); + myprod[25] = Formats.DOUBLE.parseValue(m_jStockUnits.getText()); + myprod[26] = m_jPrintTo.getSelectedItem().toString(); + myprod[27] = m_SuppliersModel.getSelectedKey(); + myprod[28] = m_UomModel.getSelectedKey(); + myprod[29] = Formats.TIMESTAMP.parseValue(m_jdate.getText()); + + myprod[30] = m_jInCatalog.isSelected(); + myprod[31] = Formats.INT.parseValue(m_jCatalogOrder.getText()); + + if (m_jName.getText().contains("&")) { + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.ampersand")); + } + + return myprod; + } + + /** + * @param value + */ + @Override + public void writeValueEdit(Object value) { + + reportlock = true; + + Object[] myprod = (Object[]) value; + + m_jTitle.setText(Formats.STRING.formatValue(myprod[1]) + + " - " + Formats.STRING.formatValue(myprod[4])); + m_oId = myprod[0]; + m_jRef.setText(Formats.STRING.formatValue(myprod[1])); + m_jCode.setText(Formats.STRING.formatValue(myprod[2])); + m_jCodetype.setSelectedItem(myprod[3]); + m_jName.setText(Formats.STRING.formatValue(myprod[4])); + m_jPriceBuy.setText(Formats.CURRENCY.formatValue(myprod[5])); + setPriceSell(myprod[6]); + m_CategoryModel.setSelectedKey(myprod[7]); + taxcatmodel.setSelectedKey(myprod[8]); + attmodel.setSelectedKey(myprod[9]); + m_jstockcost.setText(Formats.CURRENCY.formatValue(myprod[10])); + m_jstockvolume.setText(Formats.DOUBLE.formatValue(myprod[11])); +// JG 3 feb 16 speedup m_jImage.setImage((BufferedImage) myprod[12]); + m_jImage.setImage(findImage(m_oId)); + m_jComment.setSelected(((Boolean) myprod[13])); + m_jScale.setSelected(((Boolean) myprod[14])); + m_jConstant.setSelected(((Boolean) myprod[15])); + m_jPrintKB.setSelected(((Boolean) myprod[16])); + m_jSendStatus.setSelected(((Boolean) myprod[17])); + m_jService.setSelected(((Boolean) myprod[18])); + txtAttributes.setText(Formats.BYTEA.formatValue(myprod[19])); + m_jDisplay.setText(Formats.STRING.formatValue(myprod[20])); + m_jVprice.setSelected(((Boolean) myprod[21])); + m_jVerpatrib.setSelected(((Boolean) myprod[22])); + m_jTextTip.setText(Formats.STRING.formatValue(myprod[23])); + m_jCheckWarrantyReceipt.setSelected(((Boolean) myprod[24])); + m_jStockUnits.setText(Formats.DOUBLE.formatValue(myprod[25])); + m_jPrintTo.setSelectedItem(myprod[26]); + m_SuppliersModel.setSelectedKey(myprod[27]); + m_UomModel.setSelectedKey(myprod[28]); + + m_jdate.setText(Formats.DATE.formatValue(myprod[29])); + + m_jInCatalog.setSelected(((Boolean) myprod[30])); + m_jCatalogOrder.setText(Formats.INT.formatValue(myprod[31])); + + txtAttributes.setCaretPosition(0); + reportlock = false; + +// Tab General + m_jRef.setEnabled(true); + m_jCode.setEnabled(true); + m_jCodetype.setEnabled(true); + m_jName.setEnabled(true); + m_jCategory.setEnabled(true); + m_jTax.setEnabled(true); + m_jAtt.setEnabled(true); + m_jVerpatrib.setEnabled(true); + m_jUom.setEnabled(true); + m_jPriceBuy.setEnabled(true); + m_jPriceSell.setEnabled(true); + m_jPriceSellTax.setEnabled(true); + m_jmargin.setEnabled(true); + m_jSupplier.setEnabled(true); + +// Tab Stock + m_jInCatalog.setEnabled(true); + m_jConstant.setEnabled(true); + m_jCatalogOrder.setEnabled(m_jInCatalog.isSelected()); + m_jPrintTo.setEnabled(true); + m_jService.setEnabled(true); + m_jCheckWarrantyReceipt.setEnabled(true); + m_jComment.setEnabled(true); + m_jScale.setEnabled(true); + m_jVprice.setEnabled(true); + m_jstockcost.setEnabled(true); + m_jstockvolume.setEnabled(true); + m_jdate.setEnabled(true); + jTableProductStock.setVisible(false); + jTableProductStock.setEnabled(true); + +// Tab Image + m_jImage.setEnabled(true); + +// Tab Button + m_jDisplay.setEnabled(true); + m_jTextTip.setEnabled(true); + colourChooser.setEnabled(true); + setButtonHTML(); + + resetTranxTable(); + jTableProductStock.repaint(); + +// Tab Properties + txtAttributes.setEnabled(true); + + calculateMargin(); + calculatePriceSellTax(); + calculateGP(); + + } + + /** + * @param value + */ + @Override + public void writeValueDelete(Object value) { + + reportlock = true; + Object[] myprod = (Object[]) value; + m_jTitle.setText(Formats.STRING.formatValue(myprod[1]) + + " - " + Formats.STRING.formatValue(myprod[4]) + + " " + AppLocal.getIntString("label.recorddeleted")); + + m_oId = myprod[0]; + m_jRef.setText(Formats.STRING.formatValue(myprod[1])); + m_jCode.setText(Formats.STRING.formatValue(myprod[2])); + m_jCodetype.setSelectedItem(myprod[3]); + m_jName.setText(Formats.STRING.formatValue(myprod[4])); + m_jPriceBuy.setText(Formats.CURRENCY.formatValue(myprod[5])); + setPriceSell(myprod[6]); + m_CategoryModel.setSelectedKey(myprod[7]); + taxcatmodel.setSelectedKey(myprod[8]); + attmodel.setSelectedKey(myprod[9]); + m_jstockcost.setText(Formats.CURRENCY.formatValue(myprod[10])); + m_jstockvolume.setText(Formats.DOUBLE.formatValue(myprod[11])); +// JG 3 feb 16 speed test m_jImage.setImage((BufferedImage) myprod[12]); + m_jImage.setImage(findImage(m_oId)); + m_jComment.setSelected(((Boolean) myprod[13])); + m_jScale.setSelected(((Boolean) myprod[14])); + m_jConstant.setSelected(((Boolean) myprod[15])); + m_jPrintKB.setSelected(((Boolean) myprod[16])); + m_jService.setSelected(((Boolean) myprod[17])); + m_jSendStatus.setSelected(((Boolean) myprod[18])); + txtAttributes.setText(Formats.BYTEA.formatValue(myprod[19])); + m_jDisplay.setText(Formats.STRING.formatValue(myprod[20])); + m_jVprice.setSelected(((Boolean) myprod[21])); + m_jVerpatrib.setSelected(((Boolean) myprod[22])); + m_jTextTip.setText(Formats.STRING.formatValue(myprod[23])); + m_jCheckWarrantyReceipt.setSelected(((Boolean) myprod[24])); + m_jStockUnits.setText(Formats.DOUBLE.formatValue(myprod[25])); + m_jPrintTo.setSelectedItem(myprod[26]); + m_SuppliersModel.setSelectedKey(myprod[27]); + m_UomModel.setSelectedKey(myprod[28]); + m_jdate.setText(Formats.DATE.formatValue(myprod[29])); + + m_jInCatalog.setSelected(((Boolean) myprod[30])); + m_jCatalogOrder.setText(Formats.INT.formatValue(myprod[31])); + + txtAttributes.setCaretPosition(0); + + reportlock = false; + +// Tab General + m_jRef.setEnabled(false); + m_jCode.setEnabled(false); + m_jCodetype.setEnabled(false); + m_jName.setEnabled(false); + m_jCategory.setEnabled(false); + m_jTax.setEnabled(false); + m_jAtt.setEnabled(false); + m_jVerpatrib.setEnabled(false); + m_jUom.setEnabled(false); + m_jPriceBuy.setEnabled(false); + m_jPriceSell.setEnabled(false); + m_jPriceSellTax.setEnabled(false); + m_jmargin.setEnabled(false); + m_jPrintTo.setEnabled(false); + +// Tab Stock + m_jInCatalog.setEnabled(false); + m_jConstant.setEnabled(false); + m_jCatalogOrder.setEnabled(false); + m_jSupplier.setEnabled(false); + m_jService.setEnabled(false); + m_jCheckWarrantyReceipt.setEnabled(false); + m_jComment.setEnabled(false); + m_jScale.setEnabled(false); + m_jVprice.setEnabled(false); + m_jstockcost.setEnabled(false); + m_jstockvolume.setEnabled(false); + stockModel = new ProductsEditor.StockTableModel(getProductOfName((String) m_oId)); + jTableProductStock.setModel(stockModel); + jTableProductStock.setEnabled(false); + m_jdate.setEnabled(false); + +// Tab Image + m_jImage.setEnabled(false); + +// Tab Button + m_jDisplay.setEnabled(false); + m_jTextTip.setEnabled(false); + colourChooser.setEnabled(false); + +// Tab Properties + txtAttributes.setEnabled(false); + + calculateMargin(); + calculatePriceSellTax(); + calculateGP(); + } + + + public void resetTranxTable() { + + jTableProductStock.getColumnModel().getColumn(0).setPreferredWidth(100); + jTableProductStock.getColumnModel().getColumn(1).setPreferredWidth(50); + jTableProductStock.getColumnModel().getColumn(2).setPreferredWidth(50); + jTableProductStock.getColumnModel().getColumn(3).setPreferredWidth(50); + + jTableProductStock.repaint(); + + } + + /** + * @return this + */ + @Override + public Component getComponent() { + return this; + } + + private void setCode() { + + Long lDateTime = new Date().getTime(); + + if (!reportlock) { + reportlock = true; + + if (m_jRef == null) { + m_jCode.setText(Long.toString(lDateTime)); + } else { + if (m_jCode.getText() == null || "".equals(m_jCode.getText())) { + m_jCode.setText(m_jRef.getText()); + } + } + reportlock = false; + } + } + + private List<ProductStock> getProductOfName(String pId) { + + try { + productStockList = dlSales.getProductStockList(pId); + + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + + List<ProductStock> productList = new ArrayList<>(); + + for (ProductStock productStock : productStockList) { + String productId = productStock.getProductId(); + if (productId.equals(pId)) { + productList.add(productStock); + } + } + + repaint(); + refresh(); + + return productList; + } + + public AppView getAppView() { + return appView; + } + + public void setAppView(AppView appView) { + this.appView = appView; + } + + class StockTableModel extends AbstractTableModel { + String loc = AppLocal.getIntString("label.tblProdHeaderCol1"); + String qty = AppLocal.getIntString("label.tblProdHeaderCol2"); + String min = AppLocal.getIntString("label.tblProdHeaderCol3"); + String max = AppLocal.getIntString("label.tblProdHeaderCol4"); + + List<ProductStock> stockList; + String[] columnNames = {loc, qty, min, max}; + + public StockTableModel(List<ProductStock> list) { + stockList = list; + } + + @Override + public int getColumnCount() { + return 4; + } + + @Override + public int getRowCount() { + return stockList.size(); + } + + @Override + public Object getValueAt(int row, int column) { + ProductStock productStock = stockList.get(row); + + switch (column) { + case 0: + return productStock.getLocation(); + case 1: + return productStock.getUnits(); + case 2: + return productStock.getMinimum(); + case 3: + return productStock.getMaximum(); + case 4: + return productStock.getProductId(); + default: + return ""; + } + } + + @Override + public String getColumnName(int col) { + return columnNames[col]; + } + } + + + private void setDisplay(int btn) { + + String htmlString = (m_jDisplay.getText()); + String ohtmlString = "<html><center>" + m_jName.getText(); + + switch (btn) { + case 1: + m_jDisplay.insert("<br>", m_jDisplay.getCaretPosition()); + break; + case 2: + String hexcolor = color2HexString(colourChooser.getColor()); + m_jDisplay.insert("<font color=" + hexcolor + ">" + , m_jDisplay.getCaretPosition()); + break; + case 3: + m_jDisplay.insert("<font size=+2>" + , m_jDisplay.getCaretPosition()); + break; + case 4: + m_jDisplay.insert("<font size=-2>" + , m_jDisplay.getCaretPosition()); + break; + case 5: + m_jDisplay.insert("<b> </b>" + , m_jDisplay.getCaretPosition()); + break; + case 6: + m_jDisplay.insert("<i> </i>" + , m_jDisplay.getCaretPosition()); + break; + case 7: +// defaults to file:/ for local disk +// http:// also usable for remote image + JFileChooser fc = new JFileChooser(); + FileFilter imageFilter = new FileNameExtensionFilter( + "Image files", ImageIO.getReaderFileSuffixes()); + fc.setFileFilter(imageFilter); + int returnValue = fc.showOpenDialog(null); + File selectedFile = fc.getSelectedFile(); + if (selectedFile != null) { + m_jDisplay.insert("<img src=file:" + selectedFile.getAbsolutePath() + ">" + , m_jDisplay.getCaretPosition()); + } + break; + + case 8: + htmlString = ohtmlString; + m_jDisplay.setText(htmlString); + break; + case 9: + m_jDisplay.insert("<div style=background-color:black;color:white;padding:10px;>" + , m_jDisplay.getCaretPosition()); + break; + default: + htmlString += ""; + m_jDisplay.setText(htmlString); + } + } + + private void setButtonHTML() { + + jButtonHTML.setText(m_jDisplay.getText()); + } + + public String color2HexString(Color color) { + return "#" + Integer.toHexString(color.getRGB() & 0x00ffffff); + } + + // 3 feb 16 speed test + private BufferedImage findImage(Object id) { + try { + return (BufferedImage) loadimage.find(id); + } catch (BasicException e) { + return null; + } + } + + // end of speed test + private void calculateMargin() { + + if (!reportlock) { + reportlock = true; + + Double dPriceBuy = readCurrency(m_jPriceBuy.getText()); + Double dPriceSell = (Double) pricesell; + + if (dPriceBuy == null || dPriceSell == null) { + m_jmargin.setText(null); + } else { + m_jmargin.setText(Formats.PERCENT.formatValue(dPriceSell.doubleValue() / dPriceBuy.doubleValue() - 1.0)); + } + reportlock = false; + } + } + + private void calculatePriceSellTax() { + + if (!reportlock) { + reportlock = true; + + Double dPriceSell = (Double) pricesell; + + if (dPriceSell == null) { + m_jPriceSellTax.setText(null); + } else { + double dTaxRate = taxeslogic.getTaxRate((TaxCategoryInfo) taxcatmodel.getSelectedItem()); + m_jPriceSellTax.setText(Formats.CURRENCY.formatValue(dPriceSell.doubleValue() * (1.0 + dTaxRate))); + } + reportlock = false; + } + } + + private void calculateGP() { + + if (!reportlock) { + reportlock = true; + + Double dPriceBuy = readCurrency(m_jPriceBuy.getText()); + Double dPriceSell = (Double) pricesell; + + if (dPriceBuy == null || dPriceSell == null) { + m_jGrossProfit.setText(null); + } else { + m_jGrossProfit.setText(Formats.PERCENT.formatValue( + (dPriceSell.doubleValue() - dPriceBuy.doubleValue()) + / dPriceSell.doubleValue())); + } + reportlock = false; + } + } + + + private void calculatePriceSellfromMargin() { + + if (!reportlock) { + reportlock = true; + + Double dPriceBuy = readCurrency(m_jPriceBuy.getText()); + Double dMargin = readPercent(m_jmargin.getText()); + + if (dMargin == null || dPriceBuy == null) { + setPriceSell(null); + } else { + setPriceSell(dPriceBuy.doubleValue() * (1.0 + dMargin.doubleValue())); + } + + reportlock = false; + } + + } + + private void calculatePriceSellfromPST() { + + if (!reportlock) { + reportlock = true; + + Double dPriceSellTax = readCurrency(m_jPriceSellTax.getText()); + + if (dPriceSellTax == null) { + setPriceSell(null); + } else { + double dTaxRate = taxeslogic.getTaxRate((TaxCategoryInfo) taxcatmodel.getSelectedItem()); + setPriceSell(dPriceSellTax.doubleValue() / (1.0 + dTaxRate)); + } + + reportlock = false; + } + } + + + private void setPriceSell(Object value) { + + if (!priceselllock) { + priceselllock = true; + pricesell = value; + m_jPriceSell.setText(Formats.CURRENCY.formatValue(pricesell)); + priceselllock = false; + } + } + + private class PriceSellManager implements DocumentListener { + @Override + public void changedUpdate(DocumentEvent e) { + if (!priceselllock) { + priceselllock = true; + pricesell = readCurrency(m_jPriceSell.getText()); + priceselllock = false; + } + calculateMargin(); + calculatePriceSellTax(); + calculateGP(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + if (!priceselllock) { + priceselllock = true; + pricesell = readCurrency(m_jPriceSell.getText()); + priceselllock = false; + } + calculateMargin(); + calculatePriceSellTax(); + calculateGP(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + if (!priceselllock) { + priceselllock = true; + pricesell = readCurrency(m_jPriceSell.getText()); + priceselllock = false; + } + calculateMargin(); + calculatePriceSellTax(); + calculateGP(); + } + } + + private class FieldsManager implements DocumentListener, ActionListener { + @Override + public void changedUpdate(DocumentEvent e) { + calculateMargin(); + calculatePriceSellTax(); + calculateGP(); + + } + + @Override + public void insertUpdate(DocumentEvent e) { + calculateMargin(); + calculatePriceSellTax(); + calculateGP(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + calculateMargin(); + calculatePriceSellTax(); + calculateGP(); + } + + @Override + public void actionPerformed(ActionEvent e) { + calculateMargin(); + calculatePriceSellTax(); + calculateGP(); + } + } + + private class PriceTaxManager implements DocumentListener { + @Override + public void changedUpdate(DocumentEvent e) { + calculatePriceSellfromPST(); + calculateMargin(); + calculateGP(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + calculatePriceSellfromPST(); + calculateMargin(); + calculateGP(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + calculatePriceSellfromPST(); + calculateMargin(); + calculateGP(); + } + } + + private class MarginManager implements DocumentListener { + @Override + public void changedUpdate(DocumentEvent e) { + calculatePriceSellfromMargin(); + calculatePriceSellTax(); + calculateGP(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + calculatePriceSellfromMargin(); + calculatePriceSellTax(); + calculateGP(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + calculatePriceSellfromMargin(); + calculatePriceSellTax(); + calculateGP(); + } + } + + private static Double readCurrency(String sValue) { + try { + return (Double) Formats.CURRENCY.parseValue(sValue); + } catch (BasicException e) { + return null; + } + } + + private static Double readPercent(String sValue) { + try { + return (Double) Formats.PERCENT.parseValue(sValue); + } catch (BasicException e) { + return null; + } + } + + /** + * This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jTitle = new javax.swing.JLabel(); + jTabbedPane1 = new javax.swing.JTabbedPane(); + jPanel1 = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + m_jRef = new javax.swing.JTextField(); + jLabel6 = new javax.swing.JLabel(); + m_jCode = new javax.swing.JTextField(); + m_jCodetype = new javax.swing.JComboBox(); + jLabel2 = new javax.swing.JLabel(); + m_jName = new javax.swing.JTextField(); + jLabel5 = new javax.swing.JLabel(); + m_jCategory = new javax.swing.JComboBox(); + jLabel13 = new javax.swing.JLabel(); + m_jAtt = new javax.swing.JComboBox(); + jLabel7 = new javax.swing.JLabel(); + m_jTax = new javax.swing.JComboBox(); + jLabel16 = new javax.swing.JLabel(); + m_jPriceSellTax = new javax.swing.JTextField(); + jLabel4 = new javax.swing.JLabel(); + m_jPriceSell = new javax.swing.JTextField(); + jLabel19 = new javax.swing.JLabel(); + m_jmargin = new javax.swing.JTextField(); + jLabel3 = new javax.swing.JLabel(); + m_jPriceBuy = new javax.swing.JTextField(); + m_jVerpatrib = new javax.swing.JCheckBox(); + m_jGrossProfit = new javax.swing.JTextField(); + jLabel22 = new javax.swing.JLabel(); + jLabel26 = new javax.swing.JLabel(); + m_jUom = new javax.swing.JComboBox(); + jLabel17 = new javax.swing.JLabel(); + m_jSupplier = new javax.swing.JComboBox(); + jBtnSupplier = new javax.swing.JButton(); + jPanel2 = new javax.swing.JPanel(); + jLabel9 = new javax.swing.JLabel(); + m_jstockcost = new javax.swing.JTextField(); + jLabel10 = new javax.swing.JLabel(); + m_jstockvolume = new javax.swing.JTextField(); + jLabel8 = new javax.swing.JLabel(); + m_jInCatalog = new javax.swing.JCheckBox(); + jLabel18 = new javax.swing.JLabel(); + m_jCatalogOrder = new javax.swing.JTextField(); + jLabel15 = new javax.swing.JLabel(); + m_jService = new javax.swing.JCheckBox(); + jLabel11 = new javax.swing.JLabel(); + m_jComment = new javax.swing.JCheckBox(); + jLabel12 = new javax.swing.JLabel(); + m_jScale = new javax.swing.JCheckBox(); + m_jConstant = new javax.swing.JCheckBox(); + jLabel14 = new javax.swing.JLabel(); + jLabel20 = new javax.swing.JLabel(); + m_jVprice = new javax.swing.JCheckBox(); + jLabel33 = new javax.swing.JLabel(); + m_jCheckWarrantyReceipt = new javax.swing.JCheckBox(); + jLabel23 = new javax.swing.JLabel(); + webLabel1 = new com.alee.laf.label.WebLabel(); + m_jPrintTo = new javax.swing.JComboBox(); + jBtnShowTrans = new javax.swing.JButton(); + jScrollPane2 = new javax.swing.JScrollPane(); + jTableProductStock = new com.alee.laf.table.WebTable(); + m_jPrintKB = new javax.swing.JCheckBox(); + m_jSendStatus = new javax.swing.JCheckBox(); + m_jStockUnits = new javax.swing.JTextField(); + jLblDate = new javax.swing.JLabel(); + m_jbtndate = new javax.swing.JButton(); + m_jdate = new javax.swing.JTextField(); + jPanel3 = new javax.swing.JPanel(); + jScrollPane1 = new javax.swing.JScrollPane(); + txtAttributes = new javax.swing.JTextArea(); + jBtnXml = new javax.swing.JButton(); + jPanel6 = new javax.swing.JPanel(); + jLabel34 = new javax.swing.JLabel(); + m_jImage = new com.unicenta.data.gui.JImageEditor(); + jPanel4 = new javax.swing.JPanel(); + jLabel28 = new javax.swing.JLabel(); + jButtonHTML = new javax.swing.JButton(); + jLabel21 = new javax.swing.JLabel(); + m_jTextTip = new javax.swing.JTextField(); + jScrollPane3 = new javax.swing.JScrollPane(); + m_jDisplay = new com.alee.laf.text.WebTextArea(); + jBtnBreak = new javax.swing.JButton(); + jBtnColour = new javax.swing.JButton(); + jBtnLarge = new javax.swing.JButton(); + jBtnSmall = new javax.swing.JButton(); + jBtnBold = new javax.swing.JButton(); + jBtnItalic = new javax.swing.JButton(); + jBtnImage = new javax.swing.JButton(); + jBtnReset = new javax.swing.JButton(); + jBtnStyle = new javax.swing.JButton(); + colourChooser = new com.alee.extended.colorchooser.WebColorPicker(); + + setLayout(null); + + m_jTitle.setBackground(new java.awt.Color(255, 255, 255)); + m_jTitle.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jTitle.setForeground(new java.awt.Color(102, 102, 102)); + m_jTitle.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jTitle.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM); + m_jTitle.setFocusable(false); + m_jTitle.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT); + m_jTitle.setOpaque(true); + m_jTitle.setPreferredSize(new java.awt.Dimension(260, 25)); + add(m_jTitle); + m_jTitle.setBounds(365, 5, 260, 25); + + jTabbedPane1.setToolTipText(""); + jTabbedPane1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTabbedPane1.setPreferredSize(new java.awt.Dimension(680, 420)); + + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jPanel1.setToolTipText(bundle.getString("tooltip.product.general.tab")); // NOI18N + jPanel1.setPreferredSize(new java.awt.Dimension(0, 0)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/info.png"))); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.prodrefm")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(110, 30)); + jLabel1.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + jLabel1MouseClicked(evt); + } + }); + + m_jRef.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jRef.setToolTipText(""); + m_jRef.setPreferredSize(new java.awt.Dimension(150, 30)); + m_jRef.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusLost(java.awt.event.FocusEvent evt) { + m_jRefFocusLost(evt); + } + }); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setText(AppLocal.getIntString("label.prodbarcodem")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jCode.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCode.setPreferredSize(new java.awt.Dimension(125, 30)); + m_jCode.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusLost(java.awt.event.FocusEvent evt) { + m_jCodeFocusLost(evt); + } + }); + + m_jCodetype.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCodetype.setModel(new javax.swing.DefaultComboBoxModel(new String[]{"EAN-13", "EAN-8", "CODE128", "Upc-A", "Upc-E"})); + m_jCodetype.setPreferredSize(new java.awt.Dimension(80, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.prodnamem")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(450, 30)); + m_jName.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusLost(java.awt.event.FocusEvent evt) { + m_jNameFocusLost(evt); + } + }); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.prodcategorym")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jCategory.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCategory.setBorder(null); + m_jCategory.setPreferredSize(new java.awt.Dimension(450, 30)); + + jLabel13.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel13.setText(AppLocal.getIntString("label.attributes")); // NOI18N + jLabel13.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jAtt.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jAtt.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLabel7.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel7.setText(AppLocal.getIntString("label.taxcategorym")); // NOI18N + jLabel7.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jTax.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jTax.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLabel16.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel16.setText(AppLocal.getIntString("label.prodpriceselltaxm")); // NOI18N + jLabel16.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jPriceSellTax.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPriceSellTax.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jPriceSellTax.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jLabel4.setText(AppLocal.getIntString("label.prodpricesell")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jPriceSell.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPriceSell.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jPriceSell.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLabel19.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel19.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLabel19.setText(bundle.getString("label.margin")); // NOI18N + jLabel19.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jmargin.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jmargin.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jmargin.setCursor(new java.awt.Cursor(java.awt.Cursor.TEXT_CURSOR)); + m_jmargin.setEnabled(false); + m_jmargin.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.prodpricebuym")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jPriceBuy.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPriceBuy.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jPriceBuy.setText("0"); + m_jPriceBuy.setPreferredSize(new java.awt.Dimension(200, 30)); + + m_jVerpatrib.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jVerpatrib.setText(bundle.getString("label.mandatory")); // NOI18N + m_jVerpatrib.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING); + m_jVerpatrib.setPreferredSize(new java.awt.Dimension(49, 30)); + m_jVerpatrib.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + none(evt); + } + }); + + m_jGrossProfit.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jGrossProfit.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jGrossProfit.setDisabledTextColor(new java.awt.Color(0, 0, 0)); + m_jGrossProfit.setEnabled(false); + m_jGrossProfit.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLabel22.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel22.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLabel22.setText(bundle.getString("label.grossprofit")); // NOI18N + jLabel22.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + jLabel22.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLabel26.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel26.setText(AppLocal.getIntString("label.UOM")); // NOI18N + jLabel26.setPreferredSize(new java.awt.Dimension(70, 30)); + + m_jUom.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jUom.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel17.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel17.setText(AppLocal.getIntString("label.prodsupplier")); // NOI18N + jLabel17.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jSupplier.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSupplier.setPreferredSize(new java.awt.Dimension(200, 30)); + + jBtnSupplier.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jBtnSupplier.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/customer_add_sml.png"))); // NOI18N + jBtnSupplier.setText(bundle.getString("label.supplier")); // NOI18N + jBtnSupplier.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnSupplierActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(10, 10, 10) + .addComponent(jLabel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel16, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(m_jPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jGrossProfit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(m_jUom, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel22, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(m_jmargin, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel19, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))) + .addGap(115, 115, 115)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(m_jAtt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(m_jVerpatrib, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(m_jTax, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(m_jPriceSellTax, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(jLabel26, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, Short.MAX_VALUE))) + .addGap(50, 50, 50)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jRef, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 78, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCodetype, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel17, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jSupplier, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jBtnSupplier))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jRef, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCodetype, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jAtt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jVerpatrib, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jTax, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel16, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jPriceSellTax, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel26, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jUom, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel22, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel19, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jGrossProfit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jmargin, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel17, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jSupplier, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jBtnSupplier)) + .addGap(14, 14, 14)) + ); + + jTabbedPane1.addTab(AppLocal.getIntString("label.prodgeneral"), jPanel1); // NOI18N + + jPanel2.setToolTipText(bundle.getString("tooltip.product.stock.tab")); // NOI18N + jPanel2.setPreferredSize(new java.awt.Dimension(0, 0)); + + jLabel9.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel9.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel9.setText(AppLocal.getIntString("label.prodstockcost")); // NOI18N + jLabel9.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jstockcost.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jstockcost.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jstockcost.setPreferredSize(new java.awt.Dimension(85, 30)); + + jLabel10.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel10.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel10.setText(AppLocal.getIntString("label.prodstockvol")); // NOI18N + jLabel10.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jstockvolume.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jstockvolume.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jstockvolume.setPreferredSize(new java.awt.Dimension(85, 30)); + + jLabel8.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel8.setText(AppLocal.getIntString("label.prodincatalog")); // NOI18N + jLabel8.setPreferredSize(new java.awt.Dimension(130, 30)); + + m_jInCatalog.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N + m_jInCatalog.setSelected(true); + m_jInCatalog.setPreferredSize(new java.awt.Dimension(30, 30)); + m_jInCatalog.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jInCatalogActionPerformed(evt); + } + }); + + jLabel18.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel18.setText(AppLocal.getIntString("label.prodorder")); // NOI18N + jLabel18.setPreferredSize(new java.awt.Dimension(130, 30)); + + m_jCatalogOrder.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCatalogOrder.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jCatalogOrder.setPreferredSize(new java.awt.Dimension(50, 30)); + + jLabel15.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel15.setText(bundle.getString("label.service")); // NOI18N + jLabel15.setPreferredSize(new java.awt.Dimension(130, 30)); + + m_jService.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N + m_jService.setToolTipText("A Service Item will not be deducted from the Inventory"); + m_jService.setPreferredSize(new java.awt.Dimension(30, 30)); + + jLabel11.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel11.setText(AppLocal.getIntString("label.prodaux")); // NOI18N + jLabel11.setPreferredSize(new java.awt.Dimension(130, 30)); + + m_jComment.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N + m_jComment.setPreferredSize(new java.awt.Dimension(30, 30)); + + jLabel12.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel12.setText(AppLocal.getIntString("label.prodscale")); // NOI18N + jLabel12.setPreferredSize(new java.awt.Dimension(130, 30)); + + m_jScale.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N + m_jScale.setPreferredSize(new java.awt.Dimension(30, 30)); + + m_jConstant.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N + m_jConstant.setPreferredSize(new java.awt.Dimension(30, 30)); + + jLabel14.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel14.setText(bundle.getString("label.prodconstant")); // NOI18N + jLabel14.setPreferredSize(new java.awt.Dimension(130, 30)); + + jLabel20.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel20.setText(bundle.getString("label.variableprice")); // NOI18N + jLabel20.setPreferredSize(new java.awt.Dimension(130, 30)); + + m_jVprice.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N + m_jVprice.setPreferredSize(new java.awt.Dimension(30, 30)); + + jLabel33.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel33.setText(bundle.getString("label.warranty")); // NOI18N + jLabel33.setToolTipText(bundle.getString("label.warranty")); // NOI18N + jLabel33.setPreferredSize(new java.awt.Dimension(130, 30)); + + m_jCheckWarrantyReceipt.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCheckWarrantyReceipt.setText(bundle.getString("label.productreceipt")); // NOI18N + m_jCheckWarrantyReceipt.setPreferredSize(new java.awt.Dimension(30, 30)); + + jLabel23.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel23.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLabel23.setText(bundle.getString("label.prodminmax")); // NOI18N + jLabel23.setVerticalAlignment(javax.swing.SwingConstants.TOP); + jLabel23.setPreferredSize(new java.awt.Dimension(531, 20)); + + webLabel1.setText(bundle.getString("label.printto")); // NOI18N + webLabel1.setToolTipText(bundle.getString("tooltip.printto")); // NOI18N + webLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + webLabel1.setPreferredSize(new java.awt.Dimension(130, 30)); + + m_jPrintTo.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPrintTo.setModel(new javax.swing.DefaultComboBoxModel(new String[]{"0", "1", "2", "3", "4", "5", "6"})); + m_jPrintTo.setPreferredSize(new java.awt.Dimension(50, 30)); + + jBtnShowTrans.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jBtnShowTrans.setText(bundle.getString("button.ProductStock")); // NOI18N + jBtnShowTrans.setToolTipText(""); + jBtnShowTrans.setPreferredSize(new java.awt.Dimension(140, 25)); + jBtnShowTrans.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnShowTransActionPerformed(evt); + } + }); + + jScrollPane2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + + jTableProductStock.setModel(new javax.swing.table.DefaultTableModel( + new Object[][]{ + {null, null, null, null}, + {null, null, null, null}, + {null, null, null, null}, + {null, null, null, null}, + {null, null, null, null}, + {null, null, null, null}, + {null, null, null, null}, + {null, null, null, null} + }, + new String[]{ + "Location", "Current", "Minimum", "Maximum" + } + )); + jTableProductStock.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTableProductStock.setRowHeight(25); + jScrollPane2.setViewportView(jTableProductStock); + + m_jPrintKB.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N + + m_jSendStatus.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N + + m_jStockUnits.setEditable(false); + m_jStockUnits.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jStockUnits.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jStockUnits.setText("0"); + m_jStockUnits.setBorder(null); + + jLblDate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblDate.setText(bundle.getString("label.proddate")); // NOI18N + jLblDate.setPreferredSize(new java.awt.Dimension(130, 30)); + + m_jbtndate.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/date.png"))); // NOI18N + m_jbtndate.setToolTipText("Open Calendar"); + m_jbtndate.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtndateActionPerformed(evt); + } + }); + + m_jdate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jdate.setPreferredSize(new java.awt.Dimension(160, 30)); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel18, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel8, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jCatalogOrder, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jInCatalog, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(webLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jPrintTo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(jLabel14, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jConstant, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jLabel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(m_jstockvolume, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jstockcost, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0)) + .addComponent(jLabel23, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel15, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel33, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(m_jService, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCheckWarrantyReceipt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jComment, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jScale, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jVprice, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(m_jPrintKB, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jSendStatus, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jStockUnits, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(18, 18, 18) + .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 372, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addComponent(jLblDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jbtndate, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) + .addComponent(m_jdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jBtnShowTrans, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addContainerGap()) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jstockcost, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel14, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(m_jConstant, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jstockvolume, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(jLabel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel23, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jInCatalog, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jCatalogOrder, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel18, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(webLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jPrintTo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jBtnShowTrans, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jbtndate, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 206, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel15, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jService, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel33, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCheckWarrantyReceipt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jComment, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jScale, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jVprice, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(m_jPrintKB, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jSendStatus, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(m_jStockUnits, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addGap(42, 42, 42)) + ); + + m_jService.getAccessibleContext().setAccessibleDescription("null"); + + jTabbedPane1.addTab(AppLocal.getIntString("label.prodstock"), jPanel2); // NOI18N + + jPanel3.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel3.setToolTipText(bundle.getString("tooltip.product.properties.tab")); // NOI18N + jPanel3.setPreferredSize(new java.awt.Dimension(0, 0)); + jPanel3.setLayout(new java.awt.BorderLayout()); + + jScrollPane1.setPreferredSize(new java.awt.Dimension(680, 400)); + + txtAttributes.setFont(new java.awt.Font("Monospaced", 0, 14)); // NOI18N + txtAttributes.setLineWrap(true); + txtAttributes.setWrapStyleWord(true); + txtAttributes.setPreferredSize(new java.awt.Dimension(580, 300)); + jScrollPane1.setViewportView(txtAttributes); + + jPanel3.add(jScrollPane1, java.awt.BorderLayout.CENTER); + + jBtnXml.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jBtnXml.setText(bundle.getString("button.injectxml")); // NOI18N + jBtnXml.setToolTipText(bundle.getString("tooltip.xmlheader")); // NOI18N + jBtnXml.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnXmlActionPerformed(evt); + } + }); + jPanel3.add(jBtnXml, java.awt.BorderLayout.PAGE_START); + + jTabbedPane1.addTab(AppLocal.getIntString("label.properties"), jPanel3); // NOI18N + + jPanel6.setToolTipText(bundle.getString("tooltip.product.image.tab")); // NOI18N + jPanel6.setPreferredSize(new java.awt.Dimension(0, 0)); + + jLabel34.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel34.setText(bundle.getString("label.imagesize")); // NOI18N + jLabel34.setPreferredSize(new java.awt.Dimension(500, 30)); + + javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6); + jPanel6.setLayout(jPanel6Layout); + jPanel6Layout.setHorizontalGroup( + jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel6Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel6Layout.createSequentialGroup() + .addComponent(jLabel34, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(115, Short.MAX_VALUE)) + .addGroup(jPanel6Layout.createSequentialGroup() + .addComponent(m_jImage, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(243, 243, 243)))) + ); + jPanel6Layout.setVerticalGroup( + jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel6Layout.createSequentialGroup() + .addContainerGap() + .addComponent(m_jImage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel34, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + + jTabbedPane1.addTab(bundle.getString("label.image"), jPanel6); // NOI18N + + jPanel4.setToolTipText(bundle.getString("tooltip.product.button.tab")); // NOI18N + jPanel4.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel4.setPreferredSize(new java.awt.Dimension(0, 0)); + + jLabel28.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel28.setText(bundle.getString("label.prodbuttonhtml")); // NOI18N + jLabel28.setPreferredSize(new java.awt.Dimension(250, 30)); + + jButtonHTML.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jButtonHTML.setText(bundle.getString("button.htmltest")); // NOI18N + jButtonHTML.setMargin(new java.awt.Insets(1, 1, 1, 1)); + jButtonHTML.setMaximumSize(new java.awt.Dimension(96, 72)); + jButtonHTML.setMinimumSize(new java.awt.Dimension(96, 72)); + jButtonHTML.setPreferredSize(new java.awt.Dimension(96, 72)); + jButtonHTML.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonHTMLActionPerformed(evt); + } + }); + + jLabel21.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel21.setText(bundle.getString("label.texttip")); // NOI18N + jLabel21.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jTextTip.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jTextTip.setPreferredSize(new java.awt.Dimension(400, 30)); + + m_jDisplay.setColumns(20); + m_jDisplay.setLineWrap(true); + m_jDisplay.setRows(4); + m_jDisplay.setWrapStyleWord(true); + m_jDisplay.setPreferredSize(new java.awt.Dimension(160, 100)); + jScrollPane3.setViewportView(m_jDisplay); + + jBtnBreak.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jBtnBreak.setText(bundle.getString("button.prodhtmldisplayBreak")); // NOI18N + jBtnBreak.setToolTipText("<html><center><h4>Inserts a Line Break<br> (a new line) for the button text"); + jBtnBreak.setPreferredSize(new java.awt.Dimension(70, 35)); + jBtnBreak.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnBreakActionPerformed(evt); + } + }); + + jBtnColour.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jBtnColour.setForeground(new java.awt.Color(0, 204, 255)); + jBtnColour.setText(bundle.getString("button.prodhtmldisplayColour")); // NOI18N + jBtnColour.setToolTipText("<html><center><h4>Set the colour <br>for the button text"); + jBtnColour.setPreferredSize(new java.awt.Dimension(70, 35)); + jBtnColour.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnColourActionPerformed(evt); + } + }); + + jBtnLarge.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jBtnLarge.setText(bundle.getString("button.prodhtmldisplayLarge")); // NOI18N + jBtnLarge.setToolTipText("<html><center><h4>Set the button<br> text to Large"); + jBtnLarge.setPreferredSize(new java.awt.Dimension(70, 35)); + jBtnLarge.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnLargeActionPerformed(evt); + } + }); + + jBtnSmall.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jBtnSmall.setText(bundle.getString("button.prodhtmldisplaySmall")); // NOI18N + jBtnSmall.setToolTipText("<html><center><h4>Set the button<br>text to Small"); + jBtnSmall.setPreferredSize(new java.awt.Dimension(70, 35)); + jBtnSmall.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnSmallActionPerformed(evt); + } + }); + + jBtnBold.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jBtnBold.setText(bundle.getString("button.prodhtmldisplayBold")); // NOI18N + jBtnBold.setToolTipText("<html><center><h4>Set the button<br> text to Italic"); + jBtnBold.setPreferredSize(new java.awt.Dimension(70, 35)); + jBtnBold.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnBoldActionPerformed(evt); + } + }); + + jBtnItalic.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jBtnItalic.setText(bundle.getString("button.prodhtmldisplayItalic")); // NOI18N + jBtnItalic.setToolTipText("<html><center><h4>Set the button<br> text to Italic"); + jBtnItalic.setPreferredSize(new java.awt.Dimension(70, 35)); + jBtnItalic.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnItalicActionPerformed(evt); + } + }); + + jBtnImage.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jBtnImage.setText(bundle.getString("button.prodhtmldisplayImage")); // NOI18N + jBtnImage.setToolTipText("<html><center><h4>Insert image from<br>local disk or internet URL"); + jBtnImage.setPreferredSize(new java.awt.Dimension(70, 35)); + jBtnImage.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnImageActionPerformed(evt); + } + }); + + jBtnReset.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jBtnReset.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reload.png"))); // NOI18N + jBtnReset.setText(bundle.getString("button.prodhtmldisplayReset")); // NOI18N + jBtnReset.setPreferredSize(new java.awt.Dimension(100, 35)); + jBtnReset.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnResetActionPerformed(evt); + } + }); + + jBtnStyle.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jBtnStyle.setText(bundle.getString("button.prodhtmldisplayStyle")); // NOI18N + jBtnStyle.setToolTipText("<html><center><h4>Insert <style> tag to change<br>button background colour"); + jBtnStyle.setPreferredSize(new java.awt.Dimension(70, 35)); + jBtnStyle.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnStyleActionPerformed(evt); + } + }); + + colourChooser.setToolTipText(bundle.getString("tooltip.prodhtmldisplayColourChooser")); // NOI18N + colourChooser.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + colourChooserActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); + jPanel4.setLayout(jPanel4Layout); + jPanel4Layout.setHorizontalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addComponent(jLabel28, javax.swing.GroupLayout.PREFERRED_SIZE, 230, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(272, 272, 272) + .addComponent(jBtnReset, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(jScrollPane3, javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addComponent(jLabel21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(m_jTextTip, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel4Layout.createSequentialGroup() + .addComponent(jBtnStyle, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jBtnBreak, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addComponent(jBtnColour, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jBtnLarge, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jBtnSmall, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel4Layout.createSequentialGroup() + .addGap(13, 13, 13) + .addComponent(colourChooser, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(49, 49, 49) + .addComponent(jButtonHTML, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jBtnBold, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jBtnItalic, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jBtnImage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel4Layout.setVerticalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel28, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jBtnReset, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jBtnSmall, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jBtnColour, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jBtnLarge, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jBtnBold, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jBtnItalic, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jBtnImage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jBtnStyle, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jBtnBreak, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jButtonHTML, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(colourChooser, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jTextTip, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(58, Short.MAX_VALUE)) + ); + + jTabbedPane1.addTab(AppLocal.getIntString("label.button"), jPanel4); // NOI18N + + add(jTabbedPane1); + jTabbedPane1.setBounds(10, 10, 630, 420); + }// </editor-fold>//GEN-END:initComponents + + private void jButtonHTMLActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonHTMLActionPerformed + setButtonHTML(); + }//GEN-LAST:event_jButtonHTMLActionPerformed + + private void none(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_none + + }//GEN-LAST:event_none + + private void m_jNameFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_m_jNameFocusLost + setDisplay(btn); +// if (m_jName.getText().contains("&")) { +// JOptionPane.showMessageDialog(null, +// AppLocal.getIntString("message.ampersand")); +// } + }//GEN-LAST:event_m_jNameFocusLost + + private void m_jRefFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_m_jRefFocusLost + setCode(); + }//GEN-LAST:event_m_jRefFocusLost + + private void jLabel1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabel1MouseClicked + + if (evt.getClickCount() == 2) { + String uuidString = m_oId.toString(); + StringSelection stringSelection = new StringSelection(uuidString); + Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard(); + clpbrd.setContents(stringSelection, null); + + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.uuidcopy")); + } + }//GEN-LAST:event_jLabel1MouseClicked + + private void jBtnXmlActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnXmlActionPerformed + txtAttributes.setText( + "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?> \n" + + "<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\">\n" + + "<properties>\n" + + " <entry key=\"identifier\">value</entry>\n" + + "</properties>"); + }//GEN-LAST:event_jBtnXmlActionPerformed + + private void jBtnSmallActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnSmallActionPerformed + btn = 4; + setDisplay(btn); + }//GEN-LAST:event_jBtnSmallActionPerformed + + private void jBtnBreakActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnBreakActionPerformed + btn = 1; + setDisplay(btn); + }//GEN-LAST:event_jBtnBreakActionPerformed + + private void jBtnColourActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnColourActionPerformed + btn = 2; + setDisplay(btn); + }//GEN-LAST:event_jBtnColourActionPerformed + + private void jBtnLargeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnLargeActionPerformed + btn = 3; + setDisplay(btn); + }//GEN-LAST:event_jBtnLargeActionPerformed + + private void jBtnBoldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnBoldActionPerformed + btn = 5; + setDisplay(btn); + }//GEN-LAST:event_jBtnBoldActionPerformed + + private void jBtnItalicActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnItalicActionPerformed + btn = 6; + setDisplay(btn); + }//GEN-LAST:event_jBtnItalicActionPerformed + + private void jBtnImageActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnImageActionPerformed + btn = 7; + setDisplay(btn); + }//GEN-LAST:event_jBtnImageActionPerformed + + private void jBtnResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnResetActionPerformed + btn = 8; + setDisplay(btn); + }//GEN-LAST:event_jBtnResetActionPerformed + + private void jBtnStyleActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnStyleActionPerformed + btn = 9; + setDisplay(btn); + }//GEN-LAST:event_jBtnStyleActionPerformed + + private void jBtnSupplierActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnSupplierActionPerformed + JDialogNewSupplier dialog = JDialogNewSupplier.getDialog(this, appView); + dialog.setVisible(true); + + if (dialog.getSelectedSupplier() != null) { + try { + m_SuppliersModel = new ComboBoxValModel(m_sentsuppliers.list()); + m_jSupplier.setModel(m_SuppliersModel); + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + } + }//GEN-LAST:event_jBtnSupplierActionPerformed + + private void colourChooserActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_colourChooserActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_colourChooserActionPerformed + + private void m_jCodeFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_m_jCodeFocusLost + if (m_jCode.getText().length() < 8) { + m_jCodetype.setSelectedIndex(2); + } + }//GEN-LAST:event_m_jCodeFocusLost + + private void m_jbtndateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtndateActionPerformed + + Date date; + try { + date = (Date) Formats.TIMESTAMP.parseValue(m_jdate.getText()); + } catch (BasicException e) { + date = null; + } + date = JCalendarDialog.showCalendarTime(this, date); + if (date != null) { + m_jdate.setText(Formats.TIMESTAMP.formatValue(date)); + } + }//GEN-LAST:event_m_jbtndateActionPerformed + + private void jBtnShowTransActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnShowTransActionPerformed + String pId = m_oId.toString(); + if (pId != null) { + stockModel = new StockTableModel(getProductOfName(pId)); + jTableProductStock.setModel(stockModel); + if (stockModel.getRowCount() > 0) { + jTableProductStock.setVisible(true); + } else { + jTableProductStock.setVisible(false); + JOptionPane.showMessageDialog(null, + "No Stock Locations for this Product", "Locations", JOptionPane.INFORMATION_MESSAGE); + } + resetTranxTable(); + } + }//GEN-LAST:event_jBtnShowTransActionPerformed + + private void m_jInCatalogActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jInCatalogActionPerformed + + if (m_jInCatalog.isSelected()) { + m_jCatalogOrder.setEnabled(true); + } else { + m_jCatalogOrder.setEnabled(false); + m_jCatalogOrder.setText(null); + } + }//GEN-LAST:event_m_jInCatalogActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private com.alee.extended.colorchooser.WebColorPicker colourChooser; + private javax.swing.JButton jBtnBold; + private javax.swing.JButton jBtnBreak; + private javax.swing.JButton jBtnColour; + private javax.swing.JButton jBtnImage; + private javax.swing.JButton jBtnItalic; + private javax.swing.JButton jBtnLarge; + private javax.swing.JButton jBtnReset; + private javax.swing.JButton jBtnShowTrans; + private javax.swing.JButton jBtnSmall; + private javax.swing.JButton jBtnStyle; + private javax.swing.JButton jBtnSupplier; + private javax.swing.JButton jBtnXml; + private javax.swing.JButton jButtonHTML; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel10; + private javax.swing.JLabel jLabel11; + private javax.swing.JLabel jLabel12; + private javax.swing.JLabel jLabel13; + private javax.swing.JLabel jLabel14; + private javax.swing.JLabel jLabel15; + private javax.swing.JLabel jLabel16; + private javax.swing.JLabel jLabel17; + private javax.swing.JLabel jLabel18; + private javax.swing.JLabel jLabel19; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel20; + private javax.swing.JLabel jLabel21; + private javax.swing.JLabel jLabel22; + private javax.swing.JLabel jLabel23; + private javax.swing.JLabel jLabel26; + private javax.swing.JLabel jLabel28; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel33; + private javax.swing.JLabel jLabel34; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JLabel jLabel9; + private javax.swing.JLabel jLblDate; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel6; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JScrollPane jScrollPane2; + private javax.swing.JScrollPane jScrollPane3; + private javax.swing.JTabbedPane jTabbedPane1; + private com.alee.laf.table.WebTable jTableProductStock; + private javax.swing.JComboBox m_jAtt; + private javax.swing.JTextField m_jCatalogOrder; + private javax.swing.JComboBox m_jCategory; + private javax.swing.JCheckBox m_jCheckWarrantyReceipt; + private javax.swing.JTextField m_jCode; + private javax.swing.JComboBox m_jCodetype; + private javax.swing.JCheckBox m_jComment; + private javax.swing.JCheckBox m_jConstant; + private com.alee.laf.text.WebTextArea m_jDisplay; + private javax.swing.JTextField m_jGrossProfit; + private com.unicenta.data.gui.JImageEditor m_jImage; + private javax.swing.JCheckBox m_jInCatalog; + private javax.swing.JTextField m_jName; + private javax.swing.JTextField m_jPriceBuy; + private javax.swing.JTextField m_jPriceSell; + private javax.swing.JTextField m_jPriceSellTax; + private javax.swing.JCheckBox m_jPrintKB; + private javax.swing.JComboBox m_jPrintTo; + private javax.swing.JTextField m_jRef; + private javax.swing.JCheckBox m_jScale; + private javax.swing.JCheckBox m_jSendStatus; + private javax.swing.JCheckBox m_jService; + private javax.swing.JTextField m_jStockUnits; + private javax.swing.JComboBox m_jSupplier; + private javax.swing.JComboBox m_jTax; + private javax.swing.JTextField m_jTextTip; + private javax.swing.JLabel m_jTitle; + private javax.swing.JComboBox m_jUom; + private javax.swing.JCheckBox m_jVerpatrib; + private javax.swing.JCheckBox m_jVprice; + private javax.swing.JButton m_jbtndate; + private javax.swing.JTextField m_jdate; + private javax.swing.JTextField m_jmargin; + private javax.swing.JTextField m_jstockcost; + private javax.swing.JTextField m_jstockvolume; + private javax.swing.JTextArea txtAttributes; + private com.alee.laf.label.WebLabel webLabel1; + // End of variables declaration//GEN-END:variables + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/inventory/ProductsPanel.java b/src/main/java/com/unicenta/pos/inventory/ProductsPanel.java new file mode 100644 index 0000000..a288dc0 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/ProductsPanel.java @@ -0,0 +1,144 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.user.EditorListener; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.panels.JPanelTable2; +import com.unicenta.pos.ticket.ProductFilter; + +import java.awt.Component; +import javax.swing.JButton; + +/** + * + * @author JG uniCenta + * + */ +public class ProductsPanel extends JPanelTable2 implements EditorListener { + + private ProductsEditor jeditor; + private ProductFilter jproductfilter; + + private DataLogicSales m_dlSales = null; + + public ProductsPanel() { + } + + /** + * + */ + @Override + protected void init() { + m_dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + + jproductfilter = new ProductFilter(); + jproductfilter.init(app); + + row = m_dlSales.getProductsRow(); + + lpr = new ListProviderCreator(m_dlSales.getProductCatQBF(), jproductfilter); + + spr = new SaveProvider( + m_dlSales.getProductCatUpdate(), + m_dlSales.getProductCatInsert(), + m_dlSales.getProductCatDelete()); + + jeditor = new ProductsEditor(app, dirty); + } + + /** + * + * @return value + */ + @Override + public EditorRecord getEditor() { + return jeditor; + } + + /** + * + * @return value + */ + @Override + public Component getFilter() { + return jproductfilter.getComponent(); + } + + /** + * + * @return btnScanPal + */ + @Override + public Component getToolbarExtras() { + + JButton btnScanPal = new JButton(); + btnScanPal.setText("ScanPal"); + btnScanPal.setVisible(app.getDeviceScanner() != null); + btnScanPal.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnScanPalActionPerformed(evt); + } + }); + + return btnScanPal; + } + + private void btnScanPalActionPerformed(java.awt.event.ActionEvent evt) { + + JDlgUploadProducts.showMessage(this, app.getDeviceScanner(), bd); + } + + /** + * + * @return value + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.Products"); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + + jeditor.activate(); + jproductfilter.activate(); + + super.activate(); + } + + /** + * + * @param value + */ + @Override + public void updateValue(Object value) { + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/inventory/ProductsWarehouseEditor.form b/src/main/java/com/unicenta/pos/inventory/ProductsWarehouseEditor.form new file mode 100644 index 0000000..25705cb --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/ProductsWarehouseEditor.form @@ -0,0 +1,157 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel4" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jMinimum" min="-2" pref="80" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel5" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jMaximum" min="-2" pref="80" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jQuantity" min="-2" pref="80" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jTitle" min="-2" pref="314" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jTitle" min="-2" pref="30" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jQuantity" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jMinimum" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jMaximum" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="m_jTitle"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.units" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jQuantity"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.minimum" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jMinimum"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.maximum" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jMaximum"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/ProductsWarehouseEditor.java b/src/main/java/com/unicenta/pos/inventory/ProductsWarehouseEditor.java new file mode 100644 index 0000000..4b9896f --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/ProductsWarehouseEditor.java @@ -0,0 +1,271 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-130 + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import java.awt.Component; + +/** + * + * @author adrianromero + */ +public class ProductsWarehouseEditor extends javax.swing.JPanel implements EditorRecord { + + /** + * + */ + public Object id; + public Object prodid; + public Object prodref; + public Object prodname; + public Object location; + + /** Creates new form ProductsWarehouseEditor + * @param dirty */ + public ProductsWarehouseEditor(DirtyManager dirty) { + initComponents(); + + m_jMinimum.getDocument().addDocumentListener(dirty); + m_jMaximum.getDocument().addDocumentListener(dirty); + } + + public ProductsWarehouseEditor() { + throw new UnsupportedOperationException("Not supported yet."); + } + + /** + * + */ + @Override + public void writeValueEOF() { + m_jTitle.setText(AppLocal.getIntString("label.recordeof")); + id = null; + prodid = null; + prodref = null; + prodname = null; + location = null; + m_jQuantity.setText(null); + m_jMinimum.setText(null); + m_jMaximum.setText(null); + m_jMinimum.setEnabled(false); + m_jMaximum.setEnabled(false); + } + + /** + * + */ + @Override + public void writeValueInsert() { + m_jTitle.setText(AppLocal.getIntString("label.recordnew")); + id = null; + prodid = null; + prodref = null; + prodname = null; + location = null; + m_jQuantity.setText(null); + m_jMinimum.setText(null); + m_jMaximum.setText(null); + m_jMinimum.setEnabled(true); + m_jMaximum.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueEdit(Object value) { + Object[] myprod = (Object[]) value; + id = myprod[0]; + prodid = myprod[1]; + prodref = myprod[2]; + prodname = myprod[3]; + location = myprod[4]; + m_jTitle.setText(Formats.STRING.formatValue(myprod[2]) + " - " + Formats.STRING.formatValue(myprod[3])); + m_jQuantity.setText(Formats.DOUBLE.formatValue(myprod[7])); + m_jMinimum.setText(Formats.DOUBLE.formatValue(myprod[5])); + m_jMaximum.setText(Formats.DOUBLE.formatValue(myprod[6])); + m_jMinimum.setEnabled(true); + m_jMaximum.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueDelete(Object value) { + Object[] myprod = (Object[]) value; + id = myprod[0]; + prodid = myprod[1]; + prodref = myprod[2]; + prodname = myprod[3]; + location = myprod[4]; + m_jTitle.setText(Formats.STRING.formatValue(myprod[2]) + " - " + Formats.STRING.formatValue(myprod[3])); + m_jQuantity.setText(Formats.DOUBLE.formatValue(myprod[7])); + m_jMinimum.setText(Formats.DOUBLE.formatValue(myprod[5])); + m_jMaximum.setText(Formats.DOUBLE.formatValue(myprod[6])); + m_jMinimum.setEnabled(false); + m_jMaximum.setEnabled(false); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + return new Object[] { + id, + prodid, + prodref, + prodname, + location, + Formats.DOUBLE.parseValue(m_jMinimum.getText()), + Formats.DOUBLE.parseValue(m_jMaximum.getText()), + Formats.DOUBLE.parseValue(m_jQuantity.getText()) + }; + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + */ + @Override + public void refresh() { + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jTitle = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + m_jQuantity = new javax.swing.JTextField(); + jLabel4 = new javax.swing.JLabel(); + m_jMinimum = new javax.swing.JTextField(); + jLabel5 = new javax.swing.JLabel(); + m_jMaximum = new javax.swing.JTextField(); + + m_jTitle.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jTitle.setPreferredSize(new java.awt.Dimension(300, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.units")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jQuantity.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jQuantity.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jQuantity.setEnabled(false); + m_jQuantity.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.minimum")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jMinimum.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jMinimum.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jMinimum.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.maximum")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jMaximum.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jMaximum.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jMaximum.setPreferredSize(new java.awt.Dimension(0, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jMinimum, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jMaximum, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jQuantity, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jTitle, javax.swing.GroupLayout.PREFERRED_SIZE, 314, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(m_jTitle, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jQuantity, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jMinimum, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jMaximum, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JTextField m_jMaximum; + private javax.swing.JTextField m_jMinimum; + private javax.swing.JTextField m_jQuantity; + private javax.swing.JLabel m_jTitle; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/inventory/ProductsWarehousePanel.java b/src/main/java/com/unicenta/pos/inventory/ProductsWarehousePanel.java new file mode 100644 index 0000000..1ae90e6 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/ProductsWarehousePanel.java @@ -0,0 +1,173 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.*; +import com.unicenta.data.model.Field; +import com.unicenta.data.model.Row; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.panels.JPanelTable2; +import com.unicenta.pos.reports.JParamsLocation; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.UUID; + +/** + * + * @author adrianromero + */ +public class ProductsWarehousePanel extends JPanelTable2 { + + private JParamsLocation m_paramslocation; + private ProductsWarehouseEditor jeditor; + + /** Creates a new instance of ProductsWarehousePanel */ + public ProductsWarehousePanel() { + } + + /** + * + */ + @Override + protected void init() { + + m_paramslocation = new JParamsLocation(); + m_paramslocation.init(app); + m_paramslocation.addActionListener(new ReloadActionListener()); + + row = new Row( + new Field("ID", Datas.STRING, Formats.STRING), + new Field("PRODUCT_ID", Datas.STRING, Formats.STRING), + new Field(AppLocal.getIntString("label.prodref"), Datas.STRING, Formats.STRING, true, true, true), + new Field(AppLocal.getIntString("label.prodname"), Datas.STRING, Formats.STRING, true, true, true), + new Field("LOCATION", Datas.STRING, Formats.STRING), + new Field("STOCKSECURITY", Datas.DOUBLE, Formats.DOUBLE), + new Field("STOCKMAXIMUM", Datas.DOUBLE, Formats.DOUBLE), + new Field("UNITS", Datas.DOUBLE, Formats.DOUBLE) + ); + + lpr = new ListProviderCreator(new PreparedSentence(app.getSession(), + "SELECT L.ID, P.ID, P.REFERENCE, P.NAME," + + "L.STOCKSECURITY, L.STOCKMAXIMUM, COALESCE(S.SUMUNITS, 0) " + + "FROM products P " + + "LEFT OUTER JOIN (SELECT ID, PRODUCT, LOCATION, STOCKSECURITY, STOCKMAXIMUM " + + "FROM stocklevel WHERE LOCATION = ?) L ON P.ID = L.PRODUCT " + + "LEFT OUTER JOIN (SELECT PRODUCT, SUM(UNITS) AS SUMUNITS " + + "FROM stockcurrent WHERE LOCATION = ? GROUP BY PRODUCT) S ON P.ID = S.PRODUCT " + + "ORDER BY P.NAME", + new SerializerWriteBasicExt(new Datas[] {Datas.OBJECT, Datas.STRING}, new int[]{1, 1}), + new WarehouseSerializerRead() + ), + m_paramslocation); + + SentenceExec updatesent = new SentenceExecTransaction(app.getSession()) { + @Override + public int execInTransaction(Object params) throws BasicException { + Object[] values = (Object[]) params; + if (values[0] == null) { + // INSERT + values[0] = UUID.randomUUID().toString(); + return new PreparedSentence(app.getSession() + , "INSERT INTO stocklevel (ID, LOCATION, PRODUCT, STOCKSECURITY, STOCKMAXIMUM) VALUES (?, ?, ?, ?, ?)" + , new SerializerWriteBasicExt(row.getDatas(), new int[] {0, 4, 1, 5, 6})).exec(params); + } else { + // UPDATE + return new PreparedSentence(app.getSession() + , "UPDATE stocklevel SET STOCKSECURITY = ?, STOCKMAXIMUM = ? WHERE ID = ?" + , new SerializerWriteBasicExt(row.getDatas(), new int[] {5, 6, 0})).exec(params); + } + } + }; + + spr = new SaveProvider(updatesent, null, null); + + jeditor = new ProductsWarehouseEditor(dirty); + } + + /** + * + * @return + */ + @Override + public Component getFilter() { + return m_paramslocation.getComponent(); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return jeditor; + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + + m_paramslocation.activate(); + super.activate(); + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.ProductsWarehouse"); + } + + private class ReloadActionListener implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + try { + ProductsWarehousePanel.this.bd.actionLoad(); + } catch (BasicException w) { + } + } + } + + private class WarehouseSerializerRead implements SerializerRead { + @Override + public Object readValues(DataRead dr) throws BasicException { + return new Object[] { + dr.getString(1), + dr.getString(2), + dr.getString(3), + dr.getString(4), + ((Object[]) m_paramslocation.createValue())[1], + dr.getDouble(5), + dr.getDouble(6), + dr.getDouble(7) + }; + } + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/StockDiaryEditor.form b/src/main/java/com/unicenta/pos/inventory/StockDiaryEditor.form new file mode 100644 index 0000000..dbaa681 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/StockDiaryEditor.form @@ -0,0 +1,665 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[550, 250]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[1000, 550]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,38,0,0,3,-24"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[2147483647, 2147483647]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[780, 260]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[400, 600]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="First"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLblDate" min="-2" pref="110" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jdate" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jbtndate" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="jLblReason" alignment="0" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLblLocation" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="m_jreason" alignment="0" max="-2" attributes="0"/> + <Component id="m_jLocation" max="-2" attributes="0"/> + </Group> + </Group> + <Component id="jLblMoveTo" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLblLocation1" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="m_jLocationDes" alignment="0" max="-2" attributes="0"/> + <Component id="m_jSupplier" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLblAtt" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jattributes" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jEditAttributes" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLBCode" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jcodebar" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jEnter" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLblUnits" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_junits" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLblPrice" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jprice" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLblName" alignment="0" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLblRef" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jreference" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="114" pref="114" max="-2" attributes="0"/> + <Component id="jproduct" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jEnter1" min="-2" max="-2" attributes="0"/> + <Component id="jEditProduct" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="catcontainer" pref="612" max="32767" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jdate" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLblDate" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="m_jbtndate" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jreason" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLblReason" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jLocation" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLblLocation" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLblMoveTo" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jLocationDes" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jSupplier" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLblLocation1" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" alignment="0" groupAlignment="3" attributes="0"> + <Component id="jLblName" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jproduct" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="jEditProduct" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" alignment="0" groupAlignment="3" attributes="0"> + <Component id="m_jreference" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLblRef" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="m_jEnter1" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" alignment="0" groupAlignment="3" attributes="0"> + <Component id="jattributes" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLblAtt" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="jEditAttributes" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jEnter" alignment="0" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jcodebar" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLBCode" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLblUnits" min="-2" max="-2" attributes="0"/> + <Component id="m_junits" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLblPrice" min="-2" max="-2" attributes="0"/> + <Component id="m_jprice" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace min="0" pref="47" max="32767" attributes="0"/> + </Group> + <Component id="catcontainer" max="32767" attributes="0"/> + </Group> + <EmptySpace pref="48" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLblDate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.stockdate" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[23, 20]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[23, 20]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jdate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 20]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="m_jbtndate"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/date.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Open Calendar"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[64, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jbtndateActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLblReason"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.stockreason" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[36, 20]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[36, 20]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jreason"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jreasonActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLblName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodname" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 20]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 20]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jproduct"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value=" "/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jproductActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jEditProduct"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/search24.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Search Product List"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[64, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jEditProductActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLblLocation"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="text" type="java.lang.String" value="Location"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jLocation"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLBCode"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodbarcode" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 20]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 20]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jcodebar"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jcodebarActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jEnter"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/barcode.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Get Barcode"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[54, 33]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[54, 33]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[64, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jEnterActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLblRef"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodref" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 20]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 20]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jreference"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jreferenceActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jEnter1"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/products.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Enter Product ID"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[64, 33]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[64, 33]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[64, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jEnter1ActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLblAtt"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.attributes" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[48, 20]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[48, 20]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jattributes"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jattributesActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jEditAttributes"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/attributes.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Product Attributes"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[65, 33]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[65, 33]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[64, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jEditAttributesActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLblUnits"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.units" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 20]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 20]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_junits"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblPrice"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.price" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jprice"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 30]"/> + </Property> + </Properties> + </Component> + <Container class="javax.swing.JPanel" name="catcontainer"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" red="ff" type="rgb"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[2147483647, 2147483647]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 250]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[600, 0]"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleParent" type="javax.accessibility.Accessible" editor="org.netbeans.modules.form.ComponentChooserEditor"> + <ComponentRef name="jPanel1"/> + </Property> + </AccessibilityProperties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + </Container> + <Component class="javax.swing.JComboBox" name="m_jLocationDes"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jLocationDesActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLblMoveTo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.moveto" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jSupplier"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblLocation1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.suppliername" replaceFormat="AppLocal.getIntString("button.exit")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/StockDiaryEditor.java b/src/main/java/com/unicenta/pos/inventory/StockDiaryEditor.java new file mode 100644 index 0000000..3964299 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/StockDiaryEditor.java @@ -0,0 +1,993 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.forms.DataLogicSystem; +import com.unicenta.pos.suppliers.DataLogicSuppliers; +import com.unicenta.pos.panels.JProductFinder; +import java.awt.Component; +import com.unicenta.basic.BasicException; +import com.unicenta.beans.DateUtils; +import com.unicenta.beans.JCalendarDialog; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.format.Formats; +import com.unicenta.pos.catalog.CatalogSelector; +import com.unicenta.pos.catalog.JCatalog; +import com.unicenta.pos.printer.TicketParser; +import com.unicenta.pos.sales.JProductAttEdit; +import com.unicenta.pos.ticket.ProductInfoExt; +import java.awt.BorderLayout; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Date; +import java.util.UUID; +import javax.swing.JOptionPane; + +public final class StockDiaryEditor extends javax.swing.JPanel implements EditorRecord { + + private final AppView m_App; + private final DataLogicSystem m_dlSystem; + private final DataLogicSales m_dlSales; + private final DataLogicSuppliers m_dlSuppliers; + private final TicketParser m_TTP; + + private final CatalogSelector m_cat; + private final ComboBoxValModel m_ReasonModel; + + private final SentenceList m_sentlocations; + private ComboBoxValModel m_LocationsModel; + private ComboBoxValModel m_LocationsModelDes; + + private final SentenceList m_sentsuppliers; + private ComboBoxValModel m_SuppliersModel; + private String m_sID; + + private String productid; + private String productref; + private String productcode; + private String productname; + private String attsetid; + private String attsetinstid; + private String attsetinstdesc; + private String sAppUser; + + + private final String user; + + + /** Creates new form StockDiaryEditor + * @param app + * @param dirty */ + public StockDiaryEditor(AppView app, DirtyManager dirty) { + + m_App = app; + m_dlSystem = (DataLogicSystem) m_App.getBean("com.unicenta.pos.forms.DataLogicSystem"); + m_dlSales = (DataLogicSales) m_App.getBean("com.unicenta.pos.forms.DataLogicSales"); + m_dlSuppliers = (DataLogicSuppliers) m_App.getBean("com.unicenta.pos.suppliers.DataLogicSuppliers"); + m_TTP = new TicketParser(m_App.getDeviceTicket(), m_dlSystem); + + initComponents(); + + user = m_App.getAppUserView().getUser().getName(); + m_sentlocations = m_dlSales.getLocationsList(); + m_LocationsModel = new ComboBoxValModel(); + m_LocationsModel = new ComboBoxValModel(); + m_LocationsModelDes = new ComboBoxValModel(); + + m_sentsuppliers = m_dlSuppliers.getSupplierList(); + m_SuppliersModel = new ComboBoxValModel(); + + m_ReasonModel = new ComboBoxValModel(); + m_ReasonModel.add(MovementReason.IN_PURCHASE); + m_ReasonModel.add(MovementReason.IN_REFUND); + m_ReasonModel.add(MovementReason.IN_MOVEMENT); + m_ReasonModel.add(MovementReason.OUT_SALE); + m_ReasonModel.add(MovementReason.OUT_REFUND); + m_ReasonModel.add(MovementReason.OUT_BREAK); + m_ReasonModel.add(MovementReason.OUT_MOVEMENT); + m_ReasonModel.add(MovementReason.OUT_CROSSING); + + m_jreason.setModel(m_ReasonModel); + + m_cat = new JCatalog(m_dlSales); + m_cat.addActionListener(new CatalogListener()); + + catcontainer.add(m_cat.getComponent(), BorderLayout.CENTER); + + m_jdate.getDocument().addDocumentListener(dirty); + m_jreason.addActionListener(dirty); + m_jLocation.addActionListener(dirty); + m_jLocationDes.addActionListener(dirty); + + jproduct.getDocument().addDocumentListener(dirty); + jattributes.getDocument().addDocumentListener(dirty); + m_junits.getDocument().addDocumentListener(dirty); + m_jprice.getDocument().addDocumentListener(dirty); + + m_jSupplier.addActionListener(dirty); + + writeValueEOF(); + } + + /** + * + * @throws BasicException + */ + public void activate() throws BasicException { + m_cat.loadCatalog(); + + java.util.List l = m_sentlocations.list(); + m_LocationsModel = new ComboBoxValModel(m_sentlocations.list()); + m_jLocation.setModel(m_LocationsModel); + m_LocationsModelDes = new ComboBoxValModel(l); + m_jLocationDes.setModel(m_LocationsModelDes); + + java.util.List sl = m_sentsuppliers.list(); + m_SuppliersModel = new ComboBoxValModel(m_sentsuppliers.list()); + m_jSupplier.setModel(m_SuppliersModel); + + } + + /** + * + */ + @Override + public void refresh() { + } + + /** + * + */ + @Override + public void writeValueEOF() { + m_sID = null; + m_jdate.setText(null); + m_ReasonModel.setSelectedKey(null); + m_LocationsModel.setSelectedKey(m_App.getInventoryLocation()); + m_LocationsModelDes.setSelectedKey(m_App.getInventoryLocation()); + m_SuppliersModel.setSelectedKey(null); + + productid = null; + productref = null; + productcode = null; + productname = null; + m_jreference.setText(null); + m_jcodebar.setText(null); + jproduct.setText(null); + attsetid = null; + attsetinstid = null; + attsetinstdesc = null; + jattributes.setText(null); + m_junits.setText(null); + m_jprice.setText(null); + m_jdate.setEnabled(false); + m_jbtndate.setEnabled(false); + m_jreason.setEnabled(false); + m_jreference.setEnabled(false); + m_jEnter1.setEnabled(false); + m_jcodebar.setEnabled(false); + m_jEnter.setEnabled(false); + m_jLocation.setEnabled(false); + jproduct.setEnabled(false); + jEditProduct.setEnabled(false); + jattributes.setEnabled(false); + jEditAttributes.setEnabled(false); + m_junits.setEnabled(false); + m_jprice.setEnabled(false); + m_cat.setComponentEnabled(false); + } + + /** + * + */ + @Override + public void writeValueInsert() { + m_sID = UUID.randomUUID().toString(); + m_jdate.setText(Formats.TIMESTAMP.formatValue(DateUtils.getTodayMinutes())); + m_ReasonModel.setSelectedItem(MovementReason.IN_PURCHASE); + m_LocationsModel.setSelectedKey(m_App.getInventoryLocation()); + m_LocationsModelDes.setSelectedKey(m_App.getInventoryLocation()); + m_SuppliersModel.setSelectedKey(null); + + productid = null; + productref = null; + productcode = null; + productname = null; + m_jreference.setText(null); + m_jcodebar.setText(null); + jproduct.setText(null); + attsetid = null; + attsetinstid = null; + attsetinstdesc = null; + jattributes.setText(null); + m_jcodebar.setText(null); + m_junits.setText(null); + m_jprice.setText(null); + m_jdate.setEnabled(true); + m_jbtndate.setEnabled(true); + m_jreason.setEnabled(true); + m_jreference.setEnabled(true); + m_jEnter1.setEnabled(true); + m_jcodebar.setEnabled(true); + m_jEnter.setEnabled(true); + m_jLocation.setEnabled(true); + m_jSupplier.setEnabled(true); + jproduct.setEnabled(true); + jEditProduct.setEnabled(true); + jattributes.setEnabled(true); + jEditAttributes.setEnabled(true); + m_junits.setEnabled(true); + m_jprice.setEnabled(true); + m_cat.setComponentEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueDelete(Object value) { + Object[] diary = (Object[]) value; + m_sID = (String) diary[0]; + m_jdate.setText(Formats.TIMESTAMP.formatValue(diary[1])); + m_ReasonModel.setSelectedKey(diary[2]); + m_LocationsModel.setSelectedKey(diary[3]); + productid = (String) diary[4]; + attsetinstid = (String) diary[5]; + m_junits.setText(Formats.DOUBLE.formatValue(signum((Double) diary[6], (Integer) diary[2]))); + m_jprice.setText(Formats.CURRENCY.formatValue(diary[7])); + productref = (String) diary[8]; + productcode = (String) diary[9]; + productname =(String) diary[10]; + attsetid = (String) diary[11]; + attsetinstdesc = (String) diary[12]; + m_SuppliersModel.setSelectedKey(diary[13]); + + m_jreference.setText(productref); + m_jcodebar.setText(productcode); + jproduct.setText(productname); + jattributes.setText(attsetinstdesc); + + m_jdate.setEnabled(false); + m_jbtndate.setEnabled(false); + m_jreason.setEnabled(false); + m_jreference.setEnabled(false); + m_jEnter1.setEnabled(false); + m_jcodebar.setEnabled(false); + m_jEnter.setEnabled(false); + m_jLocation.setEnabled(false); + m_jLocationDes.setEnabled(false); + m_jSupplier.setEnabled(false); + jproduct.setEnabled(false); + jEditProduct.setEnabled(false); + jattributes.setEnabled(false); + jEditAttributes.setEnabled(false); + m_junits.setEnabled(false); + m_jprice.setEnabled(false); + m_cat.setComponentEnabled(false); + } + + /** + * + * @param value + */ + @Override + public void writeValueEdit(Object value) { + Object[] diary = (Object[]) value; + m_sID = (String) diary[0]; + m_jdate.setText(Formats.TIMESTAMP.formatValue(diary[1])); + m_ReasonModel.setSelectedKey(diary[2]); + m_LocationsModel.setSelectedKey(diary[3]); + productid = (String) diary[4]; + attsetinstid = (String) diary[5]; + m_junits.setText(Formats.DOUBLE.formatValue(signum((Double) diary[6], (Integer) diary[2]))); + m_jprice.setText(Formats.CURRENCY.formatValue(diary[7])); + sAppUser = (String) diary[8]; + productref = (String) diary[9]; + productcode = (String) diary[10]; + productname =(String) diary[11]; + attsetid = (String) diary[12]; + attsetinstdesc = (String) diary[13]; + m_SuppliersModel.setSelectedKey(diary[14]); + + m_jreference.setText(productref); + m_jcodebar.setText(productcode); + jproduct.setText(productname); + jattributes.setText(attsetinstdesc); + + m_jdate.setEnabled(false); + m_jbtndate.setEnabled(false); + m_jreason.setEnabled(false); + m_jreference.setEnabled(false); + m_jEnter1.setEnabled(false); + m_jcodebar.setEnabled(false); + m_jEnter.setEnabled(false); + m_jLocation.setEnabled(false); + m_jLocationDes.setEnabled(false); + m_jSupplier.setEnabled(false); + jproduct.setEnabled(true); + jEditProduct.setEnabled(true); + jattributes.setEnabled(false); + jEditAttributes.setEnabled(false); + m_junits.setEnabled(false); + m_jprice.setEnabled(false); + m_cat.setComponentEnabled(false); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + return new Object[] { + m_sID, + Formats.TIMESTAMP.parseValue(m_jdate.getText()), + m_ReasonModel.getSelectedKey(), + m_LocationsModel.getSelectedKey(), + productid, + attsetinstid, + samesignum((Double) Formats.DOUBLE.parseValue(m_junits.getText()), (Integer) m_ReasonModel.getSelectedKey()), + Formats.CURRENCY.parseValue(m_jprice.getText()), + m_App.getAppUserView().getUser().getName(), + productref, + productcode, + productname, + attsetid, + attsetinstdesc, +// m_SuppliersModel.getSelectedKey() + }; + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } +// private ProductInfoExt getProduct(String id) { +// try { +// return m_dlSales.getProductInfo(id); +// } catch (BasicException e) { +// return null; +// } +// } + + private Double signum(Double d, Integer i) { + if (d == null || i == null) { + return d; + } else if (i < 0) { + return -d; + } else { + return d; + } + } + + private Double samesignum(Double d, Integer i) { + + if (d == null || i == null) { + return d; + } else if ((i > 0 && d < 0.0) || + (i < 0 && d > 0.0)) { + return -d; + } else { + return d; + } + } + + private void assignProduct(ProductInfoExt prod) { + + if (jproduct.isEnabled()) { + if (prod == null) { + productid = null; + productref = null; + productcode = null; + productname = null; + attsetid = null; + attsetinstid = null; + attsetinstdesc = null; + jproduct.setText(null); + m_jcodebar.setText(null); + m_jreference.setText(null); + jattributes.setText(null); +// m_jSupplier = null; + } else { + productid = prod.getID(); + productref = prod.getReference(); + productcode = prod.getCode(); + productname = prod.toString(); + attsetid = prod.getAttributeSetID(); + attsetinstid = null; + attsetinstdesc = null; + jproduct.setText(productname); + m_jcodebar.setText(productcode); + m_jreference.setText(productref); + jattributes.setText(null); + + // calculo el precio sugerido para la entrada. + MovementReason reason = (MovementReason) m_ReasonModel.getSelectedItem(); + Double dPrice = reason.getPrice(prod.getPriceBuy(), prod.getPriceSell()); + m_jprice.setText(Formats.CURRENCY.formatValue(dPrice)); + } + } + } + + private void assignProductByCode() { + try { + ProductInfoExt oProduct = m_dlSales.getProductInfoByCode(m_jcodebar.getText()); + if (oProduct == null) { + assignProduct(null); + Toolkit.getDefaultToolkit().beep(); + } else { + assignProduct(oProduct); + } + } catch (BasicException eData) { + assignProduct(null); + MessageInf msg = new MessageInf(eData); + msg.show(this); + } + } + + private void assignProductByReference() { + try { + ProductInfoExt oProduct = m_dlSales.getProductInfoByReference(m_jreference.getText()); + if (oProduct == null) { + assignProduct(null); + Toolkit.getDefaultToolkit().beep(); + } else { + assignProduct(oProduct); + } + } catch (BasicException eData) { + assignProduct(null); + MessageInf msg = new MessageInf(eData); + msg.show(this); + } + } + + private class CatalogListener implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + assignProduct((ProductInfoExt) e.getSource()); + } + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jLblDate = new javax.swing.JLabel(); + m_jdate = new javax.swing.JTextField(); + m_jbtndate = new javax.swing.JButton(); + jLblReason = new javax.swing.JLabel(); + m_jreason = new javax.swing.JComboBox(); + jLblName = new javax.swing.JLabel(); + jproduct = new javax.swing.JTextField(); + jEditProduct = new javax.swing.JButton(); + jLblLocation = new javax.swing.JLabel(); + m_jLocation = new javax.swing.JComboBox(); + jLBCode = new javax.swing.JLabel(); + m_jcodebar = new javax.swing.JTextField(); + m_jEnter = new javax.swing.JButton(); + jLblRef = new javax.swing.JLabel(); + m_jreference = new javax.swing.JTextField(); + m_jEnter1 = new javax.swing.JButton(); + jLblAtt = new javax.swing.JLabel(); + jattributes = new javax.swing.JTextField(); + jEditAttributes = new javax.swing.JButton(); + jLblUnits = new javax.swing.JLabel(); + m_junits = new javax.swing.JTextField(); + jLblPrice = new javax.swing.JLabel(); + m_jprice = new javax.swing.JTextField(); + catcontainer = new javax.swing.JPanel(); + m_jLocationDes = new javax.swing.JComboBox(); + jLblMoveTo = new javax.swing.JLabel(); + m_jSupplier = new javax.swing.JComboBox(); + jLblLocation1 = new javax.swing.JLabel(); + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setMinimumSize(new java.awt.Dimension(550, 250)); + setPreferredSize(new java.awt.Dimension(1000, 550)); + setLayout(new java.awt.BorderLayout()); + + jPanel1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel1.setMaximumSize(new java.awt.Dimension(2147483647, 2147483647)); + jPanel1.setMinimumSize(new java.awt.Dimension(780, 260)); + jPanel1.setPreferredSize(new java.awt.Dimension(400, 600)); + + jLblDate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblDate.setText(AppLocal.getIntString("label.stockdate")); // NOI18N + jLblDate.setMaximumSize(new java.awt.Dimension(23, 20)); + jLblDate.setMinimumSize(new java.awt.Dimension(23, 20)); + jLblDate.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jdate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jdate.setMinimumSize(new java.awt.Dimension(40, 20)); + m_jdate.setPreferredSize(new java.awt.Dimension(170, 30)); + + m_jbtndate.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/date.png"))); // NOI18N + m_jbtndate.setToolTipText("Open Calendar"); + m_jbtndate.setPreferredSize(new java.awt.Dimension(64, 45)); + m_jbtndate.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtndateActionPerformed(evt); + } + }); + + jLblReason.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblReason.setText(AppLocal.getIntString("label.stockreason")); // NOI18N + jLblReason.setMaximumSize(new java.awt.Dimension(36, 20)); + jLblReason.setMinimumSize(new java.awt.Dimension(36, 20)); + jLblReason.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jreason.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jreason.setPreferredSize(new java.awt.Dimension(170, 30)); + m_jreason.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jreasonActionPerformed(evt); + } + }); + + jLblName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblName.setText(AppLocal.getIntString("label.prodname")); // NOI18N + jLblName.setMaximumSize(new java.awt.Dimension(40, 20)); + jLblName.setMinimumSize(new java.awt.Dimension(40, 20)); + jLblName.setPreferredSize(new java.awt.Dimension(110, 30)); + + jproduct.setEditable(false); + jproduct.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jproduct.setText(" "); + jproduct.setPreferredSize(new java.awt.Dimension(170, 30)); + jproduct.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jproductActionPerformed(evt); + } + }); + + jEditProduct.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/search24.png"))); // NOI18N + jEditProduct.setToolTipText("Search Product List"); + jEditProduct.setPreferredSize(new java.awt.Dimension(64, 45)); + jEditProduct.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jEditProductActionPerformed(evt); + } + }); + + jLblLocation.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblLocation.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jLblLocation.setText("Location"); + jLblLocation.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jLocation.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jLocation.setPreferredSize(new java.awt.Dimension(170, 30)); + + jLBCode.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLBCode.setText(AppLocal.getIntString("label.prodbarcode")); // NOI18N + jLBCode.setMaximumSize(new java.awt.Dimension(40, 20)); + jLBCode.setMinimumSize(new java.awt.Dimension(40, 20)); + jLBCode.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jcodebar.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jcodebar.setPreferredSize(new java.awt.Dimension(170, 30)); + m_jcodebar.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jcodebarActionPerformed(evt); + } + }); + + m_jEnter.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/barcode.png"))); // NOI18N + m_jEnter.setToolTipText("Get Barcode"); + m_jEnter.setFocusPainted(false); + m_jEnter.setFocusable(false); + m_jEnter.setMaximumSize(new java.awt.Dimension(54, 33)); + m_jEnter.setMinimumSize(new java.awt.Dimension(54, 33)); + m_jEnter.setPreferredSize(new java.awt.Dimension(64, 45)); + m_jEnter.setRequestFocusEnabled(false); + m_jEnter.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jEnterActionPerformed(evt); + } + }); + + jLblRef.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblRef.setText(AppLocal.getIntString("label.prodref")); // NOI18N + jLblRef.setMaximumSize(new java.awt.Dimension(40, 20)); + jLblRef.setMinimumSize(new java.awt.Dimension(40, 20)); + jLblRef.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jreference.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jreference.setPreferredSize(new java.awt.Dimension(170, 30)); + m_jreference.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jreferenceActionPerformed(evt); + } + }); + + m_jEnter1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/products.png"))); // NOI18N + m_jEnter1.setToolTipText("Enter Product ID"); + m_jEnter1.setFocusPainted(false); + m_jEnter1.setFocusable(false); + m_jEnter1.setMaximumSize(new java.awt.Dimension(64, 33)); + m_jEnter1.setMinimumSize(new java.awt.Dimension(64, 33)); + m_jEnter1.setPreferredSize(new java.awt.Dimension(64, 45)); + m_jEnter1.setRequestFocusEnabled(false); + m_jEnter1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jEnter1ActionPerformed(evt); + } + }); + + jLblAtt.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblAtt.setText(AppLocal.getIntString("label.attributes")); // NOI18N + jLblAtt.setMaximumSize(new java.awt.Dimension(48, 20)); + jLblAtt.setMinimumSize(new java.awt.Dimension(48, 20)); + jLblAtt.setPreferredSize(new java.awt.Dimension(110, 30)); + + jattributes.setEditable(false); + jattributes.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jattributes.setPreferredSize(new java.awt.Dimension(170, 30)); + jattributes.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jattributesActionPerformed(evt); + } + }); + + jEditAttributes.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/attributes.png"))); // NOI18N + jEditAttributes.setToolTipText("Product Attributes"); + jEditAttributes.setMaximumSize(new java.awt.Dimension(65, 33)); + jEditAttributes.setMinimumSize(new java.awt.Dimension(65, 33)); + jEditAttributes.setPreferredSize(new java.awt.Dimension(64, 45)); + jEditAttributes.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jEditAttributesActionPerformed(evt); + } + }); + + jLblUnits.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblUnits.setText(AppLocal.getIntString("label.units")); // NOI18N + jLblUnits.setMaximumSize(new java.awt.Dimension(40, 20)); + jLblUnits.setMinimumSize(new java.awt.Dimension(40, 20)); + jLblUnits.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_junits.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_junits.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_junits.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLblPrice.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblPrice.setText(AppLocal.getIntString("label.price")); // NOI18N + jLblPrice.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jprice.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jprice.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jprice.setPreferredSize(new java.awt.Dimension(170, 30)); + + catcontainer.setBackground(new java.awt.Color(255, 255, 255)); + catcontainer.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + catcontainer.setMaximumSize(new java.awt.Dimension(2147483647, 2147483647)); + catcontainer.setMinimumSize(new java.awt.Dimension(0, 250)); + catcontainer.setPreferredSize(new java.awt.Dimension(600, 0)); + catcontainer.setLayout(new java.awt.BorderLayout()); + + m_jLocationDes.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jLocationDes.setEnabled(false); + m_jLocationDes.setPreferredSize(new java.awt.Dimension(170, 30)); + m_jLocationDes.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jLocationDesActionPerformed(evt); + } + }); + + jLblMoveTo.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblMoveTo.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jLblMoveTo.setText(bundle.getString("label.moveto")); // NOI18N + jLblMoveTo.setEnabled(false); + jLblMoveTo.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jSupplier.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSupplier.setPreferredSize(new java.awt.Dimension(170, 30)); + + jLblLocation1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblLocation1.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jLblLocation1.setText(AppLocal.getIntString("button.exit")); // NOI18N + jLblLocation1.setPreferredSize(new java.awt.Dimension(110, 30)); + + org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jPanel1Layout.createSequentialGroup() + .add(jLblDate, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 110, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(m_jdate, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) + .add(m_jbtndate, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(jLblReason, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(jPanel1Layout.createSequentialGroup() + .add(jLblLocation, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false) + .add(m_jreason, 0, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(m_jLocation, 0, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))) + .add(jLblMoveTo, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(jPanel1Layout.createSequentialGroup() + .add(jLblLocation1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false) + .add(m_jLocationDes, 0, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(m_jSupplier, 0, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))) + .add(jPanel1Layout.createSequentialGroup() + .add(jLblAtt, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(jattributes, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) + .add(jEditAttributes, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(jPanel1Layout.createSequentialGroup() + .add(jLBCode, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(m_jcodebar, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) + .add(m_jEnter, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(jPanel1Layout.createSequentialGroup() + .add(jLblUnits, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(m_junits, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(jPanel1Layout.createSequentialGroup() + .add(jLblPrice, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(m_jprice, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(jPanel1Layout.createSequentialGroup() + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jLblName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(jPanel1Layout.createSequentialGroup() + .add(jLblRef, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(m_jreference, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(jPanel1Layout.createSequentialGroup() + .add(114, 114, 114) + .add(jproduct, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(m_jEnter1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(jEditProduct, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) + .add(catcontainer, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 612, Short.MAX_VALUE) + .addContainerGap()) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jPanel1Layout.createSequentialGroup() + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jPanel1Layout.createSequentialGroup() + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(m_jdate, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(jLblDate, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(m_jbtndate, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(m_jreason, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(jLblReason, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(m_jLocation, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(jLblLocation, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(jLblMoveTo, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(m_jLocationDes, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(m_jSupplier, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(jLblLocation1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(jLblName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(jproduct, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(jEditProduct, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(m_jreference, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(jLblRef, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(m_jEnter1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(jattributes, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(jLblAtt, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(jEditAttributes, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(m_jEnter, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(jPanel1Layout.createSequentialGroup() + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(m_jcodebar, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(jLBCode, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(18, 18, 18) + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jLblUnits, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(m_junits, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(18, 18, 18) + .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jLblPrice, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(m_jprice, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))) + .add(0, 47, Short.MAX_VALUE)) + .add(catcontainer, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(48, Short.MAX_VALUE)) + ); + + catcontainer.getAccessibleContext().setAccessibleParent(jPanel1); + + add(jPanel1, java.awt.BorderLayout.PAGE_START); + }// </editor-fold>//GEN-END:initComponents + + private void m_jEnter1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jEnter1ActionPerformed + + assignProductByReference(); + + }//GEN-LAST:event_m_jEnter1ActionPerformed + + private void m_jreferenceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jreferenceActionPerformed + + assignProductByReference(); + + }//GEN-LAST:event_m_jreferenceActionPerformed + + private void m_jcodebarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jcodebarActionPerformed + + assignProductByCode(); + + }//GEN-LAST:event_m_jcodebarActionPerformed + + private void m_jEnterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jEnterActionPerformed + + assignProductByCode(); + + }//GEN-LAST:event_m_jEnterActionPerformed + + private void jEditAttributesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jEditAttributesActionPerformed + + if (productid == null) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.productnotselected")); + msg.show(this); + } else { + try { + JProductAttEdit attedit = JProductAttEdit.getAttributesEditor(this, m_App.getSession()); + attedit.editAttributes(attsetid, attsetinstid); + attedit.setVisible(true); + + if (attedit.isOK()) { + attsetinstid = attedit.getAttributeSetInst(); + attsetinstdesc = attedit.getAttributeSetInstDescription(); + jattributes.setText(attsetinstdesc); + } + } catch (BasicException ex) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotfindattributes"), ex); + msg.show(this); + } + } +}//GEN-LAST:event_jEditAttributesActionPerformed + + private void m_jbtndateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtndateActionPerformed + + Date date; + try { + date = (Date) Formats.TIMESTAMP.parseValue(m_jdate.getText()); + } catch (BasicException e) { + date = null; + } + date = JCalendarDialog.showCalendarTime(this, date); + if (date != null) { + m_jdate.setText(Formats.TIMESTAMP.formatValue(date)); + } + + }//GEN-LAST:event_m_jbtndateActionPerformed + + private void jEditProductActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jEditProductActionPerformed + + assignProduct(JProductFinder.showMessage(this, m_dlSales)); + +}//GEN-LAST:event_jEditProductActionPerformed + + private void jattributesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jattributesActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jattributesActionPerformed + + private void m_jLocationDesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jLocationDesActionPerformed + + }//GEN-LAST:event_m_jLocationDesActionPerformed + + private void jproductActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jproductActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jproductActionPerformed + + private void m_jreasonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jreasonActionPerformed +/* +* JG May 2017 for FUTURE - moved out of StockManagement +* for time being just let's show a message + if (m_ReasonModel.getSelectedItem() == MovementReason.OUT_CROSSING) { + m_jLocationDes.setEnabled(true); + jLblMoveTo.setEnabled(true); + }else{ + m_jLocationDes.setEnabled(false); + jLblMoveTo.setEnabled(false); + } +*/ + if (m_ReasonModel.getSelectedItem() == MovementReason.OUT_CROSSING) { + JOptionPane.showMessageDialog(this, "Transfer option in development. Please us (In) + (Out) Movement options"); + } + }//GEN-LAST:event_m_jreasonActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel catcontainer; + private javax.swing.JButton jEditAttributes; + private javax.swing.JButton jEditProduct; + private javax.swing.JLabel jLBCode; + private javax.swing.JLabel jLblAtt; + private javax.swing.JLabel jLblDate; + private javax.swing.JLabel jLblLocation; + private javax.swing.JLabel jLblLocation1; + private javax.swing.JLabel jLblMoveTo; + private javax.swing.JLabel jLblName; + private javax.swing.JLabel jLblPrice; + private javax.swing.JLabel jLblReason; + private javax.swing.JLabel jLblRef; + private javax.swing.JLabel jLblUnits; + private javax.swing.JPanel jPanel1; + private javax.swing.JTextField jattributes; + private javax.swing.JTextField jproduct; + private javax.swing.JButton m_jEnter; + private javax.swing.JButton m_jEnter1; + private javax.swing.JComboBox m_jLocation; + private javax.swing.JComboBox m_jLocationDes; + private javax.swing.JComboBox m_jSupplier; + private javax.swing.JButton m_jbtndate; + private javax.swing.JTextField m_jcodebar; + private javax.swing.JTextField m_jdate; + private javax.swing.JTextField m_jprice; + private javax.swing.JComboBox m_jreason; + private javax.swing.JTextField m_jreference; + private javax.swing.JTextField m_junits; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/inventory/StockDiaryPanel.java b/src/main/java/com/unicenta/pos/inventory/StockDiaryPanel.java new file mode 100644 index 0000000..2078ff1 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/StockDiaryPanel.java @@ -0,0 +1,104 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSales; +//import com.unicenta.pos.suppliers.DataLogicSuppliers; +import com.unicenta.pos.panels.JPanelTable; +import com.unicenta.pos.suppliers.DataLogicSuppliers; + +/** + * + * @author adrianromero + */ +public class StockDiaryPanel extends JPanelTable { + + private StockDiaryEditor jeditor; + private DataLogicSales m_dlSales; +// private DataLogicSuppliers m_dlSuppliers; + + /** Creates a new instance of JPanelDiaryEditor */ + public StockDiaryPanel() { + } + + /** + * + */ + @Override + protected void init() { + m_dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); +// DataLogicSuppliers m_dlSuppliers = (DataLogicSuppliers) app.getBean("com.unicenta.pos.suppliers.DataLogicSuppliers"); + jeditor = new StockDiaryEditor(app, dirty); + + } + + /** + * + * @return + */ + @Override + public ListProvider getListProvider() { + return null; + } + + /** + * + * @return + */ + @Override + public SaveProvider getSaveProvider() { + return new SaveProvider(null + , m_dlSales.getStockDiaryInsert() + , m_dlSales.getStockDiaryDelete()); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return jeditor; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.StockDiary"); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + jeditor.activate(); // primero activo el editor + super.activate(); // segundo activo el padre + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/StockManagement.form b/src/main/java/com/unicenta/pos/inventory/StockManagement.form new file mode 100644 index 0000000..bd681fc --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/StockManagement.form @@ -0,0 +1,828 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.5" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[550, 250]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[1000, 350]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,50,0,0,3,-24"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel8"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[1020, 320]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="First"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout"> + <Property name="useNullLayout" type="boolean" value="false"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.stockdate" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 25]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="5" y="5" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="m_jdate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="90" y="5" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JButton" name="m_jbtndate"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/date.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Open Calendar"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jbtndateActionPerformed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="50" y="5" width="40" height="30"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.stockreason" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 25]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="5" y="40" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JComboBox" name="m_jreason"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="maximumRowCount" type="int" value="13"/> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jreasonActionPerformed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="90" y="40" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.locationplace" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 25]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="5" y="75" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JComboBox" name="m_jLocation"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jLocationActionPerformed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="90" y="75" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JComboBox" name="m_jLocationDes"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="90" y="110" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="jLabel10"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.supplier" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 25]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="5" y="145" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JComboBox" name="m_jSupplier"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jSupplierActionPerformed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="90" y="145" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="jLabel9"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.supplierdocment" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="" replaceFormat="AppLocal.getIntString("button.exit")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 25]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="5" y="180" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="m_jSupplierDoc"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.supplierdocument" replaceFormat="AppLocal.getIntString("button.exit")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="90" y="180" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="cc" green="cc" red="cc" type="rgb"/> + </LineBorder> + </Border> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[455, 245]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="250" y="5" width="-1" height="190"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + </Container> + <Component class="javax.swing.JLabel" name="m_jcodebar"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" id="white" palette="1" red="ff" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="1"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ed" green="c5" red="4c" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder/> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[130, 25]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="m_jcodebarMouseClicked"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="780" y="270" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JButton" name="m_jEnter"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/barcode.png"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[54, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jEnterActionPerformed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="920" y="260" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="jTextField1"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ee" green="ee" id="Panel.background" palette="3" red="ee" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" red="ff" type="rgb"/> + </Property> + <Property name="caretColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ee" green="ee" id="Panel.background" palette="3" red="ee" type="palette"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[1, 1]"/> + </Property> + </Properties> + <Events> + <EventHandler event="keyTyped" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="jTextField1KeyTyped"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="1" y="1" width="-1" height="0"/> + </Constraint> + </Constraints> + </Component> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="0" left="5" right="5" top="0"/> + </Border> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 250]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="705" y="0" width="-1" height="-1"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> + <Property name="columns" type="int" value="1"/> + <Property name="horizontalGap" type="int" value="5"/> + <Property name="rows" type="int" value="0"/> + <Property name="verticalGap" type="int" value="5"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="m_jDelete"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/editdelete.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.saleremoveline" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[42, 36]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[42, 36]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jDeleteActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jList"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/search32.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.saleproductfind" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[42, 36]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[42, 36]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jListActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jEditLine"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/sale_editline.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.saleeditline" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[42, 36]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[42, 36]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jEditLineActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jEditAttributes"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/attributes.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.saleattributes" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[42, 36]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[42, 36]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jEditAttributesActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jBtnDelete"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/sale_delete.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.deleteticket" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Delete current Ticket"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 4, 0, 4]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jBtnDeleteActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 250]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 250]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="760" y="0" width="230" height="260"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <EmptySpace min="0" pref="230" max="32767" attributes="0"/> + <Group type="103" rootIndex="1" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="0" pref="10" max="32767" attributes="0"/> + <Component id="jNumberKeys" min="-2" max="-2" attributes="0"/> + <EmptySpace min="0" pref="10" max="32767" attributes="0"/> + </Group> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <EmptySpace min="0" pref="260" max="32767" attributes="0"/> + <Group type="103" rootIndex="1" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + <Component id="jNumberKeys" min="-2" max="-2" attributes="0"/> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + </Group> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="com.unicenta.beans.JNumberKeys" name="jNumberKeys"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[210, 240]"/> + </Property> + </Properties> + <Events> + <EventHandler event="keyPerformed" listener="com.unicenta.beans.JNumberEventListener" parameters="com.unicenta.beans.JNumberEvent" handler="jNumberKeysKeyPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JScrollPane" name="jScrollPane2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/> + </AuxValues> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="5" y="220" width="650" height="70"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="com.alee.laf.table.WebTable" name="jTableProductStock"> + <Properties> + <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor"> + <Table columnCount="6" rowCount="8"> + <Column editable="true" title="Location" type="java.lang.Object"/> + <Column editable="true" title="Current" type="java.lang.Object"/> + <Column editable="true" title="Maximum" type="java.lang.Object"/> + <Column editable="true" title="Minimum" type="java.lang.Object"/> + <Column editable="true" title="PriceSell" type="java.lang.Object"/> + <Column editable="true" title="PriceValue" type="java.lang.Object"/> + </Table> + </Property> + <Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor"> + <TableColumnModel selectionModel="0"> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + </TableColumnModel> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="rowHeight" type="int" value="25"/> + <Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor"> + <TableHeader reorderingAllowed="true" resizingAllowed="true"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JButton" name="m_jBtnShowStock"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/pay.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.salecheckstock" replaceFormat="AppLocal.getIntString("tooltip.salecheckstock")"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jBtnShowStockActionPerformed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="660" y="250" width="40" height="40"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="lblTotalQtyValue"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="horizontalTextPosition" type="int" value="2"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="118" y="290" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="lbTotalValue"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="horizontalTextPosition" type="int" value="2"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="547" y="290" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="com.alee.laf.label.WebLabel" name="webLblQty"> + <Properties> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.stock.quantity" replaceFormat="AppLocal.getIntString("label.stock.quantity")"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="1"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[90, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="5" y="290" width="100" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="com.alee.laf.label.WebLabel" name="webLblValue"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.stock.value" replaceFormat="AppLocal.getIntString("label.stock.value")"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="1"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[180, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="355" y="290" width="170" height="-1"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="catcontainer"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 250]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 250]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleParent" type="javax.accessibility.Accessible" editor="org.netbeans.modules.form.ComponentChooserEditor"> + <ComponentRef name="jPanel8"/> + </Property> + </AccessibilityProperties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/StockManagement.java b/src/main/java/com/unicenta/pos/inventory/StockManagement.java new file mode 100644 index 0000000..67beacc --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/StockManagement.java @@ -0,0 +1,1345 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.beans.DateUtils; +import com.unicenta.beans.JCalendarDialog; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.loader.LocalRes; +import com.unicenta.data.loader.SentenceExec; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.format.Formats; +import com.unicenta.pos.catalog.CatalogSelector; +import com.unicenta.pos.catalog.JCatalog; +import com.unicenta.pos.forms.*; +import com.unicenta.pos.panels.JProductFinder; +import com.unicenta.pos.printer.TicketParser; +import com.unicenta.pos.printer.TicketPrinterException; +import com.unicenta.pos.sales.JProductAttEdit2; +import com.unicenta.pos.scripting.ScriptEngine; +import com.unicenta.pos.scripting.ScriptException; +import com.unicenta.pos.scripting.ScriptFactory; +import com.unicenta.pos.suppliers.DataLogicSuppliers; +import com.unicenta.pos.suppliers.SupplierInfo; +import com.unicenta.pos.ticket.ProductInfoExt; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableModel; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +/** + * Date : Aug 2017 + * Updated : Dec 2016 § + * + * @author jack gerrard + */ +@Slf4j +public class StockManagement extends JPanel implements JPanelView { + + private final AppView m_App; + private final String user; + + private final DataLogicSystem m_dlSystem; + private final DataLogicSales m_dlSales; + private final DataLogicSuppliers m_dlSuppliers; + private final TicketParser m_TTP; + + private final CatalogSelector m_cat; + private final ComboBoxValModel m_ReasonModel; + + private final SentenceList m_sentlocations; + private ComboBoxValModel m_LocationsModel; + private ComboBoxValModel m_LocationsModelDes; + + private final SentenceList m_sentsuppliers; + private ComboBoxValModel m_SuppliersModel; + + private final JInventoryLines m_invlines; + + private int NUMBER_STATE = 0; + private int MULTIPLY = 0; + private static final int DEFAULT = 0; + private static final int ACTIVE = 1; + private static final int DECIMAL = 2; + + private List<ProductStock> productStockList; + private aStockTableModel stockModel; + + private final static int NUMBERZERO = 0; + private final static int NUMBERVALID = 1; + + private final static int NUMBER_INPUTZERO = 0; + private final static int NUMBER_INPUTZERODEC = 1; + private final static int NUMBER_INPUTINT = 2; + private final static int NUMBER_INPUTDEC = 3; + private final static int NUMBER_PORZERO = 4; + private final static int NUMBER_PORZERODEC = 5; + private final static int NUMBER_PORINT = 6; + private final static int NUMBER_PORDEC = 7; + + private int m_iNumberStatus; + private int m_iNumberStatusInput; + private int m_iNumberStatusPor; + private StringBuffer m_sBarcode; + + + /** + * Creates new form StockManagement + * + * @param app + */ + public StockManagement(AppView app) { + + m_App = app; + m_dlSystem = (DataLogicSystem) m_App.getBean("com.unicenta.pos.forms.DataLogicSystem"); + m_dlSales = (DataLogicSales) m_App.getBean("com.unicenta.pos.forms.DataLogicSales"); + m_dlSuppliers = (DataLogicSuppliers) m_App.getBean("com.unicenta.pos.suppliers.DataLogicSuppliers"); + m_TTP = new TicketParser(m_App.getDeviceTicket(), m_dlSystem); + + initComponents(); + + user = m_App.getAppUserView().getUser().getName(); + + jNumberKeys.setEnabled(true); + + lblTotalQtyValue.setText(null); + lbTotalValue.setText(null); + + m_sentlocations = m_dlSales.getLocationsList(); + m_LocationsModel = new ComboBoxValModel(); + m_LocationsModelDes = new ComboBoxValModel(); + + m_ReasonModel = new ComboBoxValModel(); + + m_ReasonModel.add(MovementReason.IN_PURCHASE); //Supplier Purchase + m_ReasonModel.add(MovementReason.OUT_SALE); //Sale + m_ReasonModel.add(MovementReason.IN_REFUND); //Customer Refund + m_ReasonModel.add(MovementReason.OUT_REFUND); //Supplier Return + m_ReasonModel.add(MovementReason.IN_MOVEMENT); //Adjust Add + m_ReasonModel.add(MovementReason.OUT_MOVEMENT); //Adjust Subtract + m_ReasonModel.add(MovementReason.OUT_SUBTRACT); //Rectify error per JM requirement + m_ReasonModel.add(MovementReason.OUT_BREAK); //Breakage + m_ReasonModel.add(MovementReason.OUT_FREE); //Given Free + m_ReasonModel.add(MovementReason.OUT_SAMPLE); //Given Sample + m_ReasonModel.add(MovementReason.OUT_USED); //Used item + m_ReasonModel.add(MovementReason.OUT_CROSSING); //Inter-Location move + + m_jreason.setModel(m_ReasonModel); + + m_sentsuppliers = m_dlSuppliers.getSupplierList(); + m_SuppliersModel = new ComboBoxValModel(); + + m_cat = new JCatalog(m_dlSales); + m_cat.addActionListener(new CatalogListener()); + catcontainer.add(m_cat.getComponent(), BorderLayout.CENTER); + + m_invlines = new JInventoryLines(); + jPanel5.add(m_invlines, BorderLayout.CENTER); + + jTableProductStock.setVisible(false); + + } + + /** + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.StockMovement"); + } + + /** + * @return + */ + @Override + public JComponent getComponent() { + return this; + } + + /** + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + m_cat.loadCatalog(); + + java.util.List l = m_sentlocations.list(); + m_LocationsModel = new ComboBoxValModel(l); + m_jLocation.setModel(m_LocationsModel); + m_LocationsModelDes = new ComboBoxValModel(l); + m_jLocationDes.setModel(m_LocationsModelDes); + + java.util.List sl = m_sentsuppliers.list(); + m_SuppliersModel = new ComboBoxValModel(sl); + m_jSupplier.setModel(m_SuppliersModel); + + stateToInsert(); + + java.awt.EventQueue.invokeLater(() -> { + jTextField1.requestFocus(); + }); + } + + /** + * + */ + public void stateToInsert() { + + m_jdate.setText(Formats.TIMESTAMP.formatValue(DateUtils.getTodayMinutes())); + m_ReasonModel.setSelectedItem(MovementReason.IN_PURCHASE); + m_LocationsModel.setSelectedKey(m_App.getInventoryLocation()); +// m_LocationsModel.setSelectedFirst(); + m_LocationsModelDes.setSelectedKey(m_App.getInventoryLocation()); + m_jcodebar.setText(null); + m_SuppliersModel.setSelectedFirst(); + m_jSupplierDoc.setText(null); + m_invlines.clear(); + resetTranxTable(); + } + + /** + * @return + */ + @Override + public boolean deactivate() { + + if (m_invlines.getCount() > 0) { + int res = JOptionPane.showConfirmDialog(this, + LocalRes.getIntString("message.wannasave"), + LocalRes.getIntString("title.editor"), + JOptionPane.YES_NO_CANCEL_OPTION, + JOptionPane.QUESTION_MESSAGE); + if (res == JOptionPane.YES_OPTION) { + saveData(); + return true; + } else return res == JOptionPane.NO_OPTION; + } else { + return true; + } + } + + private void addLine(ProductInfoExt oProduct, double dpor, double dprice) { + m_invlines.addLine(new InventoryLine(oProduct, dpor, dprice)); + showStockTable(); + } + + private void deleteLine(int index) { + if (index < 0) { + Toolkit.getDefaultToolkit().beep(); + } else { + m_invlines.deleteLine(index); + clearStockTable(); + showStockTable(); + lblTotalQtyValue.setText(null); + lbTotalValue.setText(null); + + } + } + + private void incProduct(ProductInfoExt product, double units) { + + MovementReason reason = (MovementReason) m_ReasonModel.getSelectedItem(); + addLine(product, units, reason.isInput() + ? product.getPriceBuy() + : product.getPriceSell()); + } + + private void incProductByCode(String sCode) { + incProductByCode(sCode, 1.0); + } + + private void incProductByCode(String sCode, double dQuantity) { + + try { + ProductInfoExt oProduct = m_dlSales.getProductInfoByCode(sCode); + if (oProduct == null) { + Toolkit.getDefaultToolkit().beep(); + } else { + incProduct(oProduct, dQuantity); + } + } catch (BasicException eData) { + MessageInf msg = new MessageInf(eData); + msg.show(this); + } + } + + private List<ProductStock> getProductOfName(String pId) { + + try { + productStockList = m_dlSales.getProductStockList(pId); + + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + + List<ProductStock> productList = new ArrayList<>(); + + productStockList.stream().forEach((productStock) -> { + String productId = productStock.getProductId(); + if (productId.equals(pId)) { + productList.add(productStock); + } + }); + + repaint(); + + return productList; + } + + public void resetTranxTable() { + + jTableProductStock.getColumnModel().getColumn(0).setPreferredWidth(50); + jTableProductStock.getColumnModel().getColumn(1).setPreferredWidth(50); + jTableProductStock.getColumnModel().getColumn(2).setPreferredWidth(50); + jTableProductStock.getColumnModel().getColumn(3).setPreferredWidth(50); + jTableProductStock.getColumnModel().getColumn(4).setPreferredWidth(50); + jTableProductStock.getColumnModel().getColumn(5).setPreferredWidth(50); + + jTableProductStock.repaint(); + } + + public void clearStockTable() { + + aStockTableModel model = (aStockTableModel) jTableProductStock.getModel(); + + while (model.getRowCount() > 0) { + for (int i = 0; i < model.getRowCount(); ++i) { + model.stockList.removeAll(productStockList); + } + lblTotalQtyValue.setText(null); + lbTotalValue.setText(null); + } + + jTableProductStock.repaint(); + } + + public void showStockTable() { + + String pId = null; + int i = m_invlines.getSelectedRow(); + + if (i < 0) { + Toolkit.getDefaultToolkit().beep(); + } else { + InventoryLine line = m_invlines.getLine(i); + pId = line.getProductID(); + } + if (pId != null) { + stockModel = new StockManagement.aStockTableModel(getProductOfName(pId)); + + jTableProductStock.setModel((TableModel) stockModel); + if (stockModel.getRowCount() > 0) { + jTableProductStock.setVisible(true); + } else { + jTableProductStock.setVisible(false); + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.nostocklocation"), + AppLocal.getIntString("message.title.nostocklocation"), + JOptionPane.INFORMATION_MESSAGE); + } + sumStockTable(); + resetTranxTable(); + } + + } + + public void sumStockTable() { + double totalQty = 0; + double totalVal = 0; + double lQty = 0; + double lVal = 0; + + for (int i = 0; i < stockModel.getRowCount(); i++) { + totalQty += Double.parseDouble(stockModel.getValueAt(i, 1).toString()); + totalVal += Double.parseDouble(stockModel.getValueAt(i, 5).toString()); +// deliberately explicit + totalVal = Math.round(totalVal * 100); + totalVal = totalVal / 100; + } + + int i = m_invlines.getSelectedRow(); + lQty = m_invlines.getLine(i).getMultiply(); + lVal = m_invlines.getLine(i).getPrice() * lQty; +// deliberately explicit + lVal = Math.round(lVal * 100); + lVal = lVal / 100; + + MovementReason reason = (MovementReason) m_ReasonModel.getSelectedItem(); + + if (reason == MovementReason.OUT_BREAK + || reason == MovementReason.OUT_FREE || reason == MovementReason.OUT_REFUND + || reason == MovementReason.OUT_SALE || reason == MovementReason.OUT_SAMPLE + || reason == MovementReason.OUT_SAMPLE || reason == MovementReason.OUT_SUBTRACT + || reason == MovementReason.OUT_USED) { + lblTotalQtyValue.setText(Double.toString(totalQty -= lQty)); + lbTotalValue.setText(Double.toString(totalVal -= lVal)); + } else { + lblTotalQtyValue.setText(Double.toString(lQty += totalQty)); + lbTotalValue.setText(Double.toString(lVal += totalVal)); + } + + + } + + private void addUnits(double dUnits) { + int i = m_invlines.getSelectedRow(); + if (i >= 0) { + InventoryLine inv = m_invlines.getLine(i); + double dunits = inv.getMultiply() + dUnits; + if (dunits <= 0.0) { + deleteLine(i); + } else { + inv.setMultiply(inv.getMultiply() + dUnits); + m_invlines.setLine(i, inv); + } + + sumStockTable(); + } + } + + private void setUnits(double dUnits) { + int i = m_invlines.getSelectedRow(); + if (i >= 0) { + InventoryLine inv = m_invlines.getLine(i); + inv.setMultiply(dUnits); + m_invlines.setLine(i, inv); + } + } + + private void stateTransition(char cTrans) { + if (cTrans == '\n') { + m_jEnter.doClick(); + } + if (cTrans == '\u007f') { + m_jcodebar.setText(null); + NUMBER_STATE = DEFAULT; + } else if (cTrans == '*') { + MULTIPLY = ACTIVE; + } else if (cTrans == '+') { + if (MULTIPLY != DEFAULT && NUMBER_STATE != DEFAULT) { + setUnits(Double.parseDouble(m_jcodebar.getText())); + m_jcodebar.setText(null); + } else { + if (m_jcodebar.getText() == null || m_jcodebar.getText().equals("")) { + addUnits(1.0); + } else { + addUnits(Double.parseDouble(m_jcodebar.getText())); + m_jcodebar.setText(null); + } + } + NUMBER_STATE = DEFAULT; + MULTIPLY = DEFAULT; + } else if (cTrans == '-') { + if (m_jcodebar.getText() == null || m_jcodebar.getText().equals("")) { + addUnits(-1.0); + } else { + addUnits(-Double.parseDouble(m_jcodebar.getText())); + m_jcodebar.setText(null); + } + NUMBER_STATE = DEFAULT; + MULTIPLY = DEFAULT; + } else if (cTrans == '.') { + if (m_jcodebar.getText() == null || m_jcodebar.getText().equals("")) { + m_jcodebar.setText("0."); + } else if (NUMBER_STATE != DECIMAL) { + m_jcodebar.setText(m_jcodebar.getText() + cTrans); + } + NUMBER_STATE = DECIMAL; + } else if (cTrans == ' ' || cTrans == '=') { + if (m_invlines.getCount() == 0) { + Toolkit.getDefaultToolkit().beep(); + } else { + saveData(); + jNumberKeys.setEnabled(true); + } + } else if (Character.isDigit(cTrans)) { + if (m_jcodebar.getText() == null) { + m_jcodebar.setText("" + cTrans); + } else { + m_jcodebar.setText(m_jcodebar.getText() + cTrans); + } + if (NUMBER_STATE != DECIMAL) { + NUMBER_STATE = ACTIVE; + } + } else if (Character.isAlphabetic(cTrans)) { + if (m_jcodebar.getText() == null) { + m_jcodebar.setText("" + cTrans); + } else { + m_jcodebar.setText(m_jcodebar.getText() + cTrans); + } + if (NUMBER_STATE != DECIMAL) { + NUMBER_STATE = ACTIVE; + } + + } else { + Toolkit.getDefaultToolkit().beep(); + } + } + + /** + * @param prod + */ + protected void buttonTransition(ProductInfoExt prod) { + +// if (m_iNumberStatusInput == NUMBERZERO && m_iNumberStatusPor == NUMBERZERO) { + incProduct(prod); +// } else { +// Toolkit.getDefaultToolkit().beep(); +// } + } + + private void saveData() { + try { + + Date d = (Date) Formats.TIMESTAMP.parseValue(m_jdate.getText()); + MovementReason reason = (MovementReason) m_ReasonModel.getSelectedItem(); + + if (reason == MovementReason.OUT_CROSSING) { + saveData(new InventoryRecord( + d, MovementReason.OUT_MOVEMENT, + (LocationInfo) m_LocationsModel.getSelectedItem(), + m_App.getAppUserView().getUser().getName(), + (SupplierInfo) m_SuppliersModel.getSelectedItem(), + m_invlines.getLines(), + m_jSupplierDoc.getText() + )); + saveData(new InventoryRecord( + d, MovementReason.IN_MOVEMENT, + (LocationInfo) m_LocationsModelDes.getSelectedItem(), + m_App.getAppUserView().getUser().getName(), + (SupplierInfo) m_SuppliersModel.getSelectedItem(), + m_invlines.getLines(), + m_jSupplierDoc.getText() + )); + } else { + saveData(new InventoryRecord( + d, reason, + (LocationInfo) m_LocationsModel.getSelectedItem(), + m_App.getAppUserView().getUser().getName(), + (SupplierInfo) m_SuppliersModel.getSelectedItem(), + m_invlines.getLines(), + m_jSupplierDoc.getText() + )); + } + + stateToInsert(); + } catch (BasicException eData) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, + AppLocal.getIntString("message.cannotsaveinventorydata"), eData); + msg.show(this); + } + } + + private void saveData(InventoryRecord rec) throws BasicException { + + SentenceExec sent = m_dlSales.getStockDiaryInsert1(); + + for (int i = 0; i < m_invlines.getCount(); i++) { + InventoryLine inv = rec.getLines().get(i); + + sent.exec(new Object[]{ + UUID.randomUUID().toString(), + rec.getDate(), + rec.getReason().getKey(), + rec.getLocation().getID(), + inv.getProductID(), + inv.getProductAttSetInstId(), + rec.getReason().samesignum(inv.getMultiply()), + inv.getPrice(), + rec.getUser(), + rec.getSupplier().getID(), + rec.getSupplierDoc() + }); + } + + clearStockTable(); + printTicket(rec); + } + + private void printTicket(InventoryRecord invrec) { + + String sresource = m_dlSystem.getResourceAsXML("Printer.Inventory"); + if (sresource == null) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.cannotprintticket")); + msg.show(this); + } else { + try { + ScriptEngine script = ScriptFactory.getScriptEngine(ScriptFactory.VELOCITY); + script.put("inventoryrecord", invrec); + m_TTP.printTicket(script.eval(sresource).toString()); + + } catch (ScriptException | TicketPrinterException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.cannotprintticket"), e); + msg.show(this); + } + } + } + + class aStockTableModel extends AbstractTableModel { + + String loc = AppLocal.getIntString("label.tblProdHeaderCol1"); + String qty = AppLocal.getIntString("label.tblProdHeaderCol2"); + String max = AppLocal.getIntString("label.tblProdHeaderCol3"); + String min = AppLocal.getIntString("label.tblProdHeaderCol4"); + String buy = AppLocal.getIntString("label.tblProdHeaderCol5"); + String val = AppLocal.getIntString("label.tblProdHeaderCol6"); + + List<ProductStock> stockList; + + String[] columnNames = {loc, qty, max, min, buy, val}; + + + public aStockTableModel(List<ProductStock> list) { + stockList = list; + } + + @Override + public int getColumnCount() { + return 6; + } + + @Override + public int getRowCount() { + return stockList.size(); + } + + @Override + public Object getValueAt(int row, int column) { + ProductStock productStock = stockList.get(row); + + switch (column) { + case 0: + return productStock.getLocation(); + case 1: + return productStock.getUnits(); + case 2: + return productStock.getMinimum(); + case 3: + return productStock.getMaximum(); + case 4: + return productStock.getPriceSell(); + case 5: + return productStock.getUnits() * productStock.getPriceSell(); + case 6: + return productStock.getProductId(); + default: + return ""; + } + + } + + public Object setValueAt(int row, int column) { + ProductStock productStock = stockList.get(row); + + switch (column) { + case 0: + return productStock.getLocation(); + case 1: + return productStock.getUnits(); + case 2: + return productStock.getMinimum(); + case 3: + return productStock.getMaximum(); + case 4: + return productStock.getPriceSell(); + case 5: + return productStock.getUnits() * productStock.getPriceSell(); + case 6: + return productStock.getProductId(); + default: + return ""; + } + } + + @Override + public String getColumnName(int col) { + return columnNames[col]; + } + + } + + + private class CatalogListener implements ActionListener { + + @Override + public void actionPerformed(ActionEvent e) { + + String sQty = m_jcodebar.getText(); + if (sQty != null) { + Double dQty = (Double.valueOf(sQty) == 0) ? 1.0 : Double.valueOf(sQty); + incProduct((ProductInfoExt) e.getSource(), dQty); + m_jcodebar.setText(null); + } else { + incProduct((ProductInfoExt) e.getSource(), 1.0); + } + } + } + + private void removeInvLine(int index) { + + if (index < 0) { + Toolkit.getDefaultToolkit().beep(); + } else { + m_invlines.deleteLine(index); + clearStockTable(); + showStockTable(); + lblTotalQtyValue.setText(null); + lbTotalValue.setText(null); + + } + + } + + /** + * @param index + */ + public void deleteTicket(int index) { + + while (index < m_invlines.getCount()) { + m_invlines.deleteLine(index); + } + + } + + private void incProduct(ProductInfoExt prod) { + + incProduct(1.0, prod); + } + + private void incProduct(double dPor, ProductInfoExt prod) { + + addLine(prod, dPor, prod.getPriceBuy()); + } + + private void stateToZero() { + m_sBarcode = new StringBuffer(); + + m_iNumberStatus = NUMBER_INPUTZERO; + m_iNumberStatusInput = NUMBERZERO; + m_iNumberStatusPor = NUMBERZERO; + repaint(); + } + + + /** + * This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel8 = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + m_jdate = new javax.swing.JTextField(); + m_jbtndate = new javax.swing.JButton(); + jLabel2 = new javax.swing.JLabel(); + m_jreason = new javax.swing.JComboBox(); + jLabel8 = new javax.swing.JLabel(); + m_jLocation = new javax.swing.JComboBox(); + m_jLocationDes = new javax.swing.JComboBox(); + jLabel10 = new javax.swing.JLabel(); + m_jSupplier = new javax.swing.JComboBox(); + jLabel9 = new javax.swing.JLabel(); + m_jSupplierDoc = new javax.swing.JTextField(); + jPanel5 = new javax.swing.JPanel(); + m_jcodebar = new javax.swing.JLabel(); + m_jEnter = new javax.swing.JButton(); + jTextField1 = new javax.swing.JTextField(); + jPanel2 = new javax.swing.JPanel(); + m_jDelete = new javax.swing.JButton(); + m_jList = new javax.swing.JButton(); + m_jEditLine = new javax.swing.JButton(); + m_jEditAttributes = new javax.swing.JButton(); + m_jBtnDelete = new javax.swing.JButton(); + jPanel1 = new javax.swing.JPanel(); + jNumberKeys = new com.unicenta.beans.JNumberKeys(); + jScrollPane2 = new javax.swing.JScrollPane(); + jTableProductStock = new com.alee.laf.table.WebTable(); + m_jBtnShowStock = new javax.swing.JButton(); + lblTotalQtyValue = new javax.swing.JLabel(); + lbTotalValue = new javax.swing.JLabel(); + webLblQty = new com.alee.laf.label.WebLabel(); + webLblValue = new com.alee.laf.label.WebLabel(); + catcontainer = new javax.swing.JPanel(); + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setMinimumSize(new java.awt.Dimension(550, 250)); + setPreferredSize(new java.awt.Dimension(1000, 350)); + setLayout(new java.awt.BorderLayout()); + + jPanel8.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel8.setPreferredSize(new java.awt.Dimension(1020, 320)); + jPanel8.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout()); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.stockdate")); // NOI18N + jLabel1.setMaximumSize(new java.awt.Dimension(40, 25)); + jLabel1.setMinimumSize(new java.awt.Dimension(40, 25)); + jLabel1.setPreferredSize(new java.awt.Dimension(70, 30)); + jPanel8.add(jLabel1, new org.netbeans.lib.awtextra.AbsoluteConstraints(5, 5, -1, -1)); + + m_jdate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jdate.setPreferredSize(new java.awt.Dimension(160, 30)); + jPanel8.add(m_jdate, new org.netbeans.lib.awtextra.AbsoluteConstraints(90, 5, -1, -1)); + + m_jbtndate.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/date.png"))); // NOI18N + m_jbtndate.setToolTipText("Open Calendar"); + m_jbtndate.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtndateActionPerformed(evt); + } + }); + jPanel8.add(m_jbtndate, new org.netbeans.lib.awtextra.AbsoluteConstraints(50, 5, 40, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.stockreason")); // NOI18N + jLabel2.setMaximumSize(new java.awt.Dimension(40, 25)); + jLabel2.setMinimumSize(new java.awt.Dimension(40, 25)); + jLabel2.setPreferredSize(new java.awt.Dimension(70, 30)); + jPanel8.add(jLabel2, new org.netbeans.lib.awtextra.AbsoluteConstraints(5, 40, -1, -1)); + + m_jreason.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jreason.setMaximumRowCount(13); + m_jreason.setPreferredSize(new java.awt.Dimension(160, 30)); + m_jreason.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jreasonActionPerformed(evt); + } + }); + jPanel8.add(m_jreason, new org.netbeans.lib.awtextra.AbsoluteConstraints(90, 40, -1, -1)); + + jLabel8.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel8.setText(AppLocal.getIntString("label.locationplace")); // NOI18N + jLabel8.setMaximumSize(new java.awt.Dimension(40, 25)); + jLabel8.setMinimumSize(new java.awt.Dimension(40, 25)); + jLabel8.setPreferredSize(new java.awt.Dimension(70, 30)); + jPanel8.add(jLabel8, new org.netbeans.lib.awtextra.AbsoluteConstraints(5, 75, -1, -1)); + + m_jLocation.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jLocation.setPreferredSize(new java.awt.Dimension(160, 30)); + m_jLocation.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jLocationActionPerformed(evt); + } + }); + jPanel8.add(m_jLocation, new org.netbeans.lib.awtextra.AbsoluteConstraints(90, 75, -1, -1)); + + m_jLocationDes.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jLocationDes.setPreferredSize(new java.awt.Dimension(160, 30)); + jPanel8.add(m_jLocationDes, new org.netbeans.lib.awtextra.AbsoluteConstraints(90, 110, -1, -1)); + + jLabel10.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel10.setText(AppLocal.getIntString("label.supplier")); // NOI18N + jLabel10.setMaximumSize(new java.awt.Dimension(40, 25)); + jLabel10.setMinimumSize(new java.awt.Dimension(40, 25)); + jLabel10.setPreferredSize(new java.awt.Dimension(70, 30)); + jPanel8.add(jLabel10, new org.netbeans.lib.awtextra.AbsoluteConstraints(5, 145, -1, -1)); + + m_jSupplier.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSupplier.setPreferredSize(new java.awt.Dimension(160, 30)); + m_jSupplier.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jSupplierActionPerformed(evt); + } + }); + jPanel8.add(m_jSupplier, new org.netbeans.lib.awtextra.AbsoluteConstraints(90, 145, -1, -1)); + + jLabel9.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel9.setText(AppLocal.getIntString("label.supplierdocment")); // NOI18N + jLabel9.setToolTipText("null"); + jLabel9.setMaximumSize(new java.awt.Dimension(40, 25)); + jLabel9.setMinimumSize(new java.awt.Dimension(40, 25)); + jLabel9.setPreferredSize(new java.awt.Dimension(70, 30)); + jPanel8.add(jLabel9, new org.netbeans.lib.awtextra.AbsoluteConstraints(5, 180, -1, -1)); + + m_jSupplierDoc.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSupplierDoc.setToolTipText(AppLocal.getIntString("button.exit")); // NOI18N + m_jSupplierDoc.setPreferredSize(new java.awt.Dimension(160, 30)); + jPanel8.add(m_jSupplierDoc, new org.netbeans.lib.awtextra.AbsoluteConstraints(90, 180, -1, -1)); + + jPanel5.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(204, 204, 204))); + jPanel5.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel5.setPreferredSize(new java.awt.Dimension(455, 245)); + jPanel5.setLayout(new java.awt.BorderLayout()); + jPanel8.add(jPanel5, new org.netbeans.lib.awtextra.AbsoluteConstraints(250, 5, -1, 190)); + + m_jcodebar.setBackground(java.awt.Color.white); + m_jcodebar.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + m_jcodebar.setForeground(new java.awt.Color(76, 197, 237)); + m_jcodebar.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jcodebar.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)), javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1))); + m_jcodebar.setOpaque(true); + m_jcodebar.setPreferredSize(new java.awt.Dimension(130, 25)); + m_jcodebar.setRequestFocusEnabled(false); + m_jcodebar.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + m_jcodebarMouseClicked(evt); + } + }); + jPanel8.add(m_jcodebar, new org.netbeans.lib.awtextra.AbsoluteConstraints(780, 270, -1, -1)); + + m_jEnter.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jEnter.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/barcode.png"))); // NOI18N + m_jEnter.setFocusPainted(false); + m_jEnter.setFocusable(false); + m_jEnter.setPreferredSize(new java.awt.Dimension(54, 45)); + m_jEnter.setRequestFocusEnabled(false); + m_jEnter.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jEnterActionPerformed(evt); + } + }); + jPanel8.add(m_jEnter, new org.netbeans.lib.awtextra.AbsoluteConstraints(920, 260, -1, -1)); + + jTextField1.setBackground(javax.swing.UIManager.getDefaults().getColor("Panel.background")); + jTextField1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTextField1.setForeground(new java.awt.Color(255, 255, 255)); + jTextField1.setCaretColor(javax.swing.UIManager.getDefaults().getColor("Panel.background")); + jTextField1.setPreferredSize(new java.awt.Dimension(1, 1)); + jTextField1.addKeyListener(new java.awt.event.KeyAdapter() { + public void keyTyped(java.awt.event.KeyEvent evt) { + jTextField1KeyTyped(evt); + } + }); + jPanel8.add(jTextField1, new org.netbeans.lib.awtextra.AbsoluteConstraints(1, 1, -1, 0)); + + jPanel2.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 5, 0, 5)); + jPanel2.setPreferredSize(new java.awt.Dimension(70, 250)); + jPanel2.setLayout(new java.awt.GridLayout(0, 1, 5, 5)); + + m_jDelete.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/editdelete.png"))); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + m_jDelete.setToolTipText(bundle.getString("tooltip.saleremoveline")); // NOI18N + m_jDelete.setFocusPainted(false); + m_jDelete.setFocusable(false); + m_jDelete.setMargin(new java.awt.Insets(8, 14, 8, 14)); + m_jDelete.setMaximumSize(new java.awt.Dimension(42, 36)); + m_jDelete.setMinimumSize(new java.awt.Dimension(42, 36)); + m_jDelete.setPreferredSize(new java.awt.Dimension(50, 45)); + m_jDelete.setRequestFocusEnabled(false); + m_jDelete.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jDeleteActionPerformed(evt); + } + }); + jPanel2.add(m_jDelete); + + m_jList.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/search32.png"))); // NOI18N + m_jList.setToolTipText(bundle.getString("tooltip.saleproductfind")); // NOI18N + m_jList.setFocusPainted(false); + m_jList.setFocusable(false); + m_jList.setMargin(new java.awt.Insets(8, 14, 8, 14)); + m_jList.setMaximumSize(new java.awt.Dimension(42, 36)); + m_jList.setMinimumSize(new java.awt.Dimension(42, 36)); + m_jList.setPreferredSize(new java.awt.Dimension(50, 45)); + m_jList.setRequestFocusEnabled(false); + m_jList.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jListActionPerformed(evt); + } + }); + jPanel2.add(m_jList); + + m_jEditLine.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/sale_editline.png"))); // NOI18N + m_jEditLine.setToolTipText(bundle.getString("tooltip.saleeditline")); // NOI18N + m_jEditLine.setFocusPainted(false); + m_jEditLine.setFocusable(false); + m_jEditLine.setMargin(new java.awt.Insets(8, 14, 8, 14)); + m_jEditLine.setMaximumSize(new java.awt.Dimension(42, 36)); + m_jEditLine.setMinimumSize(new java.awt.Dimension(42, 36)); + m_jEditLine.setPreferredSize(new java.awt.Dimension(50, 45)); + m_jEditLine.setRequestFocusEnabled(false); + m_jEditLine.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jEditLineActionPerformed(evt); + } + }); + jPanel2.add(m_jEditLine); + + m_jEditAttributes.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/attributes.png"))); // NOI18N + m_jEditAttributes.setToolTipText(bundle.getString("tooltip.saleattributes")); // NOI18N + m_jEditAttributes.setFocusPainted(false); + m_jEditAttributes.setFocusable(false); + m_jEditAttributes.setMargin(new java.awt.Insets(8, 14, 8, 14)); + m_jEditAttributes.setMaximumSize(new java.awt.Dimension(42, 36)); + m_jEditAttributes.setMinimumSize(new java.awt.Dimension(42, 36)); + m_jEditAttributes.setPreferredSize(new java.awt.Dimension(50, 45)); + m_jEditAttributes.setRequestFocusEnabled(false); + m_jEditAttributes.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jEditAttributesActionPerformed(evt); + } + }); + jPanel2.add(m_jEditAttributes); + + m_jBtnDelete.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jBtnDelete.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/sale_delete.png"))); // NOI18N + m_jBtnDelete.setText(AppLocal.getIntString("button.deleteticket")); // NOI18N + m_jBtnDelete.setToolTipText("Delete current Ticket"); + m_jBtnDelete.setFocusPainted(false); + m_jBtnDelete.setFocusable(false); + m_jBtnDelete.setMargin(new java.awt.Insets(0, 4, 0, 4)); + m_jBtnDelete.setMaximumSize(new java.awt.Dimension(50, 40)); + m_jBtnDelete.setMinimumSize(new java.awt.Dimension(50, 40)); + m_jBtnDelete.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jBtnDelete.setRequestFocusEnabled(false); + m_jBtnDelete.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jBtnDeleteActionPerformed(evt); + } + }); + jPanel2.add(m_jBtnDelete); + + jPanel8.add(jPanel2, new org.netbeans.lib.awtextra.AbsoluteConstraints(705, 0, -1, -1)); + + jPanel1.setMinimumSize(new java.awt.Dimension(150, 250)); + jPanel1.setPreferredSize(new java.awt.Dimension(200, 250)); + + jNumberKeys.setPreferredSize(new java.awt.Dimension(210, 240)); + jNumberKeys.addJNumberEventListener(new com.unicenta.beans.JNumberEventListener() { + public void keyPerformed(com.unicenta.beans.JNumberEvent evt) { + jNumberKeysKeyPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 230, Short.MAX_VALUE) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(0, 10, Short.MAX_VALUE) + .addComponent(jNumberKeys, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 10, Short.MAX_VALUE))) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 260, Short.MAX_VALUE) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(jNumberKeys, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE))) + ); + + jPanel8.add(jPanel1, new org.netbeans.lib.awtextra.AbsoluteConstraints(760, 0, 230, 260)); + + jScrollPane2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + + jTableProductStock.setModel(new javax.swing.table.DefaultTableModel( + new Object[][]{ + {null, null, null, null, null, null}, + {null, null, null, null, null, null}, + {null, null, null, null, null, null}, + {null, null, null, null, null, null}, + {null, null, null, null, null, null}, + {null, null, null, null, null, null}, + {null, null, null, null, null, null}, + {null, null, null, null, null, null} + }, + new String[]{ + "Location", "Current", "Maximum", "Minimum", "PriceSell", "PriceValue" + } + )); + jTableProductStock.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTableProductStock.setRowHeight(25); + jScrollPane2.setViewportView(jTableProductStock); + + jPanel8.add(jScrollPane2, new org.netbeans.lib.awtextra.AbsoluteConstraints(5, 220, 650, 70)); + + m_jBtnShowStock.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jBtnShowStock.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/pay.png"))); // NOI18N + m_jBtnShowStock.setToolTipText(AppLocal.getIntString("tooltip.salecheckstock")); // NOI18N + m_jBtnShowStock.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jBtnShowStockActionPerformed(evt); + } + }); + jPanel8.add(m_jBtnShowStock, new org.netbeans.lib.awtextra.AbsoluteConstraints(660, 250, 40, 40)); + + lblTotalQtyValue.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + lblTotalQtyValue.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + lblTotalQtyValue.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT); + lblTotalQtyValue.setPreferredSize(new java.awt.Dimension(100, 30)); + jPanel8.add(lblTotalQtyValue, new org.netbeans.lib.awtextra.AbsoluteConstraints(118, 290, -1, -1)); + + lbTotalValue.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + lbTotalValue.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + lbTotalValue.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT); + lbTotalValue.setPreferredSize(new java.awt.Dimension(100, 30)); + jPanel8.add(lbTotalValue, new org.netbeans.lib.awtextra.AbsoluteConstraints(547, 290, -1, -1)); + + webLblQty.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + webLblQty.setText(AppLocal.getIntString("label.stock.quantity")); // NOI18N + webLblQty.setFont(new java.awt.Font("Arial", 1, 12)); // NOI18N + webLblQty.setPreferredSize(new java.awt.Dimension(90, 30)); + jPanel8.add(webLblQty, new org.netbeans.lib.awtextra.AbsoluteConstraints(5, 290, 100, -1)); + + webLblValue.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + webLblValue.setText(AppLocal.getIntString("label.stock.value")); // NOI18N + webLblValue.setFont(new java.awt.Font("Arial", 1, 12)); // NOI18N + webLblValue.setPreferredSize(new java.awt.Dimension(180, 30)); + jPanel8.add(webLblValue, new org.netbeans.lib.awtextra.AbsoluteConstraints(355, 290, 170, -1)); + + add(jPanel8, java.awt.BorderLayout.PAGE_START); + + catcontainer.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + catcontainer.setMinimumSize(new java.awt.Dimension(0, 250)); + catcontainer.setPreferredSize(new java.awt.Dimension(0, 250)); + catcontainer.setRequestFocusEnabled(false); + catcontainer.setLayout(new java.awt.BorderLayout()); + add(catcontainer, java.awt.BorderLayout.CENTER); + catcontainer.getAccessibleContext().setAccessibleParent(jPanel8); + }// </editor-fold>//GEN-END:initComponents + + private void jTextField1KeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTextField1KeyTyped + jTextField1.setText(null); + stateTransition(evt.getKeyChar()); + }//GEN-LAST:event_jTextField1KeyTyped + + private void jNumberKeysKeyPerformed(com.unicenta.beans.JNumberEvent evt) {//GEN-FIRST:event_jNumberKeysKeyPerformed + + stateTransition(evt.getKey()); + + }//GEN-LAST:event_jNumberKeysKeyPerformed + + + private void m_jreasonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jreasonActionPerformed + + m_jLocationDes.setEnabled(m_ReasonModel.getSelectedItem() == MovementReason.OUT_CROSSING); + + }//GEN-LAST:event_m_jreasonActionPerformed + + private void m_jbtndateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtndateActionPerformed + + Date date; + try { + date = (Date) Formats.TIMESTAMP.parseValue(m_jdate.getText()); + } catch (BasicException e) { + date = null; + } + date = JCalendarDialog.showCalendarTime(this, date); + if (date != null) { + m_jdate.setText(Formats.TIMESTAMP.formatValue(date)); + } + }//GEN-LAST:event_m_jbtndateActionPerformed + + private void m_jEnterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jEnterActionPerformed + + incProductByCode(m_jcodebar.getText()); + m_jcodebar.setText(null); + if (m_jSupplier.getSelectedItem() != null) { +// saveData(); + } else { + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.supplierinvalid"), + AppLocal.getIntString("message.title.supplierinvalid"), + JOptionPane.WARNING_MESSAGE); + } + }//GEN-LAST:event_m_jEnterActionPerformed + + private void m_jSupplierActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jSupplierActionPerformed +/* if (m_jSupplier != null) { + catcontainer.setEnabled(false); + jNumberKeys.setEnabled(true); + m_jcodebar.setEnabled(true); + m_jEnter.setEnabled(true); + m_jSupplierDoc.setEnabled(true); + m_jcodebar.setEnabled(true); + m_jEditLine.setEnabled(true); + m_jEditAttributes.setEnabled(true); + m_jBtnShowStock.setEnabled(true); + } else { + catcontainer.setEnabled(true); + jNumberKeys.setEnabled(false); + m_jcodebar.setEnabled(false); + m_jEnter.setEnabled(false); + m_jSupplierDoc.setEnabled(false); + m_jcodebar.setEnabled(false); + m_jEditLine.setEnabled(false); + m_jEditAttributes.setEnabled(false); + m_jBtnShowStock.setEnabled(false); + + } +*/ + }//GEN-LAST:event_m_jSupplierActionPerformed + + private void m_jBtnShowStockActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jBtnShowStockActionPerformed + + showStockTable(); + + }//GEN-LAST:event_m_jBtnShowStockActionPerformed + + private void m_jDeleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jDeleteActionPerformed + + int i = m_invlines.getSelectedRow(); + + if (i < 0) { + Toolkit.getDefaultToolkit().beep(); + } else { + removeInvLine(i); + + } + }//GEN-LAST:event_m_jDeleteActionPerformed + + private void m_jListActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jListActionPerformed + + ProductInfoExt prod = JProductFinder.showMessage(StockManagement.this, m_dlSales); + if (prod != null) { + buttonTransition(prod); + } + + }//GEN-LAST:event_m_jListActionPerformed + + private void m_jEditLineActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jEditLineActionPerformed + + int i = m_invlines.getSelectedRow(); + if (i < 0) { + Toolkit.getDefaultToolkit().beep(); + } else { + InventoryLine line = m_invlines.getLine(i); + + JFrame frame = new JFrame("New Price Buy"); + String spricebuy = JOptionPane.showInputDialog(frame, + AppLocal.getIntString("message.enterbuyprice"), + JOptionPane.INFORMATION_MESSAGE); + + if (spricebuy != null) { + double dpricebuy = Double.parseDouble(spricebuy); + line.setPrice(dpricebuy); + m_invlines.setLine(i, line); + } + } + }//GEN-LAST:event_m_jEditLineActionPerformed + + private void m_jEditAttributesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jEditAttributesActionPerformed + + int i = m_invlines.getSelectedRow(); + if (i < 0) { + Toolkit.getDefaultToolkit().beep(); + } else { + try { + InventoryLine line = m_invlines.getLine(i); + JProductAttEdit2 attedit = JProductAttEdit2.getAttributesEditor(this, m_App.getSession()); + attedit.editAttributes(line.getProductAttSetId(), line.getProductAttSetInstId()); + attedit.setVisible(true); + if (attedit.isOK()) { + line.setProductAttSetInstId(attedit.getAttributeSetInst()); + line.setProductAttSetInstDesc(attedit.getAttributeSetInstDescription()); + m_invlines.setLine(i, line); + } + } catch (BasicException ex) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.cannotfindattributes"), ex); + msg.show(this); + } + } + }//GEN-LAST:event_m_jEditAttributesActionPerformed + + private void m_jBtnDeleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jBtnDeleteActionPerformed + + int res = JOptionPane.showConfirmDialog(this, + AppLocal.getIntString("message.wannadelete"), + AppLocal.getIntString("title.editor"), + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE); + + if (res == JOptionPane.YES_OPTION) { + + int i = 0; + while (i < m_invlines.getCount()) { + m_invlines.deleteLine(i); + } + + clearStockTable(); + showStockTable(); + + lblTotalQtyValue.setText(null); + lbTotalValue.setText(null); + + jTableProductStock.repaint(); + } + + }//GEN-LAST:event_m_jBtnDeleteActionPerformed + + private void m_jcodebarMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_m_jcodebarMouseClicked + m_jcodebar.requestFocusInWindow(); + jTextField1.requestFocus(); + m_jcodebar.setEnabled(true); + m_jcodebar.setText(null); + }//GEN-LAST:event_m_jcodebarMouseClicked + + private void m_jLocationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jLocationActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_m_jLocationActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel catcontainer; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel10; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel8; + private javax.swing.JLabel jLabel9; + private com.unicenta.beans.JNumberKeys jNumberKeys; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel5; + private javax.swing.JPanel jPanel8; + private javax.swing.JScrollPane jScrollPane2; + private com.alee.laf.table.WebTable jTableProductStock; + private javax.swing.JTextField jTextField1; + private javax.swing.JLabel lbTotalValue; + private javax.swing.JLabel lblTotalQtyValue; + private javax.swing.JButton m_jBtnDelete; + private javax.swing.JButton m_jBtnShowStock; + private javax.swing.JButton m_jDelete; + private javax.swing.JButton m_jEditAttributes; + private javax.swing.JButton m_jEditLine; + private javax.swing.JButton m_jEnter; + private javax.swing.JButton m_jList; + private javax.swing.JComboBox m_jLocation; + private javax.swing.JComboBox m_jLocationDes; + private javax.swing.JComboBox m_jSupplier; + private javax.swing.JTextField m_jSupplierDoc; + private javax.swing.JButton m_jbtndate; + private javax.swing.JLabel m_jcodebar; + private javax.swing.JTextField m_jdate; + private javax.swing.JComboBox m_jreason; + private com.alee.laf.label.WebLabel webLblQty; + private com.alee.laf.label.WebLabel webLblValue; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/inventory/StockModel.java b/src/main/java/com/unicenta/pos/inventory/StockModel.java new file mode 100644 index 0000000..4ebdc12 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/StockModel.java @@ -0,0 +1,73 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-130 + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.user.BrowsableData; +import com.unicenta.format.Formats; +import javax.swing.table.AbstractTableModel; + +/** + * + * @author adrianromero + */ +public class StockModel extends AbstractTableModel { + + private BrowsableData m_bd; + private Formats[] m_formats; + private boolean[] m_bedit; + + /** Creates a new instance of StockModel + * @param bd + * @param f + * @param bedit */ + public StockModel(BrowsableData bd, Formats[] f, boolean[] bedit) { + m_bd = bd; + m_formats = f; + m_bedit = bedit; + } + @Override + public int getRowCount() { + return m_bd.getSize(); + } + @Override + public int getColumnCount() { + return m_formats.length; + } + @Override + public Object getValueAt(int row, int column) { + return m_formats[column].formatValue( + ((Object[]) m_bd.getElementAt(row))[column]); + } + @Override + public boolean isCellEditable(int row, int column) { + return m_bedit[column]; + } + @Override + public void setValueAt(Object aValue, int row, int column) { + Object[] record = (Object[]) m_bd.getElementAt(row); + try { + record[column] = m_formats[column].parseValue((String) aValue); + m_bd.updateRecord(row, record); + } catch (BasicException e) { + } + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/TaxCategoriesEditor.form b/src/main/java/com/unicenta/pos/inventory/TaxCategoriesEditor.form new file mode 100644 index 0000000..f604ab9 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/TaxCategoriesEditor.form @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.6" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel2" min="-2" pref="80" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jName" min="-2" pref="200" max="-2" attributes="0"/> + <EmptySpace min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/info.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.name" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[34, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="jLabel2MouseClicked"/> + </Events> + </Component> + <Component class="javax.swing.JTextField" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[34, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/TaxCategoriesEditor.java b/src/main/java/com/unicenta/pos/inventory/TaxCategoriesEditor.java new file mode 100644 index 0000000..1016b05 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/TaxCategoriesEditor.java @@ -0,0 +1,197 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import java.awt.Component; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.util.UUID; +import javax.swing.JOptionPane; +import javax.swing.JPanel; + +/** + * + * @author JG uniCenta + */ +public final class TaxCategoriesEditor extends JPanel implements EditorRecord { + + private Object m_oId; + + /** Creates new form taxEditor + * @param dirty */ + public TaxCategoriesEditor(DirtyManager dirty) { + initComponents(); + + m_jName.getDocument().addDocumentListener(dirty); + + writeValueEOF(); + } + + /** + * + */ + @Override + public void writeValueEOF() { + m_oId = null; + m_jName.setText(null); + m_jName.setEnabled(false); + } + + /** + * + */ + @Override + public void writeValueInsert() { + m_oId = UUID.randomUUID().toString(); + m_jName.setText(null); + m_jName.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueDelete(Object value) { + + Object[] taxcustcat = (Object[]) value; + m_oId = taxcustcat[0]; + m_jName.setText(Formats.STRING.formatValue(taxcustcat[1])); + m_jName.setEnabled(false); + } + + /** + * + * @param value + */ + @Override + public void writeValueEdit(Object value) { + + Object[] taxcustcat = (Object[]) value; + m_oId = taxcustcat[0]; + m_jName.setText(Formats.STRING.formatValue(taxcustcat[1])); + m_jName.setEnabled(true); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + Object[] taxcustcat = new Object[2]; + + taxcustcat[0] = m_oId; + taxcustcat[1] = m_jName.getText(); + + return taxcustcat; + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + */ + @Override + public void refresh() { + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel2 = new javax.swing.JLabel(); + m_jName = new javax.swing.JTextField(); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/info.png"))); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.name")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(34, 30)); + jLabel2.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + jLabel2MouseClicked(evt); + } + }); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(34, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + }// </editor-fold>//GEN-END:initComponents + + private void jLabel2MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabel2MouseClicked + + if (evt.getClickCount() == 2) { + String uuidString = m_oId.toString(); + StringSelection stringSelection = new StringSelection(uuidString); + Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard(); + clpbrd.setContents(stringSelection, null); + + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.uuidcopy")); + } + }//GEN-LAST:event_jLabel2MouseClicked + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel2; + private javax.swing.JTextField m_jName; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/inventory/TaxCategoriesPanel.java b/src/main/java/com/unicenta/pos/inventory/TaxCategoriesPanel.java new file mode 100644 index 0000000..7dd8e7a --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/TaxCategoriesPanel.java @@ -0,0 +1,120 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.data.gui.ListCellRendererBasic; +import com.unicenta.data.loader.ComparatorCreator; +import com.unicenta.data.loader.TableDefinition; +import com.unicenta.data.loader.Vectorer; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.panels.JPanelTable; +import javax.swing.ListCellRenderer; + +/** + * + * @author adrianromero + */ +public class TaxCategoriesPanel extends JPanelTable { + + private TableDefinition ttaxcategories; + private TaxCustCategoriesEditor jeditor; + + /** Creates a new instance of JPanelDuty */ + public TaxCategoriesPanel() { + } + + /** + * + */ + @Override + protected void init() { + DataLogicSales dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + ttaxcategories = dlSales.getTableTaxCategories(); + jeditor = new TaxCustCategoriesEditor(dirty); + } + + /** + * + * @return + */ + @Override + public ListProvider getListProvider() { + return new ListProviderCreator(ttaxcategories); + } + + /** + * + * @return + */ + @Override + public SaveProvider getSaveProvider() { + return new SaveProvider(ttaxcategories); + } + + /** + * + * @return + */ + @Override + public Vectorer getVectorer() { + return ttaxcategories.getVectorerBasic(new int[]{1}); + } + + /** + * + * @return + */ + @Override + public ComparatorCreator getComparatorCreator() { + return ttaxcategories.getComparatorCreator(new int[] {1}); + } + + /** + * + * @return + */ + @Override + public ListCellRenderer getListCellRenderer() { + return new ListCellRendererBasic(ttaxcategories.getRenderStringBasic(new int[]{1})); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return jeditor; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.TaxCategories"); + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/inventory/TaxCategoryInfo.java b/src/main/java/com/unicenta/pos/inventory/TaxCategoryInfo.java new file mode 100644 index 0000000..883c4f1 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/TaxCategoryInfo.java @@ -0,0 +1,91 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.data.loader.IKeyed; +import java.io.Serializable; + +/** + * + * @author adrianromero + * @version + */ +public class TaxCategoryInfo implements Serializable, IKeyed { + + private static final long serialVersionUID = 8959679342805L; + private String m_sID; + private String m_sName; + + /** + * + * @param sID + * @param sName + */ + public TaxCategoryInfo(String sID, String sName) { + m_sID = sID; + m_sName = sName; + } + + /** + * + * @return + */ + @Override + public Object getKey() { + return m_sID; + } + + /** + * + * @param sID + */ + public void setID(String sID) { + m_sID = sID; + } + + /** + * + * @return + */ + public String getID() { + return m_sID; + } + + /** + * + * @return + */ + public String getName() { + return m_sName; + } + + /** + * + * @param sName + */ + public void setName(String sName) { + m_sName = sName; + } + + @Override + public String toString(){ + return m_sName; + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/inventory/TaxCustCategoriesEditor.form b/src/main/java/com/unicenta/pos/inventory/TaxCustCategoriesEditor.form new file mode 100644 index 0000000..afbd4ef --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/TaxCustCategoriesEditor.form @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.6" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout"> + <Property name="useNullLayout" type="boolean" value="true"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/info.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.name" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value=""/> + </Properties> + <Events> + <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="jLabel2MouseClicked"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="20" y="20" width="80" height="25"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="100" y="20" width="200" height="25"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/TaxCustCategoriesEditor.java b/src/main/java/com/unicenta/pos/inventory/TaxCustCategoriesEditor.java new file mode 100644 index 0000000..289ca4b --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/TaxCustCategoriesEditor.java @@ -0,0 +1,182 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +/// Foundation, Inc., 51 Franklin Street, Fifth floor, Boston, MA 02110-1301 USA + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import java.awt.Component; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.util.UUID; +import javax.swing.JOptionPane; +import javax.swing.JPanel; + +/** + * + * @author JG uniCenta + */ +public final class TaxCustCategoriesEditor extends JPanel implements EditorRecord { + + private Object m_oId; + + /** Creates new form taxEditor + * @param dirty */ + public TaxCustCategoriesEditor(DirtyManager dirty) { + initComponents(); + + m_jName.getDocument().addDocumentListener(dirty); + + writeValueEOF(); + } + + /** + * + */ + @Override + public void writeValueEOF() { + m_oId = null; + m_jName.setText(null); + m_jName.setEnabled(false); + } + + /** + * + */ + @Override + public void writeValueInsert() { + m_oId = UUID.randomUUID().toString(); + m_jName.setText(null); + m_jName.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueDelete(Object value) { + + Object[] taxcustcat = (Object[]) value; + m_oId = taxcustcat[0]; + m_jName.setText(Formats.STRING.formatValue(taxcustcat[1])); + m_jName.setEnabled(false); + } + + /** + * + * @param value + */ + @Override + public void writeValueEdit(Object value) { + + Object[] taxcustcat = (Object[]) value; + m_oId = taxcustcat[0]; + m_jName.setText(Formats.STRING.formatValue(taxcustcat[1])); + m_jName.setEnabled(true); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + Object[] taxcustcat = new Object[2]; + + taxcustcat[0] = m_oId; + taxcustcat[1] = m_jName.getText(); + + return taxcustcat; + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + */ + @Override + public void refresh() { + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel2 = new javax.swing.JLabel(); + m_jName = new javax.swing.JTextField(); + + setLayout(null); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/info.png"))); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.name")); // NOI18N + jLabel2.setToolTipText(""); + jLabel2.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + jLabel2MouseClicked(evt); + } + }); + add(jLabel2); + jLabel2.setBounds(20, 20, 80, 25); + + m_jName.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + add(m_jName); + m_jName.setBounds(100, 20, 200, 25); + }// </editor-fold>//GEN-END:initComponents + + private void jLabel2MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabel2MouseClicked + + if (evt.getClickCount() == 2) { + String uuidString = m_oId.toString(); + StringSelection stringSelection = new StringSelection(uuidString); + Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard(); + clpbrd.setContents(stringSelection, null); + + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.uuidcopy")); + } + }//GEN-LAST:event_jLabel2MouseClicked + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel2; + private javax.swing.JTextField m_jName; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/inventory/TaxCustCategoriesPanel.java b/src/main/java/com/unicenta/pos/inventory/TaxCustCategoriesPanel.java new file mode 100644 index 0000000..874b739 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/TaxCustCategoriesPanel.java @@ -0,0 +1,120 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.data.gui.ListCellRendererBasic; +import com.unicenta.data.loader.ComparatorCreator; +import com.unicenta.data.loader.TableDefinition; +import com.unicenta.data.loader.Vectorer; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.panels.JPanelTable; +import javax.swing.ListCellRenderer; + +/** + * + * @author adrianromero + */ +public class TaxCustCategoriesPanel extends JPanelTable { + + private TableDefinition ttaxcategories; + private TaxCustCategoriesEditor jeditor; + + /** Creates a new instance of JPanelDuty */ + public TaxCustCategoriesPanel() { + } + + /** + * + */ + @Override + protected void init() { + DataLogicSales dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + ttaxcategories = dlSales.getTableTaxCustCategories(); + jeditor = new TaxCustCategoriesEditor(dirty); + } + + /** + * + * @return + */ + @Override + public ListProvider getListProvider() { + return new ListProviderCreator(ttaxcategories); + } + + /** + * + * @return + */ + @Override + public SaveProvider getSaveProvider() { + return new SaveProvider(ttaxcategories); + } + + /** + * + * @return + */ + @Override + public Vectorer getVectorer() { + return ttaxcategories.getVectorerBasic(new int[]{1}); + } + + /** + * + * @return + */ + @Override + public ComparatorCreator getComparatorCreator() { + return ttaxcategories.getComparatorCreator(new int[] {1}); + } + + /** + * + * @return + */ + @Override + public ListCellRenderer getListCellRenderer() { + return new ListCellRendererBasic(ttaxcategories.getRenderStringBasic(new int[]{1})); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return jeditor; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.TaxCustCategories"); + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/TaxCustCategoryInfo.java b/src/main/java/com/unicenta/pos/inventory/TaxCustCategoryInfo.java new file mode 100644 index 0000000..5c66f83 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/TaxCustCategoryInfo.java @@ -0,0 +1,88 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.data.loader.IKeyed; + +/** + * + * @author adrianromero + * @version + */ +public class TaxCustCategoryInfo implements IKeyed { + + private static final long serialVersionUID = 8936482715929L; + private String m_sID; + private String m_sName; + + /** Creates new TaxCustCategoryInfo + * @param id + * @param name */ + public TaxCustCategoryInfo(String id, String name) { + m_sID = id; + m_sName = name; + } + + /** + * + * @return + */ + @Override + public Object getKey() { + return m_sID; + } + + /** + * + * @param sID + */ + public void setID(String sID) { + m_sID = sID; + } + + /** + * + * @return + */ + public String getID() { + return m_sID; + } + + /** + * + * @return + */ + public String getName() { + return m_sName; + } + + /** + * + * @param sName + */ + public void setName(String sName) { + m_sName = sName; + } + + @Override + public String toString(){ + return m_sName; + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/TaxEditor.form b/src/main/java/com/unicenta/pos/inventory/TaxEditor.form new file mode 100644 index 0000000..0267d6f --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/TaxEditor.form @@ -0,0 +1,259 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jTaxCategory" min="-2" pref="200" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jLabel4" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCustTaxCategory" min="-2" pref="200" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jLabel5" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jTaxParent" min="-2" pref="200" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jRate" min="-2" pref="60" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="16" max="-2" attributes="0"/> + <Component id="jCascade" min="-2" pref="110" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jName" min="-2" pref="200" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel6" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jOrder" min="-2" pref="60" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace pref="50" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jTaxCategory" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCustTaxCategory" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jTaxParent" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jRate" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="jCascade" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel6" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jOrder" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JTextField" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/info.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.name" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="jLabel2MouseClicked"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.dutyrate" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jRate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.taxcategory" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.custtaxcategory" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.taxparent" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="jCascade"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.cascade" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jTaxCategory"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jTaxParent"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCustTaxCategory"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.order" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jOrder"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/TaxEditor.java b/src/main/java/com/unicenta/pos/inventory/TaxEditor.java new file mode 100644 index 0000000..6d7449d --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/TaxEditor.java @@ -0,0 +1,428 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import java.awt.Component; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import javax.swing.JOptionPane; +import javax.swing.JPanel; + +/** + * + * @author JG uniCenta + */ +public class TaxEditor extends JPanel implements EditorRecord { + + private Object m_oId; + + private SentenceList taxcatsent; + private ComboBoxValModel taxcatmodel; + + private SentenceList taxcustcatsent; + private ComboBoxValModel taxcustcatmodel; + + private SentenceList taxparentsent; + private ComboBoxValModel taxparentmodel; + + /** Creates new form taxEditor + * @param app + * @param dirty */ + public TaxEditor(AppView app, DirtyManager dirty) { + + DataLogicSales dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + + initComponents(); + + taxcatsent = dlSales.getTaxCategoriesList(); + taxcatmodel = new ComboBoxValModel(); + + taxcustcatsent = dlSales.getTaxCustCategoriesList(); + taxcustcatmodel = new ComboBoxValModel(); + + taxparentsent = dlSales.getTaxList(); + taxparentmodel = new ComboBoxValModel(); + + m_jName.getDocument().addDocumentListener(dirty); + m_jTaxCategory.addActionListener(dirty); + m_jCustTaxCategory.addActionListener(dirty); + m_jTaxParent.addActionListener(dirty); + m_jRate.getDocument().addDocumentListener(dirty); + jCascade.addActionListener(dirty); + jOrder.getDocument().addDocumentListener(dirty); + + writeValueEOF(); + } + + /** + * + * @throws BasicException + */ + public void activate() throws BasicException { + + List a = taxcatsent.list(); + taxcatmodel = new ComboBoxValModel(a); + m_jTaxCategory.setModel(taxcatmodel); + + a = taxcustcatsent.list(); + a.add(0, null); // The null item + taxcustcatmodel = new ComboBoxValModel(a); + m_jCustTaxCategory.setModel(taxcustcatmodel); + + + } + + /** + * + */ + @Override + public void refresh() { + + List a; + + try { + a = taxparentsent.list(); + } catch (BasicException eD) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, AppLocal.getIntString("message.cannotloadlists"), eD); + msg.show(this); + a = new ArrayList(); + } + + a.add(0, null); // The null item + taxparentmodel = new ComboBoxValModel(a); + m_jTaxParent.setModel(taxparentmodel); + } + + /** + * + */ + @Override + public void writeValueEOF() { + m_oId = null; + m_jName.setText(null); + taxcatmodel.setSelectedKey(null); + taxcustcatmodel.setSelectedKey(null); + taxparentmodel.setSelectedKey(null); + m_jRate.setText(null); + jCascade.setSelected(false); + jOrder.setText(null); + + m_jName.setEnabled(false); + m_jTaxCategory.setEnabled(false); + m_jCustTaxCategory.setEnabled(false); + m_jTaxParent.setEnabled(false); + m_jRate.setEnabled(false); + jCascade.setEnabled(false); + jOrder.setEnabled(false); + } + + /** + * + */ + @Override + public void writeValueInsert() { + m_oId = UUID.randomUUID().toString(); + m_jName.setText(null); + taxcatmodel.setSelectedKey(null); + taxcustcatmodel.setSelectedKey(null); + taxparentmodel.setSelectedKey(null); + m_jRate.setText(null); + jCascade.setSelected(false); + jOrder.setText(null); + + m_jName.setEnabled(true); + m_jTaxCategory.setEnabled(true); + m_jCustTaxCategory.setEnabled(true); + m_jTaxParent.setEnabled(true); + m_jRate.setEnabled(true); + jCascade.setEnabled(true); + jOrder.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueDelete(Object value) { + + Object[] tax = (Object[]) value; + m_oId = tax[0]; + m_jName.setText(Formats.STRING.formatValue(tax[1])); + taxcatmodel.setSelectedKey(tax[2]); + taxcustcatmodel.setSelectedKey(tax[3]); + taxparentmodel.setSelectedKey(tax[4]); + m_jRate.setText(Formats.PERCENT.formatValue(tax[5])); + jCascade.setSelected((Boolean) tax[6]); + jOrder.setText(Formats.INT.formatValue(tax[7])); + + m_jName.setEnabled(false); + m_jTaxCategory.setEnabled(false); + m_jCustTaxCategory.setEnabled(false); + m_jTaxParent.setEnabled(false); + m_jRate.setEnabled(false); + jCascade.setEnabled(false); + jOrder.setEnabled(false); + } + + /** + * + * @param value + */ + @Override + public void writeValueEdit(Object value) { + + Object[] tax = (Object[]) value; + m_oId = tax[0]; + m_jName.setText(Formats.STRING.formatValue(tax[1])); + taxcatmodel.setSelectedKey(tax[2]); + taxcustcatmodel.setSelectedKey(tax[3]); + taxparentmodel.setSelectedKey(tax[4]); + m_jRate.setText(Formats.PERCENT.formatValue(tax[5])); + jCascade.setSelected((Boolean) tax[6]); + jOrder.setText(Formats.INT.formatValue(tax[7])); + + m_jName.setEnabled(true); + m_jTaxCategory.setEnabled(true); + m_jCustTaxCategory.setEnabled(true); + m_jTaxParent.setEnabled(true); + m_jRate.setEnabled(true); + jCascade.setEnabled(true); + jOrder.setEnabled(true); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + Object[] tax = new Object[8]; + + tax[0] = m_oId; + tax[1] = m_jName.getText(); + tax[2] = taxcatmodel.getSelectedKey(); + tax[3] = taxcustcatmodel.getSelectedKey(); + tax[4] = taxparentmodel.getSelectedKey(); + tax[5] = Formats.PERCENT.parseValue(m_jRate.getText()); + tax[6] = Boolean.valueOf(jCascade.isSelected()); + tax[7] = Formats.INT.parseValue(jOrder.getText()); + + return tax; + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jName = new javax.swing.JTextField(); + jLabel2 = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + m_jRate = new javax.swing.JTextField(); + jLabel1 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + jLabel5 = new javax.swing.JLabel(); + jCascade = new javax.swing.JCheckBox(); + m_jTaxCategory = new javax.swing.JComboBox(); + m_jTaxParent = new javax.swing.JComboBox(); + m_jCustTaxCategory = new javax.swing.JComboBox(); + jLabel6 = new javax.swing.JLabel(); + jOrder = new javax.swing.JTextField(); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/info.png"))); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.name")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(170, 30)); + jLabel2.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + jLabel2MouseClicked(evt); + } + }); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.dutyrate")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(170, 30)); + + m_jRate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jRate.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.taxcategory")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(170, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.custtaxcategory")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(170, 30)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.taxparent")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(170, 30)); + + jCascade.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jCascade.setText(AppLocal.getIntString("label.cascade")); // NOI18N + jCascade.setPreferredSize(new java.awt.Dimension(0, 30)); + + m_jTaxCategory.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jTaxCategory.setPreferredSize(new java.awt.Dimension(0, 30)); + + m_jTaxParent.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jTaxParent.setPreferredSize(new java.awt.Dimension(0, 30)); + + m_jCustTaxCategory.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCustTaxCategory.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setText(AppLocal.getIntString("label.order")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(170, 30)); + + jOrder.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jOrder.setPreferredSize(new java.awt.Dimension(0, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jTaxCategory, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCustTaxCategory, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jTaxParent, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jRate, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(16, 16, 16) + .addComponent(jCascade, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jOrder, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(50, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jTaxCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCustTaxCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jTaxParent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jRate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jCascade, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jOrder, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + ); + }// </editor-fold>//GEN-END:initComponents + + private void jLabel2MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabel2MouseClicked + + if (evt.getClickCount() == 2) { + String uuidString = m_oId.toString(); + StringSelection stringSelection = new StringSelection(uuidString); + Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard(); + clpbrd.setContents(stringSelection, null); + + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.uuidcopy")); + } + }//GEN-LAST:event_jLabel2MouseClicked + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JCheckBox jCascade; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JTextField jOrder; + private javax.swing.JComboBox m_jCustTaxCategory; + private javax.swing.JTextField m_jName; + private javax.swing.JTextField m_jRate; + private javax.swing.JComboBox m_jTaxCategory; + private javax.swing.JComboBox m_jTaxParent; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/inventory/TaxPanel.java b/src/main/java/com/unicenta/pos/inventory/TaxPanel.java new file mode 100644 index 0000000..e4d988e --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/TaxPanel.java @@ -0,0 +1,132 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ListCellRendererBasic; +import com.unicenta.data.loader.ComparatorCreator; +import com.unicenta.data.loader.TableDefinition; +import com.unicenta.data.loader.Vectorer; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.panels.JPanelTable; +import javax.swing.ListCellRenderer; + +/** + * + * @author adrianromero + */ +public class TaxPanel extends JPanelTable { + + private TableDefinition ttaxes; + private TaxEditor jeditor; + + /** Creates a new instance of JPanelDuty */ + public TaxPanel() { + } + + /** + * + */ + @Override + protected void init() { + DataLogicSales dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + ttaxes = dlSales.getTableTaxes(); + jeditor = new TaxEditor(app, dirty); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + + jeditor.activate(); + super.activate(); + } + + /** + * + * @return + */ + @Override + public ListProvider getListProvider() { + return new ListProviderCreator(ttaxes); + } + + /** + * + * @return + */ + @Override + public SaveProvider getSaveProvider() { + return new SaveProvider(ttaxes); + } + + /** + * + * @return + */ + @Override + public Vectorer getVectorer() { + return ttaxes.getVectorerBasic(new int[]{1, 5, 7}); + } + + /** + * + * @return + */ + @Override + public ComparatorCreator getComparatorCreator() { + return ttaxes.getComparatorCreator(new int[] {1, 5, 7}); + } + + /** + * + * @return + */ + @Override + public ListCellRenderer getListCellRenderer() { + return new ListCellRendererBasic(ttaxes.getRenderStringBasic(new int[]{1})); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return jeditor; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.Taxes"); + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/UomEditor.form b/src/main/java/com/unicenta/pos/inventory/UomEditor.form new file mode 100644 index 0000000..72401aa --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/UomEditor.form @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="36" max="-2" attributes="0"/> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jName" min="-2" max="-2" attributes="0"/> + <EmptySpace pref="54" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="25" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace pref="35" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/info.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.name" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="jLabel2MouseClicked"/> + </Events> + </Component> + <Component class="javax.swing.JTextField" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/inventory/UomEditor.java b/src/main/java/com/unicenta/pos/inventory/UomEditor.java new file mode 100644 index 0000000..557bbdc --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/UomEditor.java @@ -0,0 +1,158 @@ +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import java.awt.Component; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.util.UUID; +import javax.swing.JOptionPane; + +public final class UomEditor extends javax.swing.JPanel implements EditorRecord { + private Object m_id; + + /** Creates new form JPanelUnits Of Measure + * @param app + * @param dirty */ + public UomEditor(AppView app, DirtyManager dirty) { + + initComponents(); + + m_jName.getDocument().addDocumentListener(dirty); + + writeValueEOF(); + } + + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel2 = new javax.swing.JLabel(); + m_jName = new javax.swing.JTextField(); + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/info.png"))); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.name")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(100, 30)); + jLabel2.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + jLabel2MouseClicked(evt); + } + }); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(200, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(36, 36, 36) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(54, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(25, 25, 25) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(35, Short.MAX_VALUE)) + ); + }// </editor-fold>//GEN-END:initComponents + + private void jLabel2MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabel2MouseClicked + + if (evt.getClickCount() == 2) { + String uuidString = m_id.toString(); + StringSelection stringSelection = new StringSelection(uuidString); + Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard(); + clpbrd.setContents(stringSelection, null); + + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.uuidcopy")); + } + }//GEN-LAST:event_jLabel2MouseClicked + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel2; + private javax.swing.JTextField m_jName; + // End of variables declaration//GEN-END:variables + + @Override + public void writeValueEOF() { + m_id = null; + m_jName.setText(null); + m_jName.setEnabled(false); + } + + @Override + public void writeValueInsert() { + + m_id = UUID.randomUUID().toString(); + m_jName.setText(null); + m_jName.setEnabled(true); + + } + + @Override + public void writeValueEdit(Object value) { + Object[] obj = (Object[]) value; + + m_id = obj[0]; + m_jName.setText(Formats.STRING.formatValue(obj[1])); + m_jName.setEnabled(true); + + } + + @Override + public void writeValueDelete(Object value) { + Object[] obj = (Object[]) value; + + m_id = obj[0]; + m_jName.setText(Formats.STRING.formatValue(obj[1])); + m_jName.setEnabled(false); + + } + + @Override + public void refresh() { + } + + @Override + public Component getComponent() { + return this; + } + + @Override + public Object createValue() throws BasicException { + Object[] obj = new Object[2]; + obj[0] = m_id; + obj[1] = m_jName.getText(); + + return obj; + + } + + public boolean isDataValid() { + return true; + } +} diff --git a/src/main/java/com/unicenta/pos/inventory/UomInfo.java b/src/main/java/com/unicenta/pos/inventory/UomInfo.java new file mode 100644 index 0000000..6720324 --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/UomInfo.java @@ -0,0 +1,59 @@ +package com.unicenta.pos.inventory; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.IKeyed; +import com.unicenta.data.loader.SerializerRead; + +public class UomInfo implements IKeyed { + + private String m_sID; + private String m_sName; + + + + /** Creates new CategoryInfo + * @param id + * @param name */ + public UomInfo(String id, String name) { + m_sID = id; + m_sName = name; + } + + + public void setID(String sID) { + m_sID = sID; + } + + public String getID() { + return m_sID; + } + + public String getName() { + return m_sName; + } + + public void setName(String sName) { + m_sName = sName; + } + + + @Override + public Object getKey() { + return m_sID; + } + + @Override + public String toString() { + return m_sName; + } + + public static SerializerRead getSerializerRead() { + return new SerializerRead() {@Override + public Object readValues(DataRead dr) throws BasicException { + return new UomInfo(dr.getString(1), dr.getString(2)); + }}; + } + + +} diff --git a/src/main/java/com/unicenta/pos/inventory/UomPanel.java b/src/main/java/com/unicenta/pos/inventory/UomPanel.java new file mode 100644 index 0000000..364ad4e --- /dev/null +++ b/src/main/java/com/unicenta/pos/inventory/UomPanel.java @@ -0,0 +1,59 @@ +package com.unicenta.pos.inventory; + +import com.unicenta.data.gui.ListCellRendererBasic; +import com.unicenta.data.loader.ComparatorCreator; +import com.unicenta.data.loader.TableDefinition; +import com.unicenta.data.loader.Vectorer; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.panels.JPanelTable; +import javax.swing.ListCellRenderer; + +public class UomPanel extends JPanelTable { + + private TableDefinition tuom; + private UomEditor jeditor; + + @Override + protected void init() { + DataLogicSales dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + tuom = dlSales.getTableUom(); + jeditor = new UomEditor(app, dirty); + } + + @Override + public EditorRecord getEditor() { + return jeditor; + } + + @Override + public ListProvider getListProvider() { + return new ListProviderCreator(tuom); + } + + @Override + public SaveProvider getSaveProvider() { + return new SaveProvider(tuom); + } + + @Override + public Vectorer getVectorer() { + return tuom.getVectorerBasic(new int[]{1}); + } + + + @Override + public ListCellRenderer getListCellRenderer() { + return new ListCellRendererBasic(tuom.getRenderStringBasic(new int[]{1})); + } + + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.Uom"); + } + +} diff --git a/src/main/java/com/unicenta/pos/mant/Applications.java b/src/main/java/com/unicenta/pos/mant/Applications.java new file mode 100644 index 0000000..ce23f36 --- /dev/null +++ b/src/main/java/com/unicenta/pos/mant/Applications.java @@ -0,0 +1,122 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.unicenta.pos.mant; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.io.Serializable; +import javax.persistence.Basic; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.Table; +import javax.persistence.Transient; + +/** + * + * @author jack + */ +@Entity +@Table(name = "applications", catalog = "unicentaopos", schema = "") +@NamedQueries({ + @NamedQuery(name = "Applications.findAll", query = "SELECT a FROM Applications a"), + @NamedQuery(name = "Applications.findById", query = "SELECT a FROM Applications a WHERE a.id = :id"), + @NamedQuery(name = "Applications.findByName", query = "SELECT a FROM Applications a WHERE a.name = :name"), + @NamedQuery(name = "Applications.findByVersion", query = "SELECT a FROM Applications a WHERE a.version = :version")}) +public class Applications implements Serializable { + @Transient + private PropertyChangeSupport changeSupport = new PropertyChangeSupport(this); + private static final long serialVersionUID = 1L; + @Id + @Basic(optional = false) + @Column(name = "ID") + private String id; + @Basic(optional = false) + @Column(name = "NAME") + private String name; + @Basic(optional = false) + @Column(name = "VERSION") + private String version; + + public Applications() { + } + + public Applications(String id) { + this.id = id; + } + + public Applications(String id, String name, String version) { + this.id = id; + this.name = name; + this.version = version; + } + + public String getId() { + return id; + } + + public void setId(String id) { + String oldId = this.id; + this.id = id; + changeSupport.firePropertyChange("id", oldId, id); + } + + public String getName() { + return name; + } + + public void setName(String name) { + String oldName = this.name; + this.name = name; + changeSupport.firePropertyChange("name", oldName, name); + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + String oldVersion = this.version; + this.version = version; + changeSupport.firePropertyChange("version", oldVersion, version); + } + + @Override + public int hashCode() { + int hash = 0; + hash += (id != null ? id.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) { + // TODO: Warning - this method won't work in the case the id fields are not set + if (!(object instanceof Applications)) { + return false; + } + Applications other = (Applications) object; + if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { + return false; + } + return true; + } + + @Override + public String toString() { + return "com.unicenta.pos.mant.Applications[ id=" + id + " ]"; + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + changeSupport.addPropertyChangeListener(listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + changeSupport.removePropertyChangeListener(listener); + } + +} diff --git a/src/main/java/com/unicenta/pos/mant/Floors.java b/src/main/java/com/unicenta/pos/mant/Floors.java new file mode 100644 index 0000000..4d9c015 --- /dev/null +++ b/src/main/java/com/unicenta/pos/mant/Floors.java @@ -0,0 +1,121 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.unicenta.pos.mant; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.io.Serializable; +import javax.persistence.Basic; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Lob; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.Table; +import javax.persistence.Transient; + +/** + * + * @author jack + */ +@Entity +@Table(name = "floors", catalog = "unicentaopos", schema = "") +@NamedQueries({ + @NamedQuery(name = "Floors.findAll", query = "SELECT f FROM Floors f"), + @NamedQuery(name = "Floors.findById", query = "SELECT f FROM Floors f WHERE f.id = :id"), + @NamedQuery(name = "Floors.findByName", query = "SELECT f FROM Floors f WHERE f.name = :name")}) +public class Floors implements Serializable { + @Transient + private PropertyChangeSupport changeSupport = new PropertyChangeSupport(this); + private static final long serialVersionUID = 1L; + @Id + @Basic(optional = false) + @Column(name = "ID") + private String id; + @Basic(optional = false) + @Column(name = "NAME") + private String name; + @Lob + @Column(name = "IMAGE") + private byte[] image; + + public Floors() { + } + + public Floors(String id) { + this.id = id; + } + + public Floors(String id, String name) { + this.id = id; + this.name = name; + } + + public String getId() { + return id; + } + + public void setId(String id) { + String oldId = this.id; + this.id = id; + changeSupport.firePropertyChange("id", oldId, id); + } + + public String getName() { + return name; + } + + public void setName(String name) { + String oldName = this.name; + this.name = name; + changeSupport.firePropertyChange("name", oldName, name); + } + + public byte[] getImage() { + return image; + } + + public void setImage(byte[] image) { + byte[] oldImage = this.image; + this.image = image; + changeSupport.firePropertyChange("image", oldImage, image); + } + + @Override + public int hashCode() { + int hash = 0; + hash += (id != null ? id.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) { + // TODO: Warning - this method won't work in the case the id fields are not set + if (!(object instanceof Floors)) { + return false; + } + Floors other = (Floors) object; + if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { + return false; + } + return true; + } + + @Override + public String toString() { + return "com.unicenta.pos.mant.Floors[ id=" + id + " ]"; + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + changeSupport.addPropertyChangeListener(listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + changeSupport.removePropertyChangeListener(listener); + } + +} diff --git a/src/main/java/com/unicenta/pos/mant/FloorsEditor.form b/src/main/java/com/unicenta/pos/mant/FloorsEditor.form new file mode 100644 index 0000000..dcbc2bc --- /dev/null +++ b/src/main/java/com/unicenta/pos/mant/FloorsEditor.form @@ -0,0 +1,105 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[91, 125]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,12,0,0,2,-121"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 100]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout"> + <Property name="useNullLayout" type="boolean" value="true"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.name" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="20" y="20" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="130" y="20" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="0" left="5" right="0" top="0"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Component class="com.unicenta.data.gui.JImageEditor" name="m_jImage"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/mant/FloorsEditor.java b/src/main/java/com/unicenta/pos/mant/FloorsEditor.java new file mode 100644 index 0000000..fa4e394 --- /dev/null +++ b/src/main/java/com/unicenta/pos/mant/FloorsEditor.java @@ -0,0 +1,197 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.mant; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import java.awt.Component; +import java.awt.image.BufferedImage; +import java.util.UUID; +import javax.swing.JPanel; + + +/** + * + * @author adrianromero + */ +public final class FloorsEditor extends JPanel implements EditorRecord { + +// private DirtyManager m_Dirty = new DirtyManager(); + private String m_sID; + + /** Creates new form FloorsEditor + * @param dirty */ + public FloorsEditor(DirtyManager dirty) { + initComponents(); + + m_jName.getDocument().addDocumentListener(dirty); + m_jImage.addPropertyChangeListener("image", dirty); + + writeValueEOF(); + } + + /** + * + */ + @Override + public void writeValueEOF() { + + m_sID = null; + m_jName.setText(null); + m_jImage.setImage(null); + + m_jName.setEnabled(false); + m_jImage.setEnabled(false); + } + + /** + * + */ + @Override + public void writeValueInsert() { + + m_sID = UUID.randomUUID().toString(); + m_jName.setText(null); + m_jImage.setImage(null); + + m_jName.setEnabled(true); + m_jImage.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueDelete(Object value) { + + Object[] floor = (Object[]) value; + m_sID = Formats.STRING.formatValue(floor[0]); + m_jName.setText(Formats.STRING.formatValue(floor[1])); + m_jImage.setImage((BufferedImage) floor[2]); + + m_jName.setEnabled(false); + m_jImage.setEnabled(false); + } + + /** + * + * @param value + */ + @Override + public void writeValueEdit(Object value) { + + Object[] floor = (Object[]) value; + m_sID = Formats.STRING.formatValue(floor[0]); + m_jName.setText(Formats.STRING.formatValue(floor[1])); + m_jImage.setImage((BufferedImage) floor[2]); + + m_jName.setEnabled(true); + m_jImage.setEnabled(true); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + Object[] floor = new Object[3]; + + floor[0] = m_sID; + floor[1] = m_jName.getText(); + floor[2] = m_jImage.getImage(); + return floor; + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + */ + @Override + public void refresh() { + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jLabel3 = new javax.swing.JLabel(); + m_jName = new javax.swing.JTextField(); + jPanel3 = new javax.swing.JPanel(); + m_jImage = new com.unicenta.data.gui.JImageEditor(); + + setMinimumSize(new java.awt.Dimension(91, 125)); + setLayout(new java.awt.BorderLayout()); + + jPanel1.setPreferredSize(new java.awt.Dimension(150, 100)); + jPanel1.setLayout(null); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.name")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(110, 30)); + jPanel1.add(jLabel3); + jLabel3.setBounds(20, 20, 110, 30); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(250, 30)); + jPanel1.add(m_jName); + m_jName.setBounds(130, 20, 250, 30); + + add(jPanel1, java.awt.BorderLayout.NORTH); + + jPanel3.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 5, 0, 0)); + jPanel3.setLayout(new java.awt.BorderLayout()); + + m_jImage.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel3.add(m_jImage, java.awt.BorderLayout.CENTER); + + add(jPanel3, java.awt.BorderLayout.CENTER); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel3; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel3; + private com.unicenta.data.gui.JImageEditor m_jImage; + private javax.swing.JTextField m_jName; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/mant/FloorsInfo.java b/src/main/java/com/unicenta/pos/mant/FloorsInfo.java new file mode 100644 index 0000000..05375e8 --- /dev/null +++ b/src/main/java/com/unicenta/pos/mant/FloorsInfo.java @@ -0,0 +1,101 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.mant; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.IKeyed; +import com.unicenta.data.loader.SerializableRead; + +/** + * + * @author adrianromero + * Created on 26 de febrero de 2007, 23:49 + * + */ +public class FloorsInfo implements SerializableRead, IKeyed { + + private static final long serialVersionUID = 8906929819402L; + private String m_sID; + private String m_sName; + + /** Creates a new instance of FloorsInfo */ + public FloorsInfo() { + m_sID = null; + m_sName = null; + } + + /** + * + * @return + */ + @Override + public Object getKey() { + return m_sID; + } + + /** + * + * @param dr + * @throws BasicException + */ + @Override + public void readValues(DataRead dr) throws BasicException { + m_sID = dr.getString(1); + m_sName = dr.getString(2); + } + + /** + * + * @param sID + */ + public void setID(String sID) { + m_sID = sID; + } + + /** + * + * @return + */ + public String getID() { + return m_sID; + } + + /** + * + * @return + */ + public String getName() { + return m_sName; + } + + /** + * + * @param sName + */ + public void setName(String sName) { + m_sName = sName; + } + + @Override + public String toString(){ + return m_sName; + } +} diff --git a/src/main/java/com/unicenta/pos/mant/JPanelFloors.java b/src/main/java/com/unicenta/pos/mant/JPanelFloors.java new file mode 100644 index 0000000..75bc329 --- /dev/null +++ b/src/main/java/com/unicenta/pos/mant/JPanelFloors.java @@ -0,0 +1,117 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.mant; + +import com.unicenta.data.gui.ListCellRendererBasic; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.loader.TableDefinition; +import com.unicenta.data.loader.Vectorer; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.panels.JPanelTable; +import javax.swing.ListCellRenderer; + +/** + * + * @author adrianromero + */ +public class JPanelFloors extends JPanelTable { + + private TableDefinition tfloors; + private FloorsEditor jeditor; + + /** Creates a new instance of JPanelFloors */ + public JPanelFloors() { + } + + /** + * + */ + @Override + protected void init() { + tfloors = new TableDefinition(app.getSession(), + "floors" + , new String[] {"ID", "NAME", "IMAGE"} + , new String[] {"ID", AppLocal.getIntString("label.name"), "IMAGE"} + , new Datas[] {Datas.STRING, Datas.STRING, Datas.IMAGE} + , new Formats[] {Formats.NULL, Formats.STRING} + , new int[] {0} + ); + jeditor = new FloorsEditor(dirty); + } + + /** + * + * @return + */ + @Override + public ListProvider getListProvider() { + return new ListProviderCreator(tfloors); + } + + /** + * + * @return + */ + @Override + public Vectorer getVectorer() { + return tfloors.getVectorerBasic(new int[]{1}); + } + + /** + * + * @return + */ + @Override + public ListCellRenderer getListCellRenderer() { + return new ListCellRendererBasic(tfloors.getRenderStringBasic(new int[]{1})); + } + + /** + * + * @return + */ + @Override + public SaveProvider getSaveProvider() { + return new SaveProvider(tfloors); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return jeditor; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.Floors"); + } +} diff --git a/src/main/java/com/unicenta/pos/mant/JPanelPlaces.java b/src/main/java/com/unicenta/pos/mant/JPanelPlaces.java new file mode 100644 index 0000000..c9bfc4c --- /dev/null +++ b/src/main/java/com/unicenta/pos/mant/JPanelPlaces.java @@ -0,0 +1,141 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.mant; +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ListCellRendererBasic; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.loader.TableDefinition; +import com.unicenta.data.loader.Vectorer; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.panels.JPanelTable; +import javax.swing.ListCellRenderer; + +/** + * + * @author adrianromero + */ +public class JPanelPlaces extends JPanelTable { + + private TableDefinition tplaces; + private PlacesEditor jeditor; + + /** Creates a new instance of JPanelPlaces */ + public JPanelPlaces() { + } + + /** + * + */ + @Override + protected void init() { + DataLogicSales dlSales = null; + dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + + tplaces = new TableDefinition(app.getSession(), + "places" + , new String[] {"ID", "NAME", "SEATS", "X", "Y", "FLOOR", "WIDTH", "HEIGHT"} + , new String[] {"ID", AppLocal.getIntString("label.name"), + AppLocal.getIntString("label.seats"), "X", "Y", + AppLocal.getIntString("label.placefloor")} + , new Datas[] { + Datas.STRING, Datas.STRING, Datas.STRING, + Datas.INT, Datas.INT, + Datas.STRING, + Datas.INT, Datas.INT } + , new Formats[] { + Formats.STRING, Formats.STRING, Formats.STRING, + Formats.INT, Formats.INT, + Formats.NULL, + Formats.INT, Formats.INT } + , new int[] {0} + ); + jeditor = new PlacesEditor(dlSales, dirty); + } + + /** + * + * @return + */ + @Override + public ListProvider getListProvider() { + return new ListProviderCreator(tplaces); + } + + /** + * + * @return + */ + @Override + public SaveProvider getSaveProvider() { + return new SaveProvider(tplaces); + } + + /** + * + * @return + */ + @Override + public Vectorer getVectorer() { + return tplaces.getVectorerBasic(new int[]{1}); + } + + /** + * + * @return + */ + @Override + public ListCellRenderer getListCellRenderer() { + return new ListCellRendererBasic(tplaces.getRenderStringBasic(new int[]{1})); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return jeditor; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.Tables"); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + jeditor.activate(); + super.activate(); + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/mant/Places.java b/src/main/java/com/unicenta/pos/mant/Places.java new file mode 100644 index 0000000..36f9368 --- /dev/null +++ b/src/main/java/com/unicenta/pos/mant/Places.java @@ -0,0 +1,245 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.unicenta.pos.mant; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.io.Serializable; +import javax.persistence.Basic; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.Table; +import javax.persistence.Transient; + +/** + * + * @author jack + */ +@Entity +@Table(name = "places", catalog = "unicentaopos", schema = "") +@NamedQueries({ + @NamedQuery(name = "Places.findAll", query = "SELECT p FROM Places p"), + @NamedQuery(name = "Places.findById", query = "SELECT p FROM Places p WHERE p.id = :id"), + @NamedQuery(name = "Places.findByName", query = "SELECT p FROM Places p WHERE p.name = :name"), + @NamedQuery(name = "Places.findByX", query = "SELECT p FROM Places p WHERE p.x = :x"), + @NamedQuery(name = "Places.findByY", query = "SELECT p FROM Places p WHERE p.y = :y"), + @NamedQuery(name = "Places.findByFloor", query = "SELECT p FROM Places p WHERE p.floor = :floor"), + @NamedQuery(name = "Places.findByCustomer", query = "SELECT p FROM Places p WHERE p.customer = :customer"), + @NamedQuery(name = "Places.findByWaiter", query = "SELECT p FROM Places p WHERE p.waiter = :waiter"), + @NamedQuery(name = "Places.findByTicketid", query = "SELECT p FROM Places p WHERE p.ticketid = :ticketid"), + @NamedQuery(name = "Places.findByTablemoved", query = "SELECT p FROM Places p WHERE p.tablemoved = :tablemoved")}) +public class Places implements Serializable { + @Transient + private PropertyChangeSupport changeSupport = new PropertyChangeSupport(this); + private static final long serialVersionUID = 1L; + @Id + @Basic(optional = false) + @Column(name = "ID") + private String id; + @Basic(optional = false) + @Column(name = "NAME") + private String name; + @Column(name = "SEATS") + private String seats; + @Basic(optional = false) + @Column(name = "X") + private int x; + @Basic(optional = false) + @Column(name = "Y") + private int y; + @Basic(optional = false) + @Column(name = "FLOOR") + private String floor; + @Column(name = "CUSTOMER") + private String customer; + @Column(name = "WAITER") + private String waiter; + @Column(name = "TICKETID") + private String ticketid; + @Basic(optional = false) + @Column(name = "TABLEMOVED") + private short tablemoved; + + @Column(name = "WIDTH") + private int width; + @Basic(optional = false) + @Column(name = "HEIGHT") + private int height; + + public Places() { + } + + public Places(String id) { + this.id = id; + } + + public Places(String id, String name, String seats, int x, int y, int width, int height, String floor, short tablemoved) { + this.id = id; + this.name = name; + this.seats = seats; + this.x = x; + this.y = y; + this.floor = floor; + this.tablemoved = tablemoved; + this.width = width; + this.height = height; + } + + public String getId() { + return id; + } + + public void setId(String id) { + String oldId = this.id; + this.id = id; + changeSupport.firePropertyChange("id", oldId, id); + } + + public String getName() { + return name; + } + public void setName(String name) { + String oldName = this.name; + this.name = name; + changeSupport.firePropertyChange("name", oldName, name); + } + + public String getSeats() { + return seats; + } + public void setSeats(String seats) { + String oldSeats = this.seats; + this.seats = seats; + changeSupport.firePropertyChange("seats", oldSeats, seats); + } + + public int getX() { + return x; + } + + public void setX(int x) { + int oldX = this.x; + this.x = x; + changeSupport.firePropertyChange("x", oldX, x); + } + + public int getY() { + return y; + } + + public void setY(int y) { + int oldY = this.y; + this.y = y; + changeSupport.firePropertyChange("y", oldY, y); + } + + public String getFloor() { + return floor; + } + + public void setFloor(String floor) { + String oldFloor = this.floor; + this.floor = floor; + changeSupport.firePropertyChange("floor", oldFloor, floor); + } + + public String getCustomer() { + return customer; + } + + public void setCustomer(String customer) { + String oldCustomer = this.customer; + this.customer = customer; + changeSupport.firePropertyChange("customer", oldCustomer, customer); + } + + public String getWaiter() { + return waiter; + } + + public void setWaiter(String waiter) { + String oldWaiter = this.waiter; + this.waiter = waiter; + changeSupport.firePropertyChange("waiter", oldWaiter, waiter); + } + + public String getTicketid() { + return ticketid; + } + + public void setTicketid(String ticketid) { + String oldTicketid = this.ticketid; + this.ticketid = ticketid; + changeSupport.firePropertyChange("ticketid", oldTicketid, ticketid); + } + + public short getTablemoved() { + return tablemoved; + } + + public void setTablemoved(short tablemoved) { + short oldTablemoved = this.tablemoved; + this.tablemoved = tablemoved; + changeSupport.firePropertyChange("tablemoved", oldTablemoved, tablemoved); + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + int oldWidth = this.width; + this.width = width; + changeSupport.firePropertyChange("width", oldWidth, width); + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + int oldHeight = this.height; + this.height = height; + changeSupport.firePropertyChange("height", oldHeight, height); + } + + @Override + public int hashCode() { + int hash = 0; + hash += (id != null ? id.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) { + // TODO: Warning - this method won't work in the case the id fields are not set + if (!(object instanceof Places)) { + return false; + } + Places other = (Places) object; + if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { + return false; + } + return true; + } + + @Override + public String toString() { + return "com.unicenta.pos.mant.Places[ id=" + id + " ]"; + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + changeSupport.addPropertyChangeListener(listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + changeSupport.removePropertyChangeListener(listener); + } + +} diff --git a/src/main/java/com/unicenta/pos/mant/PlacesEditor.form b/src/main/java/com/unicenta/pos/mant/PlacesEditor.form new file mode 100644 index 0000000..c30054f --- /dev/null +++ b/src/main/java/com/unicenta/pos/mant/PlacesEditor.form @@ -0,0 +1,349 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jName" min="-2" pref="200" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="14" max="-2" attributes="0"/> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jFloor" min="-2" pref="200" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="1" attributes="0"> + <Component id="jLabel10" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="jLabel11" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jHeight" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="m_jY" alignment="1" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" attributes="0"> + <Component id="jLabel6" min="-2" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + <Component id="m_jX" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel3" min="-2" pref="40" max="-2" attributes="0"/> + <Component id="jLabel5" alignment="0" min="-2" pref="50" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" pref="12" max="-2" attributes="0"/> + <Component id="jLabel7" min="-2" pref="384" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel8" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jSeats" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel9" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jWidth" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" alignment="0" groupAlignment="3" attributes="0"> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="103" alignment="0" groupAlignment="3" attributes="0"> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jFloor" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel8" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jSeats" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel9" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jWidth" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel10" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jHeight" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel6" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jX" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jY" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel11" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="52" max="-2" attributes="0"/> + <Component id="jLabel7" min="-2" pref="96" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace pref="180" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.name" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.placefloor" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.placepositionx" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="Across"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="Down"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel7"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" red="ff" type="rgb"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="message.places" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="verticalAlignment" type="int" value="1"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="99" green="99" red="99" type="rgb"/> + </LineBorder> + </Border> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[489, 40]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.seats" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel9"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.btnwidth" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel11"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.placepositiony" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel10"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.btnheight" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jFloor"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jSeats"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jWidth"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jHeight"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jX"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jY"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/mant/PlacesEditor.java b/src/main/java/com/unicenta/pos/mant/PlacesEditor.java new file mode 100644 index 0000000..adda7bb --- /dev/null +++ b/src/main/java/com/unicenta/pos/mant/PlacesEditor.java @@ -0,0 +1,418 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.mant; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSales; +import java.awt.Component; +import java.util.UUID; +import javax.swing.JPanel; + +/** + * + * @author adrianromero + */ +public final class PlacesEditor extends JPanel implements EditorRecord { + + private final SentenceList m_sentfloor; + private ComboBoxValModel m_FloorModel; + + private String m_sID; + + /** Creates new form PlacesEditor + * @param dlSales + * @param dirty */ + public PlacesEditor(DataLogicSales dlSales, DirtyManager dirty) { + initComponents(); + + m_sentfloor = dlSales.getFloorsList(); + m_FloorModel = new ComboBoxValModel(); + + m_jName.getDocument().addDocumentListener(dirty); + m_jSeats.getDocument().addDocumentListener(dirty); + m_jFloor.addActionListener(dirty); + m_jX.getDocument().addDocumentListener(dirty); + m_jY.getDocument().addDocumentListener(dirty); + + m_jWidth.getDocument().addDocumentListener(dirty); + m_jHeight.getDocument().addDocumentListener(dirty); + + writeValueEOF(); + } + + /** + * + * @throws BasicException + */ + public void activate() throws BasicException { + + m_FloorModel = new ComboBoxValModel(m_sentfloor.list()); + m_jFloor.setModel(m_FloorModel); + } + + /** + * + */ + @Override + public void refresh() { + } + + /** + * + */ + @Override + public void writeValueEOF() { + + m_sID = null; + m_jName.setText(null); + m_jSeats.setText(null); + m_FloorModel.setSelectedKey(null); + m_jX.setText(null); + m_jY.setText(null); + + m_jWidth.setText(null); + m_jHeight.setText(null); + + m_jName.setEnabled(false); + m_jSeats.setEnabled(false); + m_jFloor.setEnabled(false); + m_jX.setEnabled(false); + m_jY.setEnabled(false); + + m_jWidth.setEnabled(false); + m_jHeight.setEnabled(false); + } + + /** + * + */ + @Override + public void writeValueInsert() { + + m_sID = UUID.randomUUID().toString(); + m_jName.setText(null); + m_jSeats.setText(null); + m_FloorModel.setSelectedKey(null); + m_jX.setText(null); + m_jY.setText(null); + m_jWidth.setText(null); + m_jHeight.setText(null); + + m_jName.setEnabled(true); + m_jSeats.setEnabled(true); + m_jFloor.setEnabled(true); + m_jX.setEnabled(true); + m_jY.setEnabled(true); + m_jWidth.setEnabled(true); + m_jHeight.setEnabled(true); + } + + /** + * + * @param value + */ + @Override + public void writeValueDelete(Object value) { + + Object[] place = (Object[]) value; + m_sID = Formats.STRING.formatValue(place[0]); + m_jName.setText(Formats.STRING.formatValue(place[1])); + m_jSeats.setText(Formats.STRING.formatValue(place[2])); + m_jX.setText(Formats.INT.formatValue(place[3])); + m_jY.setText(Formats.INT.formatValue(place[4])); + m_FloorModel.setSelectedKey(place[5]); + m_jWidth.setText(Formats.INT.formatValue(place[6])); + m_jHeight.setText(Formats.INT.formatValue(place[7])); + + m_jName.setEnabled(false); + m_jSeats.setEnabled(false); + m_jFloor.setEnabled(false); + m_jX.setEnabled(false); + m_jY.setEnabled(false); + m_jWidth.setEnabled(false); + m_jHeight.setEnabled(false); + } + + /** + * + * @param value + */ + @Override + public void writeValueEdit(Object value) { + + Object[] place = (Object[]) value; + m_sID = Formats.STRING.formatValue(place[0]); + m_jName.setText(Formats.STRING.formatValue(place[1])); + m_jSeats.setText(Formats.STRING.formatValue(place[2])); + m_jX.setText(Formats.INT.formatValue(place[3])); + m_jY.setText(Formats.INT.formatValue(place[4])); + m_FloorModel.setSelectedKey(place[5]); + m_jWidth.setText(Formats.INT.formatValue(place[6])); + m_jHeight.setText(Formats.INT.formatValue(place[7])); + + m_jName.setEnabled(true); + m_jSeats.setEnabled(true); + m_jFloor.setEnabled(true); + m_jX.setEnabled(true); + m_jY.setEnabled(true); + m_jWidth.setEnabled(true); + m_jHeight.setEnabled(true); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + Object[] place = new Object[8]; + place[0] = m_sID; + place[1] = m_jName.getText(); + place[2] = m_jSeats.getText(); + place[3] = Formats.INT.parseValue(m_jX.getText()); + place[4] = Formats.INT.parseValue(m_jY.getText()); + place[5] = m_FloorModel.getSelectedKey(); + place[6] = Formats.INT.parseValue(m_jWidth.getText()); + place[7] = Formats.INT.parseValue(m_jHeight.getText()); + return place; + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel2 = new javax.swing.JLabel(); + jLabel1 = new javax.swing.JLabel(); + jLabel6 = new javax.swing.JLabel(); + jLabel5 = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + jLabel7 = new javax.swing.JLabel(); + jLabel8 = new javax.swing.JLabel(); + jLabel9 = new javax.swing.JLabel(); + jLabel11 = new javax.swing.JLabel(); + jLabel10 = new javax.swing.JLabel(); + m_jName = new javax.swing.JTextField(); + m_jFloor = new javax.swing.JComboBox(); + m_jSeats = new javax.swing.JTextField(); + m_jWidth = new javax.swing.JTextField(); + m_jHeight = new javax.swing.JTextField(); + m_jX = new javax.swing.JTextField(); + m_jY = new javax.swing.JTextField(); + + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.name")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.placefloor")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setText(AppLocal.getIntString("label.placepositionx")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText("Across"); + jLabel5.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText("Down"); + jLabel3.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel7.setBackground(new java.awt.Color(255, 255, 255)); + jLabel7.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel7.setForeground(new java.awt.Color(102, 102, 102)); + jLabel7.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jLabel7.setText(bundle.getString("message.places")); // NOI18N + jLabel7.setVerticalAlignment(javax.swing.SwingConstants.TOP); + jLabel7.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(153, 153, 153))); + jLabel7.setMinimumSize(new java.awt.Dimension(50, 40)); + jLabel7.setOpaque(true); + jLabel7.setPreferredSize(new java.awt.Dimension(489, 40)); + + jLabel8.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel8.setText(AppLocal.getIntString("label.seats")); // NOI18N + jLabel8.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLabel9.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel9.setText(AppLocal.getIntString("label.btnwidth")); // NOI18N + jLabel9.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLabel11.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel11.setText(AppLocal.getIntString("label.placepositiony")); // NOI18N + jLabel11.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLabel10.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel10.setText(AppLocal.getIntString("label.btnheight")); // NOI18N + jLabel10.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(0, 30)); + + m_jFloor.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jFloor.setPreferredSize(new java.awt.Dimension(0, 30)); + + m_jSeats.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSeats.setPreferredSize(new java.awt.Dimension(50, 30)); + + m_jWidth.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jWidth.setPreferredSize(new java.awt.Dimension(50, 30)); + + m_jHeight.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jHeight.setPreferredSize(new java.awt.Dimension(50, 30)); + + m_jX.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jX.setPreferredSize(new java.awt.Dimension(50, 30)); + + m_jY.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jY.setPreferredSize(new java.awt.Dimension(50, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(14, 14, 14) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jFloor, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel11, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jHeight, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jY, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(m_jX, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(12, 12, 12) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, 384, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jSeats, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jWidth, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jFloor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jSeats, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jWidth, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jHeight, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jX, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jY, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(layout.createSequentialGroup() + .addGap(52, 52, 52) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, 96, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(180, Short.MAX_VALUE)) + ); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel10; + private javax.swing.JLabel jLabel11; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JLabel jLabel9; + private javax.swing.JComboBox m_jFloor; + private javax.swing.JTextField m_jHeight; + private javax.swing.JTextField m_jName; + private javax.swing.JTextField m_jSeats; + private javax.swing.JTextField m_jWidth; + private javax.swing.JTextField m_jX; + private javax.swing.JTextField m_jY; + // End of variables declaration//GEN-END:variables + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/panels/AuxiliarFilter.form b/src/main/java/com/unicenta/pos/panels/AuxiliarFilter.form new file mode 100644 index 0000000..c7ddeae --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/AuxiliarFilter.form @@ -0,0 +1,208 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.6" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[750, 130]"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleName" type="java.lang.String" value="By product"/> + </AccessibilityProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel6" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jReference1" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="m_jSearch" min="-2" pref="260" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="search" alignment="0" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Component id="Enter1" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="22" max="-2" attributes="0"/> + <Component id="jLabel7" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jBarcode1" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="Enter2" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" alignment="0" groupAlignment="3" attributes="0"> + <Component id="m_jBarcode1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel7" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="Enter2" min="-2" max="-2" attributes="0"/> + <Component id="Enter1" alignment="0" min="-2" max="-2" attributes="0"/> + <Group type="103" alignment="0" groupAlignment="3" attributes="0"> + <Component id="jLabel6" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jReference1" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="search" min="-2" max="-2" attributes="0"/> + <Component id="m_jSearch" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodref" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 20]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 20]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jReference1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jReference1ActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="Enter1"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/products24.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Enter Product ID"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="Enter1ActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel7"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodbarcode" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jBarcode1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jBarcode1ActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="Enter2"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/barcode.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Get Barcode"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="Enter2ActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JTextField" name="m_jSearch"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor"> + <Color id="Default Cursor"/> + </Property> + <Property name="focusable" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 30]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jSearchActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="search"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/search24.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Search Products"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="searchActionPerformed"/> + </Events> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/panels/AuxiliarFilter.java b/src/main/java/com/unicenta/pos/panels/AuxiliarFilter.java new file mode 100644 index 0000000..3579e73 --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/AuxiliarFilter.java @@ -0,0 +1,362 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.panels; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.loader.SerializerWrite; +import com.unicenta.data.loader.SerializerWriteString; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.reports.ReportEditorCreator; +import com.unicenta.pos.ticket.ProductInfoExt; +import java.awt.Component; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.EventListener; +import javax.swing.event.EventListenerList; + +/** + * + * @author jaroslawwozniak + * @author adrianromero + */ +public class AuxiliarFilter extends javax.swing.JPanel implements ReportEditorCreator { + + private ProductInfoExt product; + private DataLogicSales m_dlSales; + + /** + * + */ + protected EventListenerList listeners = new EventListenerList(); + + /** Creates new form AuxiliarFilter */ + public AuxiliarFilter() { + initComponents(); + } + + /** + * + * @param app + */ + @Override + public void init(AppView app) { + m_dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + product = null; + m_jSearch.setText(null); + m_jBarcode1.setText(null); + m_jReference1.setText(null); + } + + /** + * + * @return + */ + @Override + public SerializerWrite getSerializerWrite() { + return SerializerWriteString.INSTANCE; + } + + /** + * + * @param l + */ + public void addActionListener(ActionListener l){ + listeners.add(ActionListener.class, l); + } + + /** + * + * @param l + */ + public void removeActionListener(ActionListener l) { + listeners.remove(ActionListener.class, l); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + return product == null ? null : product.getID(); + } + + /** + * + * @return + */ + public ProductInfoExt getProductInfoExt() { + return product; + } + + private void assignProduct(ProductInfoExt prod) { + + product = prod; + if (product == null) { + m_jSearch.setText(null); + m_jBarcode1.setText(null); + m_jReference1.setText(null); + } else { + m_jSearch.setText(product.getReference() + " - " + product.getName()); + m_jBarcode1.setText(product.getCode()); + m_jReference1.setText(product.getReference()); + } + + fireSelectedProduct(); + } + + /** + * + */ + protected void fireSelectedProduct() { + EventListener[] l = listeners.getListeners(ActionListener.class); + ActionEvent e = null; + for (int i = 0; i < l.length; i++) { + if (e == null) { + e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "SELECTED"); + } + ((ActionListener) l[i]).actionPerformed(e); + } + } + + private void assignProductByCode() { + try { + ProductInfoExt prod = m_dlSales.getProductInfoByCode(m_jBarcode1.getText()); + if (prod == null) { + Toolkit.getDefaultToolkit().beep(); + } + assignProduct(prod); + } catch (BasicException eData) { + MessageInf msg = new MessageInf(eData); + msg.show(this); + assignProduct(null); + } + } + + private void assignProductByReference() { + try { + ProductInfoExt prod = m_dlSales.getProductInfoByReference(m_jReference1.getText()); + if (prod == null) { + Toolkit.getDefaultToolkit().beep(); + } + assignProduct(prod); + } catch (BasicException eData) { + MessageInf msg = new MessageInf(eData); + msg.show(this); + assignProduct(null); + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel6 = new javax.swing.JLabel(); + m_jReference1 = new javax.swing.JTextField(); + Enter1 = new javax.swing.JButton(); + jLabel7 = new javax.swing.JLabel(); + m_jBarcode1 = new javax.swing.JTextField(); + Enter2 = new javax.swing.JButton(); + m_jSearch = new javax.swing.JTextField(); + search = new javax.swing.JButton(); + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setPreferredSize(new java.awt.Dimension(750, 130)); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setText(AppLocal.getIntString("label.prodref")); // NOI18N + jLabel6.setMaximumSize(new java.awt.Dimension(50, 20)); + jLabel6.setMinimumSize(new java.awt.Dimension(50, 20)); + jLabel6.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jReference1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jReference1.setPreferredSize(new java.awt.Dimension(150, 30)); + m_jReference1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jReference1ActionPerformed(evt); + } + }); + + Enter1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/products24.png"))); // NOI18N + Enter1.setToolTipText("Enter Product ID"); + Enter1.setPreferredSize(new java.awt.Dimension(80, 45)); + Enter1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + Enter1ActionPerformed(evt); + } + }); + + jLabel7.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel7.setText(AppLocal.getIntString("label.prodbarcode")); // NOI18N + jLabel7.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jBarcode1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jBarcode1.setPreferredSize(new java.awt.Dimension(150, 30)); + m_jBarcode1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jBarcode1ActionPerformed(evt); + } + }); + + Enter2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/barcode.png"))); // NOI18N + Enter2.setToolTipText("Get Barcode"); + Enter2.setPreferredSize(new java.awt.Dimension(80, 45)); + Enter2.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + Enter2ActionPerformed(evt); + } + }); + + m_jSearch.setEditable(false); + m_jSearch.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSearch.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + m_jSearch.setFocusable(false); + m_jSearch.setPreferredSize(new java.awt.Dimension(70, 30)); + m_jSearch.setRequestFocusEnabled(false); + m_jSearch.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jSearchActionPerformed(evt); + } + }); + + search.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/search24.png"))); // NOI18N + search.setToolTipText("Search Products"); + search.setPreferredSize(new java.awt.Dimension(80, 45)); + search.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + searchActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jReference1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(m_jSearch, javax.swing.GroupLayout.PREFERRED_SIZE, 260, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(search, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createSequentialGroup() + .addComponent(Enter1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(22, 22, 22) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jBarcode1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(Enter2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jBarcode1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(Enter2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(Enter1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jReference1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(search, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addContainerGap()) + ); + + getAccessibleContext().setAccessibleName("By product"); + }// </editor-fold>//GEN-END:initComponents + + private void m_jReference1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jReference1ActionPerformed + this.assignProductByReference(); + }//GEN-LAST:event_m_jReference1ActionPerformed + + private void searchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchActionPerformed + + assignProduct(JProductFinder.showMessage(this, m_dlSales, JProductFinder.PRODUCT_NORMAL)); + +}//GEN-LAST:event_searchActionPerformed + + private void Enter2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_Enter2ActionPerformed + this.assignProductByCode(); + }//GEN-LAST:event_Enter2ActionPerformed + + private void Enter1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_Enter1ActionPerformed + this.assignProductByReference(); + }//GEN-LAST:event_Enter1ActionPerformed + + private void m_jBarcode1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jBarcode1ActionPerformed + this.assignProductByCode(); + }//GEN-LAST:event_m_jBarcode1ActionPerformed + + private void m_jSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jSearchActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_m_jSearchActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton Enter1; + private javax.swing.JButton Enter2; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JTextField m_jBarcode1; + private javax.swing.JTextField m_jReference1; + private javax.swing.JTextField m_jSearch; + private javax.swing.JButton search; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/panels/BundleFilter.form b/src/main/java/com/unicenta/pos/panels/BundleFilter.form new file mode 100644 index 0000000..e40e598 --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/BundleFilter.form @@ -0,0 +1,194 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.6" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleName" type="java.lang.String" value="By product"/> + </AccessibilityProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel6" min="-2" max="-2" attributes="1"/> + <Component id="jLabel7" alignment="0" min="-2" max="-2" attributes="1"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="m_jBarcode1" min="-2" max="-2" attributes="1"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="Enter2" min="-2" max="-2" attributes="1"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="m_jReference1" min="-2" max="-2" attributes="1"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="Enter1" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jSearch" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="search" min="-2" max="-2" attributes="1"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="2" attributes="0"> + <Component id="jLabel6" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="m_jReference1" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="Enter1" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="m_jSearch" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="search" alignment="2" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="2" attributes="0"> + <Component id="jLabel7" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="m_jBarcode1" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="Enter2" alignment="2" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodref" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 20]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 20]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jReference1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jReference1ActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="Enter1"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/products24.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Enter Product ID"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="Enter1ActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel7"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodbarcode" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jBarcode1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jBarcode1ActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="Enter2"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/barcode.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Get Barcode"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="Enter2ActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JTextField" name="m_jSearch"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor"> + <Color id="Default Cursor"/> + </Property> + <Property name="focusable" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="search"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/search24.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Search Products"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="searchActionPerformed"/> + </Events> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/panels/BundleFilter.java b/src/main/java/com/unicenta/pos/panels/BundleFilter.java new file mode 100644 index 0000000..677e1fa --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/BundleFilter.java @@ -0,0 +1,310 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.panels; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.loader.SerializerWrite; +import com.unicenta.data.loader.SerializerWriteString; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.reports.ReportEditorCreator; +import com.unicenta.pos.ticket.ProductInfoExt; +import java.awt.Component; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.EventListener; +import javax.swing.event.EventListenerList; + +/** + * + * @author Jack + */ +public class BundleFilter extends javax.swing.JPanel implements ReportEditorCreator { + + private ProductInfoExt product; + private DataLogicSales m_dlSales; + + protected EventListenerList listeners = new EventListenerList(); + + /** Creates new form BundleFilter */ + public BundleFilter() { + initComponents(); + } + + @Override + public void init(AppView app) { + m_dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + } + + @Override + public void activate() throws BasicException { + product = null; + m_jSearch.setText(null); + m_jBarcode1.setText(null); + m_jReference1.setText(null); + } + + @Override + public SerializerWrite getSerializerWrite() { + return SerializerWriteString.INSTANCE; + } + + public void addActionListener(ActionListener l){ + listeners.add(ActionListener.class, l); + } + + public void removeActionListener(ActionListener l) { + listeners.remove(ActionListener.class, l); + } + + @Override + public Component getComponent() { + return this; + } + + @Override + public Object createValue() throws BasicException { + return product == null ? null : product.getID(); + } + + public ProductInfoExt getProductInfoExt() { + return product; + } + + private void assignProduct(ProductInfoExt prod) { + + product = prod; + if (product == null) { + m_jSearch.setText(null); + m_jBarcode1.setText(null); + m_jReference1.setText(null); + } else { + m_jSearch.setText(product.getReference() + " - " + product.getName()); + m_jBarcode1.setText(product.getCode()); + m_jReference1.setText(product.getReference()); + } + + fireSelectedProduct(); + } + + + + protected void fireSelectedProduct() { + EventListener[] l = listeners.getListeners(ActionListener.class); + ActionEvent e = null; + for (int i = 0; i < l.length; i++) { + if (e == null) { + e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "SELECTED"); + } + ((ActionListener) l[i]).actionPerformed(e); + } + } + + private void assignProductByCode() { + try { + ProductInfoExt prod = m_dlSales.getProductInfoByCode(m_jBarcode1.getText()); + if (prod == null) { + Toolkit.getDefaultToolkit().beep(); + } + assignProduct(prod); + } catch (BasicException eData) { + MessageInf msg = new MessageInf(eData); + msg.show(this); + assignProduct(null); + } + } + + private void assignProductByReference() { + try { + ProductInfoExt prod = m_dlSales.getProductInfoByReference(m_jReference1.getText()); + if (prod == null) { + Toolkit.getDefaultToolkit().beep(); + } + assignProduct(prod); + } catch (BasicException eData) { + MessageInf msg = new MessageInf(eData); + msg.show(this); + assignProduct(null); + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel6 = new javax.swing.JLabel(); + m_jReference1 = new javax.swing.JTextField(); + Enter1 = new javax.swing.JButton(); + jLabel7 = new javax.swing.JLabel(); + m_jBarcode1 = new javax.swing.JTextField(); + Enter2 = new javax.swing.JButton(); + m_jSearch = new javax.swing.JTextField(); + search = new javax.swing.JButton(); + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setText(AppLocal.getIntString("label.prodref")); // NOI18N + jLabel6.setMaximumSize(new java.awt.Dimension(50, 20)); + jLabel6.setMinimumSize(new java.awt.Dimension(50, 20)); + jLabel6.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jReference1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jReference1.setPreferredSize(new java.awt.Dimension(150, 30)); + m_jReference1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jReference1ActionPerformed(evt); + } + }); + + Enter1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/products24.png"))); // NOI18N + Enter1.setToolTipText("Enter Product ID"); + Enter1.setPreferredSize(new java.awt.Dimension(80, 45)); + Enter1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + Enter1ActionPerformed(evt); + } + }); + + jLabel7.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel7.setText(AppLocal.getIntString("label.prodbarcode")); // NOI18N + jLabel7.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jBarcode1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jBarcode1.setPreferredSize(new java.awt.Dimension(150, 30)); + m_jBarcode1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jBarcode1ActionPerformed(evt); + } + }); + + Enter2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/barcode.png"))); // NOI18N + Enter2.setToolTipText("Get Barcode"); + Enter2.setPreferredSize(new java.awt.Dimension(80, 45)); + Enter2.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + Enter2ActionPerformed(evt); + } + }); + + m_jSearch.setEditable(false); + m_jSearch.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSearch.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + m_jSearch.setFocusable(false); + m_jSearch.setPreferredSize(new java.awt.Dimension(200, 30)); + m_jSearch.setRequestFocusEnabled(false); + + search.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/search24.png"))); // NOI18N + search.setToolTipText("Search Products"); + search.setPreferredSize(new java.awt.Dimension(80, 45)); + search.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + searchActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addComponent(m_jBarcode1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(Enter2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addComponent(m_jReference1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(Enter1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(search, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jReference1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(Enter1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(search, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jBarcode1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(Enter2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + + getAccessibleContext().setAccessibleName("By product"); + }// </editor-fold>//GEN-END:initComponents + + private void m_jReference1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jReference1ActionPerformed + this.assignProductByReference(); + }//GEN-LAST:event_m_jReference1ActionPerformed + + private void searchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchActionPerformed + + assignProduct(JProductFinder.showMessage(this, m_dlSales, JProductFinder.PRODUCT_NORMAL)); + +}//GEN-LAST:event_searchActionPerformed + + private void Enter2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_Enter2ActionPerformed + this.assignProductByCode(); + }//GEN-LAST:event_Enter2ActionPerformed + + private void Enter1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_Enter1ActionPerformed + this.assignProductByReference(); + }//GEN-LAST:event_Enter1ActionPerformed + + private void m_jBarcode1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jBarcode1ActionPerformed + this.assignProductByCode(); + }//GEN-LAST:event_m_jBarcode1ActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton Enter1; + private javax.swing.JButton Enter2; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JTextField m_jBarcode1; + private javax.swing.JTextField m_jReference1; + private javax.swing.JTextField m_jSearch; + private javax.swing.JButton search; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/panels/ComboItemLocal.java b/src/main/java/com/unicenta/pos/panels/ComboItemLocal.java new file mode 100644 index 0000000..593745d --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/ComboItemLocal.java @@ -0,0 +1,73 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.panels; + +import com.unicenta.data.loader.IKeyed; +import com.unicenta.pos.forms.AppLocal; + +/** + * + * @author adrianromero + * Created on February 12, 2007, 10:49 PM + * + */ +public class ComboItemLocal implements IKeyed { + + /** + * + */ + protected Integer m_iKey; + + /** + * + */ + protected String m_sKeyValue; + + /** + * + * @param iKey + * @param sKeyValue + */ + public ComboItemLocal(Integer iKey, String sKeyValue) { + m_iKey = iKey; + m_sKeyValue = sKeyValue; + } + + /** + * + * @return + */ + @Override + public Object getKey() { + return m_iKey; + } + + /** + * + * @return + */ + public Object getValue() { + return m_sKeyValue; + } + @Override + public String toString() { + return AppLocal.getIntString(m_sKeyValue); + } +} diff --git a/src/main/java/com/unicenta/pos/panels/EnumerationIter.java b/src/main/java/com/unicenta/pos/panels/EnumerationIter.java new file mode 100644 index 0000000..067a589 --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/EnumerationIter.java @@ -0,0 +1,49 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-130 + +package com.unicenta.pos.panels; + +import java.util.Enumeration; +import java.util.Iterator; + +/** + * + * @author adrianromero + */ +public class EnumerationIter implements Enumeration { + + private Iterator i; + + /** + * + * @param i + */ + public EnumerationIter(Iterator i) { + this.i = i; + } + @Override + public boolean hasMoreElements() { + return i.hasNext(); + } + @Override + public Object nextElement() { + return i.next(); + } +} diff --git a/src/main/java/com/unicenta/pos/panels/JPanelCloseMoney.form b/src/main/java/com/unicenta/pos/panels/JPanelCloseMoney.form new file mode 100644 index 0000000..c10bdba --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/JPanelCloseMoney.form @@ -0,0 +1,613 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,54,0,0,4,35"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout"> + <Property name="useNullLayout" type="boolean" value="false"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel11"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.sequence" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[125, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="10" y="11" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="m_jSequence"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="145" y="12" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.StartDate" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[125, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="10" y="50" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="m_jMinDate"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="145" y="50" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.EndDate" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[125, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="355" y="50" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="m_jMaxDate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="515" y="50" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.sales" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="355" y="137" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="m_jCash"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="515" y="306" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.cash" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="355" y="305" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="m_jCount"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="515" y="96" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="m_jLinesRemoved"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="513" y="360" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.Tickets" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="355" y="95" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JSeparator" name="jSeparator1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="353" y="347" width="312" height="10"/> + </Constraint> + </Constraints> + </Component> + <Container class="javax.swing.JScrollPane" name="m_jScrollTableTicket"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="horizontalScrollBarPolicy" type="int" value="31"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[350, 140]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[325, 150]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="JPanelCloseMoney_m_jScrollTableTicket"/> + </AuxValues> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="10" y="95" width="-1" height="-1"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JTable" name="m_jTicketTable"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor"> + <Table columnCount="0" rowCount="0"/> + </Property> + <Property name="focusable" type="boolean" value="false"/> + <Property name="intercellSpacing" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 1]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + <Property name="showVerticalLines" type="boolean" value="false"/> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JLabel" name="jLabel9"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.linevoids" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="353" y="359" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="m_jNoCashSales"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="513" y="402" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.nocashsales" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="353" y="401" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="m_jSalesTotal"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="515" y="264" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="jLabel7"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.total" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="355" y="263" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="jLabel12"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.taxes" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="355" y="221" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="m_jSalesTaxes"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="515" y="222" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Container class="javax.swing.JScrollPane" name="m_jScrollSales"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="horizontalScrollBarPolicy" type="int" value="31"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[325, 150]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="10" y="250" width="-1" height="-1"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JTable" name="m_jsalestable"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="focusable" type="boolean" value="false"/> + <Property name="intercellSpacing" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 1]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + <Property name="showVerticalLines" type="boolean" value="false"/> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JTextField" name="m_jSales"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="515" y="138" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="m_jSalesSubtotal"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="515" y="180" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.totalnet" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="355" y="179" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JButton" name="m_jCloseCash"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/calculator.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.closecash" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.btn.closecash" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="iconTextGap" type="int" value="2"/> + <Property name="inheritsPopupMenu" type="boolean" value="true"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[85, 33]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[85, 33]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jCloseCashActionPerformed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="170" y="450" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JButton" name="m_jPrintCash"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/printer.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.printcash" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.btn.partialcash" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="iconTextGap" type="int" value="2"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[85, 33]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[85, 33]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jPrintCashActionPerformed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="10" y="450" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JComboBox" name="jCBCloseCash"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.closecashactions" replaceFormat="AppLocal.getIntString("tooltip.closecashactions")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jCBCloseCashActionPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/> + </AuxValues> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="510" y="450" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/panels/JPanelCloseMoney.java b/src/main/java/com/unicenta/pos/panels/JPanelCloseMoney.java new file mode 100644 index 0000000..6c5102a --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/JPanelCloseMoney.java @@ -0,0 +1,797 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.panels; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.gui.TableRendererBasic; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.loader.SerializerWriteBasic; +import com.unicenta.data.loader.Session; +import com.unicenta.data.loader.StaticSentence; +import com.unicenta.format.Formats; +import com.unicenta.plugins.Application; +import com.unicenta.pos.forms.*; +import com.unicenta.pos.printer.TicketParser; +import com.unicenta.pos.printer.TicketPrinterException; +import com.unicenta.pos.scripting.ScriptEngine; +import com.unicenta.pos.scripting.ScriptException; +import com.unicenta.pos.scripting.ScriptFactory; +import lombok.extern.slf4j.Slf4j; + +import java.awt.*; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.UUID; +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableColumnModel; + +/** + * + * @author adrianromero + */ +@Slf4j +public class JPanelCloseMoney extends JPanel implements JPanelView, BeanFactoryApp { + + private AppView m_App; + private DataLogicSystem m_dlSystem; + + private PaymentsModel m_PaymentsToClose = null; + + private TicketParser m_TTP; + private final DateFormat df= new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); + + private Session s; + private Connection con; + private Statement stmt; + private Integer result; + private Integer dresult; + private String SQL; + private ResultSet rs; + + private AppUser m_User; + + private final ComboBoxValModel m_ReasonModel; + + /** Creates new form JPanelCloseMoney */ + public JPanelCloseMoney() { + initComponents(); + + m_ReasonModel = new ComboBoxValModel(); + m_ReasonModel.add(AppLocal.getIntString("cboption.preview")); + m_ReasonModel.add(AppLocal.getIntString("cboption.reprint")); + jCBCloseCash.setModel(m_ReasonModel); + } + + /** + * + * @param app + * @throws BeanFactoryException + */ + @Override + public void init(AppView app) throws BeanFactoryException { + + m_App = app; + m_dlSystem = (DataLogicSystem) m_App.getBean("com.unicenta.pos.forms.DataLogicSystem"); + m_TTP = new TicketParser(m_App.getDeviceTicket(), m_dlSystem); + + m_jTicketTable.setDefaultRenderer(Object.class, new TableRendererBasic( + new Formats[] {new FormatsPayment(), Formats.CURRENCY})); + m_jTicketTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); + m_jScrollTableTicket.getVerticalScrollBar().setPreferredSize(new Dimension(25,25)); + m_jTicketTable.getTableHeader().setReorderingAllowed(false); + m_jTicketTable.setRowHeight(25); + m_jTicketTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + m_jsalestable.setDefaultRenderer(Object.class, new TableRendererBasic( + new Formats[] {Formats.STRING, Formats.CURRENCY, Formats.CURRENCY, Formats.CURRENCY})); + m_jsalestable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); + m_jScrollSales.getVerticalScrollBar().setPreferredSize(new Dimension(25,25)); + m_jsalestable.getTableHeader().setReorderingAllowed(false); + m_jsalestable.setRowHeight(25); + m_jsalestable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + } + + /** + * + * @return + */ + @Override + public Object getBean() { + return this; + } + + /** + * + * @return + */ + @Override + public JComponent getComponent() { + return this; + } + /** + * @return + */ + + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.CloseTPV"); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + loadData(); + } + + /** + * + * @return + */ + @Override + public boolean deactivate() { + + return true; + } + + private void loadData() throws BasicException { + + // Reset + m_jSequence.setText(null); + m_jMinDate.setText(null); + m_jMaxDate.setText(null); + m_jPrintCash.setEnabled(false); + m_jCloseCash.setEnabled(false); + + + m_jCount.setText(null); + m_jCash.setText(null); + + m_jSales.setText(null); + m_jSalesSubtotal.setText(null); + m_jSalesTaxes.setText(null); + m_jSalesTotal.setText(null); + + m_jTicketTable.setModel(new DefaultTableModel()); + m_jsalestable.setModel(new DefaultTableModel()); + + // LoadData + m_PaymentsToClose = PaymentsModel.loadInstance(m_App); + + // Populate Data + m_jSequence.setText(m_PaymentsToClose.printSequence()); + m_jMinDate.setText(m_PaymentsToClose.printDateStart()); + m_jMaxDate.setText(m_PaymentsToClose.printDateEnd()); + + if (m_PaymentsToClose.getPayments() != 0 + || m_PaymentsToClose.getSales() != 0) { + + m_jPrintCash.setEnabled(true); + m_jCloseCash.setEnabled(true); + + + m_jCount.setText(m_PaymentsToClose.printPayments()); + m_jCash.setText(m_PaymentsToClose.printPaymentsTotal()); + + m_jSales.setText(m_PaymentsToClose.printSales()); + m_jSalesSubtotal.setText(m_PaymentsToClose.printSalesBase()); + m_jSalesTaxes.setText(m_PaymentsToClose.printSalesTaxes()); + m_jSalesTotal.setText(m_PaymentsToClose.printSalesTotal()); + } + + m_jTicketTable.setModel(m_PaymentsToClose.getPaymentsModel()); + + TableColumnModel jColumns = m_jTicketTable.getColumnModel(); + jColumns.getColumn(0).setPreferredWidth(200); + jColumns.getColumn(0).setResizable(false); + jColumns.getColumn(1).setPreferredWidth(100); + jColumns.getColumn(1).setResizable(false); + + m_jsalestable.setModel(m_PaymentsToClose.getSalesModel()); + + jColumns = m_jsalestable.getColumnModel(); + jColumns.getColumn(0).setPreferredWidth(100); + jColumns.getColumn(0).setResizable(false); + jColumns.getColumn(1).setPreferredWidth(100); + jColumns.getColumn(1).setResizable(false); + jColumns.getColumn(2).setPreferredWidth(100); + jColumns.getColumn(2).setResizable(false); + +// read number of no cash drawer activations + try{ + result=0; + s=m_App.getSession(); + con=s.getConnection(); + String sdbmanager = m_dlSystem.getDBVersion(); + + if ("PostgreSQL".equals(sdbmanager) || "SQLite".equals(sdbmanager)) { + SQL = "SELECT * " + + "FROM draweropened " + + "WHERE TICKETID = 'No Sale' AND OPENDATE > " + "'" + m_PaymentsToClose.printDateStart() + "'"; + } else { + SQL = "SELECT * " + + "FROM draweropened " + + "WHERE TICKETID = 'No Sale' AND OPENDATE > {fn TIMESTAMP('" + m_PaymentsToClose.getDateStartDerby() + "')}"; + } + + stmt = (Statement) con.createStatement(); + rs = stmt.executeQuery(SQL); + while (rs.next()){ + result ++; + } + rs=null; + +// Get Ticket DELETES & Line Voids + dresult=0; + if ("PostgreSQL".equals(sdbmanager) || "SQLite".equals(sdbmanager)) { + SQL = "SELECT * " + + "FROM lineremoved " + + "WHERE REMOVEDDATE > " + "'" + m_PaymentsToClose.printDateStart() + "'"; + } else { + SQL = "SELECT * " + + "FROM lineremoved " + + "WHERE REMOVEDDATE > {fn TIMESTAMP('" + m_PaymentsToClose.getDateStartDerby() + "')}"; + } + log.debug("close-cash sql -> {}",SQL); + + stmt = (Statement) con.createStatement(); + rs = stmt.executeQuery(SQL); + while (rs.next()){ + dresult ++; + } + rs=null; + con=null; + s=null; + } + catch (SQLException e){ + log.error("Got a problem here! Something to with dresult "); + log.error(e.getMessage()); + } + + m_jLinesRemoved.setText(dresult.toString()); + m_jNoCashSales.setText(result.toString()); + } + + private void CloseCash() { + + int res = JOptionPane.showConfirmDialog(this, + AppLocal.getIntString("message.wannaclosecash"), + AppLocal.getIntString("message.title"), + JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); + + if (res == JOptionPane.YES_OPTION) { + + Date dNow = new Date(); + + try { + + if (m_App.getActiveCashDateEnd() == null) { + new StaticSentence(m_App.getSession() + , "UPDATE closedcash SET DATEEND = ?, NOSALES = ? WHERE HOST = ? AND MONEY = ?" + , new SerializerWriteBasic(new Datas[] { + Datas.TIMESTAMP, + Datas.INT, + Datas.STRING, + Datas.STRING})) + .exec(new Object[] {dNow, result, + m_App.getProperties().getHost(), + m_App.getActiveCashIndex()}); + } + } catch (BasicException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, + AppLocal.getIntString("message.cannotclosecash"), e); + msg.show(this); + } + + try { + // Create NEW CloshCash Sequence + m_App.setActiveCash(UUID.randomUUID().toString(), + m_App.getActiveCashSequence() + 1, dNow, null); + + // Create CURRENT CloseCash Sequence + m_dlSystem.execInsertCash( + new Object[] {m_App.getActiveCashIndex(), + m_App.getProperties().getHost(), + m_App.getActiveCashSequence(), + m_App.getActiveCashDateStart(), + m_App.getActiveCashDateEnd(),0}); + + m_dlSystem.execDrawerOpened( + new Object[] {m_App.getAppUserView().getUser().getName(),"Close Cash"}); + + // Set ENDDATE CloseCash Date + m_PaymentsToClose.setDateEnd(dNow); + + // print report + printPayments("Printer.CloseCash"); + + // Close Cash Message + JOptionPane.showMessageDialog(this, + AppLocal.getIntString("message.closecashok"), + AppLocal.getIntString("message.title"), + JOptionPane.INFORMATION_MESSAGE); + } catch (BasicException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, + AppLocal.getIntString("message.cannotclosecash"), e); + msg.show(this); + } + + try { + loadData(); + } catch (BasicException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, + AppLocal.getIntString("label.noticketstoclose"), e); + msg.show(this); + } + } + } + + private void printPayments(String report) { + + String sresource = m_dlSystem.getResourceAsXML(report); + if (sresource == null) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.cannotprintticket")); + msg.show(this); + } else { + try { + ScriptEngine script = ScriptFactory.getScriptEngine(ScriptFactory.VELOCITY); + script.put("payments", m_PaymentsToClose); + script.put("nosales",result.toString()); + m_TTP.printTicket(script.eval(sresource).toString()); + } catch (ScriptException | TicketPrinterException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.cannotprintticket"), e); + msg.show(this); + } + } + } + + private class FormatsPayment extends Formats { + @Override + protected String formatValueInt(Object value) { + return AppLocal.getIntString("transpayment." + (String) value); + } + @Override + protected Object parseValueInt(String value) throws ParseException { + return value; + } + @Override + public int getAlignment() { + return javax.swing.SwingConstants.LEFT; + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jLabel11 = new javax.swing.JLabel(); + m_jSequence = new javax.swing.JTextField(); + jLabel2 = new javax.swing.JLabel(); + m_jMinDate = new javax.swing.JTextField(); + jLabel3 = new javax.swing.JLabel(); + m_jMaxDate = new javax.swing.JTextField(); + jLabel5 = new javax.swing.JLabel(); + m_jCash = new javax.swing.JTextField(); + jLabel4 = new javax.swing.JLabel(); + m_jCount = new javax.swing.JTextField(); + m_jLinesRemoved = new javax.swing.JTextField(); + jLabel1 = new javax.swing.JLabel(); + jSeparator1 = new javax.swing.JSeparator(); + m_jScrollTableTicket = new javax.swing.JScrollPane(); + m_jTicketTable = new javax.swing.JTable(); + jLabel9 = new javax.swing.JLabel(); + m_jNoCashSales = new javax.swing.JTextField(); + jLabel8 = new javax.swing.JLabel(); + m_jSalesTotal = new javax.swing.JTextField(); + jLabel7 = new javax.swing.JLabel(); + jLabel12 = new javax.swing.JLabel(); + m_jSalesTaxes = new javax.swing.JTextField(); + m_jScrollSales = new javax.swing.JScrollPane(); + m_jsalestable = new javax.swing.JTable(); + m_jSales = new javax.swing.JTextField(); + m_jSalesSubtotal = new javax.swing.JTextField(); + jLabel6 = new javax.swing.JLabel(); + m_jCloseCash = new javax.swing.JButton(); + m_jPrintCash = new javax.swing.JButton(); + jCBCloseCash = new javax.swing.JComboBox<>(); + + setLayout(new java.awt.BorderLayout()); + + jPanel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanel1.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout()); + + jLabel11.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel11.setText(AppLocal.getIntString("label.sequence")); // NOI18N + jLabel11.setPreferredSize(new java.awt.Dimension(125, 30)); + jPanel1.add(jLabel11, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 11, -1, -1)); + + m_jSequence.setEditable(false); + m_jSequence.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSequence.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jSequence.setPreferredSize(new java.awt.Dimension(150, 30)); + jPanel1.add(m_jSequence, new org.netbeans.lib.awtextra.AbsoluteConstraints(145, 12, -1, -1)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jLabel2.setText(AppLocal.getIntString("label.StartDate")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(125, 30)); + jPanel1.add(jLabel2, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 50, -1, -1)); + + m_jMinDate.setEditable(false); + m_jMinDate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jMinDate.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jMinDate.setPreferredSize(new java.awt.Dimension(150, 30)); + jPanel1.add(m_jMinDate, new org.netbeans.lib.awtextra.AbsoluteConstraints(145, 50, -1, -1)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jLabel3.setText(AppLocal.getIntString("label.EndDate")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(125, 30)); + jPanel1.add(jLabel3, new org.netbeans.lib.awtextra.AbsoluteConstraints(355, 50, -1, -1)); + + m_jMaxDate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jMaxDate.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jMaxDate.setEnabled(false); + m_jMaxDate.setPreferredSize(new java.awt.Dimension(150, 30)); + jPanel1.add(m_jMaxDate, new org.netbeans.lib.awtextra.AbsoluteConstraints(515, 50, -1, -1)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.sales")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(150, 30)); + jPanel1.add(jLabel5, new org.netbeans.lib.awtextra.AbsoluteConstraints(355, 137, -1, -1)); + + m_jCash.setEditable(false); + m_jCash.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCash.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jCash.setPreferredSize(new java.awt.Dimension(150, 30)); + jPanel1.add(m_jCash, new org.netbeans.lib.awtextra.AbsoluteConstraints(515, 306, -1, -1)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.cash")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(150, 30)); + jPanel1.add(jLabel4, new org.netbeans.lib.awtextra.AbsoluteConstraints(355, 305, -1, -1)); + + m_jCount.setEditable(false); + m_jCount.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCount.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jCount.setPreferredSize(new java.awt.Dimension(150, 30)); + jPanel1.add(m_jCount, new org.netbeans.lib.awtextra.AbsoluteConstraints(515, 96, -1, -1)); + + m_jLinesRemoved.setEditable(false); + m_jLinesRemoved.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jLinesRemoved.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jLinesRemoved.setPreferredSize(new java.awt.Dimension(150, 30)); + jPanel1.add(m_jLinesRemoved, new org.netbeans.lib.awtextra.AbsoluteConstraints(513, 360, -1, -1)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.Tickets")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(150, 30)); + jPanel1.add(jLabel1, new org.netbeans.lib.awtextra.AbsoluteConstraints(355, 95, -1, -1)); + jPanel1.add(jSeparator1, new org.netbeans.lib.awtextra.AbsoluteConstraints(353, 347, 312, 10)); + + m_jScrollTableTicket.setBorder(null); + m_jScrollTableTicket.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + m_jScrollTableTicket.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jScrollTableTicket.setMinimumSize(new java.awt.Dimension(350, 140)); + m_jScrollTableTicket.setPreferredSize(new java.awt.Dimension(325, 150)); + + m_jTicketTable.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jTicketTable.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + + }, + new String [] { + + } + )); + m_jTicketTable.setFocusable(false); + m_jTicketTable.setIntercellSpacing(new java.awt.Dimension(0, 1)); + m_jTicketTable.setRequestFocusEnabled(false); + m_jTicketTable.setShowVerticalLines(false); + m_jScrollTableTicket.setViewportView(m_jTicketTable); + + jPanel1.add(m_jScrollTableTicket, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 95, -1, -1)); + + jLabel9.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel9.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jLabel9.setText(bundle.getString("label.linevoids")); // NOI18N + jLabel9.setPreferredSize(new java.awt.Dimension(150, 30)); + jPanel1.add(jLabel9, new org.netbeans.lib.awtextra.AbsoluteConstraints(353, 359, -1, -1)); + + m_jNoCashSales.setEditable(false); + m_jNoCashSales.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jNoCashSales.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jNoCashSales.setPreferredSize(new java.awt.Dimension(150, 30)); + jPanel1.add(m_jNoCashSales, new org.netbeans.lib.awtextra.AbsoluteConstraints(513, 402, -1, -1)); + + jLabel8.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel8.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jLabel8.setText(bundle.getString("label.nocashsales")); // NOI18N + jLabel8.setPreferredSize(new java.awt.Dimension(150, 30)); + jPanel1.add(jLabel8, new org.netbeans.lib.awtextra.AbsoluteConstraints(353, 401, -1, -1)); + + m_jSalesTotal.setEditable(false); + m_jSalesTotal.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSalesTotal.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jSalesTotal.setPreferredSize(new java.awt.Dimension(150, 30)); + jPanel1.add(m_jSalesTotal, new org.netbeans.lib.awtextra.AbsoluteConstraints(515, 264, -1, -1)); + + jLabel7.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel7.setText(AppLocal.getIntString("label.total")); // NOI18N + jLabel7.setPreferredSize(new java.awt.Dimension(150, 30)); + jPanel1.add(jLabel7, new org.netbeans.lib.awtextra.AbsoluteConstraints(355, 263, -1, -1)); + + jLabel12.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel12.setText(AppLocal.getIntString("label.taxes")); // NOI18N + jLabel12.setPreferredSize(new java.awt.Dimension(150, 30)); + jPanel1.add(jLabel12, new org.netbeans.lib.awtextra.AbsoluteConstraints(355, 221, -1, -1)); + + m_jSalesTaxes.setEditable(false); + m_jSalesTaxes.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSalesTaxes.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jSalesTaxes.setPreferredSize(new java.awt.Dimension(150, 30)); + jPanel1.add(m_jSalesTaxes, new org.netbeans.lib.awtextra.AbsoluteConstraints(515, 222, -1, -1)); + + m_jScrollSales.setBorder(null); + m_jScrollSales.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + m_jScrollSales.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jScrollSales.setPreferredSize(new java.awt.Dimension(325, 150)); + + m_jsalestable.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jsalestable.setFocusable(false); + m_jsalestable.setIntercellSpacing(new java.awt.Dimension(0, 1)); + m_jsalestable.setRequestFocusEnabled(false); + m_jsalestable.setShowVerticalLines(false); + m_jScrollSales.setViewportView(m_jsalestable); + + jPanel1.add(m_jScrollSales, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 250, -1, -1)); + + m_jSales.setEditable(false); + m_jSales.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSales.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jSales.setPreferredSize(new java.awt.Dimension(150, 30)); + jPanel1.add(m_jSales, new org.netbeans.lib.awtextra.AbsoluteConstraints(515, 138, -1, -1)); + + m_jSalesSubtotal.setEditable(false); + m_jSalesSubtotal.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSalesSubtotal.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jSalesSubtotal.setPreferredSize(new java.awt.Dimension(150, 30)); + jPanel1.add(m_jSalesSubtotal, new org.netbeans.lib.awtextra.AbsoluteConstraints(515, 180, -1, -1)); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setText(AppLocal.getIntString("label.totalnet")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(150, 30)); + jPanel1.add(jLabel6, new org.netbeans.lib.awtextra.AbsoluteConstraints(355, 179, -1, -1)); + + m_jCloseCash.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jCloseCash.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/calculator.png"))); // NOI18N + m_jCloseCash.setText(AppLocal.getIntString("button.closecash")); // NOI18N + m_jCloseCash.setToolTipText(bundle.getString("tooltip.btn.closecash")); // NOI18N + m_jCloseCash.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + m_jCloseCash.setIconTextGap(2); + m_jCloseCash.setInheritsPopupMenu(true); + m_jCloseCash.setMaximumSize(new java.awt.Dimension(85, 33)); + m_jCloseCash.setMinimumSize(new java.awt.Dimension(85, 33)); + m_jCloseCash.setPreferredSize(new java.awt.Dimension(150, 45)); + m_jCloseCash.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jCloseCashActionPerformed(evt); + } + }); + jPanel1.add(m_jCloseCash, new org.netbeans.lib.awtextra.AbsoluteConstraints(170, 450, -1, -1)); + + m_jPrintCash.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jPrintCash.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/printer.png"))); // NOI18N + m_jPrintCash.setText(AppLocal.getIntString("button.printcash")); // NOI18N + m_jPrintCash.setToolTipText(bundle.getString("tooltip.btn.partialcash")); // NOI18N + m_jPrintCash.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + m_jPrintCash.setIconTextGap(2); + m_jPrintCash.setMaximumSize(new java.awt.Dimension(85, 33)); + m_jPrintCash.setMinimumSize(new java.awt.Dimension(85, 33)); + m_jPrintCash.setPreferredSize(new java.awt.Dimension(150, 45)); + m_jPrintCash.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jPrintCashActionPerformed(evt); + } + }); + jPanel1.add(m_jPrintCash, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 450, -1, -1)); + + jCBCloseCash.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jCBCloseCash.setToolTipText(AppLocal.getIntString("tooltip.closecashactions")); // NOI18N + jCBCloseCash.setPreferredSize(new java.awt.Dimension(150, 45)); + jCBCloseCash.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jCBCloseCashActionPerformed(evt); + } + }); + jPanel1.add(jCBCloseCash, new org.netbeans.lib.awtextra.AbsoluteConstraints(510, 450, -1, -1)); + + add(jPanel1, java.awt.BorderLayout.CENTER); + }// </editor-fold>//GEN-END:initComponents + + private void m_jCloseCashActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jCloseCashActionPerformed + + int res = JOptionPane.showConfirmDialog(this, + AppLocal.getIntString("message.wannaclosecash"), + AppLocal.getIntString("message.title"), + JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); + + if (res == JOptionPane.YES_OPTION) { + + try { + //Fire cash.closed event + ScriptEngine scriptEngine = ScriptFactory.getScriptEngine(ScriptFactory.BEANSHELL); + DataLogicSystem dlSystem = (DataLogicSystem) m_App.getBean("com.unicenta.pos.forms.DataLogicSystem"); + String script = dlSystem.getResourceAsXML("cash.close"); + scriptEngine.eval(script); + } + catch (Exception e) { + log.error("Error firing cash close event {}", e.getMessage()); + } + + Date dNow = new Date(); + + try { + + if (m_App.getActiveCashDateEnd() == null) { + StaticSentence staticSentence = new StaticSentence( + m_App.getSession(), + "UPDATE closedcash SET DATEEND = ?, NOSALES = ? WHERE HOST = ? AND MONEY = ?", + new SerializerWriteBasic(Datas.TIMESTAMP, Datas.INT, Datas.STRING, Datas.STRING)); + + staticSentence.exec(dNow, result, m_App.getProperties().getHost(), m_App.getActiveCashIndex()); + } + } catch (Exception e) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, AppLocal.getIntString("message.cannotclosecash"), e); + msg.show(this); + } + + try { + // Creamos una nueva caja + m_App.setActiveCash(UUID.randomUUID().toString(), + m_App.getActiveCashSequence() + 1, dNow, null); + + // creamos la caja activa + m_dlSystem.execInsertCash( + new Object[] {m_App.getActiveCashIndex(), + m_App.getProperties().getHost(), + m_App.getActiveCashSequence(), + m_App.getActiveCashDateStart(), + m_App.getActiveCashDateEnd(),0}); + + m_dlSystem.execDrawerOpened( + new Object[] {m_App.getAppUserView().getUser().getName(),"Close Cash"}); + + // ponemos la fecha de fin + m_PaymentsToClose.setDateEnd(dNow); + + // print report + printPayments("Printer.CloseCash"); + + // Mostramos el mensaje + JOptionPane.showMessageDialog(this, + AppLocal.getIntString("message.closecashok"), + AppLocal.getIntString("message.title"), + JOptionPane.INFORMATION_MESSAGE); + } catch (BasicException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, + AppLocal.getIntString("message.cannotclosecash"), e); + msg.show(this); + } + + if (m_App.getProperties().getProperty("payment.gateway").equals("PaymentSense")) { + new Application().paymentSenseEOD(getActiveWindow()); + } + + try { + loadData(); + } catch (BasicException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, + AppLocal.getIntString("label.noticketstoclose"), e); + msg.show(this); + } + + } + }//GEN-LAST:event_m_jCloseCashActionPerformed + + Window getActiveWindow() { + for (Window window : Window.getWindows()) { + if (window.isActive()) { + return window; + } + } + return null; + } + private void m_jPrintCashActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jPrintCashActionPerformed + + printPayments("Printer.PartialCash"); + + }//GEN-LAST:event_m_jPrintCashActionPerformed + + private void jCBCloseCashActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCBCloseCashActionPerformed + if(jCBCloseCash.getSelectedIndex() == 0){ + printPayments("Printer.CloseCash.Preview"); + } + if(jCBCloseCash.getSelectedIndex() == 1) { + m_App.getAppUserView().showTask("com.unicenta.pos.panels.JPanelCloseMoneyReprint"); + } + }//GEN-LAST:event_jCBCloseCashActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JComboBox<String> jCBCloseCash; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel11; + private javax.swing.JLabel jLabel12; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JLabel jLabel9; + private javax.swing.JPanel jPanel1; + private javax.swing.JSeparator jSeparator1; + private javax.swing.JTextField m_jCash; + private javax.swing.JButton m_jCloseCash; + private javax.swing.JTextField m_jCount; + private javax.swing.JTextField m_jLinesRemoved; + private javax.swing.JTextField m_jMaxDate; + private javax.swing.JTextField m_jMinDate; + private javax.swing.JTextField m_jNoCashSales; + private javax.swing.JButton m_jPrintCash; + private javax.swing.JTextField m_jSales; + private javax.swing.JTextField m_jSalesSubtotal; + private javax.swing.JTextField m_jSalesTaxes; + private javax.swing.JTextField m_jSalesTotal; + private javax.swing.JScrollPane m_jScrollSales; + private javax.swing.JScrollPane m_jScrollTableTicket; + private javax.swing.JTextField m_jSequence; + private javax.swing.JTable m_jTicketTable; + private javax.swing.JTable m_jsalestable; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/panels/JPanelCloseMoneyReprint.form b/src/main/java/com/unicenta/pos/panels/JPanelCloseMoneyReprint.form new file mode 100644 index 0000000..5146b7a --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/JPanelCloseMoneyReprint.form @@ -0,0 +1,597 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-12,0,0,2,-70"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jScrollSales" alignment="0" max="-2" attributes="0"/> + <Component id="m_jScrollTableTicket" alignment="0" max="-2" attributes="0"/> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" alignment="0" groupAlignment="0" max="-2" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + <Component id="m_jMaxDate" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel5" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jSales" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel1" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jCount" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel6" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jSalesSubtotal" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel12" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jSalesTaxes" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel7" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jSalesTotal" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="103" alignment="1" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel4" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jCash" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel9" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jLinesRemoved" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel8" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jNoCashSales" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jMinDate" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel11" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jSequence" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="webBtnFindSequence" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="141" max="-2" attributes="0"/> + <Component id="m_jPrint" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="2" attributes="0"> + <Component id="webBtnFindSequence" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="m_jSequence" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="jLabel11" alignment="2" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" alignment="0" groupAlignment="3" attributes="0"> + <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jMaxDate" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="103" alignment="0" groupAlignment="3" attributes="0"> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jMinDate" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCount" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jSales" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel6" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jSalesSubtotal" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel12" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jSalesTaxes" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jSalesTotal" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel7" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jCash" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel9" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jLinesRemoved" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel8" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="m_jNoCashSales" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" attributes="0"> + <Component id="m_jScrollTableTicket" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jScrollSales" min="-2" max="-2" attributes="1"/> + </Group> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="m_jPrint" min="-2" max="-2" attributes="0"/> + <EmptySpace pref="15" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel11"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.sequence" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[125, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jSequence"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.button.WebButton" name="webBtnFindSequence"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/search32.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value=""/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="webBtnFindSequenceActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.StartDate" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[125, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jMinDate"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.EndDate" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jMaxDate"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Container class="javax.swing.JScrollPane" name="m_jScrollTableTicket"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="horizontalScrollBarPolicy" type="int" value="31"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[350, 140]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[350, 150]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="JPanelCloseMoney_m_jScrollTableTicket"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JTable" name="m_jTicketTable"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor"> + <Table columnCount="0" rowCount="0"/> + </Property> + <Property name="focusable" type="boolean" value="false"/> + <Property name="intercellSpacing" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 1]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + <Property name="showVerticalLines" type="boolean" value="false"/> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JScrollPane" name="m_jScrollSales"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="horizontalScrollBarPolicy" type="int" value="31"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[350, 150]"/> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JTable" name="m_jsalestable"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="focusable" type="boolean" value="false"/> + <Property name="intercellSpacing" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 1]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + <Property name="showVerticalLines" type="boolean" value="false"/> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.Tickets" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jCount"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.sales" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jSales"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.totalnet" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jSalesSubtotal"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel12"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.taxes" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jSalesTaxes"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel7"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.total" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jSalesTotal"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.Money" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jCash"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel9"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.linevoids" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jLinesRemoved"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.nocashsales" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jNoCashSales"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="m_jPrint"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/printer.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.print" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.btn.closecash" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="iconTextGap" type="int" value="2"/> + <Property name="inheritsPopupMenu" type="boolean" value="true"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[85, 33]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[85, 33]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jPrintActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/panels/JPanelCloseMoneyReprint.java b/src/main/java/com/unicenta/pos/panels/JPanelCloseMoneyReprint.java new file mode 100644 index 0000000..70c55d9 --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/JPanelCloseMoneyReprint.java @@ -0,0 +1,690 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.panels; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.gui.TableRendererBasic; +import com.unicenta.data.loader.Session; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.*; +import com.unicenta.pos.printer.TicketParser; +import com.unicenta.pos.printer.TicketPrinterException; +import com.unicenta.pos.scripting.ScriptEngine; +import com.unicenta.pos.scripting.ScriptException; +import com.unicenta.pos.scripting.ScriptFactory; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableColumnModel; +import java.awt.*; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; + +/** + * + * @author JG uniCenta + */ +@Slf4j +public class JPanelCloseMoneyReprint extends JPanel implements JPanelView, BeanFactoryApp { + private AppView m_App; + private DataLogicSystem m_dlSystem; + + private PaymentsReprintModel m_PaymentsClosed = null; + + private TicketParser m_TTP; + private final DateFormat df= new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); + + private Session s; + private Connection con; + private Statement stmt; + private Integer result; + private Integer dresult; + private String SQL; + private ResultSet rs; + + private AppUser m_User; + + /** Creates new form JPanelCloseMoneyReprint */ + public JPanelCloseMoneyReprint() { + initComponents(); + } + + /** + * + * @param app + * @throws BeanFactoryException + */ + @Override + public void init(AppView app) throws BeanFactoryException { + + m_App = app; + m_dlSystem = (DataLogicSystem) m_App.getBean("com.unicenta.pos.forms.DataLogicSystem"); + m_TTP = new TicketParser(m_App.getDeviceTicket(), m_dlSystem); + + m_jTicketTable.setDefaultRenderer(Object.class, new TableRendererBasic( + new Formats[] {new FormatsPayment(), Formats.CURRENCY})); + m_jTicketTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); + m_jScrollTableTicket.getVerticalScrollBar().setPreferredSize(new Dimension(25,25)); + m_jTicketTable.getTableHeader().setReorderingAllowed(false); + m_jTicketTable.setRowHeight(25); + m_jTicketTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + m_jsalestable.setDefaultRenderer(Object.class, new TableRendererBasic( + new Formats[] {Formats.STRING, Formats.CURRENCY, Formats.CURRENCY, Formats.CURRENCY})); + m_jsalestable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); + m_jScrollSales.getVerticalScrollBar().setPreferredSize(new Dimension(25,25)); + m_jsalestable.getTableHeader().setReorderingAllowed(false); + m_jsalestable.setRowHeight(25); + m_jsalestable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + m_jPrint.setEnabled(false); + + } + + /** + * + * @return + */ + @Override + public Object getBean() { + return this; + } + + /** + * + * @return + */ + @Override + public JComponent getComponent() { + return this; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.CloseTPV"); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { +// loadData(); + } + + /** + * + * @return + */ + @Override + public boolean deactivate() { + return true; + } + + public String getInputSequence() { + return m_jSequence.getText(); + } + + private void loadData() throws BasicException { + + m_jSequence.setText(null); + m_jMinDate.setText(null); + m_jMaxDate.setText(null); + + m_jCount.setText(null); + m_jCash.setText(null); + + m_jSales.setText(null); + m_jSalesSubtotal.setText(null); + m_jSalesTaxes.setText(null); + m_jSalesTotal.setText(null); + + m_jTicketTable.setModel(new DefaultTableModel()); + m_jsalestable.setModel(new DefaultTableModel()); + + m_PaymentsClosed = PaymentsReprintModel.loadInstance(m_App); + + if (m_PaymentsClosed.getPayments() > 0 + || m_PaymentsClosed.getSales() > 0) { + + m_jSequence.setText(m_PaymentsClosed.printSequence()); + m_jMinDate.setText(m_PaymentsClosed.reformDateStart()); + m_jMaxDate.setText(m_PaymentsClosed.reformDateEnd()); + + m_jPrint.setEnabled(true); + + m_jCount.setText(m_PaymentsClosed.printPayments()); + m_jCash.setText(m_PaymentsClosed.printPaymentsTotal()); + + m_jSales.setText(m_PaymentsClosed.printSales()); + m_jSalesSubtotal.setText(m_PaymentsClosed.printSalesBase()); + m_jSalesTaxes.setText(m_PaymentsClosed.printSalesTaxes()); + m_jSalesTotal.setText(m_PaymentsClosed.printSalesTotal()); + + m_jTicketTable.setModel(m_PaymentsClosed.getPaymentsReprintModel()); + + TableColumnModel jColumns = m_jTicketTable.getColumnModel(); + jColumns.getColumn(0).setPreferredWidth(225); + jColumns.getColumn(0).setResizable(false); + jColumns.getColumn(1).setPreferredWidth(100); + jColumns.getColumn(1).setResizable(false); + + m_jsalestable.setModel(m_PaymentsClosed.getSalesModel()); + + jColumns = m_jsalestable.getColumnModel(); + jColumns.getColumn(0).setPreferredWidth(125); + jColumns.getColumn(0).setResizable(false); + jColumns.getColumn(1).setPreferredWidth(100); + jColumns.getColumn(1).setResizable(false); + jColumns.getColumn(2).setPreferredWidth(100); + jColumns.getColumn(2).setResizable(false); + + try{ + result=0; + s=m_App.getSession(); + con=s.getConnection(); + String sdbmanager = m_dlSystem.getDBVersion(); + + if ("PostgreSQL".equals(sdbmanager)) { + SQL = "SELECT * " + + "FROM draweropened " + + "WHERE TICKETID = 'No Sale' AND OPENDATE > " + "'" + m_PaymentsClosed.printDateStart() + "'"; + } else { + SQL = "SELECT * " + + "FROM draweropened " + + "WHERE TICKETID = 'No Sale' AND DATE(OPENDATE) = " + "'" + m_PaymentsClosed.printDateStart() + "'"; + } + + stmt = (Statement) con.createStatement(); + rs = stmt.executeQuery(SQL); + while (rs.next()){ + result ++; + } + + rs=null; + dresult=0; + if ("PostgreSQL".equals(sdbmanager)) { + SQL = "SELECT * " + + "FROM lineremoved " + + "WHERE TICKETID = 'Void' AND REMOVEDDATE > " + "'" + m_PaymentsClosed.printDateStart() + "'"; + } else { + SQL = "SELECT * " + + "FROM lineremoved " + + "WHERE TICKETID = 'Void' AND DATE(REMOVEDDATE) = " + "'" + m_PaymentsClosed.printDateStart() + "'"; + } + + stmt = (Statement) con.createStatement(); + rs = stmt.executeQuery(SQL); + while (rs.next()){ + dresult ++; + } + rs=null; + con=null; + s=null; + } + + catch (SQLException e){} + + m_jLinesRemoved.setText(dresult.toString()); + m_jNoCashSales.setText(result.toString()); + } + } + + private void printPayments(String report) { + + String sresource = m_dlSystem.getResourceAsXML(report); + if (sresource == null) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.cannotprintticket")); + msg.show(this); + } else { + try { + ScriptEngine script = ScriptFactory.getScriptEngine(ScriptFactory.VELOCITY); + script.put("payments", m_PaymentsClosed); + script.put("nosales",result.toString()); + m_TTP.printTicket(script.eval(sresource).toString()); + } catch (ScriptException | TicketPrinterException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.cannotprintticket"), e); + msg.show(this); + } + } + } + + private class FormatsPayment extends Formats { + @Override + protected String formatValueInt(Object value) { + return AppLocal.getIntString("transpayment." + (String) value); + } + @Override + protected Object parseValueInt(String value) throws ParseException { + return value; + } + @Override + public int getAlignment() { + return javax.swing.SwingConstants.LEFT; + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jLabel11 = new javax.swing.JLabel(); + m_jSequence = new javax.swing.JTextField(); + webBtnFindSequence = new com.alee.laf.button.WebButton(); + jLabel2 = new javax.swing.JLabel(); + m_jMinDate = new javax.swing.JTextField(); + jLabel3 = new javax.swing.JLabel(); + m_jMaxDate = new javax.swing.JTextField(); + m_jScrollTableTicket = new javax.swing.JScrollPane(); + m_jTicketTable = new javax.swing.JTable(); + m_jScrollSales = new javax.swing.JScrollPane(); + m_jsalestable = new javax.swing.JTable(); + jLabel1 = new javax.swing.JLabel(); + m_jCount = new javax.swing.JTextField(); + jLabel5 = new javax.swing.JLabel(); + m_jSales = new javax.swing.JTextField(); + jLabel6 = new javax.swing.JLabel(); + m_jSalesSubtotal = new javax.swing.JTextField(); + jLabel12 = new javax.swing.JLabel(); + m_jSalesTaxes = new javax.swing.JTextField(); + jLabel7 = new javax.swing.JLabel(); + m_jSalesTotal = new javax.swing.JTextField(); + jLabel4 = new javax.swing.JLabel(); + m_jCash = new javax.swing.JTextField(); + jLabel9 = new javax.swing.JLabel(); + m_jLinesRemoved = new javax.swing.JTextField(); + jLabel8 = new javax.swing.JLabel(); + m_jNoCashSales = new javax.swing.JTextField(); + m_jPrint = new javax.swing.JButton(); + + setLayout(new java.awt.BorderLayout()); + + jPanel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + + jLabel11.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel11.setText(AppLocal.getIntString("label.sequence")); // NOI18N + jLabel11.setPreferredSize(new java.awt.Dimension(125, 30)); + + m_jSequence.setEditable(false); + m_jSequence.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSequence.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jSequence.setPreferredSize(new java.awt.Dimension(150, 30)); + + webBtnFindSequence.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/search32.png"))); // NOI18N + webBtnFindSequence.setToolTipText(""); + webBtnFindSequence.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + webBtnFindSequence.setPreferredSize(new java.awt.Dimension(80, 45)); + webBtnFindSequence.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + webBtnFindSequenceActionPerformed(evt); + } + }); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jLabel2.setText(AppLocal.getIntString("label.StartDate")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(125, 30)); + + m_jMinDate.setEditable(false); + m_jMinDate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jMinDate.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jMinDate.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jLabel3.setText(AppLocal.getIntString("label.EndDate")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jMaxDate.setEditable(false); + m_jMaxDate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jMaxDate.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jMaxDate.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jScrollTableTicket.setBorder(null); + m_jScrollTableTicket.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + m_jScrollTableTicket.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jScrollTableTicket.setMinimumSize(new java.awt.Dimension(350, 140)); + m_jScrollTableTicket.setPreferredSize(new java.awt.Dimension(350, 150)); + + m_jTicketTable.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jTicketTable.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + + }, + new String [] { + + } + )); + m_jTicketTable.setFocusable(false); + m_jTicketTable.setIntercellSpacing(new java.awt.Dimension(0, 1)); + m_jTicketTable.setRequestFocusEnabled(false); + m_jTicketTable.setShowVerticalLines(false); + m_jScrollTableTicket.setViewportView(m_jTicketTable); + + m_jScrollSales.setBorder(null); + m_jScrollSales.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + m_jScrollSales.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jScrollSales.setPreferredSize(new java.awt.Dimension(350, 150)); + + m_jsalestable.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jsalestable.setFocusable(false); + m_jsalestable.setIntercellSpacing(new java.awt.Dimension(0, 1)); + m_jsalestable.setRequestFocusEnabled(false); + m_jsalestable.setShowVerticalLines(false); + m_jScrollSales.setViewportView(m_jsalestable); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.Tickets")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jCount.setEditable(false); + m_jCount.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCount.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jCount.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.sales")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jSales.setEditable(false); + m_jSales.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSales.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jSales.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setText(AppLocal.getIntString("label.totalnet")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jSalesSubtotal.setEditable(false); + m_jSalesSubtotal.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSalesSubtotal.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jSalesSubtotal.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel12.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel12.setText(AppLocal.getIntString("label.taxes")); // NOI18N + jLabel12.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jSalesTaxes.setEditable(false); + m_jSalesTaxes.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSalesTaxes.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jSalesTaxes.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel7.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel7.setText(AppLocal.getIntString("label.total")); // NOI18N + jLabel7.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jSalesTotal.setEditable(false); + m_jSalesTotal.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSalesTotal.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jSalesTotal.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.Money")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jCash.setEditable(false); + m_jCash.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCash.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jCash.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel9.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel9.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jLabel9.setText(bundle.getString("label.linevoids")); // NOI18N + jLabel9.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jLinesRemoved.setEditable(false); + m_jLinesRemoved.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jLinesRemoved.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jLinesRemoved.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel8.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel8.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jLabel8.setText(bundle.getString("label.nocashsales")); // NOI18N + jLabel8.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jNoCashSales.setEditable(false); + m_jNoCashSales.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jNoCashSales.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + m_jNoCashSales.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jPrint.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jPrint.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/printer.png"))); // NOI18N + m_jPrint.setText(AppLocal.getIntString("button.print")); // NOI18N + m_jPrint.setToolTipText(bundle.getString("tooltip.btn.closecash")); // NOI18N + m_jPrint.setIconTextGap(2); + m_jPrint.setInheritsPopupMenu(true); + m_jPrint.setMaximumSize(new java.awt.Dimension(85, 33)); + m_jPrint.setMinimumSize(new java.awt.Dimension(85, 33)); + m_jPrint.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jPrint.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jPrintActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jScrollSales, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jScrollTableTicket, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(m_jMaxDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jSales, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jCount, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jSalesSubtotal, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jSalesTaxes, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel7, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jSalesTotal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jCash, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel9, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jLinesRemoved, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jNoCashSales, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jMinDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jSequence, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(webBtnFindSequence, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(141, 141, 141) + .addComponent(m_jPrint, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(webBtnFindSequence, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jSequence, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jMaxDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jMinDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(18, 18, 18) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jSales, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jSalesSubtotal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jSalesTaxes, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jSalesTotal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jCash, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jLinesRemoved, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jNoCashSales, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(m_jScrollTableTicket, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jScrollSales, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(18, 18, 18) + .addComponent(m_jPrint, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(15, Short.MAX_VALUE)) + ); + + add(jPanel1, java.awt.BorderLayout.CENTER); + }// </editor-fold>//GEN-END:initComponents + + private void m_jPrintActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jPrintActionPerformed + printPayments("Printer.CloseCash"); + }//GEN-LAST:event_m_jPrintActionPerformed + + private void webBtnFindSequenceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_webBtnFindSequenceActionPerformed + try { + m_jPrint.setEnabled(false); + + loadData(); + + if (m_jCount.getText() != null) { + m_jPrint.setEnabled(true); + } else { + m_jPrint.setEnabled(false); + JOptionPane.showMessageDialog(this, + AppLocal.getIntString("Nope"), + AppLocal.getIntString("message.title"), + JOptionPane.OK_OPTION); + } + repaint(); + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + + }//GEN-LAST:event_webBtnFindSequenceActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel11; + private javax.swing.JLabel jLabel12; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JLabel jLabel9; + private javax.swing.JPanel jPanel1; + private javax.swing.JTextField m_jCash; + private javax.swing.JTextField m_jCount; + private javax.swing.JTextField m_jLinesRemoved; + private javax.swing.JTextField m_jMaxDate; + private javax.swing.JTextField m_jMinDate; + private javax.swing.JTextField m_jNoCashSales; + private javax.swing.JButton m_jPrint; + private javax.swing.JTextField m_jSales; + private javax.swing.JTextField m_jSalesSubtotal; + private javax.swing.JTextField m_jSalesTaxes; + private javax.swing.JTextField m_jSalesTotal; + private javax.swing.JScrollPane m_jScrollSales; + private javax.swing.JScrollPane m_jScrollTableTicket; + private javax.swing.JTextField m_jSequence; + private javax.swing.JTable m_jTicketTable; + private javax.swing.JTable m_jsalestable; + private com.alee.laf.button.WebButton webBtnFindSequence; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/panels/JPanelPayments.java b/src/main/java/com/unicenta/pos/panels/JPanelPayments.java new file mode 100644 index 0000000..488470b --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/JPanelPayments.java @@ -0,0 +1,87 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.panels; + +import com.unicenta.data.user.EditorRecord; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSales; + +/** + * + * @author adrianromero + */ +public class JPanelPayments extends JPanelTable { + + private PaymentsEditor jeditor; + private DataLogicSales m_dlSales = null; + + /** Creates a new instance of JPanelPayments */ + public JPanelPayments() { + } + + /** + * + */ + @Override + protected void init() { + m_dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + jeditor = new PaymentsEditor(app, dirty); + } + + /** + * + * @return + */ + @Override + public ListProvider getListProvider() { + return null; + } + + /** + * + * @return + */ + @Override + public SaveProvider getSaveProvider() { + return new SaveProvider(null + , m_dlSales.getPaymentMovementInsert() + , m_dlSales.getPaymentMovementDelete()); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return jeditor; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.Payments"); + } +} diff --git a/src/main/java/com/unicenta/pos/panels/JPanelPrinter.form b/src/main/java/com/unicenta/pos/panels/JPanelPrinter.form new file mode 100644 index 0000000..3f00d53 --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/JPanelPrinter.form @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="m_jDisplay"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + </Container> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JTabbedPane" name="m_jPrinters"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/panels/JPanelPrinter.java b/src/main/java/com/unicenta/pos/panels/JPanelPrinter.java new file mode 100644 index 0000000..256166b --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/JPanelPrinter.java @@ -0,0 +1,129 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.panels; + +import com.unicenta.basic.BasicException; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.JPanelView; +import com.unicenta.pos.printer.DeviceFiscalPrinter; +import com.unicenta.pos.printer.DevicePrinter; +import java.util.List; +import javax.swing.JComponent; +import javax.swing.JPanel; + +/** + * + * @author adrianromero + */ +public class JPanelPrinter extends JPanel implements JPanelView { + + /** Creates new form JPrinter + * @param oApp */ + public JPanelPrinter(AppView oApp) { + + initComponents(); + + + if (oApp.getDeviceTicket().getDeviceDisplay().getDisplayComponent() != null) { + m_jDisplay.add(oApp.getDeviceTicket().getDeviceDisplay().getDisplayComponent()); + } + + List<DevicePrinter> aprinters = oApp.getDeviceTicket().getDevicePrinterAll(); + for (int i = 0; i < aprinters.size(); i++) { + DevicePrinter printer = aprinters.get(i); + if (printer.getPrinterComponent() != null) { + m_jPrinters.add(printer.getPrinterName(), printer.getPrinterComponent()); + } + } + + DeviceFiscalPrinter fp = oApp.getDeviceTicket().getFiscalPrinter(); + if (fp.getFiscalComponent() != null) { + m_jPrinters.add(fp.getFiscalName(), fp.getFiscalComponent()); + } + } + + /** + * + * @return + */ + @Override + public JComponent getComponent() { + return this; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.Printer"); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + } + + /** + * + * @return + */ + @Override + public boolean deactivate() { + return true; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jDisplay = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + m_jPrinters = new javax.swing.JTabbedPane(); + + setLayout(new java.awt.BorderLayout()); + add(m_jDisplay, java.awt.BorderLayout.NORTH); + + jPanel1.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel1.setLayout(new java.awt.BorderLayout()); + + m_jPrinters.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel1.add(m_jPrinters, java.awt.BorderLayout.CENTER); + + add(jPanel1, java.awt.BorderLayout.CENTER); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel m_jDisplay; + private javax.swing.JTabbedPane m_jPrinters; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/panels/JPanelTable.form b/src/main/java/com/unicenta/pos/panels/JPanelTable.form new file mode 100644 index 0000000..f2727ff --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/JPanelTable.form @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="container"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="toolbar"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/panels/JPanelTable.java b/src/main/java/com/unicenta/pos/panels/JPanelTable.java new file mode 100644 index 0000000..4c79f3d --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/JPanelTable.java @@ -0,0 +1,274 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.panels; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.*; +import com.unicenta.data.loader.ComparatorCreator; +import com.unicenta.data.loader.Vectorer; +import com.unicenta.data.user.*; +import com.unicenta.pos.customers.CustomerInfoGlobal; +import com.unicenta.pos.forms.*; +import java.awt.BorderLayout; +import java.awt.Component; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.ListCellRenderer; + +/** + * + * @author adrianromero + */ +public abstract class JPanelTable extends JPanel implements JPanelView, BeanFactoryApp { + + /** + * + */ + protected BrowsableEditableData bd; + + /** + * + */ + protected DirtyManager dirty; + + /** + * + */ + protected AppView app; + + /** Creates new form JPanelTableEditor */ + public JPanelTable() { + + initComponents(); + } + + /** + * + * @param app + * @throws BeanFactoryException + */ + @Override + public void init(AppView app) throws BeanFactoryException { + + this.app = app; + dirty = new DirtyManager(); + bd = null; + init(); + } + + /** + * + * @return + */ + @Override + public Object getBean() { + return this; + } + + /** + * + */ + protected void startNavigation() { + + if (bd == null) { + + // init browsable editable data + bd = new BrowsableEditableData(getListProvider(), getSaveProvider(), getEditor(), dirty); + + // Add the filter panel + Component c = getFilter(); + if (c != null) { + c.applyComponentOrientation(getComponentOrientation()); + add(c, BorderLayout.NORTH); + } + + // Add the editor + c = getEditor().getComponent(); + if (c != null) { + c.applyComponentOrientation(getComponentOrientation()); + container.add(c, BorderLayout.CENTER); + } + + // el panel este + ListCellRenderer cr = getListCellRenderer(); + if (cr != null) { + JListNavigator nl = new JListNavigator(bd); + nl.applyComponentOrientation(getComponentOrientation()); + if (cr != null) { + nl.setCellRenderer(cr); + } + container.add(nl, java.awt.BorderLayout.LINE_START); + } + + // add toolbar extras + c = getToolbarExtras(); + if (c != null) { + c.applyComponentOrientation(getComponentOrientation()); + toolbar.add(c); + } + + // La Toolbar + c = new JLabelDirty(dirty); + c.applyComponentOrientation(getComponentOrientation()); + toolbar.add(c); + c = new JCounter(bd); + c.applyComponentOrientation(getComponentOrientation()); + toolbar.add(c); + c = new JNavigator(bd, getVectorer(), getComparatorCreator()); + c.applyComponentOrientation(getComponentOrientation()); + toolbar.add(c); + c = new JSaver(bd); + c.applyComponentOrientation(getComponentOrientation()); + toolbar.add(c); + } + } + + /** + * + * @return + */ + public Component getToolbarExtras() { + return null; + } + + /** + * + * @return + */ + public Component getFilter() { + return null; + } + + /** + * + */ + protected abstract void init(); + + /** + * + * @return + */ + public abstract EditorRecord getEditor(); + + /** + * + * @return + */ + public abstract ListProvider getListProvider(); + + /** + * + * @return + */ + public abstract SaveProvider getSaveProvider(); + + /** + * + * @return + */ + public Vectorer getVectorer() { + return null; + } + + /** + * + * @return + */ + public ComparatorCreator getComparatorCreator() { + return null; + } + + /** + * + * @return + */ + public ListCellRenderer getListCellRenderer() { + return null; + } + + /** + * + * @return + */ + @Override + public JComponent getComponent() { + return this; + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + startNavigation(); + bd.actionLoad(); + + //HS insert new customer 20.03.2014 + if (CustomerInfoGlobal.getInstance()!=null){ + bd.actionInsert(); + } + + } + + /** + * + * @return + */ + @Override + public boolean deactivate() { + + try { + return bd.actionClosingForm(this); + } catch (BasicException eD) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, AppLocal.getIntString("message.CannotMove"), eD); + msg.show(this); + return false; + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + container = new javax.swing.JPanel(); + toolbar = new javax.swing.JPanel(); + + setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + setLayout(new java.awt.BorderLayout()); + + container.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + container.setLayout(new java.awt.BorderLayout()); + container.add(toolbar, java.awt.BorderLayout.NORTH); + + add(container, java.awt.BorderLayout.CENTER); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel container; + private javax.swing.JPanel toolbar; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/panels/JPanelTable2.java b/src/main/java/com/unicenta/pos/panels/JPanelTable2.java new file mode 100644 index 0000000..c7cd34a --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/JPanelTable2.java @@ -0,0 +1,94 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.panels; + +import com.unicenta.data.loader.ComparatorCreator; +import com.unicenta.data.loader.Vectorer; +import com.unicenta.data.model.Row; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.SaveProvider; +import javax.swing.ListCellRenderer; + +/** + * + * @author adrianromero + */ +public abstract class JPanelTable2 extends JPanelTable { + + /** + * + */ + protected Row row; + + /** + * + */ + protected ListProvider lpr; + + /** + * + */ + protected SaveProvider spr; + + /** + * + * @return + */ + @Override + public final ListProvider getListProvider() { + return lpr; + } + + /** + * + * @return + */ + @Override + public final SaveProvider getSaveProvider() { + return spr; + } + + /** + * + * @return + */ + @Override + public final Vectorer getVectorer() { + return row.getVectorer(); + } + + /** + * + * @return + */ + @Override + public final ComparatorCreator getComparatorCreator() { + return row.getComparatorCreator(); + } + + /** + * + * @return + */ + @Override + public final ListCellRenderer getListCellRenderer() { + return row.getListCellRenderer(); + } +} diff --git a/src/main/java/com/unicenta/pos/panels/JProductFinder.form b/src/main/java/com/unicenta/pos/panels/JProductFinder.form new file mode 100644 index 0000000..6e6a4d6 --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/JProductFinder.form @@ -0,0 +1,280 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="form.productslist" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[750, 600]"/> + </Property> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,122,0,0,2,-10"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[450, 0]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="West"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="m_jProductSelect"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JButton" name="jButton3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.executefilter" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Execute Filter"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton3ActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[450, 140]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="West"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JScrollPane" name="jScrollPane1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[400, 147]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JList" name="jListProducts"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="selectionMode" type="int" value="0"/> + </Properties> + <Events> + <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="jListProductsMouseClicked"/> + <EventHandler event="valueChanged" listener="javax.swing.event.ListSelectionListener" parameters="javax.swing.event.ListSelectionEvent" handler="jListProductsValueChanged"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 0]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Component class="com.unicenta.editor.JEditorKeys" name="m_jKeys"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[290, 300]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jKeysActionPerformed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + </Component> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Last"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="2"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="jcmdCancel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.cancel" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[103, 44]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[103, 44]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jcmdCancelActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jcmdOK"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.OK" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[103, 44]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[103, 44]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jcmdOKActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel6"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jImageViewerProduct" pref="280" max="32767" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace max="32767" attributes="0"/> + <Component id="jImageViewerProduct" min="-2" pref="222" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="com.unicenta.data.gui.JImageViewerProduct" name="jImageViewerProduct"> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/panels/JProductFinder.java b/src/main/java/com/unicenta/pos/panels/JProductFinder.java new file mode 100644 index 0000000..c835669 --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/JProductFinder.java @@ -0,0 +1,372 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.panels; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.ticket.ProductFilterSales; +import com.unicenta.pos.ticket.ProductInfoExt; +import com.unicenta.pos.ticket.ProductRenderer; +import java.awt.*; +import javax.swing.JFrame; + +/** + * + * @author JG uniCenta + */ +public class JProductFinder extends javax.swing.JDialog { + + private ProductInfoExt m_ReturnProduct; + private ListProvider lpr; + public final static int PRODUCT_ALL = 0; + public final static int PRODUCT_NORMAL = 1; + public final static int PRODUCT_AUXILIAR = 2; + public final static int PRODUCT_BUNDLE = 3; + private Object dlSales; + + private JProductFinder(java.awt.Frame parent, boolean modal) { + super(parent, modal); + } + + private JProductFinder(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + } + + private ProductInfoExt init(DataLogicSales dlSales, int productsType) { + + initComponents(); + + jScrollPane1.getVerticalScrollBar().setPreferredSize(new Dimension(35, 35)); + jScrollPane1.getHorizontalScrollBar().setPreferredSize(new Dimension(35, 35)); + + ProductFilterSales jproductfilter = new ProductFilterSales(dlSales, m_jKeys); + jproductfilter.activate(); + m_jProductSelect.add(jproductfilter, BorderLayout.CENTER); + switch (productsType) { + case PRODUCT_NORMAL: + lpr = new ListProviderCreator(dlSales.getProductListNormal(), jproductfilter); + break; + case PRODUCT_AUXILIAR: + lpr = new ListProviderCreator(dlSales.getProductListAuxiliar(), jproductfilter); + break; + default: // PRODUCT_ALL + lpr = new ListProviderCreator(dlSales.getProductList(), jproductfilter); + break; + + } + jListProducts.setCellRenderer(new ProductRenderer()); + + + getRootPane().setDefaultButton(jcmdOK); + m_ReturnProduct = null; + + setVisible(true); + + return m_ReturnProduct; + + + } + + + private static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window)parent; + } else { + return getWindow(parent.getParent()); + } + } + + /** + * + * @param parent + * @param dlSales + * @return + */ + public static ProductInfoExt showMessage(Component parent, DataLogicSales dlSales) { + return showMessage(parent, dlSales, PRODUCT_ALL); + } + + /** + * + * @param parent + * @param dlSales + * @param productsType + * @return + */ + public static ProductInfoExt showMessage(Component parent, DataLogicSales dlSales, int productsType) { + + Window window = getWindow(parent); + + JProductFinder myMsg; + if (window instanceof Frame) { + myMsg = new JProductFinder((Frame) window, true); + } else { + myMsg = new JProductFinder((Dialog) window, true); + } + return myMsg.init(dlSales, productsType); + } + + private static class MyListData extends javax.swing.AbstractListModel { + + private final java.util.List m_data; + + public MyListData(java.util.List data) { + m_data = data; + } + + @Override + public Object getElementAt(int index) { + return m_data.get(index); + } + + @Override + public int getSize() { + return m_data.size(); + } + } + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel2 = new javax.swing.JPanel(); + m_jProductSelect = new javax.swing.JPanel(); + jPanel3 = new javax.swing.JPanel(); + jButton3 = new javax.swing.JButton(); + jPanel5 = new javax.swing.JPanel(); + jScrollPane1 = new javax.swing.JScrollPane(); + jListProducts = new javax.swing.JList(); + jPanel4 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel1 = new javax.swing.JPanel(); + jcmdCancel = new javax.swing.JButton(); + jcmdOK = new javax.swing.JButton(); + jPanel6 = new javax.swing.JPanel(); + jImageViewerProduct = new com.unicenta.data.gui.JImageViewerProduct(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(AppLocal.getIntString("form.productslist")); // NOI18N + setPreferredSize(new java.awt.Dimension(750, 600)); + + jPanel2.setPreferredSize(new java.awt.Dimension(450, 0)); + jPanel2.setLayout(new java.awt.BorderLayout()); + + m_jProductSelect.setLayout(new java.awt.BorderLayout()); + + jButton3.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jButton3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jButton3.setText(AppLocal.getIntString("button.executefilter")); // NOI18N + jButton3.setToolTipText("Execute Filter"); + jButton3.setPreferredSize(new java.awt.Dimension(110, 45)); + jButton3.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton3ActionPerformed(evt); + } + }); + jPanel3.add(jButton3); + + m_jProductSelect.add(jPanel3, java.awt.BorderLayout.SOUTH); + + jPanel2.add(m_jProductSelect, java.awt.BorderLayout.NORTH); + + jPanel5.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel5.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel5.setPreferredSize(new java.awt.Dimension(450, 140)); + jPanel5.setLayout(new java.awt.BorderLayout()); + + jScrollPane1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jScrollPane1.setPreferredSize(new java.awt.Dimension(400, 147)); + + jListProducts.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jListProducts.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); + jListProducts.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + jListProductsMouseClicked(evt); + } + }); + jListProducts.addListSelectionListener(new javax.swing.event.ListSelectionListener() { + public void valueChanged(javax.swing.event.ListSelectionEvent evt) { + jListProductsValueChanged(evt); + } + }); + jScrollPane1.setViewportView(jListProducts); + + jPanel5.add(jScrollPane1, java.awt.BorderLayout.CENTER); + + jPanel2.add(jPanel5, java.awt.BorderLayout.WEST); + + getContentPane().add(jPanel2, java.awt.BorderLayout.WEST); + + jPanel4.setPreferredSize(new java.awt.Dimension(300, 0)); + jPanel4.setLayout(new java.awt.BorderLayout()); + + m_jKeys.setPreferredSize(new java.awt.Dimension(290, 300)); + m_jKeys.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jKeysActionPerformed(evt); + } + }); + jPanel4.add(m_jKeys, java.awt.BorderLayout.NORTH); + + jPanel1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT)); + + jcmdCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + jcmdCancel.setText(AppLocal.getIntString("button.cancel")); // NOI18N + jcmdCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdCancel.setMaximumSize(new java.awt.Dimension(103, 44)); + jcmdCancel.setMinimumSize(new java.awt.Dimension(103, 44)); + jcmdCancel.setPreferredSize(new java.awt.Dimension(110, 45)); + jcmdCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdCancelActionPerformed(evt); + } + }); + jPanel1.add(jcmdCancel); + + jcmdOK.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jcmdOK.setText(AppLocal.getIntString("button.OK")); // NOI18N + jcmdOK.setEnabled(false); + jcmdOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdOK.setMaximumSize(new java.awt.Dimension(103, 44)); + jcmdOK.setMinimumSize(new java.awt.Dimension(103, 44)); + jcmdOK.setPreferredSize(new java.awt.Dimension(110, 45)); + jcmdOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdOKActionPerformed(evt); + } + }); + jPanel1.add(jcmdOK); + + jPanel4.add(jPanel1, java.awt.BorderLayout.PAGE_END); + + javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6); + jPanel6.setLayout(jPanel6Layout); + jPanel6Layout.setHorizontalGroup( + jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel6Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jImageViewerProduct, javax.swing.GroupLayout.DEFAULT_SIZE, 280, Short.MAX_VALUE) + .addContainerGap()) + ); + jPanel6Layout.setVerticalGroup( + jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel6Layout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jImageViewerProduct, javax.swing.GroupLayout.PREFERRED_SIZE, 222, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + + jPanel4.add(jPanel6, java.awt.BorderLayout.CENTER); + + getContentPane().add(jPanel4, java.awt.BorderLayout.EAST); + + setSize(new java.awt.Dimension(758, 634)); + setLocationRelativeTo(null); + }// </editor-fold>//GEN-END:initComponents + + private void jListProductsMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jListProductsMouseClicked + + m_ReturnProduct = (ProductInfoExt) jListProducts.getSelectedValue(); + + if (m_ReturnProduct != null) { + m_ReturnProduct = (ProductInfoExt) jListProducts.getSelectedValue(); + + if (m_ReturnProduct != null) { + jImageViewerProduct.setImage(m_ReturnProduct.getImage()); + } + } + + }//GEN-LAST:event_jListProductsMouseClicked + + private void jcmdOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdOKActionPerformed + + m_ReturnProduct = (ProductInfoExt) jListProducts.getSelectedValue(); + dispose(); + + }//GEN-LAST:event_jcmdOKActionPerformed + + private void jcmdCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdCancelActionPerformed + + m_ReturnProduct=null; + dispose(); + + }//GEN-LAST:event_jcmdCancelActionPerformed + + private void jListProductsValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_jListProductsValueChanged + + m_ReturnProduct = (ProductInfoExt) jListProducts.getSelectedValue(); + + if (m_ReturnProduct != null) { + m_ReturnProduct = (ProductInfoExt) jListProducts.getSelectedValue(); + + if (m_ReturnProduct != null) { + jImageViewerProduct.setImage(m_ReturnProduct.getImage()); + } + } + + jcmdOK.setEnabled(jListProducts.getSelectedValue() != null); + + }//GEN-LAST:event_jListProductsValueChanged + + private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed + + try { + jListProducts.setModel(new MyListData(lpr.loadData())); + if (jListProducts.getModel().getSize() > 0) { + jListProducts.setSelectedIndex(0); + } + } catch (BasicException e) { + } + + }//GEN-LAST:event_jButton3ActionPerformed + + private void m_jKeysActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jKeysActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_m_jKeysActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton3; + private com.unicenta.data.gui.JImageViewerProduct jImageViewerProduct; + private javax.swing.JList jListProducts; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JPanel jPanel6; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JButton jcmdCancel; + private javax.swing.JButton jcmdOK; + private com.unicenta.editor.JEditorKeys m_jKeys; + private javax.swing.JPanel m_jProductSelect; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/panels/JTextFieldLimit.java b/src/main/java/com/unicenta/pos/panels/JTextFieldLimit.java new file mode 100644 index 0000000..fd0507f --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/JTextFieldLimit.java @@ -0,0 +1,22 @@ +package com.unicenta.pos.panels; + +import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; +import javax.swing.text.PlainDocument; + +public class JTextFieldLimit extends PlainDocument { + private int limit; + + JTextFieldLimit(int limit) { + super(); + this.limit = limit; + } + + public void insertString(int offset, String str, AttributeSet attr ) throws BadLocationException { + if (str == null) return; + + if ((getLength() + str.length()) <= limit) { + super.insertString(offset, str, attr); + } + } +} diff --git a/src/main/java/com/unicenta/pos/panels/JTicketsFinder.form b/src/main/java/com/unicenta/pos/panels/JTicketsFinder.form new file mode 100644 index 0000000..dc1ed2d --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/JTicketsFinder.form @@ -0,0 +1,642 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="form.tickettitle" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[568, 600]"/> + </Property> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,122,0,0,2,-10"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="First"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel7"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 210]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" max="-2" attributes="0"> + <Component id="jLabel6" alignment="0" pref="115" max="32767" attributes="0"/> + <Component id="labelCustomer" alignment="0" max="32767" attributes="0"/> + <Component id="jLabel4" alignment="0" max="32767" attributes="0"/> + <Component id="jLabel3" alignment="0" max="32767" attributes="0"/> + <Component id="jLabel1" alignment="0" max="32767" attributes="0"/> + <Component id="jLabel7" max="32767" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="1" max="-2" attributes="0"> + <Component id="jtxtCustomer" alignment="0" max="32767" attributes="0"/> + <Component id="jTxtStartDate" alignment="0" max="32767" attributes="0"/> + <Component id="jTxtEndDate" alignment="0" max="32767" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="btnDateEnd" min="-2" max="-2" attributes="0"/> + <Component id="btnDateStart" min="-2" max="-2" attributes="0"/> + <Component id="btnCustomer" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" attributes="0"> + <Component id="jcboMoney" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jtxtMoney" min="-2" pref="131" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jtxtTicketID" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jComboBoxTicket" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="jcboUser" min="-2" pref="150" max="-2" attributes="0"/> + </Group> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="1" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/> + <Group type="103" alignment="0" groupAlignment="1" attributes="0"> + <Component id="jComboBoxTicket" max="-2" attributes="0"/> + <Component id="jtxtTicketID" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel3" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="btnDateStart" min="-2" max="-2" attributes="0"/> + <Component id="jTxtStartDate" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="2" attributes="0"> + <Component id="jLabel4" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="jTxtEndDate" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="btnDateEnd" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="2" attributes="0"> + <Component id="labelCustomer" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="jtxtCustomer" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="btnCustomer" alignment="2" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jcboUser" alignment="3" max="-2" attributes="0"/> + <Component id="jLabel6" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="2" attributes="0"> + <Component id="jtxtMoney" alignment="0" min="-2" max="-2" attributes="0"/> + <Group type="103" alignment="1" groupAlignment="3" attributes="0"> + <Component id="jcboMoney" alignment="3" max="32767" attributes="0"/> + <Component id="jLabel7" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace min="-2" pref="19" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.ticketid" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.user" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel7"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.totalcash" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorCurrency" name="jtxtMoney"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="jcboUser"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[220, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jcboUserActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jcboMoney"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorIntegerPositive" name="jtxtTicketID"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="labelCustomer"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.customer" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.StartDate" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.EndDate" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTxtStartDate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTxtEndDate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="btnDateStart"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/date.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Open Calendar"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnDateStartActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="btnDateEnd"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/date.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Open Calendar"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnDateEndActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JTextField" name="jtxtCustomer"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="btnCustomer"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/customer_sml.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Open Customers"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnCustomerActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboBoxTicket"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel6"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JButton" name="jbtnReset"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/reload.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.clean" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Clear Filter"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnResetActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jbtnExecute"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.executefilter" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Execute Filter"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnExecuteActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JScrollPane" name="jScrollPane1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JList" name="jListTickets"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="focusable" type="boolean" value="false"/> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="jListTicketsMouseClicked"/> + <EventHandler event="valueChanged" listener="javax.swing.event.ListSelectionListener" parameters="javax.swing.event.ListSelectionEvent" handler="jListTicketsValueChanged"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 250]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="After"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout"> + <Property name="useNullLayout" type="boolean" value="false"/> + </Layout> + <SubComponents> + <Component class="com.unicenta.editor.JEditorKeys" name="m_jKeys"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[290, 300]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jKeysActionPerformed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="0" y="0" width="300" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Container class="javax.swing.JPanel" name="jPanel8"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="0" y="536" width="300" height="-1"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="After"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JButton" name="jcmdCancel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.cancel" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jcmdCancelActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jcmdOK"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.OK" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[103, 44]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[103, 44]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jcmdOKActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Component class="javax.swing.JLabel" name="jLblTicketCount"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="cc" red="33" type="rgb"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Century Gothic" size="18" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" red="ff" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="ff" green="cc" red="33" type="rgb"/> + </LineBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 50]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="10" y="306" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="jLblReturnCount"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.ticketsfound" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="ff" green="cc" red="0" type="rgb"/> + </LineBorder> + </Border> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 50]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="90" y="306" width="200" height="-1"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/panels/JTicketsFinder.java b/src/main/java/com/unicenta/pos/panels/JTicketsFinder.java new file mode 100644 index 0000000..9801b08 --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/JTicketsFinder.java @@ -0,0 +1,820 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.panels; + +import com.unicenta.basic.BasicException; +import com.unicenta.beans.JCalendarDialog; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.gui.ListQBFModelNumber; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.loader.QBFCompareEnum; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.user.EditorCreator; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.format.Formats; +import com.unicenta.pos.customers.DataLogicCustomers; +import com.unicenta.pos.customers.JCustomerFinder; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.inventory.TaxCategoryInfo; +import com.unicenta.pos.ticket.FindTicketsInfo; +import com.unicenta.pos.ticket.FindTicketsRenderer; +import java.awt.*; +import java.time.LocalTime; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JFrame; + +/** + * + * @author Mikel irurita + */ +public class JTicketsFinder extends javax.swing.JDialog implements EditorCreator { + + private ListProvider listProvider; + private SentenceList m_sentcat; + private ComboBoxValModel m_CategoryModel; + private DataLogicSales dlSales; + private DataLogicCustomers dlCustomers; + private FindTicketsInfo selectedTicket; + + /** Creates new form JTicketsFinder */ + private JTicketsFinder(java.awt.Frame parent, boolean modal) { + super(parent, modal); + } + + /** Creates new form JTicketsFinder */ + private JTicketsFinder(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + } + + /** + * + * @param parent + * @param dlSales + * @param dlCustomers + * @return + */ + public static JTicketsFinder getReceiptFinder(Component parent, DataLogicSales dlSales, DataLogicCustomers dlCustomers) { + Window window = getWindow(parent); + + JTicketsFinder myMsg; + if (window instanceof Frame) { + myMsg = new JTicketsFinder((Frame) window, true); + } else { + myMsg = new JTicketsFinder((Dialog) window, true); + } + myMsg.init(dlSales, dlCustomers); + myMsg.applyComponentOrientation(parent.getComponentOrientation()); + return myMsg; + } + + /** + * + * @return + */ + public FindTicketsInfo getSelectedCustomer() { + return selectedTicket; + } + + private void init(DataLogicSales dlSales, DataLogicCustomers dlCustomers) { + + this.dlSales = dlSales; + this.dlCustomers = dlCustomers; + + initComponents(); + + jScrollPane1.getVerticalScrollBar().setPreferredSize(new Dimension(35, 35)); + + jtxtTicketID.addEditorKeys(m_jKeys); + jtxtMoney.addEditorKeys(m_jKeys); + + listProvider = new ListProviderCreator(dlSales.getTicketsList(), this); + + jListTickets.setCellRenderer(new FindTicketsRenderer()); + + getRootPane().setDefaultButton(jcmdOK); + + initCombos(); + + defaultValues(); + + selectedTicket = null; + + } + + /** + * + */ + public void executeSearch() { + + jLblTicketCount.setVisible(false); + jLblReturnCount.setVisible(false); + jLblTicketCount.setText(null); + + try { + MyListData myListData = new MyListData(listProvider.loadData()); + jListTickets.setModel(myListData); + if (jListTickets.getModel().getSize() > 0) { + String count = String.valueOf(jListTickets.getModel().getSize()); + jLblTicketCount.setVisible(true); + jLblReturnCount.setVisible(true); + jListTickets.setSelectedIndex(0); + jLblTicketCount.setText(count); + } + } catch (BasicException e) { + System.err.println("Search Error: "+e); + } + } + + private void initCombos() { + String[] values = new String[] {AppLocal.getIntString("label.sales"), + AppLocal.getIntString("label.refunds"), AppLocal.getIntString("label.all")}; + jComboBoxTicket.setModel(new DefaultComboBoxModel(values)); + + jcboMoney.setModel(ListQBFModelNumber.getMandatoryNumber()); + + m_sentcat = dlSales.getUserList(); + m_CategoryModel = new ComboBoxValModel(); + + List catlist=null; + + try { + catlist = m_sentcat.list(); + } catch (BasicException ex) { + ex.getMessage(); + } + + catlist.add(0, null); + + m_CategoryModel = new ComboBoxValModel(catlist); + jcboUser.setModel(m_CategoryModel); + } + + private void defaultValues() { + + jListTickets.setModel(new MyListData(new ArrayList())); + jcboUser.setSelectedItem(null); + jtxtTicketID.reset(); + jtxtTicketID.activate(); + jTxtStartDate.setText(null); + jTxtEndDate.setText(null); + jtxtCustomer.setText(null); + jComboBoxTicket.setSelectedIndex(0); + jcboUser.setSelectedItem(null); + + jcboMoney.setSelectedItem( ((ListQBFModelNumber)jcboMoney.getModel()).getElementAt(0) ); + jcboMoney.revalidate(); + jcboMoney.repaint(); + jtxtMoney.reset(); + jTxtStartDate.setText(null); + jTxtEndDate.setText(null); + jtxtCustomer.setText(null); + jtxtCardNumber.setText(null); + + jLblTicketCount.setVisible(false); + jLblReturnCount.setVisible(false); + jLblTicketCount.setText(null); + + Date startOfToday = Date.from(ZonedDateTime.now().with(LocalTime.MIN).toInstant()); + jTxtStartDate.setText(Formats.TIMESTAMP.formatValue(startOfToday)); + + repaint(); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + /* + This is where you build your search criteria + */ + + + Object[] afilter = new Object[16]; + + if (jtxtTicketID.getText() == null || jtxtTicketID.getText().equals("")) { + afilter[0] = QBFCompareEnum.COMP_NONE; + afilter[1] = null; + } else { + afilter[0] = QBFCompareEnum.COMP_EQUALS; + afilter[1] = jtxtTicketID.getValueInteger(); + } + + switch (jComboBoxTicket.getSelectedIndex()) { + case 2: + afilter[2] = QBFCompareEnum.COMP_DISTINCT; + afilter[3] = 2; + break; + case 0: + afilter[2] = QBFCompareEnum.COMP_EQUALS; + afilter[3] = 0; + break; + case 1: + afilter[2] = QBFCompareEnum.COMP_EQUALS; + afilter[3] = 1; + break; + default: + break; + } + + afilter[5] = jtxtMoney.getDoubleValue(); + afilter[4] = afilter[5] == null ? QBFCompareEnum.COMP_NONE : jcboMoney.getSelectedItem(); + + Object startdate = Formats.TIMESTAMP.parseValue(jTxtStartDate.getText()); + Object enddate = Formats.TIMESTAMP.parseValue(jTxtEndDate.getText()); + + afilter[6] = (startdate == null) ? QBFCompareEnum.COMP_NONE : QBFCompareEnum.COMP_GREATEROREQUALS; + afilter[7] = startdate; + afilter[8] = (enddate == null) ? QBFCompareEnum.COMP_NONE : QBFCompareEnum.COMP_LESS; + afilter[9] = enddate; + + if (jcboUser.getSelectedItem() == null) { + afilter[10] = QBFCompareEnum.COMP_NONE; + afilter[11] = null; + } else { + afilter[10] = QBFCompareEnum.COMP_EQUALS; + afilter[11] = ((TaxCategoryInfo)jcboUser.getSelectedItem()).getName(); + } + + if (jtxtCustomer.getText() == null || jtxtCustomer.getText().equals("")) { + afilter[12] = QBFCompareEnum.COMP_NONE; + afilter[13] = null; + } else { + afilter[12] = QBFCompareEnum.COMP_RE; + afilter[13] = "%" + jtxtCustomer.getText() + "%"; + } + + if (jtxtCardNumber.getText() == null || jtxtCardNumber.getText().equals("")) { + afilter[14] = QBFCompareEnum.COMP_NONE; + afilter[15] = null; + } else { + afilter[14] = QBFCompareEnum.COMP_EQUALS; + afilter[15] = jtxtCardNumber.getText(); + } + + return afilter; + + } + + private static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window) parent; + } else { + return getWindow(parent.getParent()); + } + } + + + private static class MyListData extends javax.swing.AbstractListModel { + + private final java.util.List m_data; + + public MyListData(java.util.List data) { + m_data = data; + } + + @Override + public Object getElementAt(int index) { + return m_data.get(index); + } + + @Override + public int getSize() { + return m_data.size(); + } + } + /** + * + * @param d + */ + public void setStartDate(Date d) { + Date startOfDay = Date.from(ZonedDateTime.now().with(LocalTime.MIN).toInstant()); + jTxtStartDate.setText(Formats.TIMESTAMP.formatValue(startOfDay)); + } + public void setEndDate(Date d) { + Date endOfDay = Date.from(ZonedDateTime.now().with(LocalTime.MAX).toInstant()); + jTxtEndDate.setText(Formats.TIMESTAMP.formatValue(endOfDay)); + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel3 = new javax.swing.JPanel(); + jPanel5 = new javax.swing.JPanel(); + jPanel7 = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + jLabel6 = new javax.swing.JLabel(); + jLabel7 = new javax.swing.JLabel(); + jtxtMoney = new com.unicenta.editor.JEditorCurrency(); + jcboUser = new javax.swing.JComboBox(); + jcboMoney = new javax.swing.JComboBox(); + jtxtTicketID = new com.unicenta.editor.JEditorIntegerPositive(); + labelCustomer = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + jTxtStartDate = new javax.swing.JTextField(); + jTxtEndDate = new javax.swing.JTextField(); + btnDateStart = new javax.swing.JButton(); + btnDateEnd = new javax.swing.JButton(); + jtxtCustomer = new javax.swing.JTextField(); + btnCustomer = new javax.swing.JButton(); + jComboBoxTicket = new javax.swing.JComboBox(); + jtxtCardNumber = new javax.swing.JTextField(4); + jLabelCardNumber = new javax.swing.JLabel(); + jPanel6 = new javax.swing.JPanel(); + jbtnReset = new javax.swing.JButton(); + jbtnExecute = new javax.swing.JButton(); + jPanel4 = new javax.swing.JPanel(); + jScrollPane1 = new javax.swing.JScrollPane(); + jListTickets = new javax.swing.JList(); + jPanel2 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel8 = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + jcmdCancel = new javax.swing.JButton(); + jcmdOK = new javax.swing.JButton(); + jLblTicketCount = new javax.swing.JLabel(); + jLblReturnCount = new javax.swing.JLabel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(AppLocal.getIntString("form.tickettitle")); // NOI18N + setPreferredSize(new java.awt.Dimension(568, 600)); + + jPanel3.setLayout(new java.awt.BorderLayout()); + + jPanel5.setLayout(new java.awt.BorderLayout()); + + jPanel7.setPreferredSize(new java.awt.Dimension(0, 250)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.ticketid")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setText(AppLocal.getIntString("label.user")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel7.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel7.setText(AppLocal.getIntString("label.totalcash")); // NOI18N + jLabel7.setPreferredSize(new java.awt.Dimension(100, 30)); + + jtxtMoney.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtMoney.setPreferredSize(new java.awt.Dimension(150, 30)); + + jcboUser.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboUser.setPreferredSize(new java.awt.Dimension(220, 30)); + jcboUser.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcboUserActionPerformed(evt); + } + }); + + jcboMoney.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jcboMoney.setPreferredSize(new java.awt.Dimension(150, 30)); + + jtxtTicketID.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jtxtTicketID.setPreferredSize(new java.awt.Dimension(150, 30)); + + labelCustomer.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + labelCustomer.setText(AppLocal.getIntString("label.customer")); // NOI18N + labelCustomer.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.StartDate")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.EndDate")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(100, 30)); + + jTxtStartDate.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jTxtStartDate.setPreferredSize(new java.awt.Dimension(150, 30)); + + jTxtEndDate.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jTxtEndDate.setPreferredSize(new java.awt.Dimension(150, 30)); + + btnDateStart.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/date.png"))); // NOI18N + btnDateStart.setToolTipText("Open Calendar"); + btnDateStart.setPreferredSize(new java.awt.Dimension(100, 30)); + btnDateStart.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnDateStartActionPerformed(evt); + } + }); + + btnDateEnd.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/date.png"))); // NOI18N + btnDateEnd.setToolTipText("Open Calendar"); + btnDateEnd.setPreferredSize(new java.awt.Dimension(100, 30)); + btnDateEnd.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnDateEndActionPerformed(evt); + } + }); + + jtxtCustomer.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jtxtCustomer.setPreferredSize(new java.awt.Dimension(150, 30)); + + btnCustomer.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/customer_sml.png"))); // NOI18N + btnCustomer.setToolTipText("Open Customers"); + btnCustomer.setFocusPainted(false); + btnCustomer.setFocusable(false); + btnCustomer.setMargin(new java.awt.Insets(8, 14, 8, 14)); + btnCustomer.setPreferredSize(new java.awt.Dimension(100, 30)); + btnCustomer.setRequestFocusEnabled(false); + btnCustomer.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnCustomerActionPerformed(evt); + } + }); + + jComboBoxTicket.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jComboBoxTicket.setPreferredSize(new java.awt.Dimension(150, 30)); + + jtxtCardNumber.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jtxtCardNumber.setPreferredSize(new java.awt.Dimension(150, 30)); + jtxtCardNumber.setDocument(new JTextFieldLimit(4)); + + jLabelCardNumber.setText("CC number (last 4)"); + + javax.swing.GroupLayout jPanel7Layout = new javax.swing.GroupLayout(jPanel7); + jPanel7.setLayout(jPanel7Layout); + jPanel7Layout.setHorizontalGroup( + jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel7Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(jLabel6, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 115, Short.MAX_VALUE) + .addComponent(labelCustomer, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel4, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel7, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(jLabelCardNumber)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel7Layout.createSequentialGroup() + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(jtxtCustomer, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jTxtStartDate, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jTxtEndDate, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jtxtCardNumber, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(btnDateEnd, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(btnDateStart, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(btnCustomer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanel7Layout.createSequentialGroup() + .addComponent(jcboMoney, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jtxtMoney, javax.swing.GroupLayout.PREFERRED_SIZE, 131, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel7Layout.createSequentialGroup() + .addComponent(jtxtTicketID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboBoxTicket, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jcboUser, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(25, Short.MAX_VALUE)) + ); + jPanel7Layout.setVerticalGroup( + jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel7Layout.createSequentialGroup() + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jComboBoxTicket, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtTicketID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(btnDateStart, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTxtStartDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTxtEndDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(btnDateEnd, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(labelCustomer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtCustomer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(btnCustomer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jtxtCardNumber, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabelCardNumber)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jcboUser, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jtxtMoney, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jcboMoney, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(19, 19, 19)) + ); + + jPanel5.add(jPanel7, java.awt.BorderLayout.CENTER); + + jbtnReset.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnReset.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reload.png"))); // NOI18N + jbtnReset.setText(AppLocal.getIntString("button.clean")); // NOI18N + jbtnReset.setToolTipText("Clear Filter"); + jbtnReset.setPreferredSize(new java.awt.Dimension(110, 45)); + jbtnReset.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnResetActionPerformed(evt); + } + }); + jPanel6.add(jbtnReset); + + jbtnExecute.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnExecute.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jbtnExecute.setText(AppLocal.getIntString("button.executefilter")); // NOI18N + jbtnExecute.setToolTipText("Execute Filter"); + jbtnExecute.setFocusPainted(false); + jbtnExecute.setFocusable(false); + jbtnExecute.setPreferredSize(new java.awt.Dimension(110, 45)); + jbtnExecute.setRequestFocusEnabled(false); + jbtnExecute.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnExecuteActionPerformed(evt); + } + }); + jPanel6.add(jbtnExecute); + + jPanel5.add(jPanel6, java.awt.BorderLayout.SOUTH); + + jPanel3.add(jPanel5, java.awt.BorderLayout.PAGE_START); + + jPanel4.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel4.setLayout(new java.awt.BorderLayout()); + + jListTickets.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jListTickets.setFocusable(false); + jListTickets.setRequestFocusEnabled(false); + jListTickets.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + jListTicketsMouseClicked(evt); + } + }); + jListTickets.addListSelectionListener(new javax.swing.event.ListSelectionListener() { + public void valueChanged(javax.swing.event.ListSelectionEvent evt) { + jListTicketsValueChanged(evt); + } + }); + jScrollPane1.setViewportView(jListTickets); + + jPanel4.add(jScrollPane1, java.awt.BorderLayout.CENTER); + + jPanel3.add(jPanel4, java.awt.BorderLayout.CENTER); + + getContentPane().add(jPanel3, java.awt.BorderLayout.CENTER); + + jPanel2.setPreferredSize(new java.awt.Dimension(300, 250)); + jPanel2.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout()); + + m_jKeys.setPreferredSize(new java.awt.Dimension(290, 300)); + m_jKeys.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jKeysActionPerformed(evt); + } + }); + jPanel2.add(m_jKeys, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, 300, -1)); + + jPanel8.setLayout(new java.awt.BorderLayout()); + + jcmdCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + jcmdCancel.setText(AppLocal.getIntString("button.cancel")); // NOI18N + jcmdCancel.setFocusPainted(false); + jcmdCancel.setFocusable(false); + jcmdCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdCancel.setPreferredSize(new java.awt.Dimension(110, 45)); + jcmdCancel.setRequestFocusEnabled(false); + jcmdCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdCancelActionPerformed(evt); + } + }); + jPanel1.add(jcmdCancel); + + jcmdOK.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jcmdOK.setText(AppLocal.getIntString("button.OK")); // NOI18N + jcmdOK.setEnabled(false); + jcmdOK.setFocusPainted(false); + jcmdOK.setFocusable(false); + jcmdOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdOK.setMaximumSize(new java.awt.Dimension(103, 44)); + jcmdOK.setMinimumSize(new java.awt.Dimension(103, 44)); + jcmdOK.setPreferredSize(new java.awt.Dimension(110, 45)); + jcmdOK.setRequestFocusEnabled(false); + jcmdOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdOKActionPerformed(evt); + } + }); + jPanel1.add(jcmdOK); + + jPanel8.add(jPanel1, java.awt.BorderLayout.LINE_END); + + jPanel2.add(jPanel8, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 536, 300, -1)); + + jLblTicketCount.setBackground(new java.awt.Color(51, 204, 255)); + jLblTicketCount.setFont(new java.awt.Font("Century Gothic", 0, 18)); // NOI18N + jLblTicketCount.setForeground(new java.awt.Color(255, 255, 255)); + jLblTicketCount.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLblTicketCount.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(51, 204, 255))); + jLblTicketCount.setOpaque(true); + jLblTicketCount.setPreferredSize(new java.awt.Dimension(80, 50)); + jPanel2.add(jLblTicketCount, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 306, -1, -1)); + + jLblReturnCount.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jLblReturnCount.setText(bundle.getString("label.ticketsfound")); // NOI18N + jLblReturnCount.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 204, 255))); + jLblReturnCount.setPreferredSize(new java.awt.Dimension(80, 50)); + jPanel2.add(jLblReturnCount, new org.netbeans.lib.awtextra.AbsoluteConstraints(90, 306, 200, -1)); + + getContentPane().add(jPanel2, java.awt.BorderLayout.LINE_END); + + setSize(new java.awt.Dimension(758, 634)); + setLocationRelativeTo(null); + }// </editor-fold>//GEN-END:initComponents + private void jcmdOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdOKActionPerformed + + selectedTicket = (FindTicketsInfo) jListTickets.getSelectedValue(); + dispose(); + + }//GEN-LAST:event_jcmdOKActionPerformed + + private void jcmdCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdCancelActionPerformed + + dispose(); + + }//GEN-LAST:event_jcmdCancelActionPerformed + + private void jbtnExecuteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnExecuteActionPerformed + + executeSearch(); + + jLblTicketCount.setVisible(true); + jLblReturnCount.setVisible(true); + jLblReturnCount.setText(" Tickets found"); + + }//GEN-LAST:event_jbtnExecuteActionPerformed + + private void jListTicketsValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_jListTicketsValueChanged + + jcmdOK.setEnabled(jListTickets.getSelectedValue() != null); + + }//GEN-LAST:event_jListTicketsValueChanged + + private void jListTicketsMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jListTicketsMouseClicked + + if (evt.getClickCount() == 2) { + selectedTicket = (FindTicketsInfo) jListTickets.getSelectedValue(); + dispose(); + } + + }//GEN-LAST:event_jListTicketsMouseClicked + + private void jbtnResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnResetActionPerformed + + defaultValues(); + }//GEN-LAST:event_jbtnResetActionPerformed + + private void btnDateStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDateStartActionPerformed + + jLblTicketCount.setVisible(false); + jLblReturnCount.setVisible(false); + + Date date; + try { + date = (Date) Formats.TIMESTAMP.parseValue(jTxtStartDate.getText()); + } catch (BasicException e) { + date = null; + } + date = JCalendarDialog.showCalendarTimeHours(this, date); + if (date != null) { + jTxtStartDate.setText(Formats.TIMESTAMP.formatValue(date)); + } + }//GEN-LAST:event_btnDateStartActionPerformed + + private void btnDateEndActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDateEndActionPerformed + jLblTicketCount.setVisible(false); + jLblReturnCount.setVisible(false); + + Date date; + try { + date = (Date) Formats.TIMESTAMP.parseValue(jTxtEndDate.getText()); + } catch (BasicException e) { + date = null; + } + date = JCalendarDialog.showCalendarTimeHours(this, date); + if (date != null) { + jTxtEndDate.setText(Formats.TIMESTAMP.formatValue(date)); + } + }//GEN-LAST:event_btnDateEndActionPerformed + + private void btnCustomerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCustomerActionPerformed + jLblTicketCount.setVisible(false); + jLblReturnCount.setVisible(false); + + JCustomerFinder finder = JCustomerFinder.getCustomerFinder(this, dlCustomers); + finder.search(null); + finder.setVisible(true); + + try { + jtxtCustomer.setText(finder.getSelectedCustomer() == null + ? null + : dlSales.loadCustomerExt(finder.getSelectedCustomer().getId()).toString()); + } catch (BasicException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotfindcustomer"), e); + msg.show(this); + } + + }//GEN-LAST:event_btnCustomerActionPerformed + + private void m_jKeysActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jKeysActionPerformed + + }//GEN-LAST:event_m_jKeysActionPerformed + + private void jcboUserActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcboUserActionPerformed + + }//GEN-LAST:event_jcboUserActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btnCustomer; + private javax.swing.JButton btnDateEnd; + private javax.swing.JButton btnDateStart; + private javax.swing.JComboBox jComboBoxTicket; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabelCardNumber; + private javax.swing.JLabel jLblReturnCount; + private javax.swing.JLabel jLblTicketCount; + private javax.swing.JList jListTickets; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JPanel jPanel6; + private javax.swing.JPanel jPanel7; + private javax.swing.JPanel jPanel8; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JTextField jTxtEndDate; + private javax.swing.JTextField jTxtStartDate; + private javax.swing.JButton jbtnExecute; + private javax.swing.JButton jbtnReset; + private javax.swing.JComboBox jcboMoney; + private javax.swing.JComboBox jcboUser; + private javax.swing.JButton jcmdCancel; + private javax.swing.JButton jcmdOK; + private javax.swing.JTextField jtxtCardNumber; + private javax.swing.JTextField jtxtCustomer; + private com.unicenta.editor.JEditorCurrency jtxtMoney; + private com.unicenta.editor.JEditorIntegerPositive jtxtTicketID; + private javax.swing.JLabel labelCustomer; + private com.unicenta.editor.JEditorKeys m_jKeys; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/panels/PaymentsEditor.form b/src/main/java/com/unicenta/pos/panels/PaymentsEditor.form new file mode 100644 index 0000000..1004c2d --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/PaymentsEditor.form @@ -0,0 +1,150 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,2,-100"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel5" min="-2" max="-2" attributes="1"/> + <Component id="jLabel3" alignment="0" min="-2" max="-2" attributes="1"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="m_jNotes" alignment="0" pref="234" max="32767" attributes="0"/> + <Component id="m_jreason" alignment="0" min="-2" max="-2" attributes="1"/> + <Component id="jTotal" alignment="0" max="32767" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jreason" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" attributes="0"> + <Component id="jTotal" min="-2" max="-2" attributes="0"/> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="m_jNotes" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.paymentreason" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jreason"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="focusable" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.paymenttotal" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorCurrency" name="jTotal"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="PaymentsEditor_jTotal"/> + </AuxValues> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jNotes"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[132, 100]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="After"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Component class="com.unicenta.editor.JEditorKeys" name="m_jKeys"> + <Events> + <EventHandler event="propertyChange" listener="java.beans.PropertyChangeListener" parameters="java.beans.PropertyChangeEvent" handler="m_jKeysPropertyChange"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/panels/PaymentsEditor.java b/src/main/java/com/unicenta/pos/panels/PaymentsEditor.java new file mode 100644 index 0000000..98be6f4 --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/PaymentsEditor.java @@ -0,0 +1,357 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.panels; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.loader.IKeyed; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import java.awt.Component; +import java.util.Date; +import java.util.UUID; + + +/** + * + * @author adrianromero + */ +public final class PaymentsEditor extends javax.swing.JPanel implements EditorRecord { + + private final ComboBoxValModel m_ReasonModel; + + private String m_sId; + private String m_sPaymentId; + private Date datenew; + + private final AppView m_App; + private String m_sNotes; + + /** Creates new form JPanelPayments + * @param oApp + * @param dirty */ + public PaymentsEditor(AppView oApp, DirtyManager dirty) { + + m_App = oApp; + + initComponents(); + + m_ReasonModel = new ComboBoxValModel(); + m_ReasonModel.add(new PaymentReasonPositive("cashin", AppLocal.getIntString("transpayment.cashin"))); + m_ReasonModel.add(new PaymentReasonNegative("cashout", AppLocal.getIntString("transpayment.cashout"))); + m_jreason.setModel(m_ReasonModel); + + jTotal.addEditorKeys(m_jKeys); + + m_jreason.addActionListener(dirty); + jTotal.addPropertyChangeListener("Text", dirty); + m_jNotes.addPropertyChangeListener("Text", dirty); + m_jNotes.addEditorKeys(m_jKeys); + + writeValueEOF(); + } + + /** + * + */ + @Override + public void writeValueEOF() { + m_sId = null; + m_sPaymentId = null; + datenew = null; + setReasonTotal(null, null); + m_jreason.setEnabled(false); + jTotal.setEnabled(false); +// JG Added July 2011 + m_sNotes = null; + m_jNotes.setEnabled(false); + + } + + /** + * + */ + @Override + public void writeValueInsert() { + + m_sId = null; + m_sPaymentId = null; + datenew = null; + setReasonTotal("cashin", null); + m_jreason.setEnabled(true); + jTotal.setEnabled(true); + jTotal.activate(); +// JG Added July 2011 + m_sNotes = null; + m_jNotes.setEnabled(true); + m_jNotes.setText(m_sNotes); + } + + /** + * + * @param value + */ + @Override + public void writeValueDelete(Object value) { + Object[] payment = (Object[]) value; + m_sId = (String) payment[0]; + datenew = (Date) payment[2]; + m_sPaymentId = (String) payment[3]; + setReasonTotal(payment[4], payment[5]); + m_jreason.setEnabled(false); + jTotal.setEnabled(false); +// JG Added July 2011 + m_sNotes = (String) payment[6]; + m_jNotes.setEnabled(false); + } + + /** + * + * @param value + */ + @Override + public void writeValueEdit(Object value) { + Object[] payment = (Object[]) value; + m_sId = (String) payment[0]; + datenew = (Date) payment[2]; + m_sPaymentId = (String) payment[3]; + setReasonTotal(payment[4], payment[5]); + m_jreason.setEnabled(false); + jTotal.setEnabled(false); + jTotal.activate(); +// JG Added July 2011 + m_sNotes = (String) payment[6]; + m_jNotes.setEnabled(false); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { +//JG Modified Array + 1 - July 2011 + Object[] payment = new Object[7]; + payment[0] = m_sId == null ? UUID.randomUUID().toString() : m_sId; + payment[1] = m_App.getActiveCashIndex(); + payment[2] = datenew == null ? new Date() : datenew; + payment[3] = m_sPaymentId == null ? UUID.randomUUID().toString() : m_sPaymentId; + payment[4] = m_ReasonModel.getSelectedKey(); + PaymentReason reason = (PaymentReason) m_ReasonModel.getSelectedItem(); + Double dtotal = jTotal.getDoubleValue(); + payment[5] = reason == null ? dtotal : reason.addSignum(dtotal); +// JG Added July 2011 + String snotes = ""; + m_sNotes = m_jNotes.getText(); + payment[6] = m_sNotes == null ? snotes : m_sNotes; + return payment; + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + */ + @Override + public void refresh() { + } + + private void setReasonTotal(Object reasonfield, Object totalfield) { + + m_ReasonModel.setSelectedKey(reasonfield); + + PaymentReason reason = (PaymentReason) m_ReasonModel.getSelectedItem(); + + if (reason == null) { + jTotal.setDoubleValue((Double) totalfield); + } else { + jTotal.setDoubleValue(reason.positivize((Double) totalfield)); + } + } + + private static abstract class PaymentReason implements IKeyed { + private String m_sKey; + private String m_sText; + + public PaymentReason(String key, String text) { + m_sKey = key; + m_sText = text; + } + @Override + public Object getKey() { + return m_sKey; + } + public abstract Double positivize(Double d); + public abstract Double addSignum(Double d); + + @Override + public String toString() { + return m_sText; + } + } + private static class PaymentReasonPositive extends PaymentReason { + public PaymentReasonPositive(String key, String text) { + super(key, text); + } + @Override + public Double positivize(Double d) { + return d; + } + @Override + public Double addSignum(Double d) { + if (d == null) { + return null; + } else if (d.doubleValue() < 0.0) { + return new Double(-d.doubleValue()); + } else { + return d; + } + } + } + private static class PaymentReasonNegative extends PaymentReason { + public PaymentReasonNegative(String key, String text) { + super(key, text); + } + @Override + public Double positivize(Double d) { + return d == null ? null : new Double(-d.doubleValue()); + } + @Override + public Double addSignum(Double d) { + if (d == null) { + return null; + } else if (d.doubleValue() > 0.0) { + return new Double(-d.doubleValue()); + } else { + return d; + } + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel3 = new javax.swing.JPanel(); + jLabel5 = new javax.swing.JLabel(); + m_jreason = new javax.swing.JComboBox(); + jLabel3 = new javax.swing.JLabel(); + jTotal = new com.unicenta.editor.JEditorCurrency(); + m_jNotes = new com.unicenta.editor.JEditorString(); + jPanel2 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + + setLayout(new java.awt.BorderLayout()); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.paymentreason")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jreason.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jreason.setFocusable(false); + m_jreason.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.paymenttotal")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(110, 30)); + + jTotal.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTotal.setPreferredSize(new java.awt.Dimension(200, 30)); + + m_jNotes.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jNotes.setPreferredSize(new java.awt.Dimension(132, 100)); + + javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); + jPanel3.setLayout(jPanel3Layout); + jPanel3Layout.setHorizontalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(m_jNotes, javax.swing.GroupLayout.DEFAULT_SIZE, 234, Short.MAX_VALUE) + .addComponent(m_jreason, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTotal, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + jPanel3Layout.setVerticalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jreason, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jTotal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addComponent(m_jNotes, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + + add(jPanel3, java.awt.BorderLayout.CENTER); + + jPanel2.setLayout(new java.awt.BorderLayout()); + + m_jKeys.addPropertyChangeListener(new java.beans.PropertyChangeListener() { + public void propertyChange(java.beans.PropertyChangeEvent evt) { + m_jKeysPropertyChange(evt); + } + }); + jPanel2.add(m_jKeys, java.awt.BorderLayout.NORTH); + + add(jPanel2, java.awt.BorderLayout.LINE_END); + }// </editor-fold>//GEN-END:initComponents + + private void m_jKeysPropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_m_jKeysPropertyChange + + }//GEN-LAST:event_m_jKeysPropertyChange + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel5; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private com.unicenta.editor.JEditorCurrency jTotal; + private com.unicenta.editor.JEditorKeys m_jKeys; + private com.unicenta.editor.JEditorString m_jNotes; + private javax.swing.JComboBox m_jreason; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/panels/PaymentsModel.java b/src/main/java/com/unicenta/pos/panels/PaymentsModel.java new file mode 100644 index 0000000..bf8e9ce --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/PaymentsModel.java @@ -0,0 +1,1106 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.panels; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.*; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.util.StringUtils; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import javax.swing.table.AbstractTableModel; + +/** + * + * @authors adrianromero, jackgerrard, janarnagel + * + */ +public class PaymentsModel { + + private String m_sHost; + private String m_sUser; + private int m_iSeq; + private Date m_dDateStart; + private Date m_dDateEnd; + private Date rDate; + private Date m_dPrintDate; + + + private Integer m_iPayments; + private Double m_dPaymentsTotal; + private java.util.List<PaymentsLine> m_lpayments; + +// JG 9 Nov 12 + private Integer m_iCategorySalesRows; + private Double m_dCategorySalesTotalUnits; + private Double m_dCategorySalesTotal; + private java.util.List<CategorySalesLine> m_lcategorysales; +// end + + // by janar153 @ 01.12.2013 + private Integer m_iProductSalesRows; + private Double m_dProductSalesTotalUnits; + private Double m_dProductSalesTotal; + private java.util.List<ProductSalesLine> m_lproductsales; + // end + + // added by janar153 @ 29.12.2013 + private java.util.List<RemovedProductLines> m_lremovedlines; + + private java.util.List<DrawerOpenedLines> m_ldraweropenedlines; + + private final static String[] PAYMENTHEADERS = {"label.Payment", "label.Money"}; + + private Integer m_iSales; + private Double m_dSalesBase; + private Double m_dSalesTaxes; + private Double m_dSalesTaxNet; + private java.util.List<SalesLine> m_lsales; + + private final static String[] SALEHEADERS = {"label.taxcategory", "label.totaltax", "label.totalnet"}; + + private PaymentsModel() { + } + + /** + * + * @return + */ + public static PaymentsModel emptyInstance() { + + PaymentsModel p = new PaymentsModel(); + + p.m_iPayments = 0; + p.m_dPaymentsTotal = 0.0; +// JG 16 May 2013 use diamond inference + p.m_lpayments = new ArrayList<>(); + +// JG 9 Nov 12 + p.m_iCategorySalesRows = 0; + p.m_dCategorySalesTotalUnits = 0.0; + p.m_dCategorySalesTotal = 0.0; + p.m_lcategorysales = new ArrayList<>(); +// end + p.m_iSales = null; + p.m_dSalesBase = null; + p.m_dSalesTaxes = null; + p.m_dSalesTaxNet = null; + +// JG 16 May 2013 use diamond inference + + // by janar153 @ 01.12.2013 + p.m_iProductSalesRows = 0; + p.m_dProductSalesTotalUnits = 0.0; + p.m_dProductSalesTotal = 0.0; + p.m_lproductsales = new ArrayList<>(); + p.m_lremovedlines = new ArrayList<>(); + + p.m_lsales = new ArrayList<>(); + + return p; + } + + /** + * + * @param app + * @return + * @throws BasicException + */ + public static PaymentsModel loadInstance(AppView app) throws BasicException { + + PaymentsModel p = new PaymentsModel(); + + // Propiedades globales + p.m_sHost = app.getProperties().getHost(); + p.m_sUser = app.getAppUserView().getUser().getName(); + p.m_iSeq = app.getActiveCashSequence(); + p.m_dDateStart = app.getActiveCashDateStart(); + p.m_dDateEnd = null; + + + +// JG 9 Nov 12 + // Product category Sales + Object[] valcategorysales = (Object []) new StaticSentence(app.getSession() + , "SELECT COUNT(*), " + + "SUM(ticketlines.UNITS), " + + "SUM((ticketlines.PRICE + ticketlines.PRICE * taxes.RATE ) * ticketlines.UNITS) " + + "FROM ticketlines, tickets, receipts, taxes " + + "WHERE ticketlines.TICKET = tickets.ID AND tickets.ID = receipts.ID " + + "AND ticketlines.TAXID = taxes.ID " + + "AND ticketlines.PRODUCT IS NOT NULL " + + "AND receipts.MONEY = ? " + + "GROUP BY receipts.MONEY" + , SerializerWriteString.INSTANCE + , new SerializerReadBasic(new Datas[] {Datas.INT, Datas.DOUBLE, Datas.DOUBLE})) + .find(app.getActiveCashIndex()); + + if (valcategorysales == null) { + p.m_iCategorySalesRows = 0; + p.m_dCategorySalesTotalUnits = 0.0; + p.m_dCategorySalesTotal = 0.0; + } else { + p.m_iCategorySalesRows = (Integer) valcategorysales[0]; + p.m_dCategorySalesTotalUnits = (Double) valcategorysales[1]; + p.m_dCategorySalesTotal= (Double) valcategorysales[2]; + } + + List categorys = new StaticSentence(app.getSession() + , "SELECT a.NAME, sum(c.UNITS), sum(c.UNITS * (c.PRICE + (c.PRICE * d.RATE))) " + + "FROM categories as a " + + "LEFT JOIN products as b on a.id = b.CATEGORY " + + "LEFT JOIN ticketlines as c on b.id = c.PRODUCT " + + "LEFT JOIN taxes as d on c.TAXID = d.ID " + + "LEFT JOIN receipts as e on c.TICKET = e.ID " + + "WHERE e.MONEY = ? " + + "GROUP BY a.NAME" + , SerializerWriteString.INSTANCE + , new SerializerReadClass(PaymentsModel.CategorySalesLine.class)) + .list(app.getActiveCashIndex()); + + if (categorys == null) { + p.m_lcategorysales = new ArrayList(); + } else { + p.m_lcategorysales = categorys; + } +// end + + // Payments + Object[] valtickets = (Object []) new StaticSentence(app.getSession() + , "SELECT COUNT(*), SUM(payments.TOTAL) " + + "FROM payments, receipts " + + "WHERE payments.RECEIPT = receipts.ID AND receipts.MONEY = ?" + , SerializerWriteString.INSTANCE + , new SerializerReadBasic(new Datas[] {Datas.INT, Datas.DOUBLE})) + .find(app.getActiveCashIndex()); + + if (valtickets == null) { + p.m_iPayments = 0; + p.m_dPaymentsTotal = 0.0; + } else { + p.m_iPayments = (Integer) valtickets[0]; + p.m_dPaymentsTotal = (Double) valtickets[1]; + } + + List l = new StaticSentence(app.getSession(), + "SELECT payments.PAYMENT, SUM(payments.TOTAL), payments.NOTES " + + "FROM payments, receipts " + + "WHERE payments.RECEIPT = receipts.ID AND receipts.MONEY = ? " + + "GROUP BY payments.PAYMENT, payments.NOTES" + , SerializerWriteString.INSTANCE + , new SerializerReadClass(PaymentsModel.PaymentsLine.class)) + .list(app.getActiveCashIndex()); + + if (l == null) { + p.m_lpayments = new ArrayList(); + } else { + p.m_lpayments = l; + } + + // Sales + Object[] recsales = (Object []) new StaticSentence(app.getSession(), + "SELECT COUNT(DISTINCT receipts.ID), SUM(ticketlines.UNITS * ticketlines.PRICE) " + + "FROM receipts, ticketlines " + + "WHERE receipts.ID = ticketlines.TICKET AND receipts.MONEY = ?", + SerializerWriteString.INSTANCE, + new SerializerReadBasic(new Datas[] {Datas.INT, Datas.DOUBLE})) + .find(app.getActiveCashIndex()); + + if (recsales == null) { + p.m_iSales = null; + p.m_dSalesBase = null; + } else { + p.m_iSales = (Integer) recsales[0]; + p.m_dSalesBase = (Double) recsales[1]; + } + + // Taxes + Object[] rectaxes = (Object []) new StaticSentence(app.getSession(), + "SELECT SUM(taxlines.AMOUNT), SUM(taxlines.BASE) " + + "FROM receipts, taxlines " + + "WHERE receipts.ID = taxlines.RECEIPT AND receipts.MONEY = ?" + , SerializerWriteString.INSTANCE + , new SerializerReadBasic(new Datas[] {Datas.DOUBLE, Datas.DOUBLE})) + .find(app.getActiveCashIndex()); + + if (rectaxes == null) { + p.m_dSalesTaxes = null; + p.m_dSalesTaxNet = null; + } else { + p.m_dSalesTaxes = (Double) rectaxes[0]; + p.m_dSalesTaxNet = (Double) rectaxes[1]; + } + + // JG June 2014 Added .BASE for array + List<SalesLine> asales = new StaticSentence(app.getSession(), + "SELECT taxcategories.NAME, SUM(taxlines.AMOUNT), SUM(taxlines.BASE), SUM(taxlines.BASE + taxlines.AMOUNT) " + + "FROM receipts, taxlines, taxes, taxcategories " + + "WHERE receipts.ID = taxlines.RECEIPT AND taxlines.TAXID = taxes.ID AND taxes.CATEGORY = taxcategories.ID " + + "AND receipts.MONEY = ?" + + "GROUP BY taxcategories.NAME" + , SerializerWriteString.INSTANCE + , new SerializerReadClass(PaymentsModel.SalesLine.class)) + .list(app.getActiveCashIndex()); + + if (asales == null) { + p.m_lsales = new ArrayList<>(); + } else { + p.m_lsales = asales; + } + + // added by janar153 @ 29.12.2013 + // removed lines list + SimpleDateFormat ndf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String startDateFormatted = ndf.format(app.getActiveCashDateStart()); + List removedLines = new StaticSentence(app.getSession() + , "SELECT lineremoved.NAME, lineremoved.TICKETID, lineremoved.PRODUCTNAME, SUM(lineremoved.UNITS) AS TOTAL_UNITS " + + "FROM lineremoved " + + "WHERE lineremoved.REMOVEDDATE > ? " + + "GROUP BY lineremoved.NAME, lineremoved.TICKETID, lineremoved.PRODUCTNAME" + , SerializerWriteString.INSTANCE + , new SerializerReadClass(PaymentsModel.RemovedProductLines.class)) //new SerializerReadBasic(new Datas[] {Datas.STRING, Datas.DOUBLE})) + .list(startDateFormatted); + + if (removedLines == null) { + p.m_lremovedlines = new ArrayList(); + } else { + p.m_lremovedlines = removedLines; + } + +/** + * JG Dec 14 + * Open Drawer List +*/ + + List drawerOpenedLines = new StaticSentence(app.getSession() + , "SELECT OPENDATE, NAME, TICKETID " + + "FROM draweropened " + + "WHERE TICKETID = 'No Sale' AND OPENDATE > ? " + + "GROUP BY NAME, OPENDATE, TICKETID" + , SerializerWriteString.INSTANCE + , new SerializerReadClass(PaymentsModel.DrawerOpenedLines.class)) //new SerializerReadBasic(new Datas[] {Datas.STRING, Datas.DOUBLE})) + .list(startDateFormatted); + + if (drawerOpenedLines == null) { + p.m_ldraweropenedlines = new ArrayList(); + } else { + p.m_ldraweropenedlines = drawerOpenedLines; + } + + // by janar153 @ 01.12.2013 + // Product Sales + Object[] valproductsales = (Object []) new StaticSentence(app.getSession() + , "SELECT COUNT(*), SUM(ticketlines.UNITS), " + + "SUM((ticketlines.PRICE + ticketlines.PRICE * taxes.RATE ) * ticketlines.UNITS) " + + "FROM ticketlines, tickets, receipts, taxes " + + "WHERE ticketlines.TICKET = tickets.ID " + + "AND tickets.ID = receipts.ID " + + "AND ticketlines.TAXID = taxes.ID " + + "AND ticketlines.PRODUCT IS NOT NULL " + + "AND receipts.MONEY = ? " + + "GROUP BY receipts.MONEY" + , SerializerWriteString.INSTANCE + , new SerializerReadBasic(new Datas[] {Datas.INT, Datas.DOUBLE, Datas.DOUBLE})) + .find(app.getActiveCashIndex()); + + if (valproductsales == null) { + p.m_iProductSalesRows = 0; + p.m_dProductSalesTotalUnits = 0.0; + p.m_dProductSalesTotal = 0.0; + } else { + p.m_iProductSalesRows = (Integer) valproductsales[0]; + p.m_dProductSalesTotalUnits = (Double) valproductsales[1]; + p.m_dProductSalesTotal= (Double) valproductsales[2]; + } + + List products = new StaticSentence(app.getSession() + , "SELECT products.NAME, SUM(ticketlines.UNITS), ticketlines.PRICE, taxes.RATE " + + "FROM ticketlines, tickets, receipts, products, taxes " + + "WHERE ticketlines.PRODUCT = products.ID " + + "AND ticketlines.TICKET = tickets.ID " + + "AND tickets.ID = receipts.ID " + + "AND ticketlines.TAXID = taxes.ID " + + "AND receipts.MONEY = ? " + + "GROUP BY products.NAME, ticketlines.PRICE, taxes.RATE" + , SerializerWriteString.INSTANCE + , new SerializerReadClass(PaymentsModel.ProductSalesLine.class)) + .list(app.getActiveCashIndex()); + + if (products == null) { + p.m_lproductsales = new ArrayList(); + } else { + p.m_lproductsales = products; + } + + return p; + } + + /** + * + * @return + */ + public int getPayments() { + return m_iPayments; + } + + /** + * + * @return + */ + public double getTotal() { + return m_dPaymentsTotal; + } + + /** + * + * @return + */ + public String getHost() { + return m_sHost; + } + /** + * + * @return + */ + public String getUser() { + return m_sUser; + } + + /** + * + * @return + */ + public int getSequence() { + return m_iSeq; + } + + public String getPrintDate() { + Date m_dPrintDate = new Date(); + return Formats.TIMESTAMP.formatValue(m_dPrintDate); + } + /** + * + * @return + */ + public Date getDateStart() { + return m_dDateStart; + } + + /** + * + * @param dValue + */ + public void setDateEnd(Date dValue) { + m_dDateEnd = dValue; + } + + /** + * + * @return + */ + public Date getDateEnd() { + return m_dDateEnd; + } + + /** + * + * @return + */ + public String getDateStartDerby(){ + SimpleDateFormat ndf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return ndf.format(m_dDateStart); + } + + /** + * + * @return + */ + public String printHost() { +// return m_sHost; + return StringUtils.encodeXML(m_sHost); + } + + /** + * + * @return + */ + public String printUser() { + return StringUtils.encodeXML(m_sUser); + } + + /** + * + * @return + */ + public String printSequence() { + return Formats.INT.formatValue(m_iSeq); + } + + public String printDate() { + Date m_dPrintDate = new Date(); + return Formats.TIMESTAMP.formatValue(m_dPrintDate); + } + + + /** + * + * @return + */ + public String printDateStart() { + return Formats.TIMESTAMP.formatValue(m_dDateStart); + } + + /** + * + * @return + */ + public String printDateEnd() { + return Formats.TIMESTAMP.formatValue(m_dDateEnd); + } + + /** + * + * @return + */ + public String printPayments() { + return Formats.INT.formatValue(m_iPayments); + } + + /** + * + * @return + */ + public String printPaymentsTotal() { + return Formats.CURRENCY.formatValue(m_dPaymentsTotal); + } + + /** + * + * @return + */ + public List<PaymentsLine> getPaymentLines() { + return m_lpayments; + } + + /** + * + * @return + */ + public int getSales() { + return m_iSales == null ? 0 : m_iSales; + } + + /** + * + * @return + */ + public String printSales() { + return Formats.INT.formatValue(m_iSales); + } + + /** + * + * @return + */ + public String printSalesBase() { + return Formats.CURRENCY.formatValue(m_dSalesBase); + } + + /** + * + * @return + */ + public String printSalesTaxes() { + return Formats.CURRENCY.formatValue(m_dSalesTaxes); + } + + /** + * + * @return + */ + public String printSalesTotal() { + return Formats.CURRENCY.formatValue((m_dSalesBase == null || m_dSalesTaxes == null) + ? null + : m_dSalesBase + m_dSalesTaxes); + } + + /** + * + * @return + */ + public List<SalesLine> getSaleLines() { + return m_lsales; + } + +// JG 9 Nov 12 + + /** + * + * @return + */ + public double getCategorySalesRows() { + return m_iCategorySalesRows; + } + + /** + * + * @return + */ + public String printCategorySalesRows() { + return Formats.INT.formatValue(m_iCategorySalesRows); + } + + /** + * + * @return + */ + public double getCategorySalesTotalUnits() { + return m_dCategorySalesTotalUnits; + } + + /** + * + * @return + */ + public String printCategorySalesTotalUnits() { + return Formats.DOUBLE.formatValue(m_dCategorySalesTotalUnits); + } + + /** + * + * @return + */ + public double getCategorySalesTotal() { + return m_dCategorySalesTotal; + } + + /** + * + * @return + */ + public String printCategorySalesTotal() { + return Formats.CURRENCY.formatValue(m_dCategorySalesTotal); + } + + /** + * + * @return + */ + public List<CategorySalesLine> getCategorySalesLines() { + return m_lcategorysales; + } +// end + + // by janar153 @ 01.12.2013 + + /** + * + * @return + */ + public double getProductSalesRows() { + return m_iProductSalesRows; + } + + /** + * + * @return + */ + public String printProductSalesRows() { + return Formats.INT.formatValue(m_iProductSalesRows); + } + + /** + * + * @return + */ + public double getProductSalesTotalUnits() { + return m_dProductSalesTotalUnits; + } + + /** + * + * @return + */ + public String printProductSalesTotalUnits() { + return Formats.DOUBLE.formatValue(m_dProductSalesTotalUnits); + } + + /** + * + * @return + */ + public double getProductSalesTotal() { + return m_dProductSalesTotal; + } + + /** + * + * @return + */ + public String printProductSalesTotal() { + return Formats.CURRENCY.formatValue(m_dProductSalesTotal); + } + + /** + * + * @return + */ + public List<ProductSalesLine> getProductSalesLines() { + return m_lproductsales; + } + // end + + /** + * janar153 @ 29.12.2013 + * @return + */ + public List<RemovedProductLines> getRemovedProductLines() { + return m_lremovedlines; + } + + /** + * JG Dec 14 + * @return + */ + public List<DrawerOpenedLines> getDrawerOpenedLines() { + return m_ldraweropenedlines; + } + + /** + * + * @return + */ + public AbstractTableModel getPaymentsModel() { + return new AbstractTableModel() { + @Override + public String getColumnName(int column) { + return AppLocal.getIntString(PAYMENTHEADERS[column]); + } + @Override + public int getRowCount() { + return m_lpayments.size(); + } + @Override + public int getColumnCount() { + return PAYMENTHEADERS.length; + } + @Override + public Object getValueAt(int row, int column) { + PaymentsLine l = m_lpayments.get(row); + switch (column) { + case 0: return l.getType(); + case 1: return l.getValue(); + default: return null; + } + } + }; + } + +// JG 9 Nov 12 + // Products category sales class + + /** + * + */ + public static class CategorySalesLine implements SerializableRead { + + private String m_CategoryName; + private Double m_CategoryUnits; + private Double m_CategorySum; + + /** + * + * @param dr + * @throws BasicException + */ + @Override + public void readValues(DataRead dr) throws BasicException { + m_CategoryName = dr.getString(1); + m_CategoryUnits = dr.getDouble(2); + m_CategorySum = dr.getDouble(3); + } + + /** + * + * @return + */ + public String printCategoryName() { + return m_CategoryName; + } + + /** + * + * @return + */ + public String printCategoryUnits() { + return Formats.DOUBLE.formatValue(m_CategoryUnits); + } + + /** + * + * @return + */ + public Double getCategoryUnits() { + return m_CategoryUnits; + } + + /** + * + * @return + */ + public String printCategorySum() { + return Formats.CURRENCY.formatValue(m_CategorySum); + } + + /** + * + * @return + */ + public Double getCategorySum() { + return m_CategorySum; + } + } +// end + + /** + * janar153 @ 29.12.2013 + */ + public static class RemovedProductLines implements SerializableRead { + + private String m_Name; + private String m_TicketId; + private String m_ProductName; + private Double m_TotalUnits; + + @Override + public void readValues(DataRead dr) throws BasicException { + m_Name = dr.getString(1); + m_TicketId = dr.getString(2); + m_ProductName = dr.getString(3); + m_TotalUnits = dr.getDouble(4); + } + + public String printWorkerName() { + return StringUtils.encodeXML(m_Name); + } + + public String printTicketId() { + return StringUtils.encodeXML(m_TicketId); + } + + public String printProductName() { + return StringUtils.encodeXML(m_ProductName); + } + + public String printTotalUnits() { + return Formats.DOUBLE.formatValue(m_TotalUnits); + } + + } + + /** + * JG Dec 14 + */ + public static class DrawerOpenedLines implements SerializableRead { + + private String m_DrawerOpened; + private String m_Name; + private String m_TicketId; + + @Override + public void readValues(DataRead dr) throws BasicException { + m_DrawerOpened = dr.getString(1); + m_Name = dr.getString(2); + m_TicketId = dr.getString(3); + } + + public String printDrawerOpened() { + return StringUtils.encodeXML(m_DrawerOpened); + } + + public String printUserName() { + return StringUtils.encodeXML(m_Name); + } + + public String printTicketId() { + return StringUtils.encodeXML(m_TicketId); + } + } + + public static class ProductSalesLine implements SerializableRead { + + private String m_ProductName; + private Double m_ProductUnits; + private Double m_ProductPrice; + private Double m_TaxRate; + private Double m_ProductPriceTax; + private Double m_ProductPriceNet; //JG 7 June 2014 + + @Override + public void readValues(DataRead dr) throws BasicException { + m_ProductName = dr.getString(1); + m_ProductUnits = dr.getDouble(2); + m_ProductPrice = dr.getDouble(3); + m_TaxRate = dr.getDouble(4); + + m_ProductPriceTax = m_ProductPrice + m_ProductPrice*m_TaxRate; + m_ProductPriceNet = m_ProductPrice * m_TaxRate; + } + + public String printProductName() { + return StringUtils.encodeXML(m_ProductName); + } + + public String printProductUnits() { + return Formats.DOUBLE.formatValue(m_ProductUnits); + } + + public Double getProductUnits() { + return m_ProductUnits; + } + + public String printProductPrice() { + return Formats.CURRENCY.formatValue(m_ProductPrice); + } + + public Double getProductPrice() { + return m_ProductPrice; + } + + public String printTaxRate() { + return Formats.PERCENT.formatValue(m_TaxRate); + } + + public Double getTaxRate() { + return m_TaxRate; + } + + public String printProductPriceTax() { + return Formats.CURRENCY.formatValue(m_ProductPriceTax); + } + + public String printProductSubValue() { + return Formats.CURRENCY.formatValue(m_ProductPriceTax*m_ProductUnits); + } + + /** + * JG 4 Jun 2014 + * @return + */ + public String printProductPriceNet() { + return Formats.CURRENCY.formatValue(m_ProductPrice*m_ProductUnits); + } + + } + + public static class SalesLine implements SerializableRead { + + private String m_SalesTaxName; + private Double m_SalesTaxes; + private Double m_SalesTaxNet; //JG June 2014 + private Double m_SalesTaxGross; //JG June 2014 + /** + * + * @param dr + * @throws BasicException + */ + @Override + public void readValues(DataRead dr) throws BasicException { + m_SalesTaxName = dr.getString(1); + m_SalesTaxes = dr.getDouble(2); + m_SalesTaxNet = dr.getDouble(3); //JG June 2014 + m_SalesTaxGross = dr.getDouble(4); //JG June 2014 + } + + /** + * + * @return + */ + public String printTaxName() { + return m_SalesTaxName; + } + + /** + * + * @return + */ + public String printTaxes() { + return Formats.CURRENCY.formatValue(m_SalesTaxes); + } + + /** + * JG June 2014 + * @return + */ + public String printTaxNet() { + return Formats.CURRENCY.formatValue(m_SalesTaxNet); + } + + /** + * JG June 2014 + * @return + */ + public String printTaxGross() { + return Formats.CURRENCY.formatValue(m_SalesTaxes + m_SalesTaxNet); + } + + + /** + * + * @return + */ + public String getTaxName() { + return m_SalesTaxName; + } + + /** + * + * @return + */ + public Double getTaxes() { + return m_SalesTaxes; + } + + /** + * JG June 2014 + * @return + */ + public Double getTaxNet() { + return m_SalesTaxNet; + } + + /** + * JG June 2014 + * @return + */ + public Double getTaxGross() { + return m_SalesTaxGross; + } + + + + } + + /** + * + * @return + */ + public AbstractTableModel getSalesModel() { + return new AbstractTableModel() { + @Override + public String getColumnName(int column) { + return AppLocal.getIntString(SALEHEADERS[column]); + } + @Override + public int getRowCount() { + return m_lsales.size(); + } + @Override + public int getColumnCount() { + return SALEHEADERS.length; + } + @Override + public Object getValueAt(int row, int column) { + SalesLine l = m_lsales.get(row); + switch (column) { + case 0: return l.getTaxName(); + case 1: return l.getTaxes(); + case 2: return l.getTaxNet(); //JG June 2014 + default: return null; + } + } + }; + } + + /** + * + */ + public static class PaymentsLine implements SerializableRead { + + private String m_PaymentType; + private Double m_PaymentValue; +// JG 1 Oct 13 - Add Payment Reason for Partial Cash - thanks Shaun Cains + private String s_PaymentReason; + + /** + * + * @param dr + * @throws BasicException + */ + @Override + public void readValues(DataRead dr) throws BasicException { + m_PaymentType = dr.getString(1); + m_PaymentValue = dr.getDouble(2); + s_PaymentReason=dr.getString(3) == null ? "": dr.getString(3); + } + + /** + * + * @return + */ + public String printType() { + return AppLocal.getIntString("transpayment." + m_PaymentType); + } + + /** + * + * @return + */ + public String getType() { + return m_PaymentType; + } + + /** + * + * @return + */ + public String printValue() { + return Formats.CURRENCY.formatValue(m_PaymentValue); + } + + /** + * + * @return + */ + public Double getValue() { + return m_PaymentValue; + } + + /** + * + * @return + */ + public String printReason() { + return s_PaymentReason; + } + + /** + * + * @return + */ + public String getReason() { + return s_PaymentReason; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/panels/PaymentsReprintModel.java b/src/main/java/com/unicenta/pos/panels/PaymentsReprintModel.java new file mode 100644 index 0000000..5fef018 --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/PaymentsReprintModel.java @@ -0,0 +1,1097 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.panels; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.*; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.util.StringUtils; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * October 2018 + * + * @authors JG + */ +@Slf4j +public class PaymentsReprintModel { + + private String m_sHost; + private String m_sUser; + private int m_iSeq; + + private String m_dDateStart; + private String m_dDateEnd; + private Date rDate; + private Date m_dPrintDate; + + + private Integer m_iPayments; + private Double m_dPaymentsTotal; + private java.util.List<PaymentsLine> m_lpayments; + + private Integer m_iCategorySalesRows; + private Double m_dCategorySalesTotalUnits; + private Double m_dCategorySalesTotal; + private java.util.List<CategorySalesLine> m_lcategorysales; + + private Integer m_iProductSalesRows; + private Double m_dProductSalesTotalUnits; + private Double m_dProductSalesTotal; + private java.util.List<ProductSalesLine> m_lproductsales; + + private java.util.List<RemovedProductLines> m_lremovedlines; + + private java.util.List<DrawerOpenedLines> m_ldraweropenedlines; + + private final static String[] PAYMENTHEADERS = {"label.Payment", "label.Money"}; + + private Integer m_iSales; + private Double m_dSalesBase; + private Double m_dSalesTaxes; + private Double m_dSalesTaxNet; + private java.util.List<SalesLine> m_lsales; + + private final static String[] SALEHEADERS = {"label.taxcategory", "label.totaltax", "label.totalnet"}; + + private PaymentsReprintModel() { + } + + /** + * @return + */ + public static PaymentsReprintModel emptyInstance() { + + PaymentsReprintModel p = new PaymentsReprintModel(); + + p.m_iPayments = 0; + p.m_dPaymentsTotal = 0.0; + p.m_lpayments = new ArrayList<>(); + + p.m_iCategorySalesRows = 0; + p.m_dCategorySalesTotalUnits = 0.0; + p.m_dCategorySalesTotal = 0.0; + p.m_lcategorysales = new ArrayList<>(); + + p.m_iSales = 0; + p.m_dSalesBase = 0.0; + p.m_dSalesTaxes = 0.0; + p.m_dSalesTaxNet = 0.0; + + p.m_iProductSalesRows = 0; + p.m_dProductSalesTotalUnits = 0.0; + p.m_dProductSalesTotal = 0.0; + p.m_lproductsales = new ArrayList<>(); + p.m_lremovedlines = new ArrayList<>(); + + p.m_lsales = new ArrayList<>(); + + return p; + } + + /** + * @param app + * @return + * @throws BasicException + */ + public static PaymentsReprintModel loadInstance(AppView app) throws BasicException { + + PaymentsReprintModel p = new PaymentsReprintModel(); + + p.m_sUser = app.getAppUserView().getUser().getName(); + p.m_sHost = app.getProperties().getHost(); + + JFrame frame = new JFrame("Sequence"); + String sequence = JOptionPane.showInputDialog(frame, + AppLocal.getIntString("message.ccentersequence"), + JOptionPane.INFORMATION_MESSAGE); + if (sequence != null) { + int isequence = Integer.parseInt(sequence); + p.m_iSeq = isequence; + } else { + app.getAppUserView().showTask("com.unicenta.pos.panels.JPanelCloseMoneyReprint"); + } + + Object[] ccash; + ccash = (Object[]) new StaticSentence(app.getSession(), + "SELECT money, host, hostsequence, datestart, dateend, nosales " + + "FROM closedcash " + + "where hostsequence = ? and dateend is not null " + + "AND host = " + "'" + app.getProperties().getHost() + "'" + , SerializerWriteString.INSTANCE + , new SerializerReadBasic(new Datas[]{ + Datas.STRING, Datas.STRING, Datas.INT, Datas.STRING, Datas.STRING, Datas.INT})) + .find(sequence); + + if (ccash == null) { + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.ccsequencenotfound"), + "", + JOptionPane.WARNING_MESSAGE); + } else { + p.m_dDateStart = ccash[3].toString(); + p.m_dDateEnd = ccash[4].toString(); + + // Product category Sales + Object[] valcategorysales = (Object[]) new StaticSentence(app.getSession() + , "SELECT COUNT(*), " + + "SUM(ticketlines.UNITS), " + + "SUM((ticketlines.PRICE + ticketlines.PRICE * taxes.RATE ) * ticketlines.UNITS) " + + "FROM ticketlines, tickets, receipts, taxes " + + "WHERE ticketlines.TICKET = tickets.ID " + + "AND tickets.ID = receipts.ID " + + "AND ticketlines.TAXID = taxes.ID " + + "AND ticketlines.PRODUCT IS NOT NULL " + + "AND receipts.MONEY = ? " + + "GROUP BY receipts.MONEY" + , SerializerWriteString.INSTANCE + , new SerializerReadBasic(new Datas[]{Datas.INT, Datas.DOUBLE, Datas.DOUBLE})) + .find(ccash[0]); + + if (valcategorysales == null) { + p.m_iCategorySalesRows = 0; + p.m_dCategorySalesTotalUnits = 0.0; + p.m_dCategorySalesTotal = 0.0; + } else { + p.m_iCategorySalesRows = (Integer) valcategorysales[0]; + p.m_dCategorySalesTotalUnits = (Double) valcategorysales[1]; + p.m_dCategorySalesTotal = (Double) valcategorysales[2]; + } + + List categorys = new StaticSentence(app.getSession() + , "SELECT a.NAME, sum(c.UNITS), sum(c.UNITS * (c.PRICE + (c.PRICE * d.RATE))) " + + "FROM categories as a " + + "LEFT JOIN products as b on a.id = b.CATEGORY " + + "LEFT JOIN ticketlines as c on b.id = c.PRODUCT " + + "LEFT JOIN taxes as d on c.TAXID = d.ID " + + "LEFT JOIN receipts as e on c.TICKET = e.ID " + + "WHERE e.MONEY = ? " + + "GROUP BY a.NAME" + , SerializerWriteString.INSTANCE + , new SerializerReadClass(PaymentsReprintModel.CategorySalesLine.class)) + .list(ccash[0]); + + if (categorys == null) { + p.m_lcategorysales = new ArrayList(); + } else { + p.m_lcategorysales = categorys; + } + + // Payments + Object[] valtickets = (Object[]) new StaticSentence(app.getSession() + , "SELECT COUNT(*), SUM(payments.TOTAL) " + + "FROM payments, receipts " + + "WHERE payments.RECEIPT = receipts.ID AND receipts.MONEY = ?" + , SerializerWriteString.INSTANCE + , new SerializerReadBasic(new Datas[]{Datas.INT, Datas.DOUBLE})) + .find(ccash[0]); + + if (valtickets == null) { + p.m_iPayments = 0; + p.m_dPaymentsTotal = 0.0; + } else { + p.m_iPayments = (Integer) valtickets[0]; + p.m_dPaymentsTotal = (Double) valtickets[1]; + } + + List l = new StaticSentence(app.getSession(), + "SELECT payments.PAYMENT, SUM(payments.TOTAL), payments.NOTES " + + "FROM payments, receipts " + + "WHERE payments.RECEIPT = receipts.ID AND receipts.MONEY = ? " + + "GROUP BY payments.PAYMENT, payments.NOTES" + , SerializerWriteString.INSTANCE + , new SerializerReadClass(PaymentsReprintModel.PaymentsLine.class)) + .list(ccash[0]); + + if (l == null) { + p.m_lpayments = new ArrayList(); + } else { + p.m_lpayments = l; + } + + // Sales + Object[] recsales = (Object[]) new StaticSentence(app.getSession(), + "SELECT COUNT(DISTINCT receipts.ID), SUM(ticketlines.UNITS * ticketlines.PRICE) " + + "FROM receipts, ticketlines " + + "WHERE receipts.ID = ticketlines.TICKET AND receipts.MONEY = ?" + , SerializerWriteString.INSTANCE, + new SerializerReadBasic(new Datas[]{Datas.INT, Datas.DOUBLE})) + .find(ccash[0]); + + if (recsales == null) { + p.m_iSales = null; + p.m_dSalesBase = null; + } else { + p.m_iSales = (Integer) recsales[0]; + p.m_dSalesBase = (Double) recsales[1]; + } + + // Taxes + Object[] rectaxes = (Object[]) new StaticSentence(app.getSession(), + "SELECT SUM(taxlines.AMOUNT), SUM(taxlines.BASE) " + + "FROM receipts, taxlines " + + "WHERE receipts.ID = taxlines.RECEIPT AND receipts.MONEY = ?" + , SerializerWriteString.INSTANCE + , new SerializerReadBasic(new Datas[]{ + Datas.DOUBLE, Datas.DOUBLE})) + .find(ccash[0]); + + if (rectaxes == null) { + p.m_dSalesTaxes = null; + p.m_dSalesTaxNet = null; + } else { + p.m_dSalesTaxes = (Double) rectaxes[0]; + p.m_dSalesTaxNet = (Double) rectaxes[1]; + } + + List<SalesLine> asales = new StaticSentence(app.getSession(), + "SELECT taxcategories.NAME, SUM(taxlines.AMOUNT), SUM(taxlines.BASE), " + + "SUM(taxlines.BASE + taxlines.AMOUNT) " + + "FROM receipts, taxlines, taxes, taxcategories " + + "WHERE receipts.ID = taxlines.RECEIPT AND taxlines.TAXID = taxes.ID AND taxes.CATEGORY = taxcategories.ID " + + "AND receipts.MONEY = ? " + + "GROUP BY taxcategories.NAME" + , SerializerWriteString.INSTANCE + , new SerializerReadClass(PaymentsReprintModel.SalesLine.class)) + .list(ccash[0]); + + if (asales == null) { + p.m_lsales = new ArrayList<>(); + } else { + p.m_lsales = asales; + } + + List removedLines = new StaticSentence(app.getSession() + , "SELECT lineremoved.NAME, lineremoved.TICKETID, lineremoved.PRODUCTNAME, " + + "SUM(lineremoved.UNITS) AS TOTAL_UNITS " + + "FROM lineremoved " + + "WHERE lineremoved.REMOVEDDATE > " + "'" + p.m_dDateStart + "'" + " " + + "GROUP BY lineremoved.NAME, lineremoved.TICKETID, lineremoved.PRODUCTNAME" + , SerializerWriteString.INSTANCE + , new SerializerReadClass(PaymentsReprintModel.RemovedProductLines.class)) + .list(p.m_dDateStart); + + if (removedLines == null) { + p.m_lremovedlines = new ArrayList(); + } else { + p.m_lremovedlines = removedLines; + } + + List drawerOpenedLines = new StaticSentence(app.getSession() + , "SELECT OPENDATE, NAME, TICKETID " + + "FROM draweropened " + + "WHERE TICKETID = 'No Sale' AND OPENDATE > ? " + + "GROUP BY NAME, OPENDATE, TICKETID" + , SerializerWriteString.INSTANCE + , new SerializerReadClass(PaymentsReprintModel.DrawerOpenedLines.class)) + .list(p.m_dDateStart); + + if (drawerOpenedLines == null) { + p.m_ldraweropenedlines = new ArrayList(); + } else { + p.m_ldraweropenedlines = drawerOpenedLines; + } + + // Product Sales + Object[] valproductsales = (Object[]) new StaticSentence(app.getSession() + , "SELECT COUNT(*), SUM(ticketlines.UNITS), " + + "SUM((ticketlines.PRICE + ticketlines.PRICE * taxes.RATE ) * ticketlines.UNITS) " + + "FROM ticketlines, tickets, receipts, taxes " + + "WHERE ticketlines.TICKET = tickets.ID " + + "AND tickets.ID = receipts.ID " + + "AND ticketlines.TAXID = taxes.ID " + + "AND ticketlines.PRODUCT IS NOT NULL " + + "AND receipts.MONEY = ? " + + "GROUP BY receipts.MONEY" + , SerializerWriteString.INSTANCE + , new SerializerReadBasic(new Datas[]{Datas.INT, Datas.DOUBLE, Datas.DOUBLE})) + .find(ccash[0]); + + if (valproductsales == null) { + p.m_iProductSalesRows = 0; + p.m_dProductSalesTotalUnits = 0.0; + p.m_dProductSalesTotal = 0.0; + } else { + p.m_iProductSalesRows = (Integer) valproductsales[0]; + p.m_dProductSalesTotalUnits = (Double) valproductsales[1]; + p.m_dProductSalesTotal = (Double) valproductsales[2]; + } + + List products = new StaticSentence(app.getSession() + , "SELECT products.NAME, SUM(ticketlines.UNITS), ticketlines.PRICE, taxes.RATE " + + "FROM ticketlines, tickets, receipts, products, taxes " + + "WHERE ticketlines.PRODUCT = products.ID " + + "AND ticketlines.TICKET = tickets.ID " + + "AND tickets.ID = receipts.ID " + + "AND ticketlines.TAXID = taxes.ID " + + "AND receipts.MONEY = ? " + + "GROUP BY products.NAME, ticketlines.PRICE, taxes.RATE" + , SerializerWriteString.INSTANCE + , new SerializerReadClass(PaymentsReprintModel.ProductSalesLine.class)) + .list(ccash[0]); + + if (products == null) { + p.m_lproductsales = new ArrayList(); + } else { + p.m_lproductsales = products; + } + + return p; + } + + return null; + } + + /** + * @return + */ + public int getPayments() { + return m_iPayments; + } + + /** + * @return + */ + public double getTotal() { + return m_dPaymentsTotal; + } + + /** + * @return + */ + public String getHost() { + return m_sHost; + } + + /** + * @return + */ + public String getUser() { + return m_sUser; + } + + /** + * @return + */ + public int getSequence() { + return m_iSeq; + } + + public String getPrintDate() { + Date m_dPrintDate = new Date(); + return Formats.TIMESTAMP.formatValue(m_dPrintDate); + } + + /** + * @return + */ + public String getDateStart() { + return m_dDateStart; + } + + /** + * @param dValue + */ + public void setDateEnd(String dValue) { + m_dDateEnd = dValue; + } + + /** + * @return + */ + public String getDateEnd() { + return m_dDateEnd; + } + + /** + * @return + */ + public String getDateStartDerby() { + SimpleDateFormat ndf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return ndf.format(m_dDateStart); + } + + /** + * @return + */ + public String printHost() { + return StringUtils.encodeXML(m_sHost); + } + + /** + * @return + */ + public String printUser() { + return StringUtils.encodeXML(m_sUser); + } + + /** + * @return + */ + public String printSequence() { + return Formats.INT.formatValue(m_iSeq); + } + + public String printDate() { + Date m_dPrintDate = new Date(); + return Formats.TIMESTAMP.formatValue(m_dPrintDate); + } + + + /** + * @return + */ + public String printDateStart() { +// return Formats.TIMESTAMP.formatValue(m_dDateStart); + return m_dDateStart; + } + + public String reformDateStart() { + + SimpleDateFormat sdfIn = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + SimpleDateFormat sdfOut = new SimpleDateFormat("dd MMM yyyy HH:mm:ss"); + String input = m_dDateStart; + Date date = null; + try { + date = sdfIn.parse(input); + } catch (ParseException ex) { + log.error(ex.getMessage()); + } + +// System.out.println(sdfOut.format(date)); + m_dDateStart = sdfOut.format(date); + + return m_dDateStart; + } + + public String reformDateEnd() { + + SimpleDateFormat sdfIn = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + SimpleDateFormat sdfOut = new SimpleDateFormat("dd MMM yyyy HH:mm:ss"); + String input = m_dDateEnd; + Date date = null; + try { + date = sdfIn.parse(input); + } catch (ParseException ex) { + log.error(ex.getMessage()); + } + +// System.out.println(sdfOut.format(date)); + m_dDateEnd = sdfOut.format(date); + + return m_dDateEnd; + } + + /** + * @return + */ + public String printDateEnd() { +// return Formats.TIMESTAMP.formatValue(m_dDateEnd); + return m_dDateEnd; + } + + /** + * @return + */ + public String printPayments() { + return Formats.INT.formatValue(m_iPayments); + } + + /** + * @return + */ + public String printPaymentsTotal() { + return Formats.CURRENCY.formatValue(m_dPaymentsTotal); + } + + /** + * @return + */ + public List<PaymentsLine> getPaymentLines() { + return m_lpayments; + } + + /** + * @return + */ + public int getSales() { + return m_iSales == null ? 0 : m_iSales; + } + + /** + * @return + */ + public String printSales() { + return Formats.INT.formatValue(m_iSales); + } + + /** + * @return + */ + public String printSalesBase() { + return Formats.CURRENCY.formatValue(m_dSalesBase); + } + + /** + * @return + */ + public String printSalesTaxes() { + return Formats.CURRENCY.formatValue(m_dSalesTaxes); + } + + /** + * @return + */ + public String printSalesTotal() { + return Formats.CURRENCY.formatValue((m_dSalesBase == null || m_dSalesTaxes == null) + ? null + : m_dSalesBase + m_dSalesTaxes); + } + + /** + * @return + */ + public List<SalesLine> getSaleLines() { + return m_lsales; + } + + /** + * @return + */ + public double getCategorySalesRows() { + return m_iCategorySalesRows; + } + + /** + * @return + */ + public String printCategorySalesRows() { + return Formats.INT.formatValue(m_iCategorySalesRows); + } + + /** + * @return + */ + public double getCategorySalesTotalUnits() { + return m_dCategorySalesTotalUnits; + } + + /** + * @return + */ + public String printCategorySalesTotalUnits() { + return Formats.DOUBLE.formatValue(m_dCategorySalesTotalUnits); + } + + /** + * @return + */ + public double getCategorySalesTotal() { + return m_dCategorySalesTotal; + } + + /** + * @return + */ + public String printCategorySalesTotal() { + return Formats.CURRENCY.formatValue(m_dCategorySalesTotal); + } + + /** + * @return + */ + public List<CategorySalesLine> getCategorySalesLines() { + return m_lcategorysales; + } + + + /** + * @return + */ + public double getProductSalesRows() { + return m_iProductSalesRows; + } + + /** + * @return + */ + public String printProductSalesRows() { + return Formats.INT.formatValue(m_iProductSalesRows); + } + + /** + * @return + */ + public double getProductSalesTotalUnits() { + return m_dProductSalesTotalUnits; + } + + /** + * @return + */ + public String printProductSalesTotalUnits() { + return Formats.DOUBLE.formatValue(m_dProductSalesTotalUnits); + } + + /** + * @return + */ + public double getProductSalesTotal() { + return m_dProductSalesTotal; + } + + /** + * @return + */ + public String printProductSalesTotal() { + return Formats.CURRENCY.formatValue(m_dProductSalesTotal); + } + + /** + * @return + */ + public List<ProductSalesLine> getProductSalesLines() { + return m_lproductsales; + } + + /** + * @return + */ + public List<RemovedProductLines> getRemovedProductLines() { + return m_lremovedlines; + } + + /** + * JG Dec 14 + * + * @return + */ + public List<DrawerOpenedLines> getDrawerOpenedLines() { + return m_ldraweropenedlines; + } + + /** + * @return + */ + public AbstractTableModel getPaymentsReprintModel() { + return new AbstractTableModel() { + @Override + public String getColumnName(int column) { + return AppLocal.getIntString(PAYMENTHEADERS[column]); + } + + @Override + public int getRowCount() { + return m_lpayments.size(); + } + + @Override + public int getColumnCount() { + return PAYMENTHEADERS.length; + } + + @Override + public Object getValueAt(int row, int column) { + PaymentsLine l = m_lpayments.get(row); + switch (column) { + case 0: + return l.getType(); + case 1: + return l.getValue(); + default: + return null; + } + } + }; + } + + public static class CategorySalesLine implements SerializableRead { + + private String m_CategoryName; + private Double m_CategoryUnits; + private Double m_CategorySum; + + /** + * @param dr + * @throws BasicException + */ + @Override + public void readValues(DataRead dr) throws BasicException { + m_CategoryName = dr.getString(1); + m_CategoryUnits = dr.getDouble(2); + m_CategorySum = dr.getDouble(3); + } + + /** + * @return + */ + public String printCategoryName() { + return m_CategoryName; + } + + /** + * @return + */ + public String printCategoryUnits() { + return Formats.DOUBLE.formatValue(m_CategoryUnits); + } + + /** + * @return + */ + public Double getCategoryUnits() { + return m_CategoryUnits; + } + + /** + * @return + */ + public String printCategorySum() { + return Formats.CURRENCY.formatValue(m_CategorySum); + } + + /** + * @return + */ + public Double getCategorySum() { + return m_CategorySum; + } + } + + public static class RemovedProductLines implements SerializableRead { + + private String m_Name; + private String m_TicketId; + private String m_ProductName; + private Double m_TotalUnits; + + @Override + public void readValues(DataRead dr) throws BasicException { + m_Name = dr.getString(1); + m_TicketId = dr.getString(2); + m_ProductName = dr.getString(3); + m_TotalUnits = dr.getDouble(4); + } + + public String printWorkerName() { + return StringUtils.encodeXML(m_Name); + } + + public String printTicketId() { + return StringUtils.encodeXML(m_TicketId); + } + + public String printProductName() { + return StringUtils.encodeXML(m_ProductName); + } + + public String printTotalUnits() { + return Formats.DOUBLE.formatValue(m_TotalUnits); + } + + } + + /** + * JG Dec 14 + */ + public static class DrawerOpenedLines implements SerializableRead { + + private String m_DrawerOpened; + private String m_Name; + private String m_TicketId; + + @Override + public void readValues(DataRead dr) throws BasicException { + m_DrawerOpened = dr.getString(1); + m_Name = dr.getString(2); + m_TicketId = dr.getString(3); + } + + public String printDrawerOpened() { + return StringUtils.encodeXML(m_DrawerOpened); + } + + public String printUserName() { + return StringUtils.encodeXML(m_Name); + } + + public String printTicketId() { + return StringUtils.encodeXML(m_TicketId); + } + } + + public static class ProductSalesLine implements SerializableRead { + + private String m_ProductName; + private Double m_ProductUnits; + private Double m_ProductPrice; + private Double m_TaxRate; + private Double m_ProductPriceTax; + private Double m_ProductPriceNet; + + @Override + public void readValues(DataRead dr) throws BasicException { + m_ProductName = dr.getString(1); + m_ProductUnits = dr.getDouble(2); + m_ProductPrice = dr.getDouble(3); + m_TaxRate = dr.getDouble(4); + + m_ProductPriceTax = m_ProductPrice + m_ProductPrice * m_TaxRate; + m_ProductPriceNet = m_ProductPrice * m_TaxRate; + } + + public String printProductName() { + return StringUtils.encodeXML(m_ProductName); + } + + public String printProductUnits() { + return Formats.DOUBLE.formatValue(m_ProductUnits); + } + + public Double getProductUnits() { + return m_ProductUnits; + } + + public String printProductPrice() { + return Formats.CURRENCY.formatValue(m_ProductPrice); + } + + public Double getProductPrice() { + return m_ProductPrice; + } + + public String printTaxRate() { + return Formats.PERCENT.formatValue(m_TaxRate); + } + + public Double getTaxRate() { + return m_TaxRate; + } + + public String printProductPriceTax() { + return Formats.CURRENCY.formatValue(m_ProductPriceTax); + } + + public String printProductSubValue() { + return Formats.CURRENCY.formatValue(m_ProductPriceTax * m_ProductUnits); + } + + /** + * JG 4 Jun 2014 + * + * @return + */ + public String printProductPriceNet() { + return Formats.CURRENCY.formatValue(m_ProductPrice * m_ProductUnits); + } + + } + + public static class SalesLine implements SerializableRead { + + private String m_SalesTaxName; + private Double m_SalesTaxes; + private Double m_SalesTaxNet; + private Double m_SalesTaxGross; + + /** + * @param dr + * @throws BasicException + */ + @Override + public void readValues(DataRead dr) throws BasicException { + m_SalesTaxName = dr.getString(1); + m_SalesTaxes = dr.getDouble(2); + m_SalesTaxNet = dr.getDouble(3); + m_SalesTaxGross = dr.getDouble(4); + } + + /** + * @return + */ + public String printTaxName() { + return m_SalesTaxName; + } + + /** + * @return + */ + public String printTaxes() { + return Formats.CURRENCY.formatValue(m_SalesTaxes); + } + + /** + * @return + */ + public String printTaxNet() { + return Formats.CURRENCY.formatValue(m_SalesTaxNet); + } + + /** + * @return + */ + public String printTaxGross() { + return Formats.CURRENCY.formatValue(m_SalesTaxes + m_SalesTaxNet); + } + + + /** + * @return + */ + public String getTaxName() { + return m_SalesTaxName; + } + + /** + * @return + */ + public Double getTaxes() { + return m_SalesTaxes; + } + + /** + * @return + */ + public Double getTaxNet() { + return m_SalesTaxNet; + } + + /** + * JG June 2014 + * + * @return + */ + public Double getTaxGross() { + return m_SalesTaxGross; + } + + + } + + /** + * @return + */ + public AbstractTableModel getSalesModel() { + return new AbstractTableModel() { + @Override + public String getColumnName(int column) { + return AppLocal.getIntString(SALEHEADERS[column]); + } + + @Override + public int getRowCount() { + return m_lsales.size(); + } + + @Override + public int getColumnCount() { + return SALEHEADERS.length; + } + + @Override + public Object getValueAt(int row, int column) { + SalesLine l = m_lsales.get(row); + switch (column) { + case 0: + return l.getTaxName(); + case 1: + return l.getTaxes(); + case 2: + return l.getTaxNet(); + default: + return null; + } + } + }; + } + + /** + * + */ + public static class PaymentsLine implements SerializableRead { + + private String m_PaymentType; + private Double m_PaymentValue; + private String s_PaymentReason; + + /** + * @param dr + * @throws BasicException + */ + @Override + public void readValues(DataRead dr) throws BasicException { + m_PaymentType = dr.getString(1); + m_PaymentValue = dr.getDouble(2); + s_PaymentReason = dr.getString(3) == null ? "" : dr.getString(3); + } + + /** + * @return + */ + public String printType() { + return AppLocal.getIntString("transpayment." + m_PaymentType); + } + + /** + * @return + */ + public String getType() { + return m_PaymentType; + } + + /** + * @return + */ + public String printValue() { + return Formats.CURRENCY.formatValue(m_PaymentValue); + } + + /** + * @return + */ + public Double getValue() { + return m_PaymentValue; + } + + /** + * @return + */ + public String printReason() { + return s_PaymentReason; + } + + /** + * @return + */ + public String getReason() { + return s_PaymentReason; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/panels/Printer.PartialCash.xml b/src/main/java/com/unicenta/pos/panels/Printer.PartialCash.xml new file mode 100644 index 0000000..f579936 --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/Printer.PartialCash.xml @@ -0,0 +1,186 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + --> +<output> + <ticket> + <image>Printer.Ticket.Logo</image> + <line></line> + <line></line> + <line size="1"> + <text align ="center" length="42" bold="true">Partial Cash Report</text> + </line> + <line></line> + <line> + <text bold="true">Sales report</text> + </line> + <line> + <text align ="left" length="12">Name</text> + <text align ="right" length="14">Price+Tax</text> + <text align ="right" length="1"></text> + <text align ="right" length="5">Unit</text> + <text align ="right" length="10">Total</text> + </line> + <line> + <text>------------------------------------------</text> + </line> + #foreach ($line in $payments.getProductSalesLines()) + <line> + <text align ="left" length="12">${line.printProductName()}</text> + <text align ="right" length="10">${line.printProductPriceTax()}</text> + <text align ="right" length="5">${line.printTaxRate()}</text> + <text align ="right" length="5">${line.printProductUnits()}</text> + <text align ="right" length="10">${line.printProductSubValue()}</text> + </line> + #end + <line> + <text>------------------------------------------</text> + </line> + <line> + <text align ="left" length="32">Ticket rows:</text> + <text align ="right" length="10">${payments.printProductSalesRows()}</text> + </line> + <line></line> + <line size="1"> + <text align ="left" length="22" bold="true">Total</text> + <text align ="right" length="10" bold="true">${payments.printProductSalesTotalUnits()}</text> + <text align ="right" length="10" bold="true">${payments.printProductSalesTotal()}</text> + </line> + <line></line> + <line> + <text bold="true">Payments Report</text> + </line> + <line> + <text align ="right" length="42">Total</text> + </line> + <line> + <text>------------------------------------------</text> + </line> + #foreach ($line in $payments.getPaymentLines()) + <line> + <text align ="left" length="32">${line.printType()}</text> + <text align ="right" length="10">${line.printValue()}</text> + </line> + #end + <line> + <text>------------------------------------------</text> + </line> + <line> + <text align ="left" length="32">Payments:</text> + <text align ="right" length="10">${payments.printPayments()}</text> + </line> + <line></line> + <line size="1"> + <text align ="left" length="32" bold="true">Total</text> + <text align ="right" length="10" bold="true">${payments.printPaymentsTotal()}</text> + </line> + <line></line> + <line> + <text bold="true">Taxes Report</text> + </line> + <line> + <text align ="right" length="42">Total</text> + </line> + <line> + <text>------------------------------------------</text> + </line> + #foreach ($line in $payments.getSaleLines()) + <line> + <text align ="left" length="32">${line.printTaxName()}</text> + <text align ="right" length="10">${line.printTaxes()}</text> + </line> + #end + <line> + <text>------------------------------------------</text> + </line> +<!-- JG 9 Nov 12 for Categories --> + <line></line> + <line> + <text bold="true">Product Category Sales</text> + </line> + <line> + <text align ="left" length="22">Name</text> + <text align ="right" length="10">Qty</text> + <text align ="right" length="10">Total</text> + </line> + <line> + <text>------------------------------------------</text> + </line> + #foreach ($line in $payments.getCategorySalesLines()) + <line> + <text align ="left" length="22">${line.printCategoryName()}</text> + <text align ="right" length="10">${line.printCategoryUnits()}</text> + <text align ="right" length="10">${line.printCategorySum()}</text> + </line> + #end + <line> + <text>------------------------------------------</text> + </line> + <line> + <text align ="left" length="22">Ticket Lines:</text> + <text align ="right" length="10">${payments.printCategorySalesRows()}</text> + </line> + <line></line> + <line size="1"> + <text align ="left" length="22" bold="true">Total</text> + <text align ="right" length="10" bold="true">${payments.printCategorySalesTotalUnits()}</text> + <text align ="right" length="10" bold="true">${payments.printCategorySalesTotal()}</text> + </line> + <line> + <text>------------------------------------------</text> + </line> + <line></line> +<!-- end --> + <line> + <text align ="left" length="32">Receipts:</text> + <text align ="right" length="10">${payments.printSales()}</text> + </line> + <line></line> + <line size="1"> + <text align ="left" length="32" bold="true">Subtotal</text> + <text align ="right" length="10" bold="true">${payments.printSalesBase()}</text> + </line> + <line size="1"> + <text align ="left" length="32" bold="true">Taxes</text> + <text align ="right" length="10" bold="true">${payments.printSalesTaxes()}</text> + </line> + <line size="1"> + <text align ="left" length="32" bold="true">Total</text> + <text align ="right" length="10" bold="true">${payments.printSalesTotal()}</text> + </line> + <line></line> + <line> + <text length="18">Machine:</text> + <text>${payments.printHost()}</text> + </line> + <line> + <text length="18">Sequence:</text> + <text>${payments.printSequence()}</text> + </line> + <line> + <text length="18">Start Date:</text> + <text>${payments.printDateStart()}</text> + </line> + <line> + <text length="18">End Date:</text> + <text>${payments.printDateEnd()}</text> + </line> + </ticket> +</output> diff --git a/src/main/java/com/unicenta/pos/panels/SQLColumn.java b/src/main/java/com/unicenta/pos/panels/SQLColumn.java new file mode 100644 index 0000000..2e88873 --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/SQLColumn.java @@ -0,0 +1,75 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-130 + +package com.unicenta.pos.panels; + +import java.util.Enumeration; +import javax.swing.tree.TreeNode; + +/** + * + * @author adrianromero + */ +public class SQLColumn implements TreeNode { + + private SQLTable m_table; + private String m_sName; + + /** Creates a new instance of SQLColumn + * @param t + * @param name */ + public SQLColumn(SQLTable t, String name) { + m_table = t; + m_sName = name; + } + @Override + public String toString() { + return m_sName; + } + + @Override + public Enumeration children(){ + return null; + } + @Override + public boolean getAllowsChildren() { + return false; + } + @Override + public TreeNode getChildAt(int childIndex) { + throw new ArrayIndexOutOfBoundsException(); + } + @Override + public int getChildCount() { + return 0; + } + @Override + public int getIndex(TreeNode node){ + throw new ArrayIndexOutOfBoundsException(); + } + @Override + public TreeNode getParent() { + return m_table; + } + @Override + public boolean isLeaf() { + return true; + } +} diff --git a/src/main/java/com/unicenta/pos/panels/SQLDatabase.java b/src/main/java/com/unicenta/pos/panels/SQLDatabase.java new file mode 100644 index 0000000..8355f0f --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/SQLDatabase.java @@ -0,0 +1,97 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.panels; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import javax.swing.tree.TreeNode; + +/** + * + * @author adrianromero + */ +public class SQLDatabase implements TreeNode { + + private ArrayList m_aTables; + private HashMap m_mTables; + private String m_sName; + + /** Creates a new instance of SQLDatabase + * @param name */ + public SQLDatabase(String name) { + m_sName = name; + m_aTables = new ArrayList(); + m_mTables = new HashMap(); + } + @Override + public String toString() { + return m_sName; + } + + /** + * + * @param sTable + */ + public void addTable(String sTable) { + SQLTable t = new SQLTable(this, sTable); + m_aTables.add(t); + m_mTables.put(sTable, t); + } + + /** + * + * @param sTable + * @return + */ + public SQLTable getTable(String sTable) { + return (SQLTable) m_mTables.get(sTable); + } + + @Override + public Enumeration children(){ + return new EnumerationIter(m_aTables.iterator()); + } + @Override + public boolean getAllowsChildren() { + return true; + } + @Override + public TreeNode getChildAt(int childIndex) { + return (TreeNode) m_aTables.get(childIndex); + } + @Override + public int getChildCount() { + return m_aTables.size(); + } + @Override + public int getIndex(TreeNode node){ + return m_aTables.indexOf(node); + } + @Override + public TreeNode getParent() { + return null; + } + @Override + public boolean isLeaf() { +// JG 16 May 2013 use isEmpty + return m_aTables.isEmpty(); + } +} diff --git a/src/main/java/com/unicenta/pos/panels/SQLTable.java b/src/main/java/com/unicenta/pos/panels/SQLTable.java new file mode 100644 index 0000000..f27fee8 --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/SQLTable.java @@ -0,0 +1,111 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.panels; + +import java.util.ArrayList; +import java.util.Enumeration; +import javax.swing.tree.TreeNode; + +/** + * + * @author adrianromero + */ +public class SQLTable implements TreeNode { + + private SQLDatabase m_db; + private String m_sName; + + private ArrayList m_aColumns; + + /** Creates a new instance of SQLTable + * @param db + * @param name */ + public SQLTable(SQLDatabase db, String name) { + m_db = db; + m_sName = name; + m_aColumns = new ArrayList(); + } + + /** + * + * @return + */ + public String getName() { + return m_sName; + } + + /** + * + * @param name + */ + public void addColumn(String name) { + SQLColumn c = new SQLColumn(this, name); + m_aColumns.add(c); + } + + @Override + public String toString() { + return m_sName; + } + + @Override + public Enumeration children(){ + return new EnumerationIter(m_aColumns.iterator()); + } + @Override + public boolean getAllowsChildren() { + return true; + } + @Override + public TreeNode getChildAt(int childIndex) { + return (TreeNode) m_aColumns.get(childIndex); + } + @Override + public int getChildCount() { + return m_aColumns.size(); + } + @Override + public int getIndex(TreeNode node){ + return m_aColumns.indexOf(node); + } + @Override + public TreeNode getParent() { + return m_db; + } + @Override + public boolean isLeaf() { +// JG 16 May 2013 use isEmpty instead of size. + return m_aColumns.isEmpty(); + } +// public Enumeration children(){ +// } +// public boolean getAllowsChildren() { +// } +// public TreeNode getChildAt(int childIndex) { +// } +// public int getChildCount() { +// } +// public int getIndex(TreeNode node){ +// } +// public TreeNode getParent() { +// } +// public boolean isLeaf() { +// } +} diff --git a/src/main/java/com/unicenta/pos/panels/SQLTableModel.java b/src/main/java/com/unicenta/pos/panels/SQLTableModel.java new file mode 100644 index 0000000..c7059d6 --- /dev/null +++ b/src/main/java/com/unicenta/pos/panels/SQLTableModel.java @@ -0,0 +1,153 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.panels; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataField; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.Datas; +import java.sql.Types; +import java.util.ArrayList; +import java.util.List; +import javax.swing.table.AbstractTableModel; + +/** + * + * @author adrianromero + */ +public class SQLTableModel extends AbstractTableModel { + + private List m_aRows; + + private DataField[] m_df; + private Datas[] m_classes; + + /** Creates a new instance of SQLTableModel + * @param df */ + public SQLTableModel(DataField[] df) { + m_aRows = new ArrayList(); + + m_df = df; + m_classes = new Datas[df.length]; + for (int i = 0; i < df.length; i++) { + switch (df[i].Type) { + case Types.INTEGER: + case Types.BIGINT: + case Types.SMALLINT: + case Types.TINYINT: + m_classes[i] = Datas.INT; + break; + case Types.BIT: + case Types.BOOLEAN: + m_classes[i] = Datas.BOOLEAN; + break; + case Types.DECIMAL: + case Types.DOUBLE: + case Types.FLOAT: + case Types.REAL: + case Types.NUMERIC: + m_classes[i] = Datas.DOUBLE; + break; + case Types.CHAR: + case Types.VARCHAR: + case Types.LONGVARCHAR: + case Types.CLOB: + m_classes[i] = Datas.STRING; + break; + case Types.DATE: + case Types.TIME: + case Types.TIMESTAMP: + m_classes[i] = Datas.TIMESTAMP; + break; + case Types.BINARY: + case Types.VARBINARY: + case Types.LONGVARBINARY: + case Types.BLOB: + m_classes[i] = Datas.BYTES; + break; + case Types.ARRAY: + case Types.DATALINK: + case Types.DISTINCT: + case Types.JAVA_OBJECT: + case Types.NULL: + case Types.OTHER: + case Types.REF: + case Types.STRUCT: + default: + m_classes[i] = Datas.OBJECT; + break; + } + } + } + + /** + * + * @param dr + * @throws BasicException + */ + public void addRow(DataRead dr) throws BasicException { + + Object[] m_values = new Object[m_classes.length]; + for (int i = 0; i < m_classes.length; i++) { + m_values[i] = m_classes[i].getValue(dr, i + 1); + } + m_aRows.add(m_values); + } + + /** + * + * @param row + * @return + */ + public String getColumnString(int row) { + Object [] rowvalues = (Object[]) m_aRows.get(row); +// JG 16 May 2013 use StringBuilder instead of StringBuilder + StringBuilder s = new StringBuilder(); + for(int i = 0; i < rowvalues.length; i++) { + if (i > 0) { + s.append(", "); + } + s.append(m_classes[i].toString(rowvalues[i])); + } + return s.toString(); + } + + @Override + public Class getColumnClass(int columnIndex) { + return m_classes[columnIndex].getClassValue(); + } + @Override + public String getColumnName(int columnIndex) { + return m_df[columnIndex].Name; + } + @Override + public int getRowCount() { + return m_aRows.size(); + } + @Override + public int getColumnCount() { + return m_df.length; + } + @Override + public Object getValueAt(int row, int column) { + Object [] rowvalues = (Object[]) m_aRows.get(row); + return rowvalues[column]; + } +} diff --git a/src/main/java/com/unicenta/pos/payment/ConfigPaymentPanelEmpty.form b/src/main/java/com/unicenta/pos/payment/ConfigPaymentPanelEmpty.form new file mode 100644 index 0000000..99f1a79 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/ConfigPaymentPanelEmpty.form @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.6" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" red="ff" type="rgb"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[650, 75]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <EmptySpace min="0" pref="650" max="32767" attributes="0"/> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <EmptySpace min="0" pref="150" max="32767" attributes="0"/> + </Group> + </DimensionLayout> + </Layout> +</Form> diff --git a/src/main/java/com/unicenta/pos/payment/ConfigPaymentPanelEmpty.java b/src/main/java/com/unicenta/pos/payment/ConfigPaymentPanelEmpty.java new file mode 100644 index 0000000..ac5780b --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/ConfigPaymentPanelEmpty.java @@ -0,0 +1,92 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.pos.forms.AppConfig; +import javax.swing.JPanel; + +/** + * + * @author Mikel Irurita + */ +public class ConfigPaymentPanelEmpty extends javax.swing.JPanel implements PaymentConfiguration { + + /** Creates new form ConfigPaymentPanelGeneric */ + public ConfigPaymentPanelEmpty() { + initComponents(); + } + + /** + * + * @return + */ + @Override + public JPanel getComponent() { + return this; + } + + /** + * + * @param config + */ + @Override + public void loadProperties(AppConfig config) { + + } + + /** + * + * @param config + */ + @Override + public void saveProperties(AppConfig config) { + + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + setBackground(new java.awt.Color(255, 255, 255)); + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + setPreferredSize(new java.awt.Dimension(650, 75)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 650, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 150, Short.MAX_VALUE) + ); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/payment/ConfigPaymentPanelGeneric.form b/src/main/java/com/unicenta/pos/payment/ConfigPaymentPanelGeneric.form new file mode 100644 index 0000000..acf4b71 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/ConfigPaymentPanelGeneric.form @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.6" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" red="ff" type="rgb"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[400, 90]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="jLabel2" max="32767" attributes="0"/> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jtxtCommerceID" min="-2" max="-2" attributes="0"/> + <Component id="jtxtCommercePwd" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace pref="30" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jtxtCommerceID" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jtxtCommercePwd" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.commerceid" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jtxtCommerceID"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.commercepwd" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JPasswordField" name="jtxtCommercePwd"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/payment/ConfigPaymentPanelGeneric.java b/src/main/java/com/unicenta/pos/payment/ConfigPaymentPanelGeneric.java new file mode 100644 index 0000000..0540918 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/ConfigPaymentPanelGeneric.java @@ -0,0 +1,143 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.util.AltEncrypter; +import javax.swing.JPanel; + +/** + * + * @author Mikel Irurita + */ +public class ConfigPaymentPanelGeneric extends javax.swing.JPanel implements PaymentConfiguration { + + /** Creates new form ConfigPaymentPanelGeneric */ + public ConfigPaymentPanelGeneric() { + initComponents(); + } + + /** + * + * @return + */ + @Override + public JPanel getComponent() { + return this; + } + + /** + * + * @param config + */ + @Override + public void loadProperties(AppConfig config) { + String sCommerceID = config.getProperty("payment.commerceid"); + String sCommercePass = config.getProperty("payment.commercepassword"); + + if (sCommerceID != null && sCommercePass != null && sCommercePass.startsWith("crypt:")) { + jtxtCommerceID.setText(config.getProperty("payment.commerceid")); + AltEncrypter cypher = new AltEncrypter("cypherkey" + config.getProperty("payment.commerceid")); + jtxtCommercePwd.setText(cypher.decrypt(config.getProperty("payment.commercepassword").substring(6))); + } + } + + /** + * + * @param config + */ + @Override + public void saveProperties(AppConfig config) { + config.setProperty("payment.commerceid", jtxtCommerceID.getText()); + AltEncrypter cypher = new AltEncrypter("cypherkey" + jtxtCommerceID.getText()); + config.setProperty("payment.commercepassword", "crypt:" + cypher.encrypt(new String(jtxtCommercePwd.getPassword()))); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel1 = new javax.swing.JLabel(); + jtxtCommerceID = new javax.swing.JTextField(); + jLabel2 = new javax.swing.JLabel(); + jtxtCommercePwd = new javax.swing.JPasswordField(); + + setBackground(new java.awt.Color(255, 255, 255)); + setPreferredSize(new java.awt.Dimension(400, 90)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.commerceid")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(150, 30)); + + jtxtCommerceID.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtCommerceID.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.commercepwd")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(150, 30)); + + jtxtCommercePwd.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtCommercePwd.setPreferredSize(new java.awt.Dimension(200, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jtxtCommerceID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtCommercePwd, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(30, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtCommerceID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jtxtCommercePwd, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JTextField jtxtCommerceID; + private javax.swing.JPasswordField jtxtCommercePwd; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentBank.form b/src/main/java/com/unicenta/pos/payment/JPaymentBank.form new file mode 100644 index 0000000..14ad2fd --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentBank.form @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,49,0,0,2,99"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="1"/> + </Layout> + <SubComponents> + <Component class="com.unicenta.editor.JEditorKeys" name="m_jKeys"> + </Component> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Component class="com.unicenta.editor.JEditorCurrencyPositive" name="m_jTendered"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout"> + <Property name="useNullLayout" type="boolean" value="true"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="1"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.InputCash" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="10" y="4" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="m_jMoneyEuros"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="33" green="ff" red="cc" type="rgb"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="1"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[180, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="120" y="4" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentBank.java b/src/main/java/com/unicenta/pos/payment/JPaymentBank.java new file mode 100644 index 0000000..a11fbbe --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentBank.java @@ -0,0 +1,185 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; +import com.unicenta.format.Formats; +import com.unicenta.pos.customers.CustomerInfoExt; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.util.RoundUtils; +import java.awt.Component; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +/** + * + * @author JG uniCenta + */ +public class JPaymentBank extends javax.swing.JPanel implements JPaymentInterface { + + private JPaymentNotifier m_notifier; + + private double m_dPaid; + private double m_dTotal; + + /** Creates new form JPaymentCash + * @param notifier */ + public JPaymentBank(JPaymentNotifier notifier) { + + m_notifier = notifier; + + initComponents(); + + m_jTendered.addPropertyChangeListener("Edition", new RecalculateState()); + m_jTendered.addEditorKeys(m_jKeys); + + + + } + + /** + * + * @param customerext + * @param dTotal + * @param transID + */ + @Override + public void activate(CustomerInfoExt customerext, double dTotal, String transID) { + + m_dTotal = dTotal; + + + m_jTendered.reset(); + m_jTendered.activate(); + + printState(); + + } + + /** + * + * @return + */ + @Override + public PaymentInfo executePayment() { + return new PaymentInfoTicket(m_dPaid, "bank"); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + private void printState() { + + Double value = m_jTendered.getDoubleValue(); + if (value == null) { + m_dPaid = m_dTotal; + } else { + m_dPaid = value; + } + + m_jMoneyEuros.setText(Formats.CURRENCY.formatValue(new Double(m_dPaid))); + + int iCompare = RoundUtils.compare(m_dPaid, m_dTotal); + + // if iCompare > 0 then the payment is not valid + m_notifier.setStatus(m_dPaid > 0.0 && iCompare <= 0, iCompare == 0); + } + + private class RecalculateState implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + printState(); + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel2 = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel3 = new javax.swing.JPanel(); + m_jTendered = new com.unicenta.editor.JEditorCurrencyPositive(); + jPanel4 = new javax.swing.JPanel(); + jLabel8 = new javax.swing.JLabel(); + m_jMoneyEuros = new javax.swing.JLabel(); + + setLayout(new java.awt.BorderLayout()); + + jPanel2.setLayout(new java.awt.BorderLayout()); + + jPanel1.setLayout(new javax.swing.BoxLayout(jPanel1, javax.swing.BoxLayout.Y_AXIS)); + jPanel1.add(m_jKeys); + + jPanel3.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel3.setLayout(new java.awt.BorderLayout()); + + m_jTendered.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N + jPanel3.add(m_jTendered, java.awt.BorderLayout.CENTER); + + jPanel1.add(jPanel3); + + jPanel2.add(jPanel1, java.awt.BorderLayout.NORTH); + + add(jPanel2, java.awt.BorderLayout.EAST); + + jPanel4.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel4.setLayout(null); + + jLabel8.setFont(new java.awt.Font("Arial", 1, 18)); // NOI18N + jLabel8.setText(AppLocal.getIntString("label.InputCash")); // NOI18N + jLabel8.setPreferredSize(new java.awt.Dimension(100, 30)); + jPanel4.add(jLabel8); + jLabel8.setBounds(10, 4, 100, 30); + + m_jMoneyEuros.setBackground(new java.awt.Color(204, 255, 51)); + m_jMoneyEuros.setFont(new java.awt.Font("Arial", 1, 18)); // NOI18N + m_jMoneyEuros.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jMoneyEuros.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jMoneyEuros.setOpaque(true); + m_jMoneyEuros.setPreferredSize(new java.awt.Dimension(180, 30)); + jPanel4.add(m_jMoneyEuros); + m_jMoneyEuros.setBounds(120, 4, 180, 30); + + add(jPanel4, java.awt.BorderLayout.CENTER); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel8; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private com.unicenta.editor.JEditorKeys m_jKeys; + private javax.swing.JLabel m_jMoneyEuros; + private com.unicenta.editor.JEditorCurrencyPositive m_jTendered; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentCashPos.form b/src/main/java/com/unicenta/pos/payment/JPaymentCashPos.form new file mode 100644 index 0000000..a09fcb7 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentCashPos.form @@ -0,0 +1,230 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[700, 400]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-112,0,0,2,-18"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[450, 70]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout"> + <Property name="useNullLayout" type="boolean" value="true"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="m_jChangeEuros"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" red="ff" type="rgb"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="1"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[180, 30]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="JPaymentCashPos_m_jChangeEuros"/> + </AuxValues> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="120" y="36" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.ChangeCash" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="10" y="36" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.InputCash" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="10" y="4" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="m_jMoneyEuros"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" red="ff" type="rgb"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[180, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="120" y="4" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel6"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[450, 10]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="0"/> + </Layout> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="After"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="1"/> + </Layout> + <SubComponents> + <Component class="com.unicenta.editor.JEditorKeys" name="m_jKeys"> + </Component> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Component class="com.unicenta.editor.JEditorCurrencyPositive" name="m_jTendered"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="1"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentCashPos.java b/src/main/java/com/unicenta/pos/payment/JPaymentCashPos.java new file mode 100644 index 0000000..c1d31aa --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentCashPos.java @@ -0,0 +1,336 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.format.Formats; +import com.unicenta.pos.customers.CustomerInfoExt; +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSystem; +import com.unicenta.pos.scripting.ScriptEngine; +import com.unicenta.pos.scripting.ScriptException; +import com.unicenta.pos.scripting.ScriptFactory; +import com.unicenta.pos.util.RoundUtils; +import com.unicenta.pos.util.ThumbNailBuilder; +import java.awt.Component; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.SwingConstants; + +/** + * + * @author adrianromero + */ +public class JPaymentCashPos extends javax.swing.JPanel implements JPaymentInterface { + + private final JPaymentNotifier m_notifier; + + private double m_dPaid; + private double m_dTotal; + private final Boolean priceWith00; + + /** Creates new form JPaymentCash + * @param notifier + * @param dlSystem */ + public JPaymentCashPos(JPaymentNotifier notifier, DataLogicSystem dlSystem) { + + m_notifier = notifier; + + initComponents(); + + m_jTendered.addPropertyChangeListener("Edition", new RecalculateState()); + m_jTendered.addEditorKeys(m_jKeys); + +// added JDL 11.05.13 + AppConfig m_config = new AppConfig(new File((System.getProperty("user.home")), AppLocal.APP_ID + ".properties")); + m_config.load(); + priceWith00 =("true".equals(m_config.getProperty("till.pricewith00"))); + if (priceWith00) { + // use '00' instead of '.' + m_jKeys.dotIs00(true); + } +// m_config=null; + + String code = dlSystem.getResourceAsXML("payment.cash"); + if (code != null) { + try { + ScriptEngine script = ScriptFactory.getScriptEngine(ScriptFactory.BEANSHELL); + script.put("payment", new ScriptPaymentCash(dlSystem)); + script.eval(code); + } catch (ScriptException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, AppLocal.getIntString("message.cannotexecute"), e); + msg.show(this); + } + } + + } + + /** + * + * @param customerext + * @param dTotal + * @param transID + */ + @Override + public void activate(CustomerInfoExt customerext, double dTotal, String transID) { + + + m_dTotal = dTotal; + + m_jTendered.reset(); + m_jTendered.activate(); + + printState(); + } + + /** + * + * @return + */ + @Override + public PaymentInfo executePayment() { + if (m_dPaid - m_dTotal >= 0.0) { + // pago completo + return new PaymentInfoCash(m_dTotal, m_dPaid); + } else { + // pago parcial + return new PaymentInfoCash(m_dPaid, m_dPaid); + } + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + private void printState() { + + Double value = m_jTendered.getDoubleValue(); + if (value == null || value == 0.0) { + m_dPaid = m_dTotal; + } else { + m_dPaid = value; + + } + + int iCompare = RoundUtils.compare(m_dPaid, m_dTotal); + + m_jMoneyEuros.setText(Formats.CURRENCY.formatValue(m_dPaid)); + m_jChangeEuros.setText(iCompare > 0 + ? Formats.CURRENCY.formatValue(m_dPaid - m_dTotal) + : null); + + m_notifier.setStatus(m_dPaid > 0.0, iCompare >= 0); + } + + private class RecalculateState implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + printState(); + } + } + + /** + * + */ + public class ScriptPaymentCash { + + private final DataLogicSystem dlSystem; + private final ThumbNailBuilder tnbbutton; + private final AppConfig m_config; + + /** + * + * @param dlSystem + */ + public ScriptPaymentCash(DataLogicSystem dlSystem) { +//added 19.04.13 JDL + AppConfig m_config = new AppConfig(new File((System.getProperty("user.home")), AppLocal.APP_ID + ".properties")); + m_config.load(); + this.m_config = m_config; + + this.dlSystem = dlSystem; + tnbbutton = new ThumbNailBuilder(64, 50, "com/unicenta/images/cash.png"); + } + + /** + * + * @param image + * @param amount + */ + public void addButton(String image, double amount) { + JButton btn = new JButton(); +//added 19.04.13 JDL removal of text on payment buttons if required. + try { + if ((m_config.getProperty("payments.textoverlay")).equals("false")){ + btn.setIcon(new ImageIcon(tnbbutton.getThumbNailText(dlSystem.getResourceAsImage(image),""))); + } else { + btn.setIcon(new ImageIcon(tnbbutton.getThumbNailText(dlSystem.getResourceAsImage(image), Formats.CURRENCY.formatValue(amount)))); + } + } catch (Exception e){ + btn.setIcon(new ImageIcon(tnbbutton.getThumbNailText(dlSystem.getResourceAsImage(image), Formats.CURRENCY.formatValue(amount)))); + } + + btn.setFocusPainted(false); + btn.setFocusable(false); + btn.setRequestFocusEnabled(false); + btn.setHorizontalTextPosition(SwingConstants.CENTER); + btn.setVerticalTextPosition(SwingConstants.BOTTOM); + btn.setMargin(new Insets(2, 2, 2, 2)); + btn.addActionListener(new AddAmount(amount)); + jPanel6.add(btn); + } + } + + + + private class AddAmount implements ActionListener { + private final double amount; + public AddAmount(double amount) { + this.amount = amount; + } + @Override + public void actionPerformed(ActionEvent e) { + Double tendered = m_jTendered.getDoubleValue(); + + if (tendered == null) { + m_jTendered.setDoubleValue(amount); + } else { + m_jTendered.setDoubleValue(tendered + amount); + + } + + printState(); + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel5 = new javax.swing.JPanel(); + jPanel4 = new javax.swing.JPanel(); + m_jChangeEuros = new javax.swing.JLabel(); + jLabel6 = new javax.swing.JLabel(); + jLabel8 = new javax.swing.JLabel(); + m_jMoneyEuros = new javax.swing.JLabel(); + jPanel6 = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel3 = new javax.swing.JPanel(); + m_jTendered = new com.unicenta.editor.JEditorCurrencyPositive(); + + setPreferredSize(new java.awt.Dimension(700, 400)); + setLayout(new java.awt.BorderLayout()); + + jPanel5.setLayout(new java.awt.BorderLayout()); + + jPanel4.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel4.setPreferredSize(new java.awt.Dimension(450, 70)); + jPanel4.setLayout(null); + + m_jChangeEuros.setBackground(new java.awt.Color(255, 255, 255)); + m_jChangeEuros.setFont(new java.awt.Font("Arial", 1, 18)); // NOI18N + m_jChangeEuros.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jChangeEuros.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jChangeEuros.setOpaque(true); + m_jChangeEuros.setPreferredSize(new java.awt.Dimension(180, 30)); + jPanel4.add(m_jChangeEuros); + m_jChangeEuros.setBounds(120, 36, 180, 30); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 18)); // NOI18N + jLabel6.setText(AppLocal.getIntString("label.ChangeCash")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(100, 30)); + jPanel4.add(jLabel6); + jLabel6.setBounds(10, 36, 100, 30); + + jLabel8.setFont(new java.awt.Font("Arial", 0, 18)); // NOI18N + jLabel8.setText(AppLocal.getIntString("label.InputCash")); // NOI18N + jLabel8.setPreferredSize(new java.awt.Dimension(100, 30)); + jPanel4.add(jLabel8); + jLabel8.setBounds(10, 4, 100, 30); + + m_jMoneyEuros.setBackground(new java.awt.Color(255, 255, 255)); + m_jMoneyEuros.setFont(new java.awt.Font("Arial", 0, 18)); // NOI18N + m_jMoneyEuros.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jMoneyEuros.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jMoneyEuros.setOpaque(true); + m_jMoneyEuros.setPreferredSize(new java.awt.Dimension(180, 30)); + jPanel4.add(m_jMoneyEuros); + m_jMoneyEuros.setBounds(120, 4, 180, 30); + + jPanel5.add(jPanel4, java.awt.BorderLayout.NORTH); + + jPanel6.setPreferredSize(new java.awt.Dimension(450, 10)); + jPanel6.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT)); + jPanel5.add(jPanel6, java.awt.BorderLayout.CENTER); + + add(jPanel5, java.awt.BorderLayout.CENTER); + + jPanel2.setLayout(new java.awt.BorderLayout()); + + jPanel1.setLayout(new javax.swing.BoxLayout(jPanel1, javax.swing.BoxLayout.Y_AXIS)); + jPanel1.add(m_jKeys); + + jPanel3.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel3.setLayout(new java.awt.BorderLayout()); + + m_jTendered.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + jPanel3.add(m_jTendered, java.awt.BorderLayout.CENTER); + + jPanel1.add(jPanel3); + + jPanel2.add(jPanel1, java.awt.BorderLayout.NORTH); + + add(jPanel2, java.awt.BorderLayout.LINE_END); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel8; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JPanel jPanel6; + private javax.swing.JLabel m_jChangeEuros; + private com.unicenta.editor.JEditorKeys m_jKeys; + private javax.swing.JLabel m_jMoneyEuros; + private com.unicenta.editor.JEditorCurrencyPositive m_jTendered; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentCheque.form b/src/main/java/com/unicenta/pos/payment/JPaymentCheque.form new file mode 100644 index 0000000..3e5a15d --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentCheque.form @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,49,0,0,2,-118"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="1"/> + </Layout> + <SubComponents> + <Component class="com.unicenta.editor.JEditorKeys" name="m_jKeys"> + </Component> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Component class="com.unicenta.editor.JEditorCurrencyPositive" name="m_jTendered"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="16" style="1"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout"> + <Property name="useNullLayout" type="boolean" value="true"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="1"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.InputCash" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="10" y="4" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="m_jMoneyEuros"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="33" green="ff" red="cc" type="rgb"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="1"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[180, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="120" y="4" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentCheque.java b/src/main/java/com/unicenta/pos/payment/JPaymentCheque.java new file mode 100644 index 0000000..4291425 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentCheque.java @@ -0,0 +1,198 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; +import com.unicenta.format.Formats; +import com.unicenta.pos.customers.CustomerInfoExt; +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.util.RoundUtils; +import java.awt.Component; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; + +/** + * + * @author JG uniCenta + */ +public class JPaymentCheque extends javax.swing.JPanel implements JPaymentInterface { + + private JPaymentNotifier m_notifier; + + private double m_dPaid; + private double m_dTotal; + private Boolean priceWith00; + + /** Creates new form JPaymentCash + * @param notifier */ + public JPaymentCheque(JPaymentNotifier notifier) { + + m_notifier = notifier; + + initComponents(); + + m_jTendered.addPropertyChangeListener("Edition", new RecalculateState()); + m_jTendered.addEditorKeys(m_jKeys); + + /* added JDL 11.05.13 + AppConfig m_config = new AppConfig(new File((System.getProperty("user.home")), AppLocal.APP_ID + ".properties")); + m_config.load(); + priceWith00 =("true".equals(m_config.getProperty("till.pricewith00"))); + if (priceWith00) { + // use '00' instead of '.' + m_jKeys.dotIs00(true); + } + m_config=null; +*/ + + + } + + /** + * + * @param customerext + * @param dTotal + * @param transID + */ + @Override + public void activate(CustomerInfoExt customerext, double dTotal, String transID) { + + m_dTotal = dTotal; + + + m_jTendered.reset(); + m_jTendered.activate(); + + printState(); + + } + + /** + * + * @return + */ + @Override + public PaymentInfo executePayment() { + return new PaymentInfoTicket(m_dPaid, "cheque"); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + private void printState() { + + Double value = m_jTendered.getDoubleValue(); + if (value == null) { + m_dPaid = m_dTotal; + } else { + m_dPaid = value; + } + + m_jMoneyEuros.setText(Formats.CURRENCY.formatValue(new Double(m_dPaid))); + + int iCompare = RoundUtils.compare(m_dPaid, m_dTotal); + + // if iCompare > 0 then the payment is not valid + m_notifier.setStatus(m_dPaid > 0.0 && iCompare <= 0, iCompare == 0); + } + + private class RecalculateState implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + printState(); + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel2 = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel3 = new javax.swing.JPanel(); + m_jTendered = new com.unicenta.editor.JEditorCurrencyPositive(); + jPanel4 = new javax.swing.JPanel(); + jLabel8 = new javax.swing.JLabel(); + m_jMoneyEuros = new javax.swing.JLabel(); + + setLayout(new java.awt.BorderLayout()); + + jPanel2.setLayout(new java.awt.BorderLayout()); + + jPanel1.setLayout(new javax.swing.BoxLayout(jPanel1, javax.swing.BoxLayout.Y_AXIS)); + jPanel1.add(m_jKeys); + + jPanel3.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel3.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N + jPanel3.setLayout(new java.awt.BorderLayout()); + + m_jTendered.setFont(new java.awt.Font("Arial", 1, 16)); // NOI18N + jPanel3.add(m_jTendered, java.awt.BorderLayout.CENTER); + + jPanel1.add(jPanel3); + + jPanel2.add(jPanel1, java.awt.BorderLayout.NORTH); + + add(jPanel2, java.awt.BorderLayout.EAST); + + jPanel4.setLayout(null); + + jLabel8.setFont(new java.awt.Font("Arial", 1, 18)); // NOI18N + jLabel8.setText(AppLocal.getIntString("label.InputCash")); // NOI18N + jLabel8.setPreferredSize(new java.awt.Dimension(100, 30)); + jPanel4.add(jLabel8); + jLabel8.setBounds(10, 4, 100, 30); + + m_jMoneyEuros.setBackground(new java.awt.Color(204, 255, 51)); + m_jMoneyEuros.setFont(new java.awt.Font("Arial", 1, 18)); // NOI18N + m_jMoneyEuros.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jMoneyEuros.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jMoneyEuros.setOpaque(true); + m_jMoneyEuros.setPreferredSize(new java.awt.Dimension(180, 30)); + jPanel4.add(m_jMoneyEuros); + m_jMoneyEuros.setBounds(120, 4, 180, 30); + + add(jPanel4, java.awt.BorderLayout.CENTER); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel8; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private com.unicenta.editor.JEditorKeys m_jKeys; + private javax.swing.JLabel m_jMoneyEuros; + private com.unicenta.editor.JEditorCurrencyPositive m_jTendered; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentDebt.form b/src/main/java/com/unicenta/pos/payment/JPaymentDebt.form new file mode 100644 index 0000000..2bbfb35 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentDebt.form @@ -0,0 +1,412 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,103,0,0,2,104"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel4" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="txtCurdebt" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="txtMaxdebt" max="32767" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel12" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jScrollPane1" max="32767" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jName" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel8" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jMoneyEuros" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0"> + <Component id="jlblMessage" alignment="0" pref="0" max="32767" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel6" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="txtCurdate" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace pref="30" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel8" min="-2" max="-2" attributes="0"/> + <Component id="m_jMoneyEuros" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel12" min="-2" max="-2" attributes="0"/> + <Component id="jScrollPane1" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="txtMaxdebt" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="txtCurdebt" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="txtCurdate" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel6" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jlblMessage" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.debt" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jMoneyEuros"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="33" green="ff" red="cc" type="rgb"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="1"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.name" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jName"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel12"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.notes" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.maxdebt" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtMaxdebt"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.curdebt" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtCurdebt"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.curdate" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtCurdate"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 30]"/> + </Property> + </Properties> + </Component> + <Container class="javax.swing.JScrollPane" name="jScrollPane1"> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JTextArea" name="m_jNotes"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="f0" green="f0" red="f0" type="rgb"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[170, 80]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="JPaymentDebt_m_jNotes"/> + </AuxValues> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JTextArea" name="jlblMessage"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="0" red="cc" type="rgb"/> + </Property> + <Property name="lineWrap" type="boolean" value="true"/> + <Property name="wrapStyleWord" type="boolean" value="true"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo"> + <EtchetBorder/> + </Border> + </Property> + <Property name="focusable" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[275, 60]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel6"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Last"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout"> + <Property name="useNullLayout" type="boolean" value="false"/> + </Layout> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="1"/> + </Layout> + <SubComponents> + <Component class="com.unicenta.editor.JEditorKeys" name="m_jKeys"> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jKeysActionPerformed"/> + </Events> + </Component> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="40" max="-2" attributes="0"/> + <Component id="m_jTendered" min="-2" max="-2" attributes="0"/> + <EmptySpace pref="50" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jTendered" min="-2" max="-2" attributes="0"/> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="com.unicenta.editor.JEditorCurrencyPositive" name="m_jTendered"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentDebt.java b/src/main/java/com/unicenta/pos/payment/JPaymentDebt.java new file mode 100644 index 0000000..d3f6281 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentDebt.java @@ -0,0 +1,400 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +package com.unicenta.pos.payment; + +import com.unicenta.format.Formats; +import com.unicenta.pos.customers.CustomerInfoExt; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.util.RoundUtils; +import java.awt.Component; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +/** + * + * @author adrianromero + */ +public class JPaymentDebt extends javax.swing.JPanel implements JPaymentInterface { + + private JPaymentNotifier notifier; + private CustomerInfoExt customerext; + private double m_dPaid; + private double m_dTotal; + + /** Creates new form JPaymentDebt + * @param notifier */ + public JPaymentDebt(JPaymentNotifier notifier) { + + this.notifier = notifier; + + initComponents(); + + m_jTendered.addPropertyChangeListener("Edition", new RecalculateState()); + m_jTendered.addEditorKeys(m_jKeys); + + } + + /** + * + * @param customerext + * @param dTotal + * @param transID + */ + @Override + public void activate(CustomerInfoExt customerext, double dTotal, String transID) { + + this.customerext = customerext; + m_dTotal = dTotal; + + m_jTendered.reset(); + + if (customerext == null) { + m_jName.setText(null); + m_jNotes.setText(null); + txtMaxdebt.setText(null); + txtCurdate.setText(null); + txtCurdebt.setText(null); + + m_jKeys.setEnabled(false); + m_jTendered.setEnabled(false); + + + } else { + m_jName.setText(customerext.getName()); + m_jNotes.setText(customerext.getNotes()); + txtMaxdebt.setText(Formats.CURRENCY.formatValue(RoundUtils.getValue(customerext.getMaxdebt()))); + txtCurdate.setText(Formats.DATE.formatValue(customerext.getCurdate())); + txtCurdebt.setText(Formats.CURRENCY.formatValue(RoundUtils.getValue(customerext.getAccdebt()))); + + if (RoundUtils.compare(RoundUtils.getValue(customerext.getAccdebt()), RoundUtils.getValue(customerext.getMaxdebt())) >= 0) { + m_jKeys.setEnabled(false); + m_jTendered.setEnabled(false); + } else { + m_jKeys.setEnabled(true); + m_jTendered.setEnabled(true); + m_jTendered.activate(); + } + } + + printState(); + + } + + /** + * + * @return + */ + @Override + public PaymentInfo executePayment() { + return new PaymentInfoTicket(m_dPaid, "debt"); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + private void printState() { + + if (customerext == null) { + m_jMoneyEuros.setText(null); + jlblMessage.setText(AppLocal.getIntString("message.nocustomernodebt")); + notifier.setStatus(false, false); + } else { + Double value = m_jTendered.getDoubleValue(); + if (value == null || value == 0.0) { + m_dPaid = m_dTotal; + } else { + m_dPaid = value; + } + + m_jMoneyEuros.setText(Formats.CURRENCY.formatValue(m_dPaid)); + + +// if (RoundUtils.compare(RoundUtils.getValue(customerext.getAccdebt()) + m_dPaid, +// RoundUtils.getValue(customerext.getMaxdebt())) >= 0) { + if ((customerext.getAccdebt() + RoundUtils.round(m_dPaid)) - (customerext.getMaxdebt()) > 0) { + jlblMessage.setText(AppLocal.getIntString("message.customerdebtexceded")); + notifier.setStatus(false, false); + } else { + jlblMessage.setText(null); + int iCompare = RoundUtils.compare(m_dPaid, m_dTotal); + // if iCompare > 0 then the payment is not valid + notifier.setStatus(m_dPaid > 0.0 && iCompare <= 0, iCompare == 0); + } + } + } + + private class RecalculateState implements PropertyChangeListener { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + printState(); + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel5 = new javax.swing.JPanel(); + jPanel4 = new javax.swing.JPanel(); + jLabel8 = new javax.swing.JLabel(); + m_jMoneyEuros = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + m_jName = new javax.swing.JTextField(); + jLabel12 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + txtMaxdebt = new javax.swing.JTextField(); + jLabel4 = new javax.swing.JLabel(); + txtCurdebt = new javax.swing.JTextField(); + jLabel6 = new javax.swing.JLabel(); + txtCurdate = new javax.swing.JTextField(); + jScrollPane1 = new javax.swing.JScrollPane(); + m_jNotes = new javax.swing.JTextArea(); + jlblMessage = new javax.swing.JTextArea(); + jPanel6 = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel3 = new javax.swing.JPanel(); + m_jTendered = new com.unicenta.editor.JEditorCurrencyPositive(); + + setLayout(new java.awt.BorderLayout()); + + jPanel5.setLayout(new java.awt.BorderLayout()); + + jLabel8.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel8.setText(AppLocal.getIntString("label.debt")); // NOI18N + jLabel8.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jMoneyEuros.setBackground(new java.awt.Color(204, 255, 51)); + m_jMoneyEuros.setFont(new java.awt.Font("Arial", 1, 18)); // NOI18N + m_jMoneyEuros.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jMoneyEuros.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jMoneyEuros.setOpaque(true); + m_jMoneyEuros.setPreferredSize(new java.awt.Dimension(170, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.name")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jName.setEditable(false); + m_jName.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(170, 30)); + + jLabel12.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel12.setText(AppLocal.getIntString("label.notes")); // NOI18N + jLabel12.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.maxdebt")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(100, 30)); + + txtMaxdebt.setEditable(false); + txtMaxdebt.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + txtMaxdebt.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + txtMaxdebt.setPreferredSize(new java.awt.Dimension(170, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.curdebt")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(100, 30)); + + txtCurdebt.setEditable(false); + txtCurdebt.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + txtCurdebt.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + txtCurdebt.setPreferredSize(new java.awt.Dimension(170, 30)); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setText(AppLocal.getIntString("label.curdate")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(100, 30)); + + txtCurdate.setEditable(false); + txtCurdate.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + txtCurdate.setHorizontalAlignment(javax.swing.JTextField.CENTER); + txtCurdate.setPreferredSize(new java.awt.Dimension(170, 30)); + + m_jNotes.setEditable(false); + m_jNotes.setBackground(new java.awt.Color(240, 240, 240)); + m_jNotes.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jNotes.setBorder(null); + m_jNotes.setEnabled(false); + m_jNotes.setPreferredSize(new java.awt.Dimension(170, 80)); + jScrollPane1.setViewportView(m_jNotes); + + jlblMessage.setEditable(false); + jlblMessage.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jlblMessage.setForeground(new java.awt.Color(204, 0, 102)); + jlblMessage.setLineWrap(true); + jlblMessage.setWrapStyleWord(true); + jlblMessage.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + jlblMessage.setFocusable(false); + jlblMessage.setPreferredSize(new java.awt.Dimension(275, 60)); + jlblMessage.setRequestFocusEnabled(false); + + javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); + jPanel4.setLayout(jPanel4Layout); + jPanel4Layout.setHorizontalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtCurdebt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel4Layout.createSequentialGroup() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtMaxdebt, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel4Layout.createSequentialGroup() + .addComponent(jLabel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane1)) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel4Layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanel4Layout.createSequentialGroup() + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jMoneyEuros, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(jlblMessage, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel4Layout.createSequentialGroup() + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtCurdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addContainerGap(30, Short.MAX_VALUE)) + ); + jPanel4Layout.setVerticalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jMoneyEuros, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(txtMaxdebt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(txtCurdebt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(txtCurdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jlblMessage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + + jPanel5.add(jPanel4, java.awt.BorderLayout.CENTER); + + jPanel6.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout()); + jPanel5.add(jPanel6, java.awt.BorderLayout.PAGE_END); + + add(jPanel5, java.awt.BorderLayout.CENTER); + + jPanel2.setLayout(new java.awt.BorderLayout()); + + jPanel1.setLayout(new javax.swing.BoxLayout(jPanel1, javax.swing.BoxLayout.Y_AXIS)); + + m_jKeys.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jKeysActionPerformed(evt); + } + }); + jPanel1.add(m_jKeys); + + jPanel3.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + + m_jTendered.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jTendered.setPreferredSize(new java.awt.Dimension(200, 30)); + + javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); + jPanel3.setLayout(jPanel3Layout); + jPanel3Layout.setHorizontalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addGap(40, 40, 40) + .addComponent(m_jTendered, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(50, Short.MAX_VALUE)) + ); + jPanel3Layout.setVerticalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jTendered, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + ); + + jPanel1.add(jPanel3); + + jPanel2.add(jPanel1, java.awt.BorderLayout.NORTH); + + add(jPanel2, java.awt.BorderLayout.EAST); + }// </editor-fold>//GEN-END:initComponents + + private void m_jKeysActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jKeysActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_m_jKeysActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel12; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel8; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JPanel jPanel6; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JTextArea jlblMessage; + private com.unicenta.editor.JEditorKeys m_jKeys; + private javax.swing.JLabel m_jMoneyEuros; + private javax.swing.JTextField m_jName; + private javax.swing.JTextArea m_jNotes; + private com.unicenta.editor.JEditorCurrencyPositive m_jTendered; + private javax.swing.JTextField txtCurdate; + private javax.swing.JTextField txtCurdebt; + private javax.swing.JTextField txtMaxdebt; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentFree.form b/src/main/java/com/unicenta/pos/payment/JPaymentFree.form new file mode 100644 index 0000000..3436b5d --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentFree.form @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="148" max="-2" attributes="0"/> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <EmptySpace pref="165" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="126" max="-2" attributes="0"/> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <EmptySpace pref="131" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="36" style="1"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="message.paymentfree" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentFree.java b/src/main/java/com/unicenta/pos/payment/JPaymentFree.java new file mode 100644 index 0000000..f737f94 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentFree.java @@ -0,0 +1,113 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.pos.customers.CustomerInfoExt; +import com.unicenta.pos.forms.AppLocal; +import java.awt.Component; + +/** + * + * @author JG uniCenta + */ +public class JPaymentFree extends javax.swing.JPanel implements JPaymentInterface { + + private double m_dTotal; + private JPaymentNotifier m_notifier; + + /** Creates new form JPaymentFree + * @param notifier */ + public JPaymentFree(JPaymentNotifier notifier) { + m_notifier = notifier; + initComponents(); + } + + /** + * + * @param customerext + * @param dTotal + * @param transID + */ + @Override + public void activate(CustomerInfoExt customerext, double dTotal, String transID) { + + m_dTotal = dTotal; + + // m_jTotal.setText(Formats.CURRENCY.formatValue(new Double(m_dTotal))); + + m_notifier.setStatus(true, true); + } + + /** + * + * @return + */ + @Override + public PaymentInfo executePayment() { + return new PaymentInfoFree(m_dTotal); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel1 = new javax.swing.JLabel(); + + jLabel1.setFont(new java.awt.Font("Arial", 1, 36)); // NOI18N + jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLabel1.setText(AppLocal.getIntString("message.paymentfree")); // NOI18N + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(148, 148, 148) + .addComponent(jLabel1) + .addContainerGap(165, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(126, 126, 126) + .addComponent(jLabel1) + .addContainerGap(131, Short.MAX_VALUE)) + ); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentInterface.java b/src/main/java/com/unicenta/pos/payment/JPaymentInterface.java new file mode 100644 index 0000000..036b262 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentInterface.java @@ -0,0 +1,34 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.pos.customers.CustomerInfoExt; +import java.awt.Component; + +/** + * + * @author Adrian + */ +public interface JPaymentInterface { + + public void activate(CustomerInfoExt customerext, double dTotal, String transactionID); + public PaymentInfo executePayment(); + public Component getComponent(); +} diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentMagcard.form b/src/main/java/com/unicenta/pos/payment/JPaymentMagcard.form new file mode 100644 index 0000000..bdb9e9a --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentMagcard.form @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[500, 50]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,50,0,0,1,-12"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[290, 35]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[500, 45]"/> + </Property> + </Properties> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jlblMessage" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jlblMessage" max="32767" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jlblMessage"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentMagcard.java b/src/main/java/com/unicenta/pos/payment/JPaymentMagcard.java new file mode 100644 index 0000000..f723090 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentMagcard.java @@ -0,0 +1,162 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.pos.customers.CustomerInfoExt; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import java.awt.BorderLayout; +import java.awt.Component; + +/** + * + * @author adrianromero + */ +public class JPaymentMagcard extends javax.swing.JPanel implements JPaymentInterface { + + private PaymentPanel m_cardpanel; + private final PaymentGateway m_paymentgateway; + private final JPaymentNotifier m_notifier; + private String transaction; + + /** Creates new form JPaymentMagcard + * @param app + * @param notifier */ + public JPaymentMagcard(AppView app, JPaymentNotifier notifier) { + + initComponents(); + + m_notifier = notifier; + + m_paymentgateway = PaymentGatewayFac.getPaymentGateway(app.getProperties()); + + if (m_paymentgateway == null) { + jlblMessage.setText(AppLocal.getIntString("message.nopaymentgateway")); + } else { + // Se van a poder efectuar pagos con tarjeta + m_cardpanel = PaymentPanelFac.getPaymentPanel(app.getProperties().getProperty("payment.magcardreader"), notifier); + add(m_cardpanel.getComponent(), BorderLayout.CENTER); + jlblMessage.setText(null); + // jlblMessage.setText(AppLocal.getIntString("message.nocardreader")); + } + } + + /** + * + * @param customerext + * @param dTotal + * @param transID + */ + @Override + public void activate(CustomerInfoExt customerext, double dTotal, String transID) { + this.transaction = transID; + + if (m_cardpanel == null) { + jlblMessage.setText(AppLocal.getIntString("message.nopaymentgateway")); + m_notifier.setStatus(false, false); + } else { + jlblMessage.setText(null); + m_cardpanel.activate(transaction, dTotal); + } + } + + /** + * + * @return + */ + @Override + public PaymentInfo executePayment() { + + jlblMessage.setText(null); + + PaymentInfoMagcard payinfo = m_cardpanel.getPaymentInfoMagcard(); + + m_paymentgateway.execute(payinfo); + if (payinfo.isPaymentOK()) { + return payinfo; + } else { + jlblMessage.setText(payinfo.getMessage()); + return null; + } + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @param transid + */ + public void setTransaction(String transid){ + transaction = transid; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jlblMessage = new javax.swing.JLabel(); + + setMinimumSize(new java.awt.Dimension(300, 40)); + setPreferredSize(new java.awt.Dimension(500, 50)); + + jPanel1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel1.setMinimumSize(new java.awt.Dimension(290, 35)); + jPanel1.setPreferredSize(new java.awt.Dimension(500, 45)); + + jlblMessage.setFont(new java.awt.Font("Arial", 0, 18)); // NOI18N + jlblMessage.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jlblMessage, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jlblMessage, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) + ); + + add(jPanel1); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JLabel jlblMessage; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentNotifier.java b/src/main/java/com/unicenta/pos/payment/JPaymentNotifier.java new file mode 100644 index 0000000..b3ea141 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentNotifier.java @@ -0,0 +1,38 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + + +package com.unicenta.pos.payment; + +/** + * + * @author adrian + */ +public interface JPaymentNotifier { + +// public void setOKEnabled(boolean bValue); +// public void setAddEnabled(boolean bValue); + + /** + * + * @param isPositive + * @param isComplete + */ + public void setStatus(boolean isPositive, boolean isComplete); +} diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentPaper.form b/src/main/java/com/unicenta/pos/payment/JPaymentPaper.form new file mode 100644 index 0000000..c937600 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentPaper.form @@ -0,0 +1,254 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,127,0,0,2,88"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="webLblCustomer" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="webLblcustomerName" max="32767" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="10" pref="10" max="-2" attributes="0"/> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jMoneyEuros" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel5" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jVoucher" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <EmptySpace min="120" pref="120" max="-2" attributes="0"/> + <Component id="voucherID" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jVoucher" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <Component id="m_jMoneyEuros" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="webLblCustomer" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="webLblcustomerName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="voucherID" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="197" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="1"/> + </Property> + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor"> + <ComponentRef name="m_jVoucher"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.voucher" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jVoucher"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[180, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jVoucherActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="1"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.voucherValue" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jMoneyEuros"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="33" green="ff" red="cc" type="rgb"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="1"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[180, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.label.WebLabel" name="webLblCustomer"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.customer" replaceFormat="AppLocal.getIntString("label.customer")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value=""/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="1"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.label.WebLabel" name="webLblcustomerName"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.customer" replaceFormat="AppLocal.getIntString("label.customer")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value=""/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.label.WebLabel" name="voucherID"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.customer" replaceFormat="AppLocal.getIntString("label.customer")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value=""/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel11"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel12"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="1"/> + </Layout> + <SubComponents> + <Component class="com.unicenta.editor.JEditorKeys" name="m_jKeys"> + </Component> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Component class="com.unicenta.editor.JEditorCurrencyPositive" name="m_jTendered"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[130, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentPaper.java b/src/main/java/com/unicenta/pos/payment/JPaymentPaper.java new file mode 100644 index 0000000..683ce91 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentPaper.java @@ -0,0 +1,348 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2016 uniCenta and part works Openbravo, S.L. +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.format.Formats; +import com.unicenta.pos.customers.CustomerInfoExt; +import com.unicenta.pos.customers.DataLogicCustomers; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.util.RoundUtils; +import com.unicenta.pos.voucher.VoucherInfo; +//import com.unicenta.pos.voucher.VoucherInfo; +import java.awt.Component; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.List; + +/** + * + * @author JG uniCenta + */ +public class JPaymentPaper extends javax.swing.JPanel implements JPaymentInterface { + + private final JPaymentNotifier m_notifier; + + private DataLogicSales dlSales; + private DataLogicCustomers dlCustomers; + private ComboBoxValModel m_VoucherModel; + private SentenceList m_sentvouch; + private VoucherInfo m_voucherInfo; + + private double m_dTicket; + private double m_dTotal; + + private final String m_sPaper; // "paperin", "paperout" + private String m_sVoucher; + + /** Creates new form JPaymentTicket + * @param app + * @param notifier + * @param sPaper */ + public JPaymentPaper(AppView app, JPaymentNotifier notifier, String sPaper) { + + m_notifier = notifier; + m_sPaper = sPaper; + m_dTotal=0.0; + + init(app); + + m_jTendered.addPropertyChangeListener("Edition", new RecalculateState()); +// m_jTendered.addEditorKeys(m_jKeys); + + } + private void init(AppView app) { + + try { + dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + dlCustomers = (DataLogicCustomers) app.getBean("com.unicenta.pos.customers.DataLogicCustomers"); + m_sentvouch = dlSales.getVoucherList(); + + initComponents(); + + m_VoucherModel = new ComboBoxValModel(); + List a = m_sentvouch.list(); + a.add(0, null); + + m_VoucherModel = new ComboBoxValModel(a); + m_jVoucher.setModel(m_VoucherModel); + + webLblcustomerName.setText(null); + + } catch (BasicException ex) { + } + } + + /** + * + * @param customerext + * @param dTotal + * @param transID + */ + @Override + public void activate(CustomerInfoExt customerext, double dTotal,String transID) { + + m_dTotal = dTotal; + + m_jTendered.reset(); +// m_jTendered.activate(); + + m_jKeys.setEnabled(false); + m_jTendered.setEnabled(false); + + printState(); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @return + */ + @Override + public PaymentInfo executePayment() { +/* try { + String id = m_VoucherModel.getSelectedKey().toString(); + VoucherInfo m_voucherInfo = dlCustomers.getVoucherInfo(id); + + } catch (BasicException ex) { + } + if (m_dTicket>m_dTotal){ + return new VoucherPaymentInfo(m_dTotal, m_sPaper,m_voucherInfo.getVoucherNumber()); + }else{ + return new VoucherPaymentInfo(m_dTicket, m_sPaper,m_voucherInfo.getVoucherNumber()); + } +*/ + try { + String id = m_VoucherModel.getSelectedKey().toString(); + VoucherInfo m_voucherInfo1 = dlCustomers.getVoucherInfo(id); + m_sVoucher = m_voucherInfo1.getVoucherNumber(); + } catch (BasicException ex) { + } + return new PaymentInfoTicket(m_dTicket, m_sPaper, m_sVoucher); + + } + + private void printState() { + + Double value = m_jTendered.getDoubleValue(); + if (value == null) { + m_dTicket = 0.0; + } else { + m_dTicket = value; + } + + m_jMoneyEuros.setText(Formats.CURRENCY.formatValue(m_dTicket)); + + int iCompare = RoundUtils.compare(m_dTicket, m_dTotal); + + // it is allowed to pay more + m_notifier.setStatus(m_dTicket > 0.0, iCompare >= 0); + } + + private class RecalculateState implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + printState(); + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel4 = new javax.swing.JPanel(); + jLabel5 = new javax.swing.JLabel(); + m_jVoucher = new javax.swing.JComboBox(); + jLabel1 = new javax.swing.JLabel(); + m_jMoneyEuros = new javax.swing.JLabel(); + webLblCustomer = new com.alee.laf.label.WebLabel(); + webLblcustomerName = new com.alee.laf.label.WebLabel(); + voucherID = new com.alee.laf.label.WebLabel(); + jPanel11 = new javax.swing.JPanel(); + jPanel12 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel1 = new javax.swing.JPanel(); + m_jTendered = new com.unicenta.editor.JEditorCurrencyPositive(); + + setLayout(new java.awt.BorderLayout()); + + jLabel5.setFont(new java.awt.Font("Arial", 1, 18)); // NOI18N + jLabel5.setLabelFor(m_jVoucher); + jLabel5.setText(AppLocal.getIntString("label.voucher")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jVoucher.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jVoucher.setPreferredSize(new java.awt.Dimension(180, 30)); + m_jVoucher.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jVoucherActionPerformed(evt); + } + }); + + jLabel1.setFont(new java.awt.Font("Arial", 1, 18)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.voucherValue")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jMoneyEuros.setBackground(new java.awt.Color(204, 255, 51)); + m_jMoneyEuros.setFont(new java.awt.Font("Arial", 1, 18)); // NOI18N + m_jMoneyEuros.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jMoneyEuros.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jMoneyEuros.setOpaque(true); + m_jMoneyEuros.setPreferredSize(new java.awt.Dimension(180, 30)); + + webLblCustomer.setText(AppLocal.getIntString("label.customer")); // NOI18N + webLblCustomer.setToolTipText(""); + webLblCustomer.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + webLblCustomer.setPreferredSize(new java.awt.Dimension(100, 30)); + + webLblcustomerName.setText(AppLocal.getIntString("label.customer")); // NOI18N + webLblcustomerName.setToolTipText(""); + webLblcustomerName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + webLblcustomerName.setPreferredSize(new java.awt.Dimension(100, 30)); + + voucherID.setText(AppLocal.getIntString("label.customer")); // NOI18N + voucherID.setToolTipText(""); + voucherID.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + voucherID.setPreferredSize(new java.awt.Dimension(100, 30)); + + javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); + jPanel4.setLayout(jPanel4Layout); + jPanel4Layout.setHorizontalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addComponent(webLblCustomer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(webLblcustomerName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(jPanel4Layout.createSequentialGroup() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addGap(10, 10, 10) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jMoneyEuros, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jVoucher, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(jPanel4Layout.createSequentialGroup() + .addGap(120, 120, 120) + .addComponent(voucherID, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel4Layout.setVerticalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jVoucher, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jMoneyEuros, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(webLblCustomer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(webLblcustomerName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addComponent(voucherID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(197, 197, 197)) + ); + + add(jPanel4, java.awt.BorderLayout.CENTER); + + jPanel11.setLayout(new java.awt.BorderLayout()); + + jPanel12.setLayout(new javax.swing.BoxLayout(jPanel12, javax.swing.BoxLayout.Y_AXIS)); + jPanel12.add(m_jKeys); + + jPanel1.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel1.setLayout(new java.awt.BorderLayout()); + + m_jTendered.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jTendered.setPreferredSize(new java.awt.Dimension(130, 30)); + jPanel1.add(m_jTendered, java.awt.BorderLayout.CENTER); + + jPanel12.add(jPanel1); + + jPanel11.add(jPanel12, java.awt.BorderLayout.NORTH); + + add(jPanel11, java.awt.BorderLayout.EAST); + }// </editor-fold>//GEN-END:initComponents + + private void m_jVoucherActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jVoucherActionPerformed + + if (m_VoucherModel.getSelectedKey()!=null){ + try { + + String id = m_VoucherModel.getSelectedKey().toString(); + VoucherInfo m_voucherInfo = dlCustomers.getVoucherInfo(id); + + if (m_voucherInfo != null){ + m_jTendered.setDoubleValue(m_voucherInfo.getAmount()); + m_jMoneyEuros.setText(Formats.CURRENCY.formatValue(m_voucherInfo.getAmount())); + + webLblcustomerName.setText(m_voucherInfo.getCustomerName()); + + printState(); + } + } catch (BasicException ex) { +// ex.printStackTrace(); + } + + } + }//GEN-LAST:event_m_jVoucherActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel5; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel11; + private javax.swing.JPanel jPanel12; + private javax.swing.JPanel jPanel4; + private com.unicenta.editor.JEditorKeys m_jKeys; + private javax.swing.JLabel m_jMoneyEuros; + private com.unicenta.editor.JEditorCurrencyPositive m_jTendered; + private javax.swing.JComboBox m_jVoucher; + private com.alee.laf.label.WebLabel voucherID; + private com.alee.laf.label.WebLabel webLblCustomer; + private com.alee.laf.label.WebLabel webLblcustomerName; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentRefund.form b/src/main/java/com/unicenta/pos/payment/JPaymentRefund.form new file mode 100644 index 0000000..24fda90 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentRefund.form @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace pref="35" max="32767" attributes="0"/> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <EmptySpace pref="35" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="131" max="-2" attributes="0"/> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <EmptySpace pref="155" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="30" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="message.paymentcashneg" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentRefund.java b/src/main/java/com/unicenta/pos/payment/JPaymentRefund.java new file mode 100644 index 0000000..e6c5a5f --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentRefund.java @@ -0,0 +1,115 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.pos.customers.CustomerInfoExt; +import com.unicenta.pos.forms.AppLocal; +import java.awt.Component; + +/** + * + * @author JG uniCenta + */ +public class JPaymentRefund extends javax.swing.JPanel implements JPaymentInterface { + + private JPaymentNotifier m_notifier; + private double m_dTotal; + + private String m_sName; + + /** Creates new form JPaymentChequeRefund + * @param notifier + * @param sName */ + public JPaymentRefund(JPaymentNotifier notifier, String sName) { + + m_notifier = notifier; + m_sName = sName; + + initComponents(); + } + + /** + * + * @param customerext + * @param dTotal + * @param transID + */ + @Override + public void activate(CustomerInfoExt customerext, double dTotal, String transID) { + m_dTotal = dTotal; + + m_notifier.setStatus(true, true); + } + + /** + * + * @return + */ + @Override + public PaymentInfo executePayment() { + return new PaymentInfoTicket(m_dTotal, m_sName); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel1 = new javax.swing.JLabel(); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 30)); // NOI18N + jLabel1.setText(AppLocal.getIntString("message.paymentcashneg")); // NOI18N + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap(35, Short.MAX_VALUE) + .addComponent(jLabel1) + .addContainerGap(35, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(131, 131, 131) + .addComponent(jLabel1) + .addContainerGap(155, Short.MAX_VALUE)) + ); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentSelect.form b/src/main/java/com/unicenta/pos/payment/JPaymentSelect.form new file mode 100644 index 0000000..efc0368 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentSelect.form @@ -0,0 +1,379 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="payment.title" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[750, 127]"/> + </Property> + <Property name="resizable" type="boolean" value="false"/> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-15,0,0,2,-10"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="-2" pref="5" max="-2" attributes="0"/> + <Component id="m_jLblTotalEuros1" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jTotalEuros" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jPanel6" min="-2" max="-2" attributes="0"/> + <Group type="102" attributes="0"> + <Component id="m_jLblRemainingEuros" min="-2" pref="120" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jRemaininglEuros" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="m_jButtonAdd" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jButtonRemove" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="4" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jButtonRemove" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="m_jButtonAdd" alignment="1" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace min="5" pref="5" max="-2" attributes="0"/> + <Component id="jPanel6" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jLblTotalEuros1" min="-2" max="-2" attributes="0"/> + <Component id="m_jRemaininglEuros" min="-2" max="-2" attributes="0"/> + <Component id="m_jLblRemainingEuros" min="-2" max="-2" attributes="0"/> + <Component id="m_jTotalEuros" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="m_jLblTotalEuros1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="24" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.totalcash" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jTotalEuros"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" id="white" palette="0" red="ff" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="24" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="99" green="8a" id="Button.darkShadow" palette="3" red="7a" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jLblRemainingEuros"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="24" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.remainingcash" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[120, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jRemaininglEuros"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" id="white" palette="0" red="ff" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="24" style="1"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="99" green="8a" id="Button.darkShadow" palette="3" red="7a" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + <Container class="javax.swing.JPanel" name="jPanel6"> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="verticalGap" type="int" value="0"/> + </Layout> + </Container> + <Component class="javax.swing.JButton" name="m_jButtonRemove"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/btnminus.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Delete Part Payment"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jButtonRemoveActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jButtonAdd"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/btnplus.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Add Part Payment"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jButtonAddActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Properties> + <Property name="nextFocusableComponent" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor"> + <ComponentRef name="m_jTabPayment"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JTabbedPane" name="m_jTabPayment"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + <Property name="tabPlacement" type="int" value="2"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="m_jTabPaymentStateChanged"/> + <EventHandler event="keyPressed" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="m_jTabPaymentKeyPressed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="After"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JButton" name="m_jButtonCancel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.cancel" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jButtonCancelActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jButtonOK"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.OK" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 44]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jButtonOKActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JToggleButton" name="m_jButtonPrint"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/printer24_off.png"/> + </Property> + <Property name="selected" type="boolean" value="true"/> + <Property name="toolTipText" type="java.lang.String" value="Print Receipt"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + <Property name="selectedIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/printer24.png"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jButtonPrintActionPerformed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Before"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="jlblPrinterStatus"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="24" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.printerstatusOn" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentSelect.java b/src/main/java/com/unicenta/pos/payment/JPaymentSelect.java new file mode 100644 index 0000000..d90ee7c --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentSelect.java @@ -0,0 +1,787 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.format.Formats; +import com.unicenta.pos.customers.CustomerInfoExt; +import com.unicenta.pos.customers.DataLogicCustomers; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.forms.DataLogicSystem; + +import java.awt.*; +import java.awt.event.KeyEvent; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.swing.JFrame; +import javax.swing.SwingWorker; + +/** + * + * @author adrianromero + */ +public abstract class JPaymentSelect extends javax.swing.JDialog + implements JPaymentNotifier { + + private PaymentInfoList m_aPaymentInfo; + private boolean printselected; + + private boolean accepted; + + private AppView app; + private double m_dTotal; + private CustomerInfoExt customerext; + private DataLogicSystem dlSystem; + private DataLogicCustomers dlCustomers ; + DataLogicSales dlSales; + + // JG 16 May 12 use diamond inference + private Map<String, JPaymentInterface> payments = new HashMap<>(); + private String m_sTransactionID; + private static PaymentInfo returnPayment = null; + + public static PaymentInfo getReturnPayment() { + return returnPayment; + } + + public static void setReturnPayment(PaymentInfo returnPayment) { + JPaymentSelect.returnPayment = returnPayment; + } + + + /** + * Creates new form JPaymentSelect + * + * @param parent + * @param modal + * @param o + */ + protected JPaymentSelect(java.awt.Frame parent, boolean modal, ComponentOrientation o) { + super(parent, modal); + initComponents(); + this.applyComponentOrientation(o); + getRootPane().setDefaultButton(m_jButtonOK); + + } + + /** Creates new form JPaymentSelect + * @param parent + * @param modal + * @param o */ + protected JPaymentSelect(java.awt.Dialog parent, boolean modal, ComponentOrientation o) { + super(parent, modal); + initComponents(); + + m_jButtonPrint.setVisible(true); + this.applyComponentOrientation(o); + if (printselected) { + jlblPrinterStatus.setText("Printer ON"); + } else { + jlblPrinterStatus.setText("Printer OFF"); + } + } + + public void init(AppView app) { + this.app = app; + dlSystem = (DataLogicSystem) app.getBean("com.unicenta.pos.forms.DataLogicSystem"); + dlCustomers= (DataLogicCustomers) app.getBean("com.unicenta.pos.customers.DataLogicCustomers"); + dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + + printselected = false; + if (printselected) { + jlblPrinterStatus.setText("Printer ON"); + } else { + jlblPrinterStatus.setText("Printer OFF"); + } + + } + + public void setPrintSelected(boolean value) { + printselected = value; + } + + public boolean isPrintSelected() { + return printselected; + } + + public List<PaymentInfo> getSelectedPayments() { + return m_aPaymentInfo.getPayments(); + } + + public boolean showDialog(double total, CustomerInfoExt customerext,double deposit) { + m_aPaymentInfo = new PaymentInfoList(); + accepted = false; + total -= deposit; + m_dTotal = total; + + this.customerext = customerext; + m_jButtonPrint.setVisible(true); + m_jButtonPrint.setSelected(printselected); + m_jTotalEuros.setText(Formats.CURRENCY.formatValue(m_dTotal)); + + addTabs(); + + // gets the print button state + printselected = m_jButtonPrint.isSelected(); + + // remove all tabs + m_jTabPayment.removeAll(); + + return accepted; + } + + public boolean showDialog(double total, CustomerInfoExt customerext) { + + m_aPaymentInfo = new PaymentInfoList(); + accepted = false; + + m_dTotal = total; + + this.customerext = customerext; + + setPrintSelected(!Boolean.parseBoolean(app.getProperties().getProperty("till.receiptprintoff"))); + m_jButtonPrint.setSelected(printselected); + m_jTotalEuros.setText(Formats.CURRENCY.formatValue(m_dTotal)); + + if (printselected) { + jlblPrinterStatus.setText("Printer ON"); + } else { + jlblPrinterStatus.setText("Printer OFF"); + } + +// N. Deppe 08/11/2018 +// Fix issue where dialog keeps moving lower and lower on the screen +// Get the size of the screen, and center the dialog in the window + Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize(); + Dimension thisDim = this.getSize(); + int x = (screenDim.width - thisDim.width) / 2; + int y = (screenDim.height - thisDim.height) / 2; + this.setLocation(x, y); + + addTabs(); + + if (m_jTabPayment.getTabCount() == 0) { + // No payment panels available + m_aPaymentInfo.add(getDefaultPayment(total)); + accepted = true; + } else { + getRootPane().setDefaultButton(m_jButtonOK); + printState(); + setVisible(true); + } + + // gets the print button state + printselected = m_jButtonPrint.isSelected(); + + // remove all tabs + m_jTabPayment.removeAll(); + + return accepted; + } + + protected abstract void addTabs(); + protected abstract void setStatusPanel(boolean isPositive, boolean isComplete); + protected abstract PaymentInfo getDefaultPayment(double total); + + protected void setOKEnabled(boolean value) { + m_jButtonOK.setEnabled(value); + } + + protected void setAddEnabled(boolean value) { + m_jButtonAdd.setEnabled(value); + } + + protected void addTabPayment(JPaymentCreator jpay) { + if (app.getAppUserView().getUser().hasPermission(jpay.getKey())) { + + JPaymentInterface jpayinterface = payments.get(jpay.getKey()); + if (jpayinterface == null) { + jpayinterface = jpay.createJPayment(); + payments.put(jpay.getKey(), jpayinterface); + } + + jpayinterface.getComponent().applyComponentOrientation(getComponentOrientation()); + m_jTabPayment.addTab( + AppLocal.getIntString(jpay.getLabelKey()), + new javax.swing.ImageIcon(getClass().getResource(jpay.getIconKey())), + jpayinterface.getComponent()); + } + } + + + public interface JPaymentCreator { + public JPaymentInterface createJPayment(); + public String getKey(); + public String getLabelKey(); + public String getIconKey(); + } + + public class JPaymentCashCreator implements JPaymentCreator { + @Override + public JPaymentInterface createJPayment() { + return new JPaymentCashPos(JPaymentSelect.this, dlSystem); + } + @Override + public String getKey() { + return "payment.cash"; } + @Override + public String getLabelKey() { + return "tab.cash"; } + @Override + public String getIconKey() { + return "/com/unicenta/images/cash.png"; } + } + + public class JPaymentChequeCreator implements JPaymentCreator { + @Override + public JPaymentInterface createJPayment() { + return new JPaymentCheque(JPaymentSelect.this); + } + @Override + public String getKey() { + return "payment.cheque"; } + @Override + public String getLabelKey() { + return "tab.cheque"; } + @Override + public String getIconKey() { + return "/com/unicenta/images/cheque.png"; } + } + + public class JPaymentVoucherCreator implements JPaymentCreator { + @Override + public JPaymentInterface createJPayment() { + return new JPaymentVoucher(app, JPaymentSelect.this, "voucherin"); + } + @Override + public String getKey() { + return "payment.voucher"; } + @Override + public String getLabelKey() { + return "tab.voucher"; } + @Override + public String getIconKey() { + return "/com/unicenta/images/voucher.png"; } + } + + public class JPaymentMagcardCreator implements JPaymentCreator { + @Override + public JPaymentInterface createJPayment() { + return new JPaymentMagcard(app, JPaymentSelect.this); + } + @Override + public String getKey() { + return "payment.magcard"; } + @Override + public String getLabelKey() { + return "tab.magcard"; } + @Override + public String getIconKey() { + return "/com/unicenta/images/ccard.png"; } + } + + + + public class JPaymentFreeCreator implements JPaymentCreator { + @Override + public JPaymentInterface createJPayment() { + return new JPaymentFree(JPaymentSelect.this); + } + @Override + public String getKey() { + return "payment.free"; + } + @Override + public String getLabelKey() { + return "tab.free"; + } + @Override + public String getIconKey() { + return "/com/unicenta/images/wallet.png"; + } + } + + public class JPaymentDebtCreator implements JPaymentCreator { + @Override + public JPaymentInterface createJPayment() { + return new JPaymentDebt(JPaymentSelect.this); + } + @Override + public String getKey() { + return "payment.debt"; + } + @Override + public String getLabelKey() { + return "tab.debt"; + } + @Override + public String getIconKey() { + return "/com/unicenta/images/customer.png"; + } + } + + public class JPaymentCashRefundCreator implements JPaymentCreator { + @Override + public JPaymentInterface createJPayment() { + return new JPaymentRefund(JPaymentSelect.this, "cashrefund"); + } + @Override + public String getKey() { + return "refund.cash"; + } + @Override + public String getLabelKey() { + return "tab.cashrefund"; + } + @Override + public String getIconKey() { + return "/com/unicenta/images/cash.png"; + } + } + + public class JPaymentChequeRefundCreator implements JPaymentCreator { + @Override + public JPaymentInterface createJPayment() { + return new JPaymentRefund(JPaymentSelect.this, "chequerefund"); + } + @Override + public String getKey() { + return "refund.cheque"; + } + @Override + public String getLabelKey() { + return "tab.chequerefund"; + } + @Override + public String getIconKey() { + return "/com/unicenta/images/cheque.png"; + } + } + + public class JPaymentVoucherRefundCreator implements JPaymentCreator { + @Override + public JPaymentInterface createJPayment() { + return new JPaymentRefund(JPaymentSelect.this, "voucherout"); + } + @Override + public String getKey() { + return "refund.voucher"; + } + @Override + public String getLabelKey() { + return "tab.voucher"; + } + @Override + public String getIconKey() { + return "/com/unicenta/images/voucher.png"; + } + } + + public class JPaymentMagcardRefundCreator implements JPaymentCreator { + @Override + public JPaymentInterface createJPayment() { + return new JPaymentMagcard(app, JPaymentSelect.this); + } + @Override + public String getKey() { + return "refund.magcard"; + } + @Override + public String getLabelKey() { + return "tab.magcard"; + } + @Override + public String getIconKey() { + return "/com/unicenta/images/ccard.png"; + } + } + + public class JPaymentBankCreator implements JPaymentCreator { + @Override + public JPaymentInterface createJPayment() { + return new JPaymentBank(JPaymentSelect.this); + } + @Override + public String getKey() { + return "payment.bank"; + } + @Override + public String getLabelKey() { + return "tab.bank"; + } + @Override + public String getIconKey() { + return "/com/unicenta/images/bank.png"; + } + } + + public class JPaymentSlipCreator implements JPaymentCreator { + @Override + public JPaymentInterface createJPayment() { + return new JPaymentSlip(JPaymentSelect.this); + } + @Override + public String getKey() { + return "payment.slip"; + } + @Override + public String getLabelKey() { + return "tab.slip"; + } + @Override + public String getIconKey() { + return "/com/unicenta/images/slip.png"; + } + } + + private void printState() { + + m_jRemaininglEuros.setText(Formats.CURRENCY.formatValue( + m_dTotal - m_aPaymentInfo.getTotal())); + m_jButtonRemove.setEnabled(!m_aPaymentInfo.isEmpty()); + m_jTabPayment.setSelectedIndex(0); + ((JPaymentInterface) m_jTabPayment.getSelectedComponent()) + .activate(customerext, + m_dTotal - m_aPaymentInfo.getTotal() + , m_sTransactionID); + } + + protected static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window)parent; + } else { + return getWindow(parent.getParent()); + } + } + + @Override + public void setStatus(boolean isPositive, boolean isComplete) { + + setStatusPanel(isPositive, isComplete); + } + + public void setTransactionID(String tID){ + this.m_sTransactionID = tID; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel4 = new javax.swing.JPanel(); + m_jLblTotalEuros1 = new javax.swing.JLabel(); + m_jTotalEuros = new javax.swing.JLabel(); + m_jLblRemainingEuros = new javax.swing.JLabel(); + m_jRemaininglEuros = new javax.swing.JLabel(); + jPanel6 = new javax.swing.JPanel(); + m_jButtonRemove = new javax.swing.JButton(); + m_jButtonAdd = new javax.swing.JButton(); + jPanel3 = new javax.swing.JPanel(); + m_jTabPayment = new javax.swing.JTabbedPane(); + jPanel5 = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + m_jButtonCancel = new javax.swing.JButton(); + m_jButtonOK = new javax.swing.JButton(); + m_jButtonPrint = new javax.swing.JToggleButton(); + jlblPrinterStatus = new javax.swing.JLabel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(AppLocal.getIntString("payment.title")); // NOI18N + setPreferredSize(new java.awt.Dimension(750, 127)); + setResizable(false); + + jPanel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + + m_jLblTotalEuros1.setFont(new java.awt.Font("Arial", 0, 24)); // NOI18N + m_jLblTotalEuros1.setText(AppLocal.getIntString("label.totalcash")); // NOI18N + m_jLblTotalEuros1.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jTotalEuros.setFont(new java.awt.Font("Arial", 0, 24)); // NOI18N + m_jTotalEuros.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + m_jTotalEuros.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jTotalEuros.setOpaque(true); + m_jTotalEuros.setPreferredSize(new java.awt.Dimension(150, 30)); + m_jTotalEuros.setRequestFocusEnabled(false); + + m_jLblRemainingEuros.setFont(new java.awt.Font("Arial", 0, 24)); // NOI18N + m_jLblRemainingEuros.setText(AppLocal.getIntString("label.remainingcash")); // NOI18N + m_jLblRemainingEuros.setPreferredSize(new java.awt.Dimension(120, 30)); + + m_jRemaininglEuros.setFont(new java.awt.Font("Arial", 1, 24)); // NOI18N + m_jRemaininglEuros.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + m_jRemaininglEuros.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jRemaininglEuros.setOpaque(true); + m_jRemaininglEuros.setPreferredSize(new java.awt.Dimension(150, 30)); + m_jRemaininglEuros.setRequestFocusEnabled(false); + + jPanel6.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 5, 0)); + + m_jButtonRemove.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btnminus.png"))); // NOI18N + m_jButtonRemove.setToolTipText("Delete Part Payment"); + m_jButtonRemove.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jButtonRemove.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jButtonRemoveActionPerformed(evt); + } + }); + + m_jButtonAdd.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btnplus.png"))); // NOI18N + m_jButtonAdd.setToolTipText("Add Part Payment"); + m_jButtonAdd.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jButtonAdd.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jButtonAddActionPerformed(evt); + } + }); + + org.jdesktop.layout.GroupLayout jPanel4Layout = new org.jdesktop.layout.GroupLayout(jPanel4); + jPanel4.setLayout(jPanel4Layout); + jPanel4Layout.setHorizontalGroup( + jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jPanel4Layout.createSequentialGroup() + .add(5, 5, 5) + .add(m_jLblTotalEuros1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) + .add(m_jTotalEuros, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) + .add(jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jPanel6, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(jPanel4Layout.createSequentialGroup() + .add(m_jLblRemainingEuros, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 120, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(m_jRemaininglEuros, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))) + .add(18, 18, 18) + .add(m_jButtonAdd, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(m_jButtonRemove, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(4, 4, 4)) + ); + jPanel4Layout.setVerticalGroup( + jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel4Layout.createSequentialGroup() + .add(0, 0, Short.MAX_VALUE) + .add(jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(org.jdesktop.layout.GroupLayout.TRAILING, m_jButtonRemove, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(org.jdesktop.layout.GroupLayout.TRAILING, m_jButtonAdd, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))) + .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel4Layout.createSequentialGroup() + .add(5, 5, 5) + .add(jPanel6, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(m_jLblTotalEuros1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(m_jRemaininglEuros, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(m_jLblRemainingEuros, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(m_jTotalEuros, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + + getContentPane().add(jPanel4, java.awt.BorderLayout.NORTH); + + jPanel3.setNextFocusableComponent(m_jTabPayment); + jPanel3.setLayout(new java.awt.BorderLayout()); + + m_jTabPayment.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + m_jTabPayment.setTabPlacement(javax.swing.JTabbedPane.LEFT); + m_jTabPayment.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jTabPayment.setRequestFocusEnabled(false); + m_jTabPayment.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + m_jTabPaymentStateChanged(evt); + } + }); + m_jTabPayment.addKeyListener(new java.awt.event.KeyAdapter() { + public void keyPressed(java.awt.event.KeyEvent evt) { + m_jTabPaymentKeyPressed(evt); + } + }); + jPanel3.add(m_jTabPayment, java.awt.BorderLayout.CENTER); + + getContentPane().add(jPanel3, java.awt.BorderLayout.CENTER); + + jPanel5.setLayout(new java.awt.BorderLayout()); + + m_jButtonCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jButtonCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + m_jButtonCancel.setText(AppLocal.getIntString("button.cancel")); // NOI18N + m_jButtonCancel.setFocusPainted(false); + m_jButtonCancel.setFocusable(false); + m_jButtonCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jButtonCancel.setPreferredSize(new java.awt.Dimension(110, 45)); + m_jButtonCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jButtonCancelActionPerformed(evt); + } + }); + jPanel2.add(m_jButtonCancel); + + m_jButtonOK.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jButtonOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + m_jButtonOK.setText(AppLocal.getIntString("button.OK")); // NOI18N + m_jButtonOK.setFocusPainted(false); + m_jButtonOK.setFocusable(false); + m_jButtonOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jButtonOK.setMaximumSize(new java.awt.Dimension(100, 44)); + m_jButtonOK.setPreferredSize(new java.awt.Dimension(110, 45)); + m_jButtonOK.setRequestFocusEnabled(false); + m_jButtonOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jButtonOKActionPerformed(evt); + } + }); + jPanel2.add(m_jButtonOK); + + jPanel5.add(jPanel2, java.awt.BorderLayout.LINE_END); + + m_jButtonPrint.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/printer24_off.png"))); // NOI18N + m_jButtonPrint.setSelected(true); + m_jButtonPrint.setToolTipText("Print Receipt"); + m_jButtonPrint.setFocusPainted(false); + m_jButtonPrint.setFocusable(false); + m_jButtonPrint.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jButtonPrint.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jButtonPrint.setRequestFocusEnabled(false); + m_jButtonPrint.setSelectedIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/printer24.png"))); // NOI18N + m_jButtonPrint.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jButtonPrintActionPerformed(evt); + } + }); + jPanel5.add(m_jButtonPrint, java.awt.BorderLayout.LINE_START); + + jlblPrinterStatus.setFont(new java.awt.Font("Arial", 0, 24)); // NOI18N + jlblPrinterStatus.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jlblPrinterStatus.setText(bundle.getString("label.printerstatusOn")); // NOI18N + jPanel5.add(jlblPrinterStatus, java.awt.BorderLayout.CENTER); + + getContentPane().add(jPanel5, java.awt.BorderLayout.SOUTH); + + setSize(new java.awt.Dimension(758, 497)); + setLocationRelativeTo(null); + }// </editor-fold>//GEN-END:initComponents + + private void m_jButtonRemoveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jButtonRemoveActionPerformed + + m_aPaymentInfo.removeLast(); + printState(); + + }//GEN-LAST:event_m_jButtonRemoveActionPerformed + + private void m_jButtonAddActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jButtonAddActionPerformed + + PaymentInfo returnPayment = ( + (JPaymentInterface) m_jTabPayment.getSelectedComponent()) + .executePayment(); + if (returnPayment != null) { + m_aPaymentInfo.add(returnPayment); + printState(); + } + + }//GEN-LAST:event_m_jButtonAddActionPerformed + + private void m_jTabPaymentStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_m_jTabPaymentStateChanged + + if (m_jTabPayment.getSelectedComponent() != null) { + ((JPaymentInterface) m_jTabPayment.getSelectedComponent()) + .activate(customerext + , m_dTotal - m_aPaymentInfo.getTotal() + , m_sTransactionID); + m_jRemaininglEuros.setText( + Formats.CURRENCY.formatValue( + m_dTotal - m_aPaymentInfo.getTotal())); + } + + }//GEN-LAST:event_m_jTabPaymentStateChanged + + private void m_jButtonOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jButtonOKActionPerformed + + SwingWorker worker = new SwingWorker() { + @Override + protected Object doInBackground() throws Exception { + m_jButtonOK.setEnabled(false); + setReturnPayment(((JPaymentInterface) m_jTabPayment.getSelectedComponent()).executePayment()); + return null; + } + + @Override + public void done() { + m_jButtonOK.setEnabled(true); + m_jButtonCancel.setEnabled(true); + if (returnPayment != null) { + m_aPaymentInfo.add(returnPayment); + accepted = true; + dispose(); + } + } + }; + + worker.execute(); + }//GEN-LAST:event_m_jButtonOKActionPerformed + + private void m_jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jButtonCancelActionPerformed + + dispose(); + + }//GEN-LAST:event_m_jButtonCancelActionPerformed + + private void m_jButtonPrintActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jButtonPrintActionPerformed + if (!m_jButtonPrint.isSelected()) { + jlblPrinterStatus.setText("Printer OFF"); + } else { + jlblPrinterStatus.setText("Printer ON"); + } + }//GEN-LAST:event_m_jButtonPrintActionPerformed + + private void m_jTabPaymentKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_m_jTabPaymentKeyPressed + + if( evt.getKeyCode() == KeyEvent.VK_F1 ) { + + } else if ( evt.getKeyCode() == KeyEvent.VK_F2 ) { + + } + }//GEN-LAST:event_m_jTabPaymentKeyPressed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JPanel jPanel6; + private javax.swing.JLabel jlblPrinterStatus; + private javax.swing.JButton m_jButtonAdd; + private javax.swing.JButton m_jButtonCancel; + private javax.swing.JButton m_jButtonOK; + private javax.swing.JToggleButton m_jButtonPrint; + private javax.swing.JButton m_jButtonRemove; + private javax.swing.JLabel m_jLblRemainingEuros; + private javax.swing.JLabel m_jLblTotalEuros1; + private javax.swing.JLabel m_jRemaininglEuros; + private javax.swing.JTabbedPane m_jTabPayment; + private javax.swing.JLabel m_jTotalEuros; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentSelectCustomer.java b/src/main/java/com/unicenta/pos/payment/JPaymentSelectCustomer.java new file mode 100644 index 0000000..4c718db --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentSelectCustomer.java @@ -0,0 +1,97 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import java.awt.*; + +/** + * + * @author adrianromero + */ +public class JPaymentSelectCustomer extends JPaymentSelect { + + /** Creates new form JPaymentSelect + * @param parent + * @param modal + * @param o */ + protected JPaymentSelectCustomer(java.awt.Frame parent, boolean modal, ComponentOrientation o) { + super(parent, modal, o); + } + /** Creates new form JPaymentSelect + * @param parent + * @param modal + * @param o */ + protected JPaymentSelectCustomer(java.awt.Dialog parent, boolean modal, ComponentOrientation o) { + super(parent, modal, o); + } + + /** + * + * @param parent + * @return + */ + public static JPaymentSelect getDialog(Component parent) { + + Window window = getWindow(parent); + + if (window instanceof Frame) { + return new JPaymentSelectCustomer((Frame) window, true, parent.getComponentOrientation()); + } else { + return new JPaymentSelectCustomer((Dialog) window, true, parent.getComponentOrientation()); + } + } + + /** + * + */ + @Override + protected void addTabs() { +// Bank Payment Receipt - Thanks Steve Clough! August 2011 + addTabPayment(new JPaymentSelect.JPaymentCashCreator()); + addTabPayment(new JPaymentSelect.JPaymentChequeCreator()); + addTabPayment(new JPaymentSelect.JPaymentVoucherCreator()); + addTabPayment(new JPaymentSelect.JPaymentBankCreator()); + addTabPayment(new JPaymentSelect.JPaymentMagcardCreator()); + addTabPayment(new JPaymentSelect.JPaymentSlipCreator()); + } + + /** + * + * @param isPositive + * @param isComplete + */ + @Override + protected void setStatusPanel(boolean isPositive, boolean isComplete) { + + setAddEnabled(isPositive && !isComplete); + setOKEnabled(isPositive); + } + + /** + * + * @param total + * @return + */ + @Override + protected PaymentInfo getDefaultPayment(double total) { +// return new PaymentInfoCash_original(total, total); + return new PaymentInfoCash(total, total); + } +} diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentSelectReceipt.java b/src/main/java/com/unicenta/pos/payment/JPaymentSelectReceipt.java new file mode 100644 index 0000000..78a49d6 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentSelectReceipt.java @@ -0,0 +1,100 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import java.awt.*; + +/** + * + * @author adrianromero + */ +public class JPaymentSelectReceipt extends JPaymentSelect { + + /** Creates new form JPaymentSelect + * @param parent + * @param modal + * @param o */ + protected JPaymentSelectReceipt(java.awt.Frame parent, boolean modal, ComponentOrientation o) { + super(parent, modal, o); + } + /** Creates new form JPaymentSelect + * @param parent + * @param o + * @param modal */ + protected JPaymentSelectReceipt(java.awt.Dialog parent, boolean modal, ComponentOrientation o) { + super(parent, modal, o); + } + + /** + * + * @param parent + * @return + */ + public static JPaymentSelect getDialog(Component parent) { + + Window window = getWindow(parent); + + if (window instanceof Frame) { + return new JPaymentSelectReceipt((Frame) window, true, parent.getComponentOrientation()); + } else { + return new JPaymentSelectReceipt((Dialog) window, true, parent.getComponentOrientation()); + } + } + + /** + * + */ + @Override + protected void addTabs() { + + addTabPayment(new JPaymentSelect.JPaymentCashCreator()); + addTabPayment(new JPaymentSelect.JPaymentChequeCreator()); + addTabPayment(new JPaymentSelect.JPaymentVoucherCreator()); + addTabPayment(new JPaymentSelect.JPaymentMagcardCreator()); + addTabPayment(new JPaymentSelect.JPaymentFreeCreator()); + addTabPayment(new JPaymentSelect.JPaymentDebtCreator()); +// JG Added 1 Dec 13 + addTabPayment(new JPaymentSelect.JPaymentBankCreator()); + addTabPayment(new JPaymentSelect.JPaymentSlipCreator()); + } + + /** + * + * @param isPositive + * @param isComplete + */ + @Override + protected void setStatusPanel(boolean isPositive, boolean isComplete) { + + setAddEnabled(isPositive && !isComplete); + setOKEnabled(isComplete); + } + + /** + * + * @param total + * @return + */ + @Override + protected PaymentInfo getDefaultPayment(double total) { +// return new PaymentInfoCash_original(total, total); + return new PaymentInfoCash(total, total); + } +} diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentSelectRefund.java b/src/main/java/com/unicenta/pos/payment/JPaymentSelectRefund.java new file mode 100644 index 0000000..dc9e367 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentSelectRefund.java @@ -0,0 +1,95 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import java.awt.*; + +/** + * + * @author adrianromero + */ +public class JPaymentSelectRefund extends JPaymentSelect { + + /** Creates new form JPaymentSelect + * @param parent + * @param modal + * @param o */ + protected JPaymentSelectRefund(java.awt.Frame parent, boolean modal, ComponentOrientation o) { + super(parent, modal, o); + } + /** Creates new form JPaymentSelect + * @param parent + * @param modal + * @param o */ + protected JPaymentSelectRefund(java.awt.Dialog parent, boolean modal, ComponentOrientation o) { + super(parent, modal, o); + } + + /** + * + * @param parent + * @return + */ + public static JPaymentSelect getDialog(Component parent) { + + Window window = getWindow(parent); + + if (window instanceof Frame) { + return new JPaymentSelectRefund((Frame) window, true, parent.getComponentOrientation()); + } else { + return new JPaymentSelectRefund((Dialog) window, true, parent.getComponentOrientation()); + } + } + + /** + * + */ + @Override + protected void addTabs() { + + addTabPayment(new JPaymentSelect.JPaymentCashRefundCreator()); + addTabPayment(new JPaymentSelect.JPaymentChequeRefundCreator()); + addTabPayment(new JPaymentSelect.JPaymentVoucherRefundCreator()); + addTabPayment(new JPaymentSelect.JPaymentMagcardRefundCreator()); +// setHeaderVisible(false); + } + + /** + * + * @param isPositive + * @param isComplete + */ + @Override + protected void setStatusPanel(boolean isPositive, boolean isComplete) { + + setAddEnabled(isPositive && !isComplete); + setOKEnabled(isComplete); + } + + /** + * + * @param total + * @return + */ + @Override + protected PaymentInfo getDefaultPayment(double total) { + return new PaymentInfoTicket(total, "cashrefund"); + } +} diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentSlip.form b/src/main/java/com/unicenta/pos/payment/JPaymentSlip.form new file mode 100644 index 0000000..14ad2fd --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentSlip.form @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,49,0,0,2,99"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="1"/> + </Layout> + <SubComponents> + <Component class="com.unicenta.editor.JEditorKeys" name="m_jKeys"> + </Component> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Component class="com.unicenta.editor.JEditorCurrencyPositive" name="m_jTendered"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout"> + <Property name="useNullLayout" type="boolean" value="true"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="1"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.InputCash" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="10" y="4" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="m_jMoneyEuros"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="33" green="ff" red="cc" type="rgb"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="1"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[180, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="120" y="4" width="-1" height="-1"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentSlip.java b/src/main/java/com/unicenta/pos/payment/JPaymentSlip.java new file mode 100644 index 0000000..ddf9c07 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentSlip.java @@ -0,0 +1,180 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; +import com.unicenta.format.Formats; +import com.unicenta.pos.customers.CustomerInfoExt; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.util.RoundUtils; +import java.awt.Component; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +/** + * + * @author JG uniCenta + */ +public class JPaymentSlip extends javax.swing.JPanel implements JPaymentInterface { + + private final JPaymentNotifier m_notifier; + + private double m_dPaid; + private double m_dTotal; + + /** Creates new form JPaymentCash + * @param notifier */ + public JPaymentSlip(JPaymentNotifier notifier) { + + m_notifier = notifier; + + initComponents(); + + m_jTendered.addPropertyChangeListener("Edition", new RecalculateState()); + m_jTendered.addEditorKeys(m_jKeys); + + } + + /** + * + * @param customerext + * @param dTotal + * @param transID + */ + @Override + public void activate(CustomerInfoExt customerext, double dTotal, String transID) { + + m_dTotal = dTotal; + m_jTendered.reset(); + m_jTendered.activate(); + + printState(); + + } + + /** + * + * @return + */ + @Override + public PaymentInfo executePayment() { + return new PaymentInfoTicket(m_dPaid, "slip"); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + private void printState() { + + Double value = m_jTendered.getDoubleValue(); + if (value == null) { + m_dPaid = m_dTotal; + } else { + m_dPaid = value; + } + + m_jMoneyEuros.setText(Formats.CURRENCY.formatValue(m_dPaid)); + + int iCompare = RoundUtils.compare(m_dPaid, m_dTotal); + + m_notifier.setStatus(m_dPaid > 0.0 && iCompare <= 0, iCompare == 0); + } + + private class RecalculateState implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + printState(); + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel2 = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel3 = new javax.swing.JPanel(); + m_jTendered = new com.unicenta.editor.JEditorCurrencyPositive(); + jPanel4 = new javax.swing.JPanel(); + jLabel8 = new javax.swing.JLabel(); + m_jMoneyEuros = new javax.swing.JLabel(); + + setLayout(new java.awt.BorderLayout()); + + jPanel2.setLayout(new java.awt.BorderLayout()); + + jPanel1.setLayout(new javax.swing.BoxLayout(jPanel1, javax.swing.BoxLayout.Y_AXIS)); + jPanel1.add(m_jKeys); + + jPanel3.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel3.setLayout(new java.awt.BorderLayout()); + + m_jTendered.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N + jPanel3.add(m_jTendered, java.awt.BorderLayout.CENTER); + + jPanel1.add(jPanel3); + + jPanel2.add(jPanel1, java.awt.BorderLayout.NORTH); + + add(jPanel2, java.awt.BorderLayout.EAST); + + jPanel4.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel4.setLayout(null); + + jLabel8.setFont(new java.awt.Font("Arial", 1, 18)); // NOI18N + jLabel8.setText(AppLocal.getIntString("label.InputCash")); // NOI18N + jLabel8.setPreferredSize(new java.awt.Dimension(100, 30)); + jPanel4.add(jLabel8); + jLabel8.setBounds(10, 4, 100, 30); + + m_jMoneyEuros.setBackground(new java.awt.Color(204, 255, 51)); + m_jMoneyEuros.setFont(new java.awt.Font("Arial", 1, 18)); // NOI18N + m_jMoneyEuros.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jMoneyEuros.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jMoneyEuros.setOpaque(true); + m_jMoneyEuros.setPreferredSize(new java.awt.Dimension(180, 30)); + jPanel4.add(m_jMoneyEuros); + m_jMoneyEuros.setBounds(120, 4, 180, 30); + + add(jPanel4, java.awt.BorderLayout.CENTER); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel8; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private com.unicenta.editor.JEditorKeys m_jKeys; + private javax.swing.JLabel m_jMoneyEuros; + private com.unicenta.editor.JEditorCurrencyPositive m_jTendered; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentVoucher.form b/src/main/java/com/unicenta/pos/payment/JPaymentVoucher.form new file mode 100644 index 0000000..5188710 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentVoucher.form @@ -0,0 +1,292 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-101,0,0,2,88"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="10" pref="10" max="-2" attributes="0"/> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jMoneyEuros" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel5" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jVoucher" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jButton1" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="webLblCustomer" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="webLblcustomerName" max="32767" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jLabel6" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="voucherStatus" max="32767" attributes="0"/> + </Group> + </Group> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jVoucher" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" attributes="0"> + <Component id="jLabel6" min="-2" max="-2" attributes="0"/> + <Component id="voucherStatus" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <Component id="m_jMoneyEuros" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="webLblCustomer" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="webLblcustomerName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" pref="33" max="-2" attributes="0"/> + <Component id="jButton1" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="1"/> + </Property> + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor"> + <ComponentRef name="m_jVoucher"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.voucher" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jVoucher"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[180, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jVoucherActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="1"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.voucherValue" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jMoneyEuros"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="33" green="ff" red="cc" type="rgb"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="1"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[180, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.label.WebLabel" name="webLblCustomer"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.customer" replaceFormat="AppLocal.getIntString("label.customer")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value=""/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="1"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.label.WebLabel" name="webLblcustomerName"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.customer" replaceFormat="AppLocal.getIntString("label.customer")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value=""/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.label.WebLabel" name="voucherStatus"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.voucherStatus" replaceFormat="AppLocal.getIntString("label.voucherStatus")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value=""/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="1"/> + </Property> + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor"> + <ComponentRef name="m_jVoucher"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.voucherStatus" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jButton1"> + <Properties> + <Property name="text" type="java.lang.String" value="jButton1"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton1ActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel11"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel12"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="1"/> + </Layout> + <SubComponents> + <Component class="com.unicenta.editor.JEditorKeys" name="m_jKeys"> + </Component> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Component class="com.unicenta.editor.JEditorCurrencyPositive" name="m_jTendered"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[130, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/payment/JPaymentVoucher.java b/src/main/java/com/unicenta/pos/payment/JPaymentVoucher.java new file mode 100644 index 0000000..ff1895e --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/JPaymentVoucher.java @@ -0,0 +1,391 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta and part works Openbravo, S.L. +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.format.Formats; +import com.unicenta.pos.customers.CustomerInfoExt; +import com.unicenta.pos.customers.DataLogicCustomers; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.util.RoundUtils; +import com.unicenta.pos.voucher.VoucherInfo; +import lombok.extern.slf4j.Slf4j; + +import java.awt.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.List; + +/** + * @author JG uniCenta + */ +@Slf4j +public class JPaymentVoucher extends javax.swing.JPanel implements JPaymentInterface { + + private final JPaymentNotifier m_notifier; + + private DataLogicSales dlSales; + private DataLogicCustomers dlCustomers; + private ComboBoxValModel m_VoucherModel; + private SentenceList m_sentvouch; + private VoucherInfo m_voucherInfo; + + private double m_dTicket; + private double m_dTotal; + + private final String m_sVoucher; // "voucherin", "voucherout" + private String m_sVoucher1; + + /** + * Creates new form JPaymentTicket + * + * @param app + * @param notifier + * @param sVoucher + */ + public JPaymentVoucher(AppView app, JPaymentNotifier notifier, String sVoucher) { + + m_notifier = notifier; + m_sVoucher = sVoucher; + m_dTotal = 0.0; + + init(app); + + m_jTendered.addPropertyChangeListener("Edition", new RecalculateState()); + + } + + private void init(AppView app) { + + dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + dlCustomers = (DataLogicCustomers) app.getBean("com.unicenta.pos.customers.DataLogicCustomers"); + initComponents(); + + webLblcustomerName.setText(null); + } + + /** + * @param customerext + * @param dTotal + * @param transID + */ + @Override + public void activate(CustomerInfoExt customerext, double dTotal, String transID) { + + m_dTotal = dTotal; + + m_jTendered.reset(); + + m_jKeys.setEnabled(false); + m_jTendered.setEnabled(false); + m_VoucherModel = new ComboBoxValModel(); + m_sentvouch = dlSales.getVoucherList(); + List a = null; + try { + a = m_sentvouch.list(); + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + m_VoucherModel = new ComboBoxValModel(a); + m_jVoucher.setModel(m_VoucherModel); + + printState(); + } + + /** + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * @return + */ + @Override + public PaymentInfo executePayment() { + + try { + String id = m_VoucherModel.getSelectedKey().toString(); + VoucherInfo m_voucherInfo1 = dlCustomers.getVoucherInfo(id); + m_sVoucher1 = m_voucherInfo1.getVoucherNumber(); + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + return new PaymentInfoTicket(m_dTicket, m_sVoucher, m_sVoucher1); + + } + + public void confirmVoucher() { + List a = null; + try { + a = m_sentvouch.list(); + +// a.forEach(System.out::println); + a.remove(m_jVoucher.getSelectedIndex()); + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + + m_VoucherModel = new ComboBoxValModel(a); + m_jVoucher.setModel(m_VoucherModel); + } + + private void printState() { + + Double value = m_jTendered.getDoubleValue(); + if (value == null) { + m_dTicket = 0.0; + } else { + m_dTicket = value; + } + + m_jMoneyEuros.setText(Formats.CURRENCY.formatValue(m_dTicket)); + + int iCompare = RoundUtils.compare(m_dTicket, m_dTotal); + + m_notifier.setStatus(m_dTicket > 0.0, iCompare >= 0); + + } + + private class RecalculateState implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + printState(); + } + } + + /** + * This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel4 = new javax.swing.JPanel(); + jLabel5 = new javax.swing.JLabel(); + m_jVoucher = new javax.swing.JComboBox(); + jLabel1 = new javax.swing.JLabel(); + m_jMoneyEuros = new javax.swing.JLabel(); + webLblCustomer = new com.alee.laf.label.WebLabel(); + webLblcustomerName = new com.alee.laf.label.WebLabel(); + voucherStatus = new com.alee.laf.label.WebLabel(); + jLabel6 = new javax.swing.JLabel(); + jButton1 = new javax.swing.JButton(); + jPanel11 = new javax.swing.JPanel(); + jPanel12 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel1 = new javax.swing.JPanel(); + m_jTendered = new com.unicenta.editor.JEditorCurrencyPositive(); + + setLayout(new java.awt.BorderLayout()); + + jLabel5.setFont(new java.awt.Font("Arial", 1, 18)); // NOI18N + jLabel5.setLabelFor(m_jVoucher); + jLabel5.setText(AppLocal.getIntString("label.voucher")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jVoucher.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jVoucher.setPreferredSize(new java.awt.Dimension(180, 30)); + m_jVoucher.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jVoucherActionPerformed(evt); + } + }); + + jLabel1.setFont(new java.awt.Font("Arial", 1, 18)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.voucherValue")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jMoneyEuros.setBackground(new java.awt.Color(204, 255, 51)); + m_jMoneyEuros.setFont(new java.awt.Font("Arial", 1, 18)); // NOI18N + m_jMoneyEuros.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jMoneyEuros.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jMoneyEuros.setOpaque(true); + m_jMoneyEuros.setPreferredSize(new java.awt.Dimension(180, 30)); + + webLblCustomer.setText(AppLocal.getIntString("label.customer")); // NOI18N + webLblCustomer.setToolTipText(""); + webLblCustomer.setFont(new java.awt.Font("Arial", 1, 18)); // NOI18N + webLblCustomer.setPreferredSize(new java.awt.Dimension(100, 30)); + + webLblcustomerName.setText(AppLocal.getIntString("label.customer")); // NOI18N + webLblcustomerName.setToolTipText(""); + webLblcustomerName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + webLblcustomerName.setPreferredSize(new java.awt.Dimension(100, 30)); + + voucherStatus.setText(AppLocal.getIntString("label.voucherStatus")); // NOI18N + voucherStatus.setToolTipText(""); + voucherStatus.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + voucherStatus.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel6.setFont(new java.awt.Font("Arial", 1, 18)); // NOI18N + jLabel6.setLabelFor(m_jVoucher); + jLabel6.setText(AppLocal.getIntString("label.voucherStatus")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(100, 30)); + + jButton1.setText("jButton1"); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); + jPanel4.setLayout(jPanel4Layout); + jPanel4Layout.setHorizontalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addGap(10, 10, 10) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jMoneyEuros, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jVoucher, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jButton1))) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addComponent(webLblCustomer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(webLblcustomerName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(jPanel4Layout.createSequentialGroup() + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(voucherStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + ); + jPanel4Layout.setVerticalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jVoucher, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(voucherStatus, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jMoneyEuros, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(webLblCustomer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(webLblcustomerName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(33, 33, 33) + .addComponent(jButton1) + .addContainerGap()) + ); + + add(jPanel4, java.awt.BorderLayout.CENTER); + + jPanel11.setLayout(new java.awt.BorderLayout()); + + jPanel12.setLayout(new javax.swing.BoxLayout(jPanel12, javax.swing.BoxLayout.Y_AXIS)); + jPanel12.add(m_jKeys); + + jPanel1.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel1.setLayout(new java.awt.BorderLayout()); + + m_jTendered.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jTendered.setPreferredSize(new java.awt.Dimension(130, 30)); + jPanel1.add(m_jTendered, java.awt.BorderLayout.CENTER); + + jPanel12.add(jPanel1); + + jPanel11.add(jPanel12, java.awt.BorderLayout.NORTH); + + add(jPanel11, java.awt.BorderLayout.EAST); + }// </editor-fold>//GEN-END:initComponents + + private void m_jVoucherActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jVoucherActionPerformed + + m_jMoneyEuros.setText(null); + + if (m_VoucherModel.getSelectedKey() != null) { + try { + String id = m_VoucherModel.getSelectedKey().toString(); + VoucherInfo m_voucherInfo = dlCustomers.getVoucherInfo(id); + + if (m_voucherInfo != null) { + m_jTendered.setDoubleValue(m_voucherInfo.getAmount()); + m_jMoneyEuros.setText(Formats.CURRENCY.formatValue(m_voucherInfo.getAmount())); + webLblcustomerName.setText(m_voucherInfo.getCustomerName()); + + if ("A".equals(m_voucherInfo.getStatus())) { + voucherStatus.setText("Available"); + } else if ("D".equals(m_voucherInfo.getStatus())) { + voucherStatus.setText("Redeemed"); + } + + printState(); + + } else { + voucherStatus.setText("Error"); + webLblcustomerName.setText(""); + } + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + + } + }//GEN-LAST:event_m_jVoucherActionPerformed + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + + }//GEN-LAST:event_jButton1ActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel11; + private javax.swing.JPanel jPanel12; + private javax.swing.JPanel jPanel4; + private com.unicenta.editor.JEditorKeys m_jKeys; + private javax.swing.JLabel m_jMoneyEuros; + private com.unicenta.editor.JEditorCurrencyPositive m_jTendered; + private javax.swing.JComboBox m_jVoucher; + private com.alee.laf.label.WebLabel voucherStatus; + private com.alee.laf.label.WebLabel webLblCustomer; + private com.alee.laf.label.WebLabel webLblcustomerName; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/payment/MagCardReader.java b/src/main/java/com/unicenta/pos/payment/MagCardReader.java new file mode 100644 index 0000000..61fe648 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/MagCardReader.java @@ -0,0 +1,40 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +public interface MagCardReader { + + public String getReaderName(); + + public void reset(); + public void appendChar(char c); + public boolean isComplete(); + + public String getHolderName(); + public String getCardNumber(); + public String getExpirationDate(); + + public String getTrack1(); + public String getTrack2(); + public String getTrack3(); + + public String getEncryptedCardData(); + public String getEncryptionKey(); +} diff --git a/src/main/java/com/unicenta/pos/payment/MagCardReaderFac.java b/src/main/java/com/unicenta/pos/payment/MagCardReaderFac.java new file mode 100644 index 0000000..de83896 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/MagCardReaderFac.java @@ -0,0 +1,43 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +/** + * + * @author adrianromero + */ +public class MagCardReaderFac { + + /** Creates a new instance of MagCarReaderFac */ + private MagCardReaderFac() { + } + + public static MagCardReader getMagCardReader(String sReader) { +// JG 16 May 12 use switch + switch (sReader) { + case "Intelligent": + return new MagCardReaderIntelligent(); + case "Generic": + return new MagCardReaderGeneric(); + default: + return null; + } + } +} diff --git a/src/main/java/com/unicenta/pos/payment/MagCardReaderGeneric.java b/src/main/java/com/unicenta/pos/payment/MagCardReaderGeneric.java new file mode 100644 index 0000000..20488eb --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/MagCardReaderGeneric.java @@ -0,0 +1,242 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.pos.util.LuhnAlgorithm; +import com.unicenta.pos.util.StringUtils; +import java.util.ArrayList; +import java.util.List; + +public class MagCardReaderGeneric implements MagCardReader { + + private String m_sHolderName; + private String m_sCardNumber; + private String m_sExpirationDate; + private StringBuffer track1; + private StringBuffer track2; + private StringBuffer track3; + private static final int READING_STARTSENTINEL1 = 0; + private static final int READING_STARTSENTINEL2 = 1; + private static final int READING_STARTSENTINEL3 = 2; + private static final int READING_CARDTYPE = 3; + private static final int READING_TRACK1 = 4; + private static final int READING_TRACK2 = 5; + private static final int READING_TRACK3 = 6; + private static final int READING_END = 7; + private int m_iAutomState; + private List m_aTrack1; + private List m_aTrack2; + private List m_aTrack3; + private StringBuffer m_sField; + private char m_cCardType; + + private String m_encryptedCardData; + private String m_encryptionKey; + + /** + * Creates a new instance of GenericMagCardReader + */ + public MagCardReaderGeneric() { + reset(); + } + + public String getReaderName() { + return "Generic magnetic card reader"; + } + + public void reset() { + m_aTrack1 = null; + m_aTrack2 = null; + m_aTrack3 = null; + m_sField = null; + m_cCardType = ' '; + + m_sHolderName = null; + m_sCardNumber = null; + m_sExpirationDate = null; + + + m_encryptedCardData = null; + m_encryptionKey = null; + + + m_iAutomState = READING_STARTSENTINEL1; + } + + public void appendChar(char c) { + // Mastercard + // %B1111222233334444^PUBLIC/JOHN?;1111222233334444=99121010000000000000? + // *---------------- ----------- ----*** + // Visa + // %B1111222233334444^PUBLIC/JOHN^9912101xxxxxxxxxxxxx?;1111222233334444=9912101xxxxxxxxxxxxx? + // *---------------- ----------- ---- *** + + if (c == '%') { // && READING_STARTSENTINEL1; + track1 = new StringBuffer(); + track2 = new StringBuffer(); + track3 = new StringBuffer(); + m_aTrack1 = new ArrayList(); + m_aTrack2 = null; + m_aTrack3 = null; + m_sField = new StringBuffer(); + m_cCardType = ' '; + m_sHolderName = null; + m_sCardNumber = null; + m_sExpirationDate = null; + m_iAutomState = READING_CARDTYPE; + } else if (m_iAutomState == READING_CARDTYPE) { + m_cCardType = c; + m_iAutomState = READING_TRACK1; + } else if (c == ';' && m_iAutomState == READING_STARTSENTINEL2) { + m_aTrack2 = new ArrayList(); + m_sField = new StringBuffer(); + m_iAutomState = READING_TRACK2; + } else if (c == ';' && m_iAutomState == READING_STARTSENTINEL3) { + m_aTrack3 = new ArrayList(); + m_sField = new StringBuffer(); + m_iAutomState = READING_TRACK3; + + } else if (c == '^' && m_iAutomState == READING_TRACK1) { + m_aTrack1.add(m_sField.toString()); + m_sField = new StringBuffer(); + } else if (c == '=' && m_iAutomState == READING_TRACK2) { + m_aTrack2.add(m_sField.toString()); + m_sField = new StringBuffer(); + } else if (c == '=' && m_iAutomState == READING_TRACK3) { + m_aTrack3.add(m_sField.toString()); + m_sField = new StringBuffer(); + + } else if (c == '?' && m_iAutomState == READING_TRACK1) { + m_aTrack1.add(m_sField.toString()); + m_sField = null; + m_iAutomState = READING_STARTSENTINEL2; + } else if (c == '?' && m_iAutomState == READING_TRACK2) { + m_aTrack2.add(m_sField.toString()); + m_sField = null; + m_iAutomState = READING_STARTSENTINEL3; + checkTracks(); // aqui ya chequeamos los paramentros que leemos... + } else if (c == '?' && m_iAutomState == READING_TRACK3) { + m_aTrack3.add(m_sField.toString()); + m_sField = null; + m_iAutomState = READING_END; + + } else if (m_iAutomState == READING_TRACK1 || m_iAutomState == READING_TRACK2 || m_iAutomState == READING_TRACK3) { + m_sField.append(c); + } + + + if (m_iAutomState == READING_CARDTYPE || m_iAutomState == READING_TRACK1 || m_iAutomState == READING_STARTSENTINEL2) { + track1.append(c); + } else if (m_iAutomState == READING_TRACK2 || m_iAutomState == READING_STARTSENTINEL3) { + track2.append(c); + } else if (m_iAutomState == READING_TRACK3 || m_iAutomState == READING_END) { + track3.append(c); + } + } + + private void checkTracks() { + + // Test del tipo de tarjeta + if (m_cCardType != 'B') { + return; + } + + // Lectura de los valores + String sCardNumber1 = (m_aTrack1 == null || m_aTrack1.size() < 1) ? null : (String) m_aTrack1.get(0); + String sCardNumber2 = (m_aTrack2 == null || m_aTrack2.size() < 1) ? null : (String) m_aTrack2.get(0); + String sHolderName = (m_aTrack1 == null || m_aTrack1.size() < 2) ? null : (String) m_aTrack1.get(1); + String sExpDate1 = (m_aTrack1 == null || m_aTrack1.size() < 3) ? null : ((String) m_aTrack1.get(2)).substring(0, 4); + String sExpDate2 = (m_aTrack2 == null || m_aTrack2.size() < 2) ? null : ((String) m_aTrack2.get(1)).substring(0, 4); + + // Test del numero de tarjeta + if (!checkCardNumber(sCardNumber1) || (sCardNumber2 != null && !sCardNumber1.equals(sCardNumber2))) { + return; + } + // Test del nombre del propietario + if (sHolderName == null) { + return; + } + // Test de la fecha de expiracion + if ((sExpDate1 != null || !checkExpDate(sExpDate2)) && (!checkExpDate(sExpDate1) || !sExpDate1.equals(sExpDate2))) { + return; + } + + m_sCardNumber = sCardNumber1; + m_sHolderName = formatHolderName(sHolderName); + String yymm = sExpDate1 == null ? sExpDate2 : sExpDate1; + m_sExpirationDate = yymm.substring(2, 4) + yymm.substring(0, 2); //MMYY format + } + + private boolean checkCardNumber(String sNumber) { + return LuhnAlgorithm.checkCC(sNumber); + } + + private boolean checkExpDate(String sDate) { + return ( sDate.length()==4 && StringUtils.isNumber(sDate.trim()) ); + } + + private String formatHolderName(String sName) { + + int iPos = sName.indexOf('/'); + if (iPos >= 0) { + return sName.substring(iPos + 1).trim() + ' ' + sName.substring(0, iPos); + } else { + return sName.trim(); + } + } + + public boolean isComplete() { + return m_sCardNumber != null; + } + + public String getHolderName() { + return m_sHolderName; + } + + public String getCardNumber() { + return m_sCardNumber; + } + + public String getExpirationDate() { + return m_sExpirationDate; + } + + public String getTrack1() { + return track1 == null ? null : track1.toString(); + } + + public String getTrack2() { + return track2 == null ? null : track2.toString(); + } + + public String getTrack3() { + return track3 == null ? null : track3.toString(); + } + + + public String getEncryptedCardData() { + return "".equals(m_encryptedCardData) ? null : m_encryptedCardData; + +} + + public String getEncryptionKey() { + return "".equals(m_encryptionKey) ? null : m_encryptionKey; + } +} diff --git a/src/main/java/com/unicenta/pos/payment/MagCardReaderIntelligent.java b/src/main/java/com/unicenta/pos/payment/MagCardReaderIntelligent.java new file mode 100644 index 0000000..6505f4d --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/MagCardReaderIntelligent.java @@ -0,0 +1,137 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +public final class MagCardReaderIntelligent implements MagCardReader { + + private String m_sHolderName; + private String m_sCardNumber; + private String m_sExpirationDate; + + private StringBuffer m_sField; + + private static final int READING_HOLDER = 0; + private static final int READING_NUMBER = 1; + private static final int READING_DATE = 2; + private static final int READING_FINISHED = 3; + private int m_iAutomState; + + /** Creates a new instance of BasicMagCardReader */ + public MagCardReaderIntelligent() { + reset(); + } + + public String getReaderName() { + return "Basic magnetic card reader"; + } + + public void reset() { + m_sHolderName = null; + m_sCardNumber = null; + m_sExpirationDate = null; + m_sField = new StringBuffer(); + m_iAutomState = READING_HOLDER; + } + + public void appendChar(char c) { + + switch (m_iAutomState) { + case READING_HOLDER: + case READING_FINISHED: + if (c == 0x0009) { + m_sHolderName = m_sField.toString(); + m_sField = new StringBuffer(); + m_iAutomState = READING_NUMBER; + } else if (c == 0x000A) { + m_sHolderName = null; + m_sCardNumber = null; + m_sExpirationDate = null; + m_sField = new StringBuffer(); + m_iAutomState = READING_HOLDER; + } else { + m_sField.append(c); + m_iAutomState = READING_HOLDER; + } + break; + case READING_NUMBER: + if (c == 0x0009) { + m_sCardNumber = m_sField.toString(); + m_sField = new StringBuffer(); + m_iAutomState = READING_DATE; + } else if (c == 0x000A) { + m_sHolderName = null; + m_sCardNumber = null; + m_sExpirationDate = null; + m_sField = new StringBuffer(); + m_iAutomState = READING_HOLDER; + } else { + m_sField.append(c); + } + break; + case READING_DATE: + if (c == 0x0009) { + m_sHolderName = m_sCardNumber; + m_sCardNumber = m_sExpirationDate; + m_sExpirationDate = null; + m_sField = new StringBuffer(); + } else if (c == 0x000A) { + m_sExpirationDate = m_sField.toString(); + m_sField = new StringBuffer(); + m_iAutomState = READING_FINISHED; + } else { + m_sField.append(c); + } + break; + } + } + + public boolean isComplete() { + return m_iAutomState == READING_FINISHED; + } + + public String getHolderName() { + return m_sHolderName; + } + public String getCardNumber() { + return m_sCardNumber; + } + public String getExpirationDate() { + return m_sExpirationDate; + } + public String getTrack1() { + return null; + } + public String getTrack2() { + return null; + } + public String getTrack3() { + return null; + } + + @Override + public String getEncryptedCardData() { + return null; + } + + @Override + public String getEncryptionKey() { + return null; + } +} diff --git a/src/main/java/com/unicenta/pos/payment/PaymentConfiguration.java b/src/main/java/com/unicenta/pos/payment/PaymentConfiguration.java new file mode 100644 index 0000000..e3a11bc --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentConfiguration.java @@ -0,0 +1,49 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.pos.forms.AppConfig; +import javax.swing.JPanel; + +/** + * + * @author Mikel Irurita + */ +public interface PaymentConfiguration { + + /** + * + * @return + */ + public JPanel getComponent(); + + /** + * + * @param config + */ + public void loadProperties(AppConfig config); + + /** + * + * @param config + */ + public void saveProperties(AppConfig config); + +} diff --git a/src/main/java/com/unicenta/pos/payment/PaymentException.java b/src/main/java/com/unicenta/pos/payment/PaymentException.java new file mode 100644 index 0000000..ad3725e --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentException.java @@ -0,0 +1,42 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +/** + * + * @author JG uniCenta + */ +public class PaymentException extends java.lang.Exception { + + /** + * Creates a new instance of <code>PaymentException</code> without detail message. + */ + public PaymentException() { + } + + + /** + * Constructs an instance of <code>PaymentException</code> with the specified detail message. + * @param msg the detail message. + */ + public PaymentException(String msg) { + super(msg); + } +} diff --git a/src/main/java/com/unicenta/pos/payment/PaymentGateway.java b/src/main/java/com/unicenta/pos/payment/PaymentGateway.java new file mode 100644 index 0000000..a1b38e2 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentGateway.java @@ -0,0 +1,33 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +/** + * + * @author JG uniCenta + */ +public interface PaymentGateway { + + /** + * + * @param payinfo + */ + public void execute(PaymentInfoMagcard payinfo); +} diff --git a/src/main/java/com/unicenta/pos/payment/PaymentGatewayExt.java b/src/main/java/com/unicenta/pos/payment/PaymentGatewayExt.java new file mode 100644 index 0000000..c5cf565 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentGatewayExt.java @@ -0,0 +1,40 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +/** + * + * @author JG uniCenta + */ +public class PaymentGatewayExt implements PaymentGateway { + + /** Creates a new instance of PaymentGatewayExt */ + public PaymentGatewayExt() { + } + + /** + * + * @param payinfo + */ + @Override + public void execute(PaymentInfoMagcard payinfo) { + payinfo.paymentOK("OK", payinfo.getTransactionID() , ""); + } +} diff --git a/src/main/java/com/unicenta/pos/payment/PaymentGatewayFac.java b/src/main/java/com/unicenta/pos/payment/PaymentGatewayFac.java new file mode 100644 index 0000000..0ef0c94 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentGatewayFac.java @@ -0,0 +1,46 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.pos.forms.AppProperties; + + +/** + * Creates a new instance of PaymentGatewayFac + */ +public class PaymentGatewayFac { + + /** Creates a new instance of PaymentGatewayFac */ + private PaymentGatewayFac() { + } + + public static PaymentGateway getPaymentGateway(AppProperties props) { + + String sReader = props.getProperty("payment.gateway"); + switch (sReader) { + case "external": + return new PaymentGatewayExt(); + case "PaymentSense": + return new PaymentGatewayPaymentSense(); + default: + return null; + } + } +} diff --git a/src/main/java/com/unicenta/pos/payment/PaymentGatewayPaymentSense.java b/src/main/java/com/unicenta/pos/payment/PaymentGatewayPaymentSense.java new file mode 100644 index 0000000..055a4bd --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentGatewayPaymentSense.java @@ -0,0 +1,86 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.plugins.Application; +import com.unicenta.plugins.common.AppContext; +import com.unicenta.pos.util.RoundUtils; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.*; +import java.awt.*; + +@Slf4j +public class PaymentGatewayPaymentSense implements PaymentGateway { + + /** Creates a new instance of PaymentGatewayExt */ + public PaymentGatewayPaymentSense() { + } + + Window getPaymentWindow() { + for (Window window : Window.getWindows()) { + if (window.isActive()) { + return window; + } + } + return null; + } + + /** + * + * @param payinfo + */ + @Override + public void execute(PaymentInfoMagcard payinfo) { + + int timer = 0; + int timeout = 180; + + new Application().paymentSenseTransaction(RoundUtils.round(payinfo.getTotal()), getPaymentWindow()); + + while (AppContext.getIsProcessing() == null || AppContext.getIsProcessing()) { + try { + log.info("uniCenta-oPos: waiting for payment to complete ...."); + Thread.sleep(1000); + timer += 1; + if (timer > timeout) break; + } catch (InterruptedException e) { + log.error(e.getMessage()); + } + } + + if (AppContext.getPaymentResult() == null) { + payinfo.paymentError("Transaction Error! Please try again", "No Response"); + } + if (AppContext.getPaymentResult().getTransactionResult().equals("SUCCESSFUL")){ + payinfo.setCardName(AppContext.getPaymentResult().getCardSchemeName()); + payinfo.setVerification(AppContext.getPaymentResult().getPaymentMethod()); + payinfo.setChipAndPin(true); + payinfo.paymentOK( + AppContext.getPaymentResult().getAuthCode(), + AppContext.getPaymentResult().getTransactionId(), + AppContext.getPaymentResult().getTransactionResult() + ); + } + else { + payinfo.paymentError("Transaction Error! Please try again", AppContext.getPaymentResult().getTransactionResult()); + } + } +} diff --git a/src/main/java/com/unicenta/pos/payment/PaymentInfo.java b/src/main/java/com/unicenta/pos/payment/PaymentInfo.java new file mode 100644 index 0000000..a5594a5 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentInfo.java @@ -0,0 +1,39 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.format.Formats; + +public abstract class PaymentInfo { + + public abstract String getName(); + public abstract double getTotal(); + public abstract PaymentInfo copyPayment(); + public abstract String getTransactionID(); + public abstract double getPaid(); + public abstract double getChange(); + public abstract double getTendered(); + public abstract String getCardName(); + public abstract String getVoucher(); + + public String printTotal() { + return Formats.CURRENCY.formatValue(getTotal()); + } +} diff --git a/src/main/java/com/unicenta/pos/payment/PaymentInfoCash.java b/src/main/java/com/unicenta/pos/payment/PaymentInfoCash.java new file mode 100644 index 0000000..88e67f1 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentInfoCash.java @@ -0,0 +1,133 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.format.Formats; + +public class PaymentInfoCash extends PaymentInfo { + + private double prePayAmount = 0.0; + private double m_dPaid; + private double m_dTotal; + private double m_dTendered; + private String m_dCardName =null; +// private double m_dTip; + + /** + * Creates a new instance of PaymentInfoCash + * @param dTotal + * @param dPaid + * @param dTendered + */ + public PaymentInfoCash(double dTotal, double dPaid, double dTendered) { + m_dTotal = dTotal; + m_dPaid = dPaid; + m_dTendered = dTendered; + } + + /** + * Creates a new instance of PaymentInfoCash + * @param dTotal + * @param dPaid + * @param dTendered + * @param prePayAmount + */ + public PaymentInfoCash(double dTotal, double dPaid, double dTendered, double prePayAmount) { + this(dTotal, dTendered, dPaid); + this.prePayAmount = prePayAmount; + } + + /** Creates a new instance of PaymentInfoCash + * @param dTotal + * @param dPaid */ + public PaymentInfoCash(double dTotal, double dPaid) { + m_dTotal = dTotal; + m_dPaid = dPaid; + } + + @Override + public PaymentInfo copyPayment() { + return new PaymentInfoCash(m_dTotal, m_dPaid, m_dTendered, prePayAmount); +// return new PaymentInfoCash(m_dTotal, m_dPaid, prePayAmount); + } + + @Override + public String getTransactionID() { + return "no ID"; + } + + @Override + public String getName() { + return "cash"; + } + @Override + public double getTotal() { + return m_dTotal; + } +// public double getTip() { +// return m_dTip; +// } + @Override + public double getPaid() { + return m_dPaid; + } + + @Override + public double getTendered() { + return m_dTendered; + } + + @Override + public double getChange(){ + return m_dPaid - m_dTotal; + } + + @Override + public String getCardName() { + return m_dCardName; + } + + public boolean hasPrePay() { + if (prePayAmount > 0) { + return true; + } + return false; + } + + public double getPrePaid() { + return prePayAmount; + } + + public String printTendered() { + return Formats.CURRENCY.formatValue(m_dTendered); + } + public String printPaid() { + return Formats.CURRENCY.formatValue(m_dPaid); + } + public String printChange() { + return Formats.CURRENCY.formatValue(m_dPaid - m_dTotal); + } + + @Override + public String getVoucher() { + return null; + } + +} diff --git a/src/main/java/com/unicenta/pos/payment/PaymentInfoCash_original.java b/src/main/java/com/unicenta/pos/payment/PaymentInfoCash_original.java new file mode 100644 index 0000000..9703cf8 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentInfoCash_original.java @@ -0,0 +1,98 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.format.Formats; + +/** + * + * @author JG uniCenta + */ +public class PaymentInfoCash_original extends PaymentInfo { + + private final double m_dPaid; + private final double m_dTotal; + private double m_dTendered; + private final String m_dCardName =null; +// private double m_dTip; + + /** Creates a new instance of PaymentInfoCash + * @param dTotal + * @param dPaid */ + public PaymentInfoCash_original(double dTotal, double dPaid) { + m_dTotal = dTotal; + m_dPaid = dPaid; + } + + @Override + public PaymentInfo copyPayment(){ + return new PaymentInfoCash_original(m_dTotal, m_dPaid); + } + + @Override + public String getTransactionID(){ + return "no ID"; + } + + @Override + public String getName() { + return "cash"; + } + @Override + public double getTotal() { + return m_dTotal; + } +/** public double getTip() { + return m_dTip; + } + * @return +*/ + @Override + public double getPaid() { + return m_dPaid; + } + + @Override + public double getTendered() { + return m_dTendered; + } + + @Override + public double getChange(){ + return m_dPaid - m_dTotal; + } + + @Override + public String getCardName() { + return m_dCardName; + } + public String printPaid() { + return Formats.CURRENCY.formatValue(m_dPaid); + } + public String printChange() { + return Formats.CURRENCY.formatValue(m_dPaid - m_dTotal); + } + + @Override + public String getVoucher() { + return null; + } + +} diff --git a/src/main/java/com/unicenta/pos/payment/PaymentInfoFree.java b/src/main/java/com/unicenta/pos/payment/PaymentInfoFree.java new file mode 100644 index 0000000..0187587 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentInfoFree.java @@ -0,0 +1,86 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +public class PaymentInfoFree extends PaymentInfo { + + private double m_dTotal; + private double m_dTendered; + private String m_dCardName =null; +// private double m_dTip; + + /** Creates a new instance of PaymentInfoFree + * @param dTotal */ + public PaymentInfoFree(double dTotal) { + m_dTotal = dTotal; + } + + public PaymentInfo copyPayment(){ + return new PaymentInfoFree(m_dTotal); + } + public String getTransactionID(){ + return "no ID"; + } + public String getName() { + return "free"; + } + public double getTotal() { + return m_dTotal; + } + public double getPaid() { + return (0.0); + } + +/** + * + public double getTip() { + return m_dTip; + } +*/ + + public double getChange(){ + return (0.00); + } + public double getTendered() { + return m_dTendered; + } + public String getCardName() { + return m_dCardName; + } + +/** + public boolean getIsProcessed() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void setIsProcessed(boolean value) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public String getReturnMessage() { + throw new UnsupportedOperationException("Not supported yet."); + } +*/ + + public String getVoucher() { + return null; + } + +} diff --git a/src/main/java/com/unicenta/pos/payment/PaymentInfoList.java b/src/main/java/com/unicenta/pos/payment/PaymentInfoList.java new file mode 100644 index 0000000..46a633c --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentInfoList.java @@ -0,0 +1,62 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import java.util.Iterator; +import java.util.LinkedList; + +public class PaymentInfoList { + + private LinkedList<PaymentInfo> m_apayment; + + /** Creates a new instance of PaymentInfoComposed */ + public PaymentInfoList() { +// JG 16 May 12 use diamond inference + m_apayment = new LinkedList<>(); + } + + public double getTotal() { + + double dTotal = 0.0; + Iterator i = m_apayment.iterator(); + while (i.hasNext()) { + PaymentInfo p = (PaymentInfo) i.next(); + dTotal += p.getTotal(); + } + + return dTotal; + } + + public boolean isEmpty() { + return m_apayment.isEmpty(); + } + + public void add(PaymentInfo p) { + m_apayment.addLast(p); + } + + public void removeLast() { + m_apayment.removeLast(); + } + + public LinkedList<PaymentInfo> getPayments() { + return m_apayment; + } +} diff --git a/src/main/java/com/unicenta/pos/payment/PaymentInfoMagcard.java b/src/main/java/com/unicenta/pos/payment/PaymentInfoMagcard.java new file mode 100644 index 0000000..29f9898 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentInfoMagcard.java @@ -0,0 +1,310 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +public class PaymentInfoMagcard extends PaymentInfo { + + protected double m_dTotal; + protected double m_dTip; + protected String m_sHolderName; + protected String m_sCardNumber; + protected String m_sExpirationDate; + protected String track1; + protected String track2; + protected String track3; + protected String m_sTransactionID; + protected String m_sAuthorization; + protected String m_sErrorMessage; + protected String m_sReturnMessage; + //JG Jan 2018 + protected String encryptedTrack; + protected String encryptionKey; + protected String m_dCardName =null; + + protected Boolean chipAndPin = Boolean.FALSE; + protected String verification; + protected String lastFourDigits; + + /** + * Creates a new instance of PaymentInfoMagcard + * @param sHolderName + * @param sCardNumber + * @param sExpirationDate + * @param track1 + * @param track2 + * @param track3 + * @param encryptedCard + * @param encryptKey + * @param sTransactionID + * @param dTotal + */ + public PaymentInfoMagcard(String sHolderName, String sCardNumber, + String sExpirationDate, String track1, String track2, String track3, String encryptedCard, String encryptKey, + String sTransactionID, double dTotal) { + m_sHolderName = sHolderName; + m_sCardNumber = sCardNumber; + m_sExpirationDate = sExpirationDate; + this.track1 = track1; + this.track2 = track2; + this.track3 = track3; + encryptedTrack = encryptedCard; + encryptionKey = encryptKey; + m_sTransactionID = sTransactionID; + m_dTotal = dTotal; + + + m_sAuthorization = null; + m_sErrorMessage = null; + m_sReturnMessage = null; + } + + /** + * Creates a new instance of PaymentInfoMagcard + * @param sHolderName + * @param sCardNumber + * @param sExpirationDate + * @param sTransactionID + * @param dTotal + */ + public PaymentInfoMagcard(String sHolderName, String sCardNumber, + String sExpirationDate, String sTransactionID, double dTotal) { + this(sHolderName, sCardNumber, sExpirationDate, + null, null, null, null, null, sTransactionID, dTotal); + } + + @Override + public PaymentInfo copyPayment() { + PaymentInfoMagcard p = new PaymentInfoMagcard(m_sHolderName, + m_sCardNumber, m_sExpirationDate, track1, track2, + track3, encryptedTrack, encryptionKey, m_sTransactionID, m_dTotal); + p.m_sAuthorization = m_sAuthorization; + p.m_sErrorMessage = m_sErrorMessage; + return p; + } + + public String getName() { +// return "magcard"; + return "ccard"; + } + + @Override + public double getTotal() { + return m_dTotal; + } + + public double getTip() { + return m_dTip; + } + + public boolean isPaymentOK() { + return m_sAuthorization != null; + } + + public String getHolderName() { + return m_sHolderName; + } + + @Override + public String getCardName() { + if (chipAndPin){ + return m_dCardName; + } + return getCardType(m_sCardNumber); + } + + public String getCardNumber() { + return m_sCardNumber; + } + + public String getExpirationDate() { + return m_sExpirationDate; + } + + @Override + public String getTransactionID() { + return m_sTransactionID; + } + + /** + * Get tracks of magnetic card. Framing characters: - start sentinel (SS) - + * end sentinel (ES) - LRC + * + * @return tracks of the magnetic card + */ + public String getEncryptedCardData() { + return encryptedTrack; + } + + public String getEncryptionKey() { + return encryptionKey; + } + + /** @param sCardNumber + * @return + */ + public String getCardType(String sCardNumber){ + String c = "UNKNOWN"; + + if (sCardNumber.startsWith("4")) { + c = "VISA"; + } else if (sCardNumber.startsWith("6")) { + c = "DISC"; + } else if (sCardNumber.startsWith("5")) { + c = "MAST"; + } else if (sCardNumber.startsWith("34") || sCardNumber.startsWith("37")) { + c = "AMEX"; + } else if (sCardNumber.startsWith("3528") || sCardNumber.startsWith("3589")) { + c = "JCB"; + } else if (sCardNumber.startsWith("3")) { + c = "DINE"; + } + m_sCardNumber = c; + return c; + } + + public String getTrack1(boolean framingChar) { + return (framingChar) + ? track1 + : track1.substring(1, track1.length() - 2); + } + + public String getTrack2(boolean framingChar) { + return (framingChar) + ? track2 + : track2.substring(1, track2.length() - 2); + } + + public String getTrack3(boolean framingChar) { + return (framingChar) + ? track3 + : track3.substring(1, track3.length() - 2); + } + + public String getAuthorization() { + return m_sAuthorization; + } + + public String getMessage() { + return m_sErrorMessage; + } + + public void paymentError(String sMessage, String moreInfo) { + m_sAuthorization = null; + m_sErrorMessage = sMessage + "\n" + moreInfo; + } + + public void setReturnMessage(String returnMessage) { + m_sReturnMessage = returnMessage; + } + + public String getReturnMessage() { + return m_sReturnMessage; + } + + public void paymentOK(String sAuthorization, String sTransactionId, String sReturnMessage) { + m_sAuthorization = sAuthorization; + m_sTransactionID = sTransactionId; + m_sReturnMessage = sReturnMessage; + m_sErrorMessage = null; + } + + public String printCardNumber() { + System.out.println(m_sCardNumber); + if (m_sCardNumber.length() > 4) { + return m_sCardNumber.substring(0, m_sCardNumber.length() - 4).replaceAll("\\.", "*") + + m_sCardNumber.substring(m_sCardNumber.length() - 4); + } else { + return "****"; + } + } + + public String printExpirationDate() { + return m_sExpirationDate; + } + + public String printAuthorization() { + return m_sAuthorization; + } + + public String printTransactionID() { + return m_sTransactionID; + } + + public boolean getIsProcessed() { + throw new UnsupportedOperationException("Not supported yet."); + } + + + public void setIsProcessed(boolean value) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public double getPaid() { + return (0.0); + } + + @Override + public double getChange(){ + return 0.00; + } + + @Override + public double getTendered() { + return 0.00; + } + + @Override + public String getVoucher() { + return null; + } + + public void setCardName(String m_dCardName){ + this.m_dCardName = m_dCardName; + } + + public Boolean isChipAndPin() { + return chipAndPin; + } + + public void setChipAndPin(Boolean chipAndPin) { + this.chipAndPin = chipAndPin; + } + + public String printVerification() { + return verification; + } + + public void setVerification(String verification) { + this.verification = verification; + } + + public String getLastFourDigits() { + return lastFourDigits; + } + + public String printLastFourDigits() { + return lastFourDigits; + } + + public void setLastFourDigits(String lastFourDigits) { + this.lastFourDigits = lastFourDigits; + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/payment/PaymentInfoMagcardRefund.java b/src/main/java/com/unicenta/pos/payment/PaymentInfoMagcardRefund.java new file mode 100644 index 0000000..0f8af93 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentInfoMagcardRefund.java @@ -0,0 +1,53 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +public class PaymentInfoMagcardRefund extends PaymentInfoMagcard { + +/** + * Creates a new instance of PaymentInfoMagcardRefund + */ + public PaymentInfoMagcardRefund(String sHolderName, String sCardNumber, String sExpirationDate, String track1, String track2, + String track3, String encryptCard, String encryptKey, String sTransactionID, double dTotal) { + super(sHolderName, sCardNumber, sExpirationDate, track1, track2, track3, encryptCard, encryptKey, sTransactionID, dTotal); + } + + /** + * Creates a new instance of PaymentInfoMagcard + */ + public PaymentInfoMagcardRefund(String sHolderName, String sCardNumber, String sExpirationDate, String sTransactionID, String encryptedCard, String encryptionKey, double dTotal) { + super(sHolderName, sCardNumber, sExpirationDate, sTransactionID, dTotal); + } + + @Override + public PaymentInfo copyPayment() { + PaymentInfoMagcard p = new PaymentInfoMagcardRefund(m_sHolderName, m_sCardNumber, m_sExpirationDate, + track1, track2, track3, encryptedTrack, encryptionKey, m_sTransactionID, m_dTotal); + p.m_sAuthorization = m_sAuthorization; + p.m_sErrorMessage = m_sErrorMessage; + return p; + } + + @Override + public String getName() { +// return "magcardrefund"; + return "ccardrefund"; + } +} diff --git a/src/main/java/com/unicenta/pos/payment/PaymentInfoTicket.java b/src/main/java/com/unicenta/pos/payment/PaymentInfoTicket.java new file mode 100644 index 0000000..624b3f6 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentInfoTicket.java @@ -0,0 +1,154 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.SerializableRead; +import com.unicenta.format.Formats; + +public class PaymentInfoTicket extends PaymentInfo implements SerializableRead { + + private static final long serialVersionUID = 8865238639097L; + private double m_dTicket; + private String m_sName; + private String m_transactionID; + private double m_dTendered; + private double m_change; + private String m_dCardName =null; + private double m_dTip; + private boolean m_isProcessed; + private String m_returnMessage; + private String m_sVoucher; + private String sVoucher; + private String m_sVoucherNumber; + + /** Creates a new instance of PaymentInfoTicket + * @param dTicket + * @param sName */ + +// call by Cheque, Bank , Slip + public PaymentInfoTicket(double dTicket, String sName) { + m_sName = sName; + m_dTicket = dTicket; + } + + public PaymentInfoTicket(double dTicket, String sName, String transactionID, String sVoucher) { + m_sName = sName; + m_dTicket = dTicket; + m_transactionID = transactionID; + m_sVoucher = sVoucher; + } + +// call by Voucher + public PaymentInfoTicket(double dTicket, String sName, String sVoucher) { + m_sName = sName; + m_dTicket = dTicket; + m_sVoucher = sVoucher; + m_sVoucherNumber = sVoucher; + } + + public PaymentInfoTicket() { + m_sName = null; + m_dTicket = 0.0; + m_transactionID = null; + m_dTendered = 0.00; + } + + @Override + public void readValues(DataRead dr) throws BasicException { + m_sName = dr.getString(1); + m_dTicket = dr.getDouble(2); + m_transactionID = dr.getString(3); + if (dr.getDouble(4) != null) { + m_dTendered = dr.getDouble(4); + } + m_dCardName = dr.getString(5); + } + + @Override + public PaymentInfo copyPayment(){ + return new PaymentInfoTicket(m_dTicket, m_sName); + } + @Override + public String getName() { + return m_sName; + } + @Override + public double getTotal() { + return m_dTicket; + } + @Override + public String getTransactionID(){ + return m_transactionID; + } + + @Override + public double getPaid() { + return (0.0); + } + + @Override + public double getChange(){ + return m_dTendered - m_dTicket; + } + + @Override + public double getTendered() { + return (0.0); + } + + @Override + public String getCardName() { + return m_dCardName; + } + + public String printPaid() { + return Formats.CURRENCY.formatValue(m_dTicket); + } + + + public String printVoucherTotal() { + return Formats.CURRENCY.formatValue(-m_dTicket); + } + + public String printChange() { + return Formats.CURRENCY.formatValue(m_dTendered - m_dTicket); + } + + public String printTendered() { + return Formats.CURRENCY.formatValue(m_dTendered); + } + + + @Override + public String getVoucher() { + return m_sVoucher; + } + public String printVoucher() { + return m_sVoucher; + } + public String getVoucherNumber() { + return m_sVoucherNumber; + } + public String printVoucherNumber() { + return m_sVoucherNumber; + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/payment/PaymentPanel.java b/src/main/java/com/unicenta/pos/payment/PaymentPanel.java new file mode 100644 index 0000000..bf97a25 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentPanel.java @@ -0,0 +1,29 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import javax.swing.JComponent; + +public interface PaymentPanel { + + public void activate(String sTransaction, double dTotal); + public JComponent getComponent(); + public PaymentInfoMagcard getPaymentInfoMagcard(); +} diff --git a/src/main/java/com/unicenta/pos/payment/PaymentPanelBasic.form b/src/main/java/com/unicenta/pos/payment/PaymentPanelBasic.form new file mode 100644 index 0000000..a69b60a --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentPanelBasic.form @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,124,0,0,1,-94"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/payment/PaymentPanelBasic.java b/src/main/java/com/unicenta/pos/payment/PaymentPanelBasic.java new file mode 100644 index 0000000..ef4adba --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentPanelBasic.java @@ -0,0 +1,102 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.pos.forms.AppLocal; +import javax.swing.JComponent; + +public class PaymentPanelBasic extends javax.swing.JPanel implements PaymentPanel { + + private double m_dTotal; + private String m_sTransactionID; + private JPaymentNotifier m_notifier; + + /** + * Creates new form PaymentPanelSimple + */ + public PaymentPanelBasic(JPaymentNotifier notifier) { + + m_notifier = notifier; + initComponents(); + } + + public JComponent getComponent() { + return this; + } + + public void activate(String sTransaction, double dTotal) { + + m_sTransactionID = sTransaction; + m_dTotal = dTotal; + + jLabel1.setText( + m_dTotal > 0.0 + ? AppLocal.getIntString("message.paymentgatewayext") + : AppLocal.getIntString("message.paymentgatewayextrefund")); + + m_notifier.setStatus(true, true); + } + + public PaymentInfoMagcard getPaymentInfoMagcard() { + + if (m_dTotal > 0.0) { + return new PaymentInfoMagcard( + "", + "", + "", + null, + null, + null, + null, + null, + m_sTransactionID, + m_dTotal); + } else { + return new PaymentInfoMagcardRefund( + "", + "", + "", + null, + null, + null, + null, + null, + m_sTransactionID, + m_dTotal); + } + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents + private void initComponents() { + jLabel1 = new javax.swing.JLabel(); + + add(jLabel1); + + } + // </editor-fold>//GEN-END:initComponents + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/payment/PaymentPanelEMV.java b/src/main/java/com/unicenta/pos/payment/PaymentPanelEMV.java new file mode 100644 index 0000000..f5ff07c --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentPanelEMV.java @@ -0,0 +1,108 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.pos.forms.AppLocal; + +import javax.swing.*; + +public class PaymentPanelEMV extends javax.swing.JPanel implements PaymentPanel { + + private double m_dTotal; + private String m_sTransactionID; + private final JPaymentNotifier m_notifier; + + /** + * Creates new form PaymentPanelSimple + * @param notifier + */ + public PaymentPanelEMV(JPaymentNotifier notifier) { + + m_notifier = notifier; + initComponents(); + } + + @Override + public JComponent getComponent() { + return this; + } + + @Override + public void activate(String sTransaction, double dTotal) { + + m_sTransactionID = sTransaction; + m_dTotal = dTotal; + + jLabel1.setText( + m_dTotal > 0.0 + //TODO: Needs to be done for all locals i.e. message.paymentgatewayemv + ? AppLocal.getIntString("message.paymentgatewayemv") + : AppLocal.getIntString("message.paymentgatewayemvrefund")); + + m_notifier.setStatus(true, true); + } + + @Override + public PaymentInfoMagcard getPaymentInfoMagcard() { + + if (m_dTotal > 0.0) { + return new PaymentInfoMagcard( + "", + "", + "", + null, + null, + null, + null, + null, + m_sTransactionID, + m_dTotal); + } else { + return new PaymentInfoMagcardRefund( + "", + "", + "", + null, + null, + null, + null, + null, + m_sTransactionID, + m_dTotal); + } + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents + private void initComponents() { + jLabel1 = new javax.swing.JLabel(); + + add(jLabel1); + + } + // </editor-fold>//GEN-END:initComponents + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + // End of variables declaration//GEN-END:variables +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/payment/PaymentPanelFac.java b/src/main/java/com/unicenta/pos/payment/PaymentPanelFac.java new file mode 100644 index 0000000..820add7 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentPanelFac.java @@ -0,0 +1,47 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +/** + * + * @author adrianromero + */ +public class PaymentPanelFac { + + /** Creates a new instance of PaymentPanelFac */ + private PaymentPanelFac() { + } + + public static PaymentPanel getPaymentPanel(String sReader, JPaymentNotifier notifier) { +// JG 16 May 12 use switch + switch (sReader) { + case "Intelligent": + return new PaymentPanelMagCard(new MagCardReaderIntelligent(), notifier); + case "Generic": + return new PaymentPanelMagCard(new MagCardReaderGeneric(), notifier); + case "Keyboard": + return new PaymentPanelType(notifier); + case "EMV": + return new PaymentPanelEMV(notifier); + default: + return new PaymentPanelBasic(notifier); + } + } +} diff --git a/src/main/java/com/unicenta/pos/payment/PaymentPanelMagCard.form b/src/main/java/com/unicenta/pos/payment/PaymentPanelMagCard.form new file mode 100644 index 0000000..081b86b --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentPanelMagCard.form @@ -0,0 +1,267 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-52,0,0,1,-7"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="message.paymentgatewayswipe" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[263, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="m_jKeyFactory" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel6" min="-2" max="-2" attributes="0"/> + <Component id="jLabel7" min="-2" max="-2" attributes="0"/> + <Component id="jLabel8" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jExpirationDate" alignment="0" min="-2" pref="70" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="1" attributes="0"> + <Component id="m_jHolderName" min="-2" max="-2" attributes="0"/> + <Component id="m_jCardNumber" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="jReset" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace min="-2" pref="22" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jKeyFactory" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jReset" alignment="0" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel8" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="m_jHolderName" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel6" min="-2" max="-2" attributes="0"/> + <Component id="m_jCardNumber" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jExpirationDate" min="-2" max="-2" attributes="0"/> + <Component id="jLabel7" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace min="-2" pref="17" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="jReset"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="11" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/reload.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.reset" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jResetActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JTextArea" name="m_jKeyFactory"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[1, 1]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.cardnumber" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel7"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.cardexpdate" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jExpirationDate"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" id="white" palette="0" red="ff" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[180, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jCardNumber"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" id="white" palette="0" red="ff" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.cardholder" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jHolderName"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" id="white" palette="1" red="ff" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/payment/PaymentPanelMagCard.java b/src/main/java/com/unicenta/pos/payment/PaymentPanelMagCard.java new file mode 100644 index 0000000..984238a --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentPanelMagCard.java @@ -0,0 +1,518 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.HeadlessException; +import java.awt.Insets; +import java.io.File; +import javax.swing.*; + +import jpos.JposException; +import jpos.MSR; +import jpos.MSRControl113; +import jpos.events.DataEvent; +import jpos.events.DataListener; +import jpos.events.ErrorEvent; +import jpos.events.ErrorListener; + +public class PaymentPanelMagCard extends javax.swing.JPanel implements PaymentPanel, + DataListener, ErrorListener { + + private JPaymentNotifier m_notifier; + private MagCardReader m_cardreader; + private String track1 = null; + private String track2 = null; + private String track3 = null; + private String m_sTransactionID; + private double m_dTotal; + // --------------------MagTeck variables----------------------------// + String track1DataTextField = null; + String track2DataTextField = null; + String track3DataTextField = null; + String additionalSecurityInformationTextField = null; + String track1DataEncryptedTextField = null; + String track2DataEncryptedTextField = null; + String track3DataEncryptedTextField = null; + //JButton clearButton = new JButton("Clear"); + String infoLine = ""; + String title = ""; + String resultValue = ""; + boolean enabled = false; + boolean openDevice = false; + boolean init = true; + String logicalDeviceName = "MagTekMSR_Encrypted"; + String encryptedCardData = null; + String encryptionKey = null; + boolean isMercury; + MSRControl113 msr = null; + //----------------------------------------------------------------------// + + /** + * Creates new form JMagCardReader + */ + // public PaymentPanelMagCard(String sReader, JPaymentNotifier notifier) { + public PaymentPanelMagCard(MagCardReader cardreader, JPaymentNotifier notifier) { + m_notifier = notifier; + m_cardreader = cardreader; + + initComponents(); + + + AppConfig config = new AppConfig(new File(new File(System.getProperty("user.home")), AppLocal.APP_ID + ".properties")); + config.load(); + + String payProcessor = config.getProperty("payment.gateway"); + if ("MercuryPay".equals(payProcessor)) { + isMercury = true; + } else { + isMercury = false; + } + + if (m_cardreader != null) { + // They will be able to pay by card + m_jKeyFactory.addKeyListener(new KeyBarsListener()); + jReset.setEnabled(true); + } else { + jReset.setEnabled(false); + } + //---------------------------------------------------// + + msr = new MSR(); + msr.addDataListener(this); + msr.addErrorListener(this); + if (isMercury) { + processMSRSession(); + } + } + + private void processMSRSession() { + + + if ((this.logicalDeviceName != null) && (!"".equals(this.logicalDeviceName))) { + if (this.openDevice) { + try { + msr.close(); + } catch (JposException localJposException1) { + JOptionPane.showMessageDialog(this, "Error Occured " + localJposException1.getMessage()); + } + } + try { + msr.open(this.logicalDeviceName); + this.openDevice = true; + } catch (JposException localJposException2) { + JOptionPane.showMessageDialog(this, "Error Occured " + localJposException2.getMessage()); + } + //Clear the field data. + clear(); + + try { + this.msr.claim(1000); + } catch (JposException localJposException3) { + JOptionPane.showMessageDialog(this, "Error Occured " + localJposException3.getMessage()); + } + try { + this.msr.setDataEventEnabled(true); + } catch (JposException localJposException5) { + JOptionPane.showMessageDialog(this, "Error Occured " + localJposException5.getMessage()); + } + try { + this.msr.setDeviceEnabled(true); + this.enabled = true; + } catch (JposException localJposException4) { + this.enabled = false; + JOptionPane.showMessageDialog(this, "Error Occured " + localJposException4.getMessage()); + } + } + } + + public void clear() { + this.track1DataTextField = ""; + this.track2DataTextField = ""; + this.track3DataTextField = ""; + this.additionalSecurityInformationTextField = ""; + this.track1DataEncryptedTextField = ""; + this.track2DataEncryptedTextField = ""; + this.track3DataEncryptedTextField = ""; + } + + @Override + public void dataOccurred(DataEvent paramDataEvent) { + String str = ""; + byte[] arrayOfByte = new byte[0]; + try { + arrayOfByte = this.msr.getTrack1Data(); + str = new String(arrayOfByte); + if (str.length() == 0) { + str = ""; + } + this.track1DataTextField = str; + + arrayOfByte = this.msr.getTrack2Data(); + str = new String(arrayOfByte); + if (str.length() == 0) { + str = ""; + } + this.track2DataTextField = str; + + arrayOfByte = this.msr.getTrack3Data(); + str = new String(arrayOfByte); + if (str.length() == 0) { + str = ""; + } + this.track3DataTextField = str; + + arrayOfByte = this.msr.getAdditionalSecurityInformation(); + str = new String(arrayOfByte); + if (str.length() == 0) { + str = ""; + } + this.additionalSecurityInformationTextField = str; + + arrayOfByte = this.msr.getTrack1EncryptedData(); + str = new String(arrayOfByte); + if (str.length() == 0) { + str = ""; + } + this.track1DataEncryptedTextField = str; + + arrayOfByte = this.msr.getTrack2EncryptedData(); + str = new String(arrayOfByte); + if (str.length() == 0) { + str = ""; + } + this.track2DataEncryptedTextField = str; + + arrayOfByte = this.msr.getTrack3EncryptedData(); + str = new String(arrayOfByte); + if (str.length() == 0) { + str = ""; + } + this.track3DataEncryptedTextField = str; + this.msr.setDataEventEnabled(true); + + encryptedCardData = track2DataEncryptedTextField; + encryptionKey = additionalSecurityInformationTextField; + + char[] cData = ("%" + track1DataTextField + "?;" + track2DataTextField + "?").toCharArray(); + + if (cData.length > 0) { + for (int i = 0; i < cData.length; i++) { + stateTransition(cData[i]); + } + } + } catch (JposException localJposException) { + processJposException(localJposException, ""); + } + } + + @Override + public void errorOccurred(ErrorEvent paramErrorEvent) { + String str1 = Integer.toString(paramErrorEvent.getErrorCode()); + String str2 = Integer.toString(paramErrorEvent.getErrorCodeExtended()); + String str3 = Integer.toString(paramErrorEvent.getErrorLocus()); + String str4 = Integer.toString(paramErrorEvent.getErrorResponse()); + + JOptionPane.showMessageDialog(this, "ErrorEvent: EC=" + str1 + ", ECE=" + str2 + ", EL=" + str3 + ", ER=" + str4, this.title, 0); + } + + private void processJposException(JposException paramJposException, String paramString) { + JOptionPane.showMessageDialog(this, "Exception...message = " + paramJposException.getMessage() + " with errorCode = " + paramJposException.getErrorCode() + ", errorCodeExtended = " + paramJposException.getErrorCodeExtended(), this.title, 0); + + } + + class XmlDialog extends JDialog { + + JScrollPane jScrollPane = new JScrollPane(); + JTextArea jTextArea = new JTextArea(); + GridBagLayout gridBagLayout1 = new GridBagLayout(); + + public XmlDialog(String arg2) throws HeadlessException { + try { + jaInit(); + String str = ""; + this.jTextArea.append(str); + } catch (Exception localException) { + localException.printStackTrace(); + } + + } + + private void jaInit() throws Exception { + getContentPane().setLayout(this.gridBagLayout1); + + this.jTextArea.setColumns(16); + this.jTextArea.setRows(18); + + getContentPane().add(this.jScrollPane, new GridBagConstraints(0, 0, 2, 1, 1.0D, 1.0D, 10, 1, new Insets(15, 17, 0, 15), 364, 213)); + + this.jScrollPane.getViewport().add(this.jTextArea, null); + } + } + //--------------------------------------------------------------// + + @Override + public JComponent getComponent() { + return this; + } + + @Override + public void activate(String sTransaction, double dTotal) { + m_sTransactionID = sTransaction; + m_dTotal = dTotal; + resetState(); + m_jKeyFactory.setText(null); + java.awt.EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + m_jKeyFactory.requestFocus(); + } + }); + } + + private void resetState() { + + m_notifier.setStatus(false, false); + + m_jHolderName.setText(null); + m_jCardNumber.setText(null); + m_jExpirationDate.setText(null); + track1 = null; + track2 = null; + track3 = null; + + if (m_cardreader != null) { + // Se van a poder efectuar pagos con tarjeta + m_cardreader.reset(); + } + //clear(); + } + + @Override + public PaymentInfoMagcard getPaymentInfoMagcard() { + + if (m_dTotal > 0.0) { + return new PaymentInfoMagcard( + m_jHolderName.getText(), + m_jCardNumber.getText(), + m_jExpirationDate.getText(), + track1, + track2, + track3, + encryptedCardData, + encryptionKey, + m_sTransactionID, + m_dTotal); + } else { + return new PaymentInfoMagcardRefund( + m_jHolderName.getText(), + m_jCardNumber.getText(), + m_jExpirationDate.getText(), + track1, + track2, + track3, + encryptedCardData, + encryptionKey, + m_sTransactionID, + m_dTotal); + } + } + + private void stateTransition(char cTrans) { + + m_cardreader.appendChar(cTrans); + + if (m_cardreader.isComplete()) { + m_jHolderName.setText(m_cardreader.getHolderName()); + m_jCardNumber.setText(m_cardreader.getCardNumber()); + m_jExpirationDate.setText(m_cardreader.getExpirationDate()); + track1 = m_cardreader.getTrack1(); + track2 = m_cardreader.getTrack2(); + track3 = m_cardreader.getTrack3(); + m_notifier.setStatus(true, true); + + m_jKeyFactory.addKeyListener(new KeyBarsListener()); + jReset.setEnabled(true); + + } else { + m_jHolderName.setText(null); + m_jCardNumber.setText(null); + m_jExpirationDate.setText(null); + track1 = null; + track3 = null; + track3 = null; + m_notifier.setStatus(false, false); + } + } + + private class KeyBarsListener extends java.awt.event.KeyAdapter { + + @Override + public void keyTyped(java.awt.event.KeyEvent e) { + m_jKeyFactory.setText(null); + stateTransition(e.getKeyChar()); + } + } + + /** + * + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel2 = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + jPanel1 = new javax.swing.JPanel(); + jReset = new javax.swing.JButton(); + m_jKeyFactory = new javax.swing.JTextArea(); + jLabel6 = new javax.swing.JLabel(); + jLabel7 = new javax.swing.JLabel(); + m_jExpirationDate = new javax.swing.JLabel(); + m_jCardNumber = new javax.swing.JLabel(); + jLabel8 = new javax.swing.JLabel(); + m_jHolderName = new javax.swing.JLabel(); + + setLayout(new java.awt.BorderLayout()); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 18)); // NOI18N + jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLabel1.setText(AppLocal.getIntString("message.paymentgatewayswipe")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(263, 30)); + jPanel2.add(jLabel1); + + add(jPanel2, java.awt.BorderLayout.NORTH); + + jReset.setFont(new java.awt.Font("Arial", 0, 11)); // NOI18N + jReset.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reload.png"))); // NOI18N + jReset.setText(AppLocal.getIntString("button.reset")); // NOI18N + jReset.setFocusPainted(false); + jReset.setFocusable(false); + jReset.setPreferredSize(new java.awt.Dimension(100, 45)); + jReset.setRequestFocusEnabled(false); + jReset.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jResetActionPerformed(evt); + } + }); + + m_jKeyFactory.setPreferredSize(new java.awt.Dimension(1, 1)); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setText(AppLocal.getIntString("label.cardnumber")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel7.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel7.setText(AppLocal.getIntString("label.cardexpdate")); // NOI18N + jLabel7.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jExpirationDate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jExpirationDate.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jExpirationDate.setOpaque(true); + m_jExpirationDate.setPreferredSize(new java.awt.Dimension(180, 30)); + + m_jCardNumber.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCardNumber.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jCardNumber.setOpaque(true); + m_jCardNumber.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLabel8.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel8.setText(AppLocal.getIntString("label.cardholder")); // NOI18N + jLabel8.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jHolderName.setBackground(java.awt.Color.white); + m_jHolderName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jHolderName.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jHolderName.setOpaque(true); + m_jHolderName.setPreferredSize(new java.awt.Dimension(200, 30)); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(m_jKeyFactory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jExpirationDate, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(m_jHolderName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCardNumber, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addComponent(jReset, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(22, 22, 22)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jKeyFactory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jReset, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jHolderName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCardNumber, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jExpirationDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addGap(17, 17, 17)) + ); + + add(jPanel1, java.awt.BorderLayout.CENTER); + }// </editor-fold>//GEN-END:initComponents + + private void jResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jResetActionPerformed + + resetState(); + + }//GEN-LAST:event_jResetActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JButton jReset; + private javax.swing.JLabel m_jCardNumber; + private javax.swing.JLabel m_jExpirationDate; + private javax.swing.JLabel m_jHolderName; + private javax.swing.JTextArea m_jKeyFactory; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/payment/PaymentPanelType.form b/src/main/java/com/unicenta/pos/payment/PaymentPanelType.form new file mode 100644 index 0000000..b7ac3c6 --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentPanelType.form @@ -0,0 +1,232 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,89,0,0,2,-18"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="1"/> + </Layout> + <SubComponents> + <Component class="com.unicenta.editor.JEditorKeys" name="m_jKeys"> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jKeysActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[400, 105]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel7" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jExpirationDate" min="-2" pref="90" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel2" min="-2" pref="61" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel8" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jHolderName" min="-2" pref="200" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel6" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCardNumber" min="-2" pref="200" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel8" min="-2" max="-2" attributes="0"/> + <Component id="m_jHolderName" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel6" min="-2" max="-2" attributes="0"/> + <Component id="m_jCardNumber" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jExpirationDate" min="-2" max="-2" attributes="0"/> + <Component id="jLabel7" min="-2" max="-2" attributes="0"/> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace pref="177" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="com.unicenta.editor.JEditorStringNumber" name="m_jCardNumber"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorStringNumber" name="m_jExpirationDate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jHolderName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.cardholder" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.cardnumber" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel7"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.cardexpdate" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="MMYY"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[350, 45]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="1"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="message.paymentgatewaytype" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/payment/PaymentPanelType.java b/src/main/java/com/unicenta/pos/payment/PaymentPanelType.java new file mode 100644 index 0000000..4dca2da --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/PaymentPanelType.java @@ -0,0 +1,273 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.util.LuhnAlgorithm; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.JComponent; + +/** + * + * @author adrianromero + */ +public class PaymentPanelType extends javax.swing.JPanel implements PaymentPanel { + + private double m_dTotal; + private String m_sTransactionID; + private JPaymentNotifier m_notifier; + + /** + * Creates new form JPaymentCash + */ + public PaymentPanelType(JPaymentNotifier notifier) { + + m_notifier = notifier; + + initComponents(); + + m_jHolderName.addPropertyChangeListener("Edition", new RecalculateName()); + m_jCardNumber.addPropertyChangeListener("Edition", new RecalculateName()); + m_jExpirationDate.addPropertyChangeListener("Edition", new RecalculateName()); + + + m_jHolderName.addEditorKeys(m_jKeys); + m_jCardNumber.addEditorKeys(m_jKeys); + m_jExpirationDate.addEditorKeys(m_jKeys); + + } + + public JComponent getComponent() { + return this; + } + + public void activate(String sTransaction, double dTotal) { + + m_sTransactionID = sTransaction; + m_dTotal = dTotal; + + resetState(); + + m_jHolderName.activate(); + } + + private void resetState() { + + m_notifier.setStatus(false, false); + + m_jHolderName.setText(null); + m_jCardNumber.setText(null); + m_jExpirationDate.setText(null); + } + + public PaymentInfoMagcard getPaymentInfoMagcard() { + + if (m_dTotal > 0.0) { + return new PaymentInfoMagcard( + m_jHolderName.getText(), + m_jCardNumber.getText(), + m_jExpirationDate.getText(), + null, + null, + null, + null, + null, + m_sTransactionID, + m_dTotal); + } else { + return new PaymentInfoMagcardRefund( + m_jHolderName.getText(), + m_jCardNumber.getText(), + m_jExpirationDate.getText(), + null, + null, + null, + null, + null, + m_sTransactionID, + m_dTotal); + } + } + + private class RecalculateName implements PropertyChangeListener { + + public void propertyChange(PropertyChangeEvent evt) { + boolean isvalid = isValidHolder() && isValidCardNumber() && isValidExpirationDate(); + m_notifier.setStatus(isvalid, isvalid); + } + } + + private boolean isValidHolder() { + return !(m_jHolderName.getText() == null || m_jHolderName.getText().equals("")); + } + + private boolean isValidCardNumber() { + return (LuhnAlgorithm.checkCC(m_jCardNumber.getText()) && m_jCardNumber.getText().length() > 13 && m_jCardNumber.getText().length() < 20); + } + + private boolean isValidExpirationDate() { + return !(m_jExpirationDate.getText() == null || m_jExpirationDate.getText().length() != 4); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel2 = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel4 = new javax.swing.JPanel(); + m_jCardNumber = new com.unicenta.editor.JEditorStringNumber(); + m_jExpirationDate = new com.unicenta.editor.JEditorStringNumber(); + m_jHolderName = new com.unicenta.editor.JEditorString(); + jLabel8 = new javax.swing.JLabel(); + jLabel6 = new javax.swing.JLabel(); + jLabel7 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + jPanel5 = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + + setLayout(new java.awt.BorderLayout()); + + jPanel2.setLayout(new java.awt.BorderLayout()); + + jPanel1.setLayout(new javax.swing.BoxLayout(jPanel1, javax.swing.BoxLayout.Y_AXIS)); + + m_jKeys.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jKeysActionPerformed(evt); + } + }); + jPanel1.add(m_jKeys); + + jPanel2.add(jPanel1, java.awt.BorderLayout.NORTH); + + add(jPanel2, java.awt.BorderLayout.EAST); + + jPanel4.setPreferredSize(new java.awt.Dimension(400, 105)); + + m_jCardNumber.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCardNumber.setMinimumSize(new java.awt.Dimension(100, 30)); + m_jCardNumber.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jExpirationDate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jExpirationDate.setMinimumSize(new java.awt.Dimension(100, 30)); + m_jExpirationDate.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jHolderName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jHolderName.setMinimumSize(new java.awt.Dimension(100, 30)); + m_jHolderName.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel8.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel8.setText(AppLocal.getIntString("label.cardholder")); // NOI18N + jLabel8.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setText(AppLocal.getIntString("label.cardnumber")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel7.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel7.setText(AppLocal.getIntString("label.cardexpdate")); // NOI18N + jLabel7.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText("MMYY"); + jLabel2.setPreferredSize(new java.awt.Dimension(150, 30)); + + javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); + jPanel4.setLayout(jPanel4Layout); + jPanel4Layout.setHorizontalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jExpirationDate, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 61, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)) + .addGroup(jPanel4Layout.createSequentialGroup() + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jHolderName, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel4Layout.createSequentialGroup() + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCardNumber, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) + ); + jPanel4Layout.setVerticalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jHolderName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCardNumber, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jExpirationDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(177, Short.MAX_VALUE)) + ); + + add(jPanel4, java.awt.BorderLayout.CENTER); + + jPanel5.setPreferredSize(new java.awt.Dimension(350, 45)); + + jLabel1.setFont(new java.awt.Font("Arial", 1, 18)); // NOI18N + jLabel1.setText(AppLocal.getIntString("message.paymentgatewaytype")); // NOI18N + jPanel5.add(jLabel1); + + add(jPanel5, java.awt.BorderLayout.NORTH); + }// </editor-fold>//GEN-END:initComponents + + private void m_jKeysActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jKeysActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_m_jKeysActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private com.unicenta.editor.JEditorStringNumber m_jCardNumber; + private com.unicenta.editor.JEditorStringNumber m_jExpirationDate; + private com.unicenta.editor.JEditorString m_jHolderName; + private com.unicenta.editor.JEditorKeys m_jKeys; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/payment/VoucherPaymentInfo.java b/src/main/java/com/unicenta/pos/payment/VoucherPaymentInfo.java new file mode 100644 index 0000000..25a0bbe --- /dev/null +++ b/src/main/java/com/unicenta/pos/payment/VoucherPaymentInfo.java @@ -0,0 +1,112 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.payment; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.SerializableRead; +import com.unicenta.format.Formats; + + +public class VoucherPaymentInfo extends PaymentInfo implements SerializableRead { + + private static final long serialVersionUID = 8865238639097L; + private double m_dTicket; + private String m_sName; + private String m_sVoucher; + + public VoucherPaymentInfo(double dTicket, String sName, String sVoucher) { + m_dTicket = dTicket; + m_sName = sName; + m_sVoucher = sVoucher; + } + + public VoucherPaymentInfo() { + m_dTicket = 0.0; + m_sName = null; + m_sVoucher = null; + } + + @Override + public void readValues(DataRead dr) throws BasicException { + m_sName = dr.getString(1); + m_dTicket = dr.getDouble(2); + m_sVoucher = dr.getString(3); + } + + @Override + public PaymentInfo copyPayment(){ + return new VoucherPaymentInfo(m_dTicket, m_sName, m_sVoucher); + } + + @Override + public String getName() { + return m_sName; + } + + @Override + public double getTotal() { + return m_dTicket; + } + + @Override + public String getTransactionID(){ + return null; + } + + public String printPaid() { + return Formats.CURRENCY.formatValue(m_dTicket); + } + + public String printVoucherTotal() { + return Formats.CURRENCY.formatValue(-m_dTicket); + } + + + @Override + public double getPaid() { + return m_dTicket; + } + + @Override + public double getChange() { + return 0; + } + + + @Override + public String getVoucher() { + return m_sVoucher; + } + + public String getCardType() { + return null; + } + + @Override + public double getTendered() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public String getCardName() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } +} diff --git a/src/main/java/com/unicenta/pos/printer/BaseAnimator.java b/src/main/java/com/unicenta/pos/printer/BaseAnimator.java new file mode 100644 index 0000000..cfd4d3f --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/BaseAnimator.java @@ -0,0 +1,83 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer; + +/** + * + * @author adrianromero + */ +public abstract class BaseAnimator implements DisplayAnimator { + + /** + * + */ + protected String baseLine1; + + /** + * + */ + protected String baseLine2; + + /** + * + */ + protected String currentLine1; + + /** + * + */ + protected String currentLine2; + + /** + * + */ + public BaseAnimator() { + baseLine1 = null; + baseLine2 = null; + } + + /** + * + * @param line1 + * @param line2 + */ + public BaseAnimator(String line1, String line2) { + baseLine1 = line1; + baseLine2 = line2; + } + + /** + * + * @return + */ + @Override + public String getLine1() { + return currentLine1; + } + + /** + * + * @return + */ + @Override + public String getLine2() { + return currentLine2; + } +} diff --git a/src/main/java/com/unicenta/pos/printer/BlinkAnimator.java b/src/main/java/com/unicenta/pos/printer/BlinkAnimator.java new file mode 100644 index 0000000..5a8faf4 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/BlinkAnimator.java @@ -0,0 +1,54 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + + +package com.unicenta.pos.printer; + +/** + * + * @author adrianromero + */ +public class BlinkAnimator extends BaseAnimator { + + /** + * + * @param line1 + * @param line2 + */ + public BlinkAnimator(String line1, String line2) { + baseLine1 = DeviceTicket.alignLeft(line1, 20); + baseLine2 = DeviceTicket.alignLeft(line2, 20); + } + + /** + * + * @param i + */ + @Override + public void setTiming(int i) { + + if ((i % 10) < 5) { + currentLine1 = ""; + currentLine2 = ""; + } else { + currentLine1 = baseLine1; + currentLine2 = baseLine2; + } + } +} diff --git a/src/main/java/com/unicenta/pos/printer/CurtainAnimator.java b/src/main/java/com/unicenta/pos/printer/CurtainAnimator.java new file mode 100644 index 0000000..59789bc --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/CurtainAnimator.java @@ -0,0 +1,56 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + + +package com.unicenta.pos.printer; + +/** + * + * @author adrianromero + */ +public class CurtainAnimator extends BaseAnimator { + + /** + * + * @param line1 + * @param line2 + */ + public CurtainAnimator(String line1, String line2) { + baseLine1 = DeviceTicket.alignLeft(line1, 20); + baseLine2 = DeviceTicket.alignLeft(line2, 20); + } + + /** + * + * @param i + */ + @Override + public void setTiming(int i) { + + int j = i / 2; + + if (j < 10) { + currentLine1 = DeviceTicket.alignCenter(baseLine1.substring(10 - j, 10 + j), 20); + currentLine2 = DeviceTicket.alignCenter(baseLine2.substring(10 - j, 10 + j), 20); + } else { + currentLine1 = baseLine1; + currentLine2 = baseLine2; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/printer/DeviceDisplay.java b/src/main/java/com/unicenta/pos/printer/DeviceDisplay.java new file mode 100644 index 0000000..099a1bc --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/DeviceDisplay.java @@ -0,0 +1,71 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer; + +import javax.swing.JComponent; + +/** + * + * @author JG uniCenta + */ +public interface DeviceDisplay { + + // INTERFAZ DESCRIPCION + + /** + * + * @return + */ + public String getDisplayName(); + + /** + * + * @return + */ + public String getDisplayDescription(); + + /** + * + * @return + */ + public JComponent getDisplayComponent(); + + // INTERFAZ VISOR + + /** + * + * @param animation + * @param sLine1 + * @param sLine2 + */ + public void writeVisor(int animation, String sLine1, String sLine2); + + /** + * + * @param sLine1 + * @param sLine2 + */ + public void writeVisor(String sLine1, String sLine2); + + /** + * + */ + public void clearVisor(); +} diff --git a/src/main/java/com/unicenta/pos/printer/DeviceDisplayBase.java b/src/main/java/com/unicenta/pos/printer/DeviceDisplayBase.java new file mode 100644 index 0000000..e66d059 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/DeviceDisplayBase.java @@ -0,0 +1,146 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * + * @author adrianromero + */ +public class DeviceDisplayBase { + + /** + * + */ + public static final int ANIMATION_NULL = 0; + + /** + * + */ + public static final int ANIMATION_FLYER = 1; + + /** + * + */ + public static final int ANIMATION_SCROLL = 2; + + /** + * + */ + public static final int ANIMATION_BLINK = 3; + + /** + * + */ + public static final int ANIMATION_CURTAIN = 4; + + private DeviceDisplayImpl impl; + private DisplayAnimator anim; + private javax.swing.Timer m_tTimeTimer; + private int counter = 0; + + /** Creates a new instance of DeviceDisplayBase + * @param impl */ + public DeviceDisplayBase(DeviceDisplayImpl impl) { + this.impl = impl; + anim = new NullAnimator("", ""); + m_tTimeTimer = new javax.swing.Timer(50, new PrintTimeAction()); + } + + /** + * + * @param animation + * @param sLine1 + * @param sLine2 + */ + public void writeVisor(int animation, String sLine1, String sLine2) { + + m_tTimeTimer.stop(); + switch (animation) { + case ANIMATION_FLYER: + anim = new FlyerAnimator(sLine1, sLine2); + break; + case ANIMATION_SCROLL: + anim = new ScrollAnimator(sLine1, sLine2); + break; + case ANIMATION_BLINK: + anim = new BlinkAnimator(sLine1, sLine2); + break; + case ANIMATION_CURTAIN: + anim = new CurtainAnimator(sLine1, sLine2); + break; + default: // ANIMATION_NULL + anim = new NullAnimator(sLine1, sLine2); + break; + } + + counter = 0; + anim.setTiming(counter); + impl.repaintLines(); + + if (animation != ANIMATION_NULL) { + counter = 0; + m_tTimeTimer.start(); + } + } + + /** + * + * @param sLine1 + * @param sLine2 + */ + public void writeVisor(String sLine1, String sLine2) { + writeVisor(ANIMATION_NULL, sLine1, sLine2); + } + + /** + * + */ + public void clearVisor() { + writeVisor(ANIMATION_NULL, "", ""); + } + + /** + * + * @return + */ + public String getLine1() { + return anim.getLine1(); + } + + /** + * + * @return + */ + public String getLine2() { + return anim.getLine2(); + } + + private class PrintTimeAction implements ActionListener { + @Override + public void actionPerformed(ActionEvent evt) { + counter ++; + anim.setTiming(counter); + impl.repaintLines(); + } + } +} diff --git a/src/main/java/com/unicenta/pos/printer/DeviceDisplayImpl.java b/src/main/java/com/unicenta/pos/printer/DeviceDisplayImpl.java new file mode 100644 index 0000000..a6db684 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/DeviceDisplayImpl.java @@ -0,0 +1,32 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer; + +/** + * + * @author JG uniCenta + */ +public interface DeviceDisplayImpl { + + /** + * + */ + public void repaintLines(); +} diff --git a/src/main/java/com/unicenta/pos/printer/DeviceDisplayNull.java b/src/main/java/com/unicenta/pos/printer/DeviceDisplayNull.java new file mode 100644 index 0000000..0712bf3 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/DeviceDisplayNull.java @@ -0,0 +1,97 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer; + +import com.unicenta.pos.forms.AppLocal; + +/** + * + * @author JG uniCenta + */ +public class DeviceDisplayNull implements DeviceDisplay { + + private String m_sName; + private String m_sDescription; + + /** Creates a new instance of DeviceDisplayNull */ + public DeviceDisplayNull() { + this(null); + } + + /** Creates a new instance of DeviceDisplayNull + * @param desc */ + public DeviceDisplayNull(String desc) { + m_sName = AppLocal.getIntString("display.null"); + m_sDescription = desc; + } + + /** + * + * @return + */ + @Override + public String getDisplayName() { + return m_sName; + } + + /** + * + * @return + */ + @Override + public String getDisplayDescription() { + return m_sDescription; + } + + /** + * + * @return + */ + @Override + public javax.swing.JComponent getDisplayComponent() { + return null; + } + + /** + * + */ + @Override + public void clearVisor() { + } + + /** + * + * @param sLine1 + * @param sLine2 + */ + @Override + public void writeVisor(String sLine1, String sLine2) { + } + + /** + * + * @param animation + * @param sLine1 + * @param sLine2 + */ + @Override + public void writeVisor(int animation, String sLine1, String sLine2) { + } +} diff --git a/src/main/java/com/unicenta/pos/printer/DeviceFiscalPrinter.java b/src/main/java/com/unicenta/pos/printer/DeviceFiscalPrinter.java new file mode 100644 index 0000000..e124e6c --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/DeviceFiscalPrinter.java @@ -0,0 +1,83 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer; + +import javax.swing.JComponent; + +/** + * + * @author JG uniCenta + */ +public interface DeviceFiscalPrinter { + + /** + * + * @return + */ + public String getFiscalName(); + + /** + * + * @return + */ + public JComponent getFiscalComponent(); + + /** + * + */ + public void beginReceipt(); + + /** + * + */ + public void endReceipt(); + + /** + * + * @param sproduct + * @param dprice + * @param dunits + * @param taxinfo + */ + public void printLine(String sproduct, double dprice, double dunits, int taxinfo); + + /** + * + * @param smessage + */ + public void printMessage(String smessage); + + /** + * + * @param sPayment + * @param dpaid + */ + public void printTotal(String sPayment, double dpaid); + + /** + * + */ + public void printZReport(); + + /** + * + */ + public void printXReport(); +} diff --git a/src/main/java/com/unicenta/pos/printer/DeviceFiscalPrinterNull.java b/src/main/java/com/unicenta/pos/printer/DeviceFiscalPrinterNull.java new file mode 100644 index 0000000..22f21c1 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/DeviceFiscalPrinterNull.java @@ -0,0 +1,114 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer; + +import javax.swing.JComponent; + +/** + * + * @author JG uniCenta + */ +public class DeviceFiscalPrinterNull implements DeviceFiscalPrinter { + + /** Creates a new instance of DeviceFiscalPrinterNull */ + public DeviceFiscalPrinterNull() { + } + + /** + * + * @param desc + */ + public DeviceFiscalPrinterNull(String desc) { + } + + /** + * + * @return + */ + @Override + public String getFiscalName() { + return null; + } + + /** + * + * @return + */ + @Override + public JComponent getFiscalComponent() { + return null; + } + + /** + * + */ + @Override + public void beginReceipt() { + } + + /** + * + */ + @Override + public void endReceipt() { + } + + /** + * + * @param sproduct + * @param dprice + * @param dunits + * @param taxinfo + */ + @Override + public void printLine(String sproduct, double dprice, double dunits, int taxinfo) { + } + + /** + * + * @param smessage + */ + @Override + public void printMessage(String smessage) { + } + + /** + * + * @param sPayment + * @param dpaid + */ + @Override + public void printTotal(String sPayment, double dpaid) { + } + + /** + * + */ + @Override + public void printZReport() { + } + + /** + * + */ + @Override + public void printXReport() { + } +} diff --git a/src/main/java/com/unicenta/pos/printer/DevicePrinter.java b/src/main/java/com/unicenta/pos/printer/DevicePrinter.java new file mode 100644 index 0000000..9a73604 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/DevicePrinter.java @@ -0,0 +1,82 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer; + +import java.awt.image.BufferedImage; +import javax.swing.JComponent; + +/** + * + * @author JG uniCenta + */ +public interface DevicePrinter { + +// Font Sizes + public static final int SIZE_0 = 0; + public static final int SIZE_1 = 1; + public static final int SIZE_2 = 2; + public static final int SIZE_3 = 3; + +// Font Enhancers + public static final int STYLE_PLAIN = 0; + public static final int STYLE_BOLD = 1; + public static final int STYLE_UNDERLINE = 2; + +// Layout + public static final int ALIGN_LEFT = 0; + public static final int ALIGN_RIGHT = 1; + public static final int ALIGN_CENTER = 2; + + public static final String POSITION_BOTTOM = "bottom"; + public static final String POSITION_NONE = "none"; + +// Barcodes + public static final String BARCODE_EAN8 = "EAN8"; + public static final String BARCODE_EAN13 = "EAN13"; + public static final String BARCODE_UPCA = "UPC-A"; + public static final String BARCODE_UPCE = "UPC-E"; + public static final String BARCODE_CODE128 = "CODE128"; + public static final String BARCODE_CODE39 = "CODE39"; + + public String getPrinterName(); + public String getPrinterDescription(); + public JComponent getPrinterComponent(); + +// Initialise + public void reset(); + public void beginReceipt(); + +// Graphic renders + public void printImage(BufferedImage image); + public void printLogo(); + public void printBarCode(String type, String position, String code); + +// Do TextLine + public void beginLine(int iTextSize); + public void printText(int iStyle, String sText); + public void endLine(); + +// Close + public void endReceipt(); + +// Transact + public void openDrawer(); + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/printer/DevicePrinterNull.java b/src/main/java/com/unicenta/pos/printer/DevicePrinterNull.java new file mode 100644 index 0000000..45d0c25 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/DevicePrinterNull.java @@ -0,0 +1,149 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer; + +import com.unicenta.pos.forms.AppLocal; + +/** + * + * @author JG uniCenta + */ +public class DevicePrinterNull implements DevicePrinter { + + private String m_sName; + private String m_sDescription; + + /** Creates a new instance of DevicePrinterNull */ + public DevicePrinterNull() { + this(null); + } + + /** Creates a new instance of DevicePrinterNull + * @param desc */ + public DevicePrinterNull(String desc) { + m_sName = AppLocal.getIntString("printer.null"); + m_sDescription = desc; + } + + /** + * + * @return + */ + @Override + public String getPrinterName() { + return m_sName; + } + + /** + * + * @return + */ + @Override + public String getPrinterDescription() { + return m_sDescription; + } + + /** + * + * @return + */ + @Override + public javax.swing.JComponent getPrinterComponent() { + return null; + } + + /** + * + */ + @Override + public void reset() { + } + + /** + * + */ + @Override + public void beginReceipt() { + } + + /** + * + * @param type + * @param position + * @param code + */ + @Override + public void printBarCode(String type, String position, String code) { + } + + /** + * + * @param image + */ + @Override + public void printImage(java.awt.image.BufferedImage image) { + } + + /** + * + * @param iTextSize + */ + @Override + public void beginLine(int iTextSize) { + } + + /** + * + * @param iStyle + * @param sText + */ + @Override + public void printText(int iStyle, String sText) { + } + + /** + * + */ + @Override + public void endLine() { + } + + /** + * + */ + @Override + public void endReceipt() { + } + + /** + * + */ + @Override + public void openDrawer() { + } + + /** + * + */ + @Override + public void printLogo() { + + } +} diff --git a/src/main/java/com/unicenta/pos/printer/DeviceTicket.java b/src/main/java/com/unicenta/pos/printer/DeviceTicket.java new file mode 100644 index 0000000..9e2c27e --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/DeviceTicket.java @@ -0,0 +1,432 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +package com.unicenta.pos.printer; + +import com.unicenta.pos.forms.AppProperties; +import com.unicenta.pos.printer.escpos.*; +import com.unicenta.pos.printer.javapos.DeviceDisplayJavaPOS; +import com.unicenta.pos.printer.javapos.DeviceFiscalPrinterJavaPOS; +import com.unicenta.pos.printer.javapos.DevicePrinterJavaPOS; +import com.unicenta.pos.printer.printer.DevicePrinterPrinter; +import com.unicenta.pos.printer.screen.DeviceDisplayPanel; +import com.unicenta.pos.printer.screen.DeviceDisplayWindow; +import com.unicenta.pos.printer.screen.DevicePrinterPanel; +import com.unicenta.pos.util.StringParser; +import lombok.extern.slf4j.Slf4j; + +import java.awt.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author JG uniCenta + */ +@Slf4j +public class DeviceTicket { + + private DeviceFiscalPrinter m_deviceFiscal; + private DeviceDisplay m_devicedisplay; + private DevicePrinter m_nullprinter; + private Map<String, DevicePrinter> m_deviceprinters; + private List<DevicePrinter> m_deviceprinterslist; + + /** + * Creates a new instance of DeviceTicket + */ + public DeviceTicket() { + // Una impresora solo de pantalla. + + m_deviceFiscal = new DeviceFiscalPrinterNull(); + + m_devicedisplay = new DeviceDisplayNull(); + + m_nullprinter = new DevicePrinterNull(); + m_deviceprinters = new HashMap<>(); + m_deviceprinterslist = new ArrayList<>(); + + DevicePrinter p = new DevicePrinterPanel(); + m_deviceprinters.put("1", p); + m_deviceprinterslist.add(p); + } + + /** + * @param parent + * @param props + */ + public DeviceTicket(Component parent, AppProperties props) { + + PrinterWritterPool pws = new PrinterWritterPool(); + + // La impresora fiscal + StringParser sf = new StringParser(props.getProperty("machine.fiscalprinter")); + String sFiscalType = sf.nextToken(':'); + String sFiscalParam1 = sf.nextToken(','); + try { + if ("javapos".equals(sFiscalType)) { + m_deviceFiscal = new DeviceFiscalPrinterJavaPOS(sFiscalParam1); + } else { + m_deviceFiscal = new DeviceFiscalPrinterNull(); + } + } catch (TicketPrinterException e) { + m_deviceFiscal = new DeviceFiscalPrinterNull(e.getMessage()); + } + + StringParser sd = new StringParser(props.getProperty("machine.display")); + String sDisplayType = sd.nextToken(':'); + String sDisplayParam1 = sd.nextToken(','); + String sDisplayParam2 = sd.nextToken(','); + + if ("serial".equals(sDisplayType) + || "rxtx".equals(sDisplayType) + || "file".equals(sDisplayType)) { + sDisplayParam2 = sDisplayParam1; + sDisplayParam1 = sDisplayType; + sDisplayType = "epson"; + } + + try { + + switch (sDisplayType) { + case "screen": + m_devicedisplay = new DeviceDisplayPanel(); + break; + case "window": + m_devicedisplay = new DeviceDisplayWindow(); + break; + case "epson": + m_devicedisplay = new DeviceDisplayESCPOS( + pws.getPrinterWritter(sDisplayParam1, sDisplayParam2) + , new UnicodeTranslatorInt()); + break; + case "surepos": + m_devicedisplay = new DeviceDisplaySurePOS( + pws.getPrinterWritter(sDisplayParam1, sDisplayParam2)); + break; + case "ld200": + m_devicedisplay = new DeviceDisplayESCPOS( + pws.getPrinterWritter(sDisplayParam1, sDisplayParam2) + , new UnicodeTranslatorEur()); + break; + case "javapos": + m_devicedisplay = new DeviceDisplayJavaPOS(sDisplayParam1); + break; + default: + m_devicedisplay = new DeviceDisplayNull(); + break; + } + } catch (TicketPrinterException e) { + log.error(e.getMessage()); + m_devicedisplay = new DeviceDisplayNull(e.getMessage()); + } + + m_nullprinter = new DevicePrinterNull(); + + m_deviceprinters = new HashMap<>(); + m_deviceprinterslist = new ArrayList<>(); + + // Empezamos a iterar por las impresoras... + int iPrinterIndex = 1; + String sPrinterIndex = Integer.toString(iPrinterIndex); + String sprinter = props.getProperty("machine.printer"); + + while (sprinter != null && !"".equals(sprinter)) { + + StringParser sp = new StringParser(sprinter); + String sPrinterType = sp.nextToken(':'); + String sPrinterParam1 = sp.nextToken(','); + String sPrinterParam2 = sp.nextToken(','); + + + if ("serial".equals(sPrinterType) + || "rxtx".equals(sPrinterType) + || "file".equals(sPrinterType)) { + sPrinterParam2 = sPrinterParam1; + sPrinterParam1 = sPrinterType; + sPrinterType = "epson"; + } + + try { + + switch (sPrinterType) { + case "screen": + addPrinter(sPrinterIndex, new DevicePrinterPanel()); + break; + case "printer": + // backward compatibility + if (sPrinterParam2 == null || sPrinterParam2.equals("") + || sPrinterParam2.equals("true")) { + sPrinterParam2 = "receipt"; + } else if (sPrinterParam2.equals("false")) { + sPrinterParam2 = "standard"; + } + addPrinter(sPrinterIndex, new DevicePrinterPrinter(parent, sPrinterParam1, + Integer.parseInt(props.getProperty("paper." + sPrinterParam2 + ".x")), + Integer.parseInt(props.getProperty("paper." + sPrinterParam2 + ".y")), + Integer.parseInt(props.getProperty("paper." + sPrinterParam2 + ".width")), + Integer.parseInt(props.getProperty("paper." + sPrinterParam2 + ".height")), + props.getProperty("paper." + sPrinterParam2 + ".mediasizename") + )); + break; + case "epson": + addPrinter(sPrinterIndex, new DevicePrinterESCPOS( + pws.getPrinterWritter(sPrinterParam1, sPrinterParam2) + , new CodesEpson(), new UnicodeTranslatorInt())); + break; + case "tmu220": + addPrinter(sPrinterIndex, new DevicePrinterESCPOS( + pws.getPrinterWritter(sPrinterParam1, sPrinterParam2) + , new CodesTMU220(), new UnicodeTranslatorInt())); + break; + case "star": + addPrinter(sPrinterIndex, new DevicePrinterESCPOS( + pws.getPrinterWritter(sPrinterParam1, sPrinterParam2) + , new CodesStar(), new UnicodeTranslatorStar())); + break; + case "ithaca": + addPrinter(sPrinterIndex, new DevicePrinterESCPOS( + pws.getPrinterWritter(sPrinterParam1, sPrinterParam2) + , new CodesIthaca(), new UnicodeTranslatorInt())); + break; + case "surepos": + addPrinter(sPrinterIndex, new DevicePrinterESCPOS( + pws.getPrinterWritter(sPrinterParam1, sPrinterParam2) + , new CodesSurePOS(), new UnicodeTranslatorSurePOS())); + break; + case "plain": + addPrinter(sPrinterIndex, new DevicePrinterPlain( + pws.getPrinterWritter(sPrinterParam1, sPrinterParam2))); + break; + case "javapos": + addPrinter(sPrinterIndex, new DevicePrinterJavaPOS( + sPrinterParam1, sPrinterParam2)); + break; + } + } catch (TicketPrinterException e) { + log.error(e.getMessage()); + } + + iPrinterIndex++; + sPrinterIndex = Integer.toString(iPrinterIndex); + sprinter = props.getProperty("machine.printer." + sPrinterIndex); + } + } + + private void addPrinter(String sPrinterIndex, DevicePrinter p) { + m_deviceprinters.put(sPrinterIndex, p); + m_deviceprinterslist.add(p); + } + + private static class PrinterWritterPool { + + private final Map<String, PrinterWritter> m_apool = new HashMap<>(); + + public PrinterWritter getPrinterWritter(String con, String port) throws TicketPrinterException { + + String skey = con + "-->" + port; + PrinterWritter pw = (PrinterWritter) m_apool.get(skey); + if (pw == null) { + + switch (con) { + case "serial": + case "rxtx": + pw = new PrinterWritterRXTX(port); + m_apool.put(skey, pw); + break; + case "file": + pw = new PrinterWritterFile(port); + m_apool.put(skey, pw); + break; + default: + throw new TicketPrinterException(); + } + } + return pw; + } + } + + + /** + * @return Fiscal printer + */ + public DeviceFiscalPrinter getFiscalPrinter() { + return m_deviceFiscal; + } + + /** + * @return Device display + */ + public DeviceDisplay getDeviceDisplay() { + return m_devicedisplay; + } + + /** + * @param key + * @return Device printer + */ + public DevicePrinter getDevicePrinter(String key) { + DevicePrinter printer = m_deviceprinters.get(key); + return printer == null ? m_nullprinter : printer; + } + + /** + * @return Device printer list + */ + public List<DevicePrinter> getDevicePrinterAll() { + return m_deviceprinterslist; + } + + /** + * @param iSize + * @param cWhiteChar + * @return Spacing string length + */ + public static String getWhiteString(int iSize, char cWhiteChar) { + + char[] cFill = new char[iSize]; + for (int i = 0; i < iSize; i++) { + cFill[i] = cWhiteChar; + } + return new String(cFill); + } + + /** + * @param iSize + * @return Space sizing + */ + public static String getWhiteString(int iSize) { + + return getWhiteString(iSize, ' '); + } + + /** + * @param sLine + * @param iSize + * @return Barcode bar inter-spacing + */ + public static String alignBarCode(String sLine, int iSize) { + + if (sLine.length() > iSize) { + return sLine.substring(sLine.length() - iSize); + } else { + return getWhiteString(iSize - sLine.length(), '0') + sLine; + } + } + + /** + * @param sLine + * @param iSize + * @return Reduce spacing + */ + public static String alignLeft(String sLine, int iSize) { + + if (sLine.length() > iSize) { + return sLine.substring(0, iSize); + } else { + return sLine + getWhiteString(iSize - sLine.length()); + } + } + + /** + * @param sLine + * @param iSize + * @return Add spacing + */ + public static String alignRight(String sLine, int iSize) { + + if (sLine.length() > iSize) { + return sLine.substring(sLine.length() - iSize); + } else { + return getWhiteString(iSize - sLine.length()) + sLine; + } + } + + /** + * @param sLine + * @param iSize + * @return Adjusts Left/Right spacing + */ + public static String alignCenter(String sLine, int iSize) { + + if (sLine.length() > iSize) { + return alignRight(sLine.substring(0, (sLine.length() + iSize) / 2), iSize); + } else { + return alignRight(sLine + getWhiteString((iSize - sLine.length()) / 2), iSize); + } + } + + /** + * @param sLine + * @return Equalise Left/Right spacing + */ + public static String alignCenter(String sLine) { + return alignCenter(sLine, 42); + } + +// JG 16 May 12 public static final byte[] transNumber(String sCad) { + + /** + * @param sCad + * @return Convert number to string + */ + public static byte[] transNumber(String sCad) { + + if (sCad == null) { + return null; + } else { + byte bAux[] = new byte[sCad.length()]; + for (int i = 0; i < sCad.length(); i++) { + bAux[i] = transNumberChar(sCad.charAt(i)); + } + return bAux; + } + } + + /** + * @param sChar + * @return Convert hex to character + */ + public static byte transNumberChar(char sChar) { + switch (sChar) { + case '0': + return 0x30; + case '1': + return 0x31; + case '2': + return 0x32; + case '3': + return 0x33; + case '4': + return 0x34; + case '5': + return 0x35; + case '6': + return 0x36; + case '7': + return 0x37; + case '8': + return 0x38; + case '9': + return 0x39; + default: + return 0x30; + } + } +} diff --git a/src/main/java/com/unicenta/pos/printer/DisplayAnimator.java b/src/main/java/com/unicenta/pos/printer/DisplayAnimator.java new file mode 100644 index 0000000..2ff5fb2 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/DisplayAnimator.java @@ -0,0 +1,45 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer; + +/** + * + * @author adrianromero + */ +public interface DisplayAnimator { + + /** + * + * @param i + */ + public void setTiming(int i); + + /** + * + * @return + */ + public String getLine1(); + + /** + * + * @return + */ + public String getLine2(); +} diff --git a/src/main/java/com/unicenta/pos/printer/FlyerAnimator.java b/src/main/java/com/unicenta/pos/printer/FlyerAnimator.java new file mode 100644 index 0000000..fb9bb24 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/FlyerAnimator.java @@ -0,0 +1,54 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + + +package com.unicenta.pos.printer; + +/** + * + * @author adrianromero + */ +public class FlyerAnimator extends BaseAnimator { + + /** + * + * @param line1 + * @param line2 + */ + public FlyerAnimator(String line1, String line2) { + baseLine1 = DeviceTicket.alignLeft(line1, 20); + baseLine2 = DeviceTicket.alignLeft(line2, 20); + } + + /** + * + * @param i + */ + @Override + public void setTiming(int i) { + + if (i < 20) { + currentLine1 = DeviceTicket.alignRight(baseLine1.substring(0, i), 20); + currentLine2 = DeviceTicket.alignRight(baseLine2.substring(0, i), 20); + } else { + currentLine1 = baseLine1; + currentLine2 = baseLine2; + } + } +} diff --git a/src/main/java/com/unicenta/pos/printer/NullAnimator.java b/src/main/java/com/unicenta/pos/printer/NullAnimator.java new file mode 100644 index 0000000..b313fff --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/NullAnimator.java @@ -0,0 +1,73 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer; + +/** + * + * @author adrianromero + */ +public class NullAnimator implements DisplayAnimator { + + /** + * + */ + protected String currentLine1; + + /** + * + */ + protected String currentLine2; + + /** + * + * @param line1 + * @param line2 + */ + public NullAnimator(String line1, String line2) { + currentLine1 = DeviceTicket.alignLeft(line1, 20); + currentLine2 = DeviceTicket.alignLeft(line2, 20); + } + + /** + * + * @param i + */ + @Override + public void setTiming(int i) { + } + + /** + * + * @return + */ + @Override + public String getLine1() { + return currentLine1; + } + + /** + * + * @return + */ + @Override + public String getLine2() { + return currentLine2; + } +} diff --git a/src/main/java/com/unicenta/pos/printer/ScrollAnimator.java b/src/main/java/com/unicenta/pos/printer/ScrollAnimator.java new file mode 100644 index 0000000..1a001c8 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/ScrollAnimator.java @@ -0,0 +1,56 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer; + +/** + * + * @author adrianromero + */ +public class ScrollAnimator extends BaseAnimator { + + private int msglength; + + /** + * + * @param line1 + * @param line2 + */ + public ScrollAnimator(String line1, String line2) { + msglength = Math.max(line1.length(), line2.length()); + baseLine1 = DeviceTicket.alignLeft(line1, msglength); + baseLine2 = DeviceTicket.alignLeft(line2, msglength); + } + + /** + * + * @param i + */ + @Override + public void setTiming(int i) { + int j = (i / 2) % (msglength + 20); + if (j < 20) { + currentLine1 = DeviceTicket.alignLeft(DeviceTicket.getWhiteString(20 - j) + baseLine1, 20); + currentLine2 = DeviceTicket.alignLeft(DeviceTicket.getWhiteString(20 - j) + baseLine2, 20); + } else { + currentLine1 = DeviceTicket.alignLeft(baseLine1.substring(j - 20), 20); + currentLine2 = DeviceTicket.alignLeft(baseLine2.substring(j - 20), 20); + } + } +} diff --git a/src/main/java/com/unicenta/pos/printer/TicketParser.java b/src/main/java/com/unicenta/pos/printer/TicketParser.java new file mode 100644 index 0000000..b988be9 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/TicketParser.java @@ -0,0 +1,506 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.LocalRes; +import com.unicenta.pos.forms.DataLogicSystem; +import com.unicenta.pos.ticket.TicketInfo; +import java.applet.Applet; +import java.applet.AudioClip; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Base64; +import java.util.Calendar; +import java.util.Date; +import javax.imageio.ImageIO; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * + * @author JG uniCenta + */ +public class TicketParser extends DefaultHandler { + + private static SAXParser m_sp = null; + + private DeviceTicket m_printer; + private DataLogicSystem m_system; + + private StringBuilder text; + + private String bctype; + private String bcposition; + private int m_iTextAlign; + private int m_iTextLength; + private int m_iTextStyle; + private int size; + + private StringBuilder m_sVisorLine; + private int m_iVisorAnimation; + private String m_sVisorLine1; + private String m_sVisorLine2; + + private double m_dValue1; + private double m_dValue2; + private int attribute3; + + private int m_iOutputType; + private static final int OUTPUT_NONE = 0; + private static final int OUTPUT_DISPLAY = 1; + private static final int OUTPUT_TICKET = 2; + private static final int OUTPUT_FISCAL = 3; + private DevicePrinter m_oOutputPrinter; + private DateFormat df= new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); + private Date today; + private String cUser; + private String ticketId; + private String pickupId; + + + /** Creates a new instance of TicketParser + * @param printer + * @param system */ + public TicketParser(DeviceTicket printer, DataLogicSystem system) { + m_printer = printer; + m_system = system; + today = Calendar.getInstance().getTime(); + } + + /** + * + * @param sIn + * @param ticket + * @throws TicketPrinterException + */ + public void printTicket(String sIn, TicketInfo ticket) throws TicketPrinterException { +// cUser=ticket.getUser().getName(); + cUser=ticket.getName(); + ticketId=Integer.toString(ticket.getTicketId()); + pickupId=Integer.toString(ticket.getPickupId()); + + if (ticket.getTicketId()==0){ + ticketId="No Sale"; + } + if (ticket.getPickupId()==0){ + pickupId="No PickupId"; + } + printTicket(new StringReader(sIn)); + + + } + + /** + * + * @param sIn + * @throws TicketPrinterException + */ + public void printTicket(String sIn) throws TicketPrinterException { + printTicket(new StringReader(sIn)); + } + + /** + * + * @param in + * @throws TicketPrinterException + */ + public void printTicket(Reader in) throws TicketPrinterException { + + try { + + if (m_sp == null) { + SAXParserFactory spf = SAXParserFactory.newInstance(); + m_sp = spf.newSAXParser(); + } + m_sp.parse(new InputSource(in), this); + + } catch (ParserConfigurationException ePC) { + throw new TicketPrinterException(LocalRes.getIntString("exception.parserconfig") , ePC); + } catch (SAXException eSAX) { + throw new TicketPrinterException(LocalRes.getIntString("exception.xmlfile") , eSAX); + } catch (IOException eIO) { + throw new TicketPrinterException(LocalRes.getIntString("exception.iofile") , eIO); + } + } + + @Override + public void startDocument() throws SAXException { + // inicalizo las variables pertinentes + text = null; + bctype = null; + bcposition = null; + m_sVisorLine = null; + m_iVisorAnimation = DeviceDisplayBase.ANIMATION_NULL; + m_sVisorLine1 = null; + m_sVisorLine2 = null; + m_iOutputType = OUTPUT_NONE; + m_oOutputPrinter = null; + } + + @Override + public void endDocument() throws SAXException { + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException{ + String openDate = df.format(today); + Date dNow = new Date(); + + switch (m_iOutputType) { + case OUTPUT_NONE: + switch (qName) { + case "opendrawer": + m_printer.getDevicePrinter(readString(attributes.getValue("printer"), "1")).openDrawer(); + // Cashdrawer has been activated record the data in the table + try { + m_system.execDrawerOpened( + //new Object[] {df.format(dNow),cUser,ticketId}); + new Object[] {cUser,ticketId}); + } catch (BasicException ex) {} + break; + case "play": + text = new StringBuilder(); + break; + case "ticket": + m_iOutputType = OUTPUT_TICKET; + m_oOutputPrinter = m_printer.getDevicePrinter(readString(attributes.getValue("printer"), "1")); + m_oOutputPrinter.beginReceipt(); + break; + case "display": + m_iOutputType = OUTPUT_DISPLAY; + String animation = attributes.getValue("animation"); + if ("scroll".equals(animation)) { + m_iVisorAnimation = DeviceDisplayBase.ANIMATION_SCROLL; + } else if ("flyer".equals(animation)) { + m_iVisorAnimation = DeviceDisplayBase.ANIMATION_FLYER; + } else if ("blink".equals(animation)) { + m_iVisorAnimation = DeviceDisplayBase.ANIMATION_BLINK; + } else if ("curtain".equals(animation)) { + m_iVisorAnimation = DeviceDisplayBase.ANIMATION_CURTAIN; + } else { // "none" + m_iVisorAnimation = DeviceDisplayBase.ANIMATION_NULL; + } + m_sVisorLine1 = null; + m_sVisorLine2 = null; + m_oOutputPrinter = null; + break; + case "fiscalreceipt": + m_iOutputType = OUTPUT_FISCAL; + m_printer.getFiscalPrinter().beginReceipt(); + break; + case "fiscalzreport": + m_printer.getFiscalPrinter().printZReport(); + break; + case "fiscalxreport": + m_printer.getFiscalPrinter().printXReport(); + break; + } + break; + case OUTPUT_TICKET: + if (null != qName)switch (qName) { + case "logo": + text = new StringBuilder(); + break; + case "image": + text = new StringBuilder(); + break; + case "barcode": + text = new StringBuilder(); + bctype = attributes.getValue("type"); + bcposition = attributes.getValue("position"); + break; + case "line": + m_oOutputPrinter.beginLine(parseInt(attributes.getValue("size"), DevicePrinter.SIZE_0)); + break; + case "text": + text = new StringBuilder(); + m_iTextStyle = ("true".equals(attributes.getValue("bold")) + ? DevicePrinter.STYLE_BOLD : DevicePrinter.STYLE_PLAIN) + | ("true".equals(attributes.getValue("underline")) + ? DevicePrinter.STYLE_UNDERLINE : DevicePrinter.STYLE_PLAIN); + String sAlign = attributes.getValue("align"); + if (null == sAlign) { + m_iTextAlign = DevicePrinter.ALIGN_LEFT; + } else switch (sAlign) { + case "right": + m_iTextAlign = DevicePrinter.ALIGN_RIGHT; + break; + case "center": + m_iTextAlign = DevicePrinter.ALIGN_CENTER; + break; + default: + m_iTextAlign = DevicePrinter.ALIGN_LEFT; + break; + } + m_iTextLength = parseInt(attributes.getValue("length"), 0); + break; + default: + break; + } + break; + case OUTPUT_DISPLAY: + if (null != qName) switch (qName) { + case "line": + // line 1 or 2 of the display + m_sVisorLine = new StringBuilder(); + break; + case "line1": + // linea 1 del visor + m_sVisorLine = new StringBuilder(); + break; + case "line2": + // linea 2 del visor + m_sVisorLine = new StringBuilder(); + break; + case "text": + text = new StringBuilder(); + String sAlign = attributes.getValue("align"); + if (null == sAlign) { + m_iTextAlign = DevicePrinter.ALIGN_LEFT; + } else switch (sAlign) { + case "right": + m_iTextAlign = DevicePrinter.ALIGN_RIGHT; + break; + case "center": + m_iTextAlign = DevicePrinter.ALIGN_CENTER; + break; + default: + m_iTextAlign = DevicePrinter.ALIGN_LEFT; + break; + } + m_iTextLength = parseInt(attributes.getValue("length")); + break; + default: + break; + } + break; + case OUTPUT_FISCAL: + if (null != qName) + switch (qName) { + case "line": + text = new StringBuilder(); + m_dValue1 = parseDouble(attributes.getValue("price")); + m_dValue2 = parseDouble(attributes.getValue("units"), 1.0); + attribute3 = parseInt(attributes.getValue("tax")); + break; + case "message": + text = new StringBuilder(); + break; + case "total": + text = new StringBuilder(); + m_dValue1 = parseDouble(attributes.getValue("paid")); + break; + default: + break; + } + break; + } + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + + switch (m_iOutputType) { + case OUTPUT_NONE: + if ("play".equals(qName)) { + try { + AudioClip oAudio = Applet.newAudioClip(getClass().getClassLoader().getResource(text.toString())); + oAudio.play(); + } catch (Exception fnfe) { + //throw new ResourceNotFoundException( fnfe.getMessage() ); + } + text = null; + } + break; + +// Added 23.05.13 used by star TSP700 to print stored logo image JDL + case OUTPUT_TICKET: + if ("logo".equals(qName)){ + m_oOutputPrinter.printLogo(); + // } + }else if ("image".equals(qName)){ + try { +// BufferedImage image = ImageIO.read(getClass().getClassLoader().getResourceAsStream(text.toString())); + BufferedImage image = m_system.getResourceAsImage(text.toString()); + + if (image == null) { + image = decodeToImage(text.toString()); + } + if (image != null) { + m_oOutputPrinter.printImage(image); + } + + } catch (Exception fnfe) { + //throw new ResourceNotFoundException( fnfe.getMessage() ); + } + text = null; + } else if ("barcode".equals(qName)) { + m_oOutputPrinter.printBarCode(bctype, bcposition, text.toString()); + text = null; + } else if ("text".equals(qName)) { + if (m_iTextLength > 0) { + switch(m_iTextAlign) { + case DevicePrinter.ALIGN_RIGHT: + m_oOutputPrinter.printText(m_iTextStyle, DeviceTicket.alignRight(text.toString(), m_iTextLength)); + break; + case DevicePrinter.ALIGN_CENTER: + m_oOutputPrinter.printText(m_iTextStyle, DeviceTicket.alignCenter(text.toString(), m_iTextLength)); + break; + default: // DevicePrinter.ALIGN_LEFT + m_oOutputPrinter.printText(m_iTextStyle, DeviceTicket.alignLeft(text.toString(), m_iTextLength)); + break; + } + } else { + m_oOutputPrinter.printText(m_iTextStyle, text.toString()); + } + text = null; + } else if ("line".equals(qName)) { + m_oOutputPrinter.endLine(); + } else if ("ticket".equals(qName)) { + m_oOutputPrinter.endReceipt(); + m_iOutputType = OUTPUT_NONE; + m_oOutputPrinter = null; + } + break; + case OUTPUT_DISPLAY: + if ("line".equals(qName)) { // line 1 or 2 of the display + if (m_sVisorLine1 == null) { + m_sVisorLine1 = m_sVisorLine.toString(); + } else { + m_sVisorLine2 = m_sVisorLine.toString(); + } + m_sVisorLine = null; + } else if ("line1".equals(qName)) { // linea 1 del visor + m_sVisorLine1 = m_sVisorLine.toString(); + m_sVisorLine = null; + } else if ("line2".equals(qName)) { // linea 2 del visor + m_sVisorLine2 = m_sVisorLine.toString(); + m_sVisorLine = null; + } else if ("text".equals(qName)) { + if (m_iTextLength > 0) { + switch(m_iTextAlign) { + case DevicePrinter.ALIGN_RIGHT: + m_sVisorLine.append(DeviceTicket.alignRight(text.toString(), m_iTextLength)); + break; + case DevicePrinter.ALIGN_CENTER: + m_sVisorLine.append(DeviceTicket.alignCenter(text.toString(), m_iTextLength)); + break; + default: // DevicePrinter.ALIGN_LEFT + m_sVisorLine.append(DeviceTicket.alignLeft(text.toString(), m_iTextLength)); + break; + } + } else { + m_sVisorLine.append(text); + } + text = null; + } else if ("display".equals(qName)) { + m_printer.getDeviceDisplay().writeVisor(m_iVisorAnimation, m_sVisorLine1, m_sVisorLine2); + m_iVisorAnimation = DeviceDisplayBase.ANIMATION_NULL; + m_sVisorLine1 = null; + m_sVisorLine2 = null; + m_iOutputType = OUTPUT_NONE; + m_oOutputPrinter = null; + } + break; + case OUTPUT_FISCAL: + if ("fiscalreceipt".equals(qName)) { + m_printer.getFiscalPrinter().endReceipt(); + m_iOutputType = OUTPUT_NONE; + } else if ("line".equals(qName)) { + m_printer.getFiscalPrinter().printLine(text.toString(), m_dValue1, m_dValue2, attribute3); + text = null; + } else if ("message".equals(qName)) { + m_printer.getFiscalPrinter().printMessage(text.toString()); + text = null; + } else if ("total".equals(qName)) { + m_printer.getFiscalPrinter().printTotal(text.toString(), m_dValue1); + text = null; + } + break; + } + } + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + if (text != null) { + text.append(ch, start, length); + } + } + + private int parseInt(String sValue, int iDefault) { + try { + return Integer.parseInt(sValue); + } catch (NumberFormatException eNF) { + return iDefault; + } + } + + private int parseInt(String sValue) { + return parseInt(sValue, 0); + } + + private double parseDouble(String sValue, double ddefault) { + try { + return Double.parseDouble(sValue); + } catch (NumberFormatException eNF) { + return ddefault; + } + } + + private double parseDouble(String sValue) { + return parseDouble(sValue, 0.0); + } + + private String readString(String sValue, String sDefault) { + if (sValue == null || sValue.equals("")) { + return sDefault; + } else { + return sValue; + } + } + private static BufferedImage decodeToImage(String imageString) { + + BufferedImage image = null; + byte[] imageByte; + try { + Base64.Decoder decoder = Base64.getMimeDecoder(); + imageByte = decoder.decode(imageString); + ByteArrayInputStream bis = new ByteArrayInputStream(imageByte); + image = ImageIO.read(bis); + bis.close(); + } catch (Exception e) { + e.printStackTrace(); + } + return image; + + + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/printer/TicketPrinterException.java b/src/main/java/com/unicenta/pos/printer/TicketPrinterException.java new file mode 100644 index 0000000..7e496cf --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/TicketPrinterException.java @@ -0,0 +1,52 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer; + +/** + * + * @author JG uniCenta + */ +public class TicketPrinterException extends java.lang.Exception { + + /** + * + */ + public TicketPrinterException() { + } + + /** + * + * @param msg + */ + public TicketPrinterException(String msg) { + super(msg); + } + + /** + * + * @param msg + * @param cause + */ + public TicketPrinterException(String msg, Throwable cause) { + super(msg, cause); + } +} + + diff --git a/src/main/java/com/unicenta/pos/printer/escpos/Codes.java b/src/main/java/com/unicenta/pos/printer/escpos/Codes.java new file mode 100644 index 0000000..f395875 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/escpos/Codes.java @@ -0,0 +1,258 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.escpos; + +import com.unicenta.pos.printer.DevicePrinter; +import com.unicenta.pos.printer.DeviceTicket; +import java.awt.image.BufferedImage; + +/** + * + * @author JG uniCenta + */ +public abstract class Codes { + + /** Creates a new instance of Codes */ + public Codes() { + } + + /** + * + * @return + */ + public abstract byte[] getInitSequence(); + + /** + * + * @return + */ + public abstract byte[] getSize0(); + + /** + * + * @return + */ + public abstract byte[] getSize1(); + + /** + * + * @return + */ + public abstract byte[] getSize2(); + + /** + * + * @return + */ + public abstract byte[] getSize3(); + + /** + * + * @return + */ + public abstract byte[] getBoldSet(); + + /** + * + * @return + */ + public abstract byte[] getBoldReset(); + + /** + * + * @return + */ + public abstract byte[] getUnderlineSet(); + + /** + * + * @return + */ + public abstract byte[] getUnderlineReset(); + + /** + * + * @return + */ + public abstract byte[] getOpenDrawer(); + + /** + * + * @return + */ + public abstract byte[] getCutReceipt(); + + /** + * + * @return + */ + public abstract byte[] getNewLine(); + + /** + * + * @return + */ + public abstract byte[] getImageHeader(); + + /** + * + * @return + */ + public abstract int getImageWidth(); + + /** + * + * @return + */ + public abstract byte[] getImageLogo(); + + /** + * + * @param out + * @param type + * @param position + * @param code + */ + public void printBarcode(PrinterWritter out, String type, String position, String code) { + + if (DevicePrinter.BARCODE_EAN13.equals(type)) { + + out.write(getNewLine()); + + out.write(ESCPOS.BAR_HEIGHT); + if (DevicePrinter.POSITION_NONE.equals(position)) { + out.write(ESCPOS.BAR_POSITIONNONE); + } else { + out.write(ESCPOS.BAR_POSITIONDOWN); + } + out.write(ESCPOS.BAR_HRIFONT1); + out.write(ESCPOS.BAR_CODE02); + out.write(DeviceTicket.transNumber(DeviceTicket.alignBarCode(code,13).substring(0,12))); + out.write(new byte[] { 0x00 }); + + out.write(getNewLine()); + } + } + + /** + * + * @param image + * @return + */ + public byte[] transImage(BufferedImage image) { + + CenteredImage centeredimage = new CenteredImage(image, getImageWidth()); + + // Imprimo los par\u00e1metros en cu\u00e1druple + int iWidth = (centeredimage.getWidth() + 7) / 8; // n\u00famero de bytes + int iHeight = centeredimage.getHeight(); + + // Array de datos + byte[] bData = new byte[getImageHeader().length + 4 + iWidth * iHeight]; + + // Comando de impresion de imagen + System.arraycopy(getImageHeader(), 0, bData, 0, getImageHeader().length); + + int index = getImageHeader().length; + + // Dimension de la imagen + // JG note: nested ++'s not good construct need change later + bData[index ++] = (byte) (iWidth % 256); + bData[index ++] = (byte) (iWidth / 256); + bData[index ++] = (byte) (iHeight % 256); + bData[index ++] = (byte) (iHeight / 256); + + // Raw data + // JG note: nested ++'s and var assignments not good construct need change later + int iRGB; + int p; + for (int i = 0; i < centeredimage.getHeight(); i++) { + for (int j = 0; j < centeredimage.getWidth(); j = j + 8) { + p = 0x00; + for (int d = 0; d < 8; d ++) { + p = p << 1; + if (centeredimage.isBlack(j + d, i)) { + p = p | 0x01; + } + } + + bData[index ++] = (byte) p; + } + } + return bData; + } + + /** + * + */ + protected class CenteredImage { + + private BufferedImage image; + private int width; + + /** + * + * @param image + * @param width + */ + public CenteredImage(BufferedImage image, int width) { + this.image = image; + this.width = width; + } + + /** + * + * @return + */ + public int getHeight() { + return image.getHeight(); + } + + /** + * + * @return + */ + public int getWidth() { + return width; + } + + /** + * + * @param x + * @param y + * @return + */ + public boolean isBlack(int x, int y) { + + int centeredx = x + (image.getWidth() - width) / 2; + if (centeredx < 0 || centeredx >= image.getWidth() || y < 0 || y >= image.getHeight()) { + return false; + } else { + int rgb = image.getRGB(centeredx, y); + + int gray = (int)(0.30 * ((rgb >> 16) & 0xff) + + 0.59 * ((rgb >> 8) & 0xff) + + 0.11 * (rgb & 0xff)); + + return gray < 128; + } + } + } +} diff --git a/src/main/java/com/unicenta/pos/printer/escpos/CodesEpson.java b/src/main/java/com/unicenta/pos/printer/escpos/CodesEpson.java new file mode 100644 index 0000000..70eb05e --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/escpos/CodesEpson.java @@ -0,0 +1,155 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.escpos; + +/** + * + * @author JG uniCenta + */ +public class CodesEpson extends Codes { + + private static final byte[] INITSEQUENCE = {}; + + private static final byte[] CHAR_SIZE_0 = {0x1D, 0x21, 0x00}; + private static final byte[] CHAR_SIZE_1 = {0x1D, 0x21, 0x01}; + private static final byte[] CHAR_SIZE_2 = {0x1D, 0x21, 0x30}; + private static final byte[] CHAR_SIZE_3 = {0x1D, 0x21, 0x31}; + + public static final byte[] BOLD_SET = {0x1B, 0x45, 0x01}; + public static final byte[] BOLD_RESET = {0x1B, 0x45, 0x00}; + + public static final byte[] UNDERLINE_SET = {0x1B, 0x2D, 0x01}; + public static final byte[] UNDERLINE_RESET = {0x1B, 0x2D, 0x00}; + + private static final byte[] OPEN_DRAWER = {0x1B, 0x70, 0x00, 0x32, -0x06}; + private static final byte[] PARTIAL_CUT_1 = {0x1B, 0x69}; + private static final byte[] IMAGE_HEADER = {0x1D, 0x76, 0x30, 0x03}; + private static final byte[] NEW_LINE = {0x0D, 0x0A}; // Print and carriage return + private static final byte[] IMAGE_LOGO = {0x1B, 0x1C, 0x70, 0x01, 0x00}; + + /** Creates a new instance of CodesEpson */ + public CodesEpson() { + } + + /** + * + * @return + */ + @Override + public byte[] getInitSequence() { return INITSEQUENCE; } + + /** + * + * @return + */ + @Override + public byte[] getSize0() { return CHAR_SIZE_0; } + + /** + * + * @return + */ + @Override + public byte[] getSize1() { return CHAR_SIZE_1; } + + /** + * + * @return + */ + @Override + public byte[] getSize2() { return CHAR_SIZE_2; } + + /** + * + * @return + */ + @Override + public byte[] getSize3() { return CHAR_SIZE_3; } + + /** + * + * @return + */ + @Override + public byte[] getBoldSet() { return BOLD_SET; } + + /** + * + * @return + */ + @Override + public byte[] getBoldReset() { return BOLD_RESET; } + + /** + * + * @return + */ + @Override + public byte[] getUnderlineSet() { return UNDERLINE_SET; } + + /** + * + * @return + */ + @Override + public byte[] getUnderlineReset() { return UNDERLINE_RESET; } + + /** + * + * @return + */ + @Override + public byte[] getOpenDrawer() { return OPEN_DRAWER; } + + /** + * + * @return + */ + @Override + public byte[] getCutReceipt() { return PARTIAL_CUT_1; } + + /** + * + * @return + */ + @Override + public byte[] getNewLine() { return NEW_LINE; } + + /** + * + * @return + */ + @Override + public byte[] getImageHeader() { return IMAGE_HEADER; } + + /** + * + * @return + */ + @Override + public int getImageWidth() { return 256; } + + /** + * + * @return + */ + @Override + public byte[] getImageLogo(){ return IMAGE_LOGO; } +} diff --git a/src/main/java/com/unicenta/pos/printer/escpos/CodesIthaca.java b/src/main/java/com/unicenta/pos/printer/escpos/CodesIthaca.java new file mode 100644 index 0000000..def339d --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/escpos/CodesIthaca.java @@ -0,0 +1,154 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.escpos; + +/** + * + * @author JG uniCenta + */ +public class CodesIthaca extends Codes { + + private static final byte[] INITSEQUENCE = {}; + + private static final byte[] CHAR_SIZE_0 = {0x1D, 0x21, 0x00}; + private static final byte[] CHAR_SIZE_1 = {0x1D, 0x21, 0x01}; + private static final byte[] CHAR_SIZE_2 = {0x1D, 0x21, 0x30}; + private static final byte[] CHAR_SIZE_3 = {0x1D, 0x21, 0x31}; + + public static final byte[] BOLD_SET = {0x1B, 0x45, 0x01}; + public static final byte[] BOLD_RESET = {0x1B, 0x45, 0x00}; + public static final byte[] UNDERLINE_SET = {0x1B, 0x2D, 0x01}; + public static final byte[] UNDERLINE_RESET = {0x1B, 0x2D, 0x00}; + + private static final byte[] OPEN_DRAWER = {0x1B, 0x78, 0x01}; + private static final byte[] PARTIAL_CUT = {0x1B, 0x50, 0x00}; + private static final byte[] IMAGE_HEADER = {0x1D, 0x76, 0x30, 0x03}; + private static final byte[] NEW_LINE = {0x0D, 0x0A}; // Print and carriage return + + private static final byte[] IMAGE_LOGO = {0x1B, 0x1C, 0x70, 0x01, 0x00}; + /** Creates a new instance of CodesIthaca */ + public CodesIthaca() { + } + + /** + * + * @return + */ + @Override + public byte[] getInitSequence() { return INITSEQUENCE; } + + /** + * + * @return + */ + @Override + public byte[] getSize0() { return CHAR_SIZE_0; } + + /** + * + * @return + */ + @Override + public byte[] getSize1() { return CHAR_SIZE_1; } + + /** + * + * @return + */ + @Override + public byte[] getSize2() { return CHAR_SIZE_2; } + + /** + * + * @return + */ + @Override + public byte[] getSize3() { return CHAR_SIZE_3; } + + /** + * + * @return + */ + @Override + public byte[] getBoldSet() { return BOLD_SET; } + + /** + * + * @return + */ + @Override + public byte[] getBoldReset() { return BOLD_RESET; } + + /** + * + * @return + */ + @Override + public byte[] getUnderlineSet() { return UNDERLINE_SET; } + + /** + * + * @return + */ + @Override + public byte[] getUnderlineReset() { return UNDERLINE_RESET; } + + /** + * + * @return + */ + @Override + public byte[] getOpenDrawer() { return OPEN_DRAWER; } + + /** + * + * @return + */ + @Override + public byte[] getCutReceipt() { return PARTIAL_CUT; } + + /** + * + * @return + */ + @Override + public byte[] getNewLine() { return NEW_LINE; } + + /** + * + * @return + */ + @Override + public byte[] getImageHeader() { return IMAGE_HEADER; } + + /** + * + * @return + */ + @Override + public int getImageWidth() { return 256; } + + /** + * + * @return + */ + @Override + public byte[] getImageLogo(){ return IMAGE_LOGO; } +} diff --git a/src/main/java/com/unicenta/pos/printer/escpos/CodesStar.java b/src/main/java/com/unicenta/pos/printer/escpos/CodesStar.java new file mode 100644 index 0000000..0094df0 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/escpos/CodesStar.java @@ -0,0 +1,258 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.escpos; + +import com.unicenta.pos.printer.DevicePrinter; +import com.unicenta.pos.printer.DeviceTicket; +import java.awt.image.BufferedImage; + +/** + * + * @author JG uniCenta + */ +public class CodesStar extends Codes { + + // set line interspacing to 4mm + + /** + * + */ + public static final byte[] INITSEQUENCE = {0x1B, 0x7A, 0x01}; + + private static final byte[] CHAR_SIZE_0 = {0x1B, 0x69, 0x00, 0x00}; + private static final byte[] CHAR_SIZE_1 = {0x1B, 0x69, 0x01, 0x00}; + private static final byte[] CHAR_SIZE_2 = {0x1B, 0x69, 0x00, 0x01}; + private static final byte[] CHAR_SIZE_3 = {0x1B, 0x69, 0x01, 0x01}; + + private static final byte[] BOLD_SET = {0x1B, 0x45}; + private static final byte[] BOLD_RESET = {0x1B, 0x46}; + + private static final byte[] UNDERLINE_SET = {0x1B, 0x2D, 0x01}; + private static final byte[] UNDERLINE_RESET = {0x1B, 0x2D, 0x00}; + + private static final byte[] OPEN_DRAWER = {0x1C}; + private static final byte[] PARTIAL_CUT = {0x1B, 0x64, 0x30}; + private static final byte[] IMAGE_BEGIN = {0x1B, 0x30}; + private static final byte[] IMAGE_END = {0x1B, 0x7A, 0x01}; + private static final byte[] IMAGE_HEADER = {0x1B, 0x4B}; + private static final byte[] IMAGE_LOGO = {0x1B, 0x1C, 0x70,0x01, 0x00}; + private static final byte[] NEW_LINE = {0x0D, 0x0A}; // Print and carriage return + + + /** Creates a new instance of CodesStar */ + public CodesStar() { + } + + /** + * + * @return + */ + @Override + public byte[] getInitSequence() { return INITSEQUENCE; } + + /** + * + * @return + */ + @Override + public byte[] getSize0() { return CHAR_SIZE_0; } + + /** + * + * @return + */ + @Override + public byte[] getSize1() { return CHAR_SIZE_1; } + + /** + * + * @return + */ + @Override + public byte[] getSize2() { return CHAR_SIZE_2; } + + /** + * + * @return + */ + @Override + public byte[] getSize3() { return CHAR_SIZE_3; } + + /** + * + * @return + */ + @Override + public byte[] getBoldSet() { return BOLD_SET; } + + /** + * + * @return + */ + @Override + public byte[] getBoldReset() { return BOLD_RESET; } + + /** + * + * @return + */ + @Override + public byte[] getUnderlineSet() { return UNDERLINE_SET; } + + /** + * + * @return + */ + @Override + public byte[] getUnderlineReset() { return UNDERLINE_RESET; } + + /** + * + * @return + */ + @Override + public byte[] getOpenDrawer() { return OPEN_DRAWER; } + + /** + * + * @return + */ + @Override + public byte[] getCutReceipt() { return PARTIAL_CUT; } + + /** + * + * @return + */ + @Override + public byte[] getNewLine() { return NEW_LINE; } + + /** + * + * @return + */ + @Override + public byte[] getImageHeader() { return IMAGE_HEADER; } + + /** + * + * @return + */ + @Override + public int getImageWidth() { return 192; } + + /** + * + * @return + */ + @Override + public byte[] getImageLogo(){ return IMAGE_LOGO; } + + /** + * + * @param image + * @return + */ + @Override + public byte[] transImage(BufferedImage image) { + + CenteredImage centeredimage = new CenteredImage(image, getImageWidth()); + + int iWidth = centeredimage.getWidth(); + int iHeight = (centeredimage.getHeight() + 7) / 8; // + + // Array de datos + byte[] bData = new byte[ + IMAGE_BEGIN.length + + (getImageHeader().length + 2 + iWidth + getNewLine().length) * iHeight + + IMAGE_END.length]; + + // Comando de impresion de imagen + + int index = 0; + + System.arraycopy(IMAGE_BEGIN, 0, bData, index, IMAGE_BEGIN.length); + index += IMAGE_BEGIN.length; + + // Raw data + int p; + for (int i = 0; i < centeredimage.getHeight(); i += 8) { + System.arraycopy(getImageHeader(), 0, bData, index, getImageHeader().length); + index += getImageHeader().length; + + // Line Dimension + // JG note: nested ++'s not good construct need change later + bData[index ++] = (byte) (iWidth % 256); + bData[index ++] = (byte) (iWidth / 256); + + for (int j = 0; j < centeredimage.getWidth(); j++) { + p = 0x00; + for (int d = 0; d < 8; d ++) { + p = p << 1; + if (centeredimage.isBlack(j, i + d)) { + p = p | 0x01; + } + } + + bData[index ++] = (byte) p; + } + System.arraycopy(getNewLine(), 0, bData, index, getNewLine().length); + index += getNewLine().length; + + } + + System.arraycopy(IMAGE_END, 0, bData, index, IMAGE_END.length); + index += IMAGE_END.length; + + return bData; + } + + /** + * + * @param out + * @param type + * @param position + * @param code + */ + @Override + public void printBarcode(PrinterWritter out, String type, String position, String code) { + + if (DevicePrinter.BARCODE_EAN13.equals(type)) { + + // out.write(getNewLine()); + + out.write(new byte[] {0x1B, 0x1D, 0x61, 0x01}); // Align center + + out.write(new byte[] {0x1B, 0x62, 0x03}); + if (DevicePrinter.POSITION_NONE.equals(position)) { + out.write(new byte[]{0x01}); + } else { + out.write(new byte[]{0x02}); + } + out.write(new byte[]{0x02}); // dots + out.write(new byte[]{0x50}); // height + out.write(DeviceTicket.transNumber(DeviceTicket.alignBarCode(code,13).substring(0,12))); + out.write(new byte[] { 0x1E }); // end char + + out.write(new byte[] {0x1B, 0x1D, 0x61, 0x00}); // Align left + + } + } +} diff --git a/src/main/java/com/unicenta/pos/printer/escpos/CodesSurePOS.java b/src/main/java/com/unicenta/pos/printer/escpos/CodesSurePOS.java new file mode 100644 index 0000000..8b94437 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/escpos/CodesSurePOS.java @@ -0,0 +1,169 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.escpos; + +/** + * + * @author JG uniCenta + */ +public class CodesSurePOS extends Codes { + + private static final byte[] INITSEQUENCE = {}; + + private static final byte[] CHAR_SIZE_0 = {0x1D, 0x21, 0x00}; + private static final byte[] CHAR_SIZE_1 = {0x1D, 0x21, 0x01}; + private static final byte[] CHAR_SIZE_2 = {0x1D, 0x21, 0x30}; + private static final byte[] CHAR_SIZE_3 = {0x1D, 0x21, 0x31}; + + /** + * + */ + public static final byte[] BOLD_SET = {0x1B, 0x45, 0x01}; + + /** + * + */ + public static final byte[] BOLD_RESET = {0x1B, 0x45, 0x00}; + + /** + * + */ + public static final byte[] UNDERLINE_SET = {0x1B, 0x2D, 0x01}; + + /** + * + */ + public static final byte[] UNDERLINE_RESET = {0x1B, 0x2D, 0x00}; + + private static final byte[] OPEN_DRAWER = {0x1B, 0x70, 0x00, 0x32, -0x06}; + private static final byte[] PARTIAL_CUT_1 = {0x1B, 0x69}; + private static final byte[] IMAGE_HEADER = {0x1D, 0x76, 0x30, 0x02}; + private static final byte[] NEW_LINE = {0x0D}; // Print and carriage return + + private static final byte[] IMAGE_LOGO = {0x1B, 0x1C, 0x70, 0x01, 0x00}; + /** Creates a new instance of CodesEpson */ + public CodesSurePOS() { + } + + /** + * + * @return + */ + @Override + public byte[] getInitSequence() { return INITSEQUENCE; } + + /** + * + * @return + */ + @Override + public byte[] getSize0() { return CHAR_SIZE_0; } + + /** + * + * @return + */ + @Override + public byte[] getSize1() { return CHAR_SIZE_1; } + + /** + * + * @return + */ + @Override + public byte[] getSize2() { return CHAR_SIZE_2; } + + /** + * + * @return + */ + @Override + public byte[] getSize3() { return CHAR_SIZE_3; } + + /** + * + * @return + */ + @Override + public byte[] getBoldSet() { return BOLD_SET; } + + /** + * + * @return + */ + @Override + public byte[] getBoldReset() { return BOLD_RESET; } + + /** + * + * @return + */ + @Override + public byte[] getUnderlineSet() { return UNDERLINE_SET; } + + /** + * + * @return + */ + @Override + public byte[] getUnderlineReset() { return UNDERLINE_RESET; } + + /** + * + * @return + */ + @Override + public byte[] getOpenDrawer() { return OPEN_DRAWER; } + + /** + * + * @return + */ + @Override + public byte[] getCutReceipt() { return PARTIAL_CUT_1; } + + /** + * + * @return + */ + @Override + public byte[] getNewLine() { return NEW_LINE; } + + /** + * + * @return + */ + @Override + public byte[] getImageHeader() { return IMAGE_HEADER; } + + /** + * + * @return + */ + @Override + public int getImageWidth() { return 256; } + + /** + * + * @return + */ + @Override + public byte[] getImageLogo(){ return IMAGE_LOGO; } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/printer/escpos/CodesTMU220.java b/src/main/java/com/unicenta/pos/printer/escpos/CodesTMU220.java new file mode 100644 index 0000000..126f4c7 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/escpos/CodesTMU220.java @@ -0,0 +1,197 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.escpos; + +import java.awt.image.BufferedImage; + +/** + * + * @author JG uniCenta + */ +public class CodesTMU220 extends Codes { + + private static final byte[] INITSEQUENCE = {}; + + /** + * + */ + public static final byte[] CHAR_SIZE_0 = {0x1B, 0x21, 0x01}; // This sets 7x9 font + + /** + * + */ + public static final byte[] CHAR_SIZE_1 = {0x1B, 0x21, 0x11}; // This sets double hight 7x9 font + + /** + * + */ + public static final byte[] CHAR_SIZE_2 = {0x1B, 0x21, 0x21}; // This sets 7x9 double width font + + /** + * + */ + public static final byte[] CHAR_SIZE_3 = {0x1B, 0x21, 0x31}; // This sets 7x9 double width/hight font + + /** + * + */ + public static final byte[] BOLD_SET = {0x1B, 0x45, 0x01}; + + /** + * + */ + public static final byte[] BOLD_RESET = {0x1B, 0x45, 0x00}; + + /** + * + */ + public static final byte[] UNDERLINE_SET = {0x1B, 0x2D, 0x01}; + + /** + * + */ + public static final byte[] UNDERLINE_RESET = {0x1B, 0x2D, 0x00}; + + private static final byte[] OPEN_DRAWER = {0x1B, 0x70, 0x00, 0x32, -0x06}; + private static final byte[] PARTIAL_CUT_1 = {0x1B, 0x69}; + private static final byte[] IMAGE_HEADER = {0x1D, 0x76, 0x30, 0x03}; + private static final byte[] NEW_LINE = {0x0D, 0x0A}; // Print and carriage return + + private static final byte[] IMAGE_LOGO = {0x1B, 0x1C, 0x70, 0x01, 0x00}; + /** Creates a new instance of CodesTMU220 */ + public CodesTMU220() { + } + + /** + * + * @return + */ + @Override + public byte[] getInitSequence() { return INITSEQUENCE; } + + /** + * + * @return + */ + @Override + public byte[] getSize0() { return CHAR_SIZE_0; } + + /** + * + * @return + */ + @Override + public byte[] getSize1() { return CHAR_SIZE_1; } + + /** + * + * @return + */ + @Override + public byte[] getSize2() { return CHAR_SIZE_2; } + + /** + * + * @return + */ + @Override + public byte[] getSize3() { return CHAR_SIZE_3; } + + /** + * + * @return + */ + @Override + public byte[] getBoldSet() { return BOLD_SET; } + + /** + * + * @return + */ + @Override + public byte[] getBoldReset() { return BOLD_RESET; } + + /** + * + * @return + */ + @Override + public byte[] getUnderlineSet() { return UNDERLINE_SET; } + + /** + * + * @return + */ + @Override + public byte[] getUnderlineReset() { return UNDERLINE_RESET; } + + /** + * + * @return + */ + @Override + public byte[] getOpenDrawer() { return OPEN_DRAWER; } + + /** + * + * @return + */ + @Override + public byte[] getCutReceipt() { return PARTIAL_CUT_1; } + + /** + * + * @return + */ + @Override + public byte[] getNewLine() { return NEW_LINE; } + + /** + * + * @return + */ + @Override + public byte[] getImageHeader() { return IMAGE_HEADER; } // Not used + + /** + * + * @return + */ + @Override + public int getImageWidth() { return 256; } + + /** + * + * @param oImage + * @return + */ + @Override + public byte[] transImage(BufferedImage oImage) { + // Nothing to print + return new byte[0]; + } + + /** + * + * @return + */ + @Override + public byte[] getImageLogo(){ return IMAGE_LOGO; } +} diff --git a/src/main/java/com/unicenta/pos/printer/escpos/DeviceDisplayESCPOS.java b/src/main/java/com/unicenta/pos/printer/escpos/DeviceDisplayESCPOS.java new file mode 100644 index 0000000..245cc93 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/escpos/DeviceDisplayESCPOS.java @@ -0,0 +1,76 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.escpos; + +import com.unicenta.pos.printer.DeviceTicket; + +/** + * + * @author JG uniCenta + */ +public class DeviceDisplayESCPOS extends DeviceDisplaySerial { + + private UnicodeTranslator trans; + + /** Creates a new instance of DeviceDisplayESCPOS + * @param display + * @param trans */ + public DeviceDisplayESCPOS(PrinterWritter display, UnicodeTranslator trans) { + this.trans = trans; + init(display); + } + + /** + * + */ + @Override + public void initVisor() { + display.init(ESCPOS.INIT); + display.write(ESCPOS.SELECT_DISPLAY); // Al visor + display.write(trans.getCodeTable()); + display.write(ESCPOS.VISOR_HIDE_CURSOR); + display.write(ESCPOS.VISOR_CLEAR); + display.write(ESCPOS.VISOR_HOME); + display.flush(); + } + +// @Override +// public void clearLines() { +// display.write(ESCPOS.SELECT_DISPLAY); +// display.write(ESCPOS.VISOR_CLEAR); +// display.write(ESCPOS.VISOR_HOME); +// display.flush(); +// } + + /** + * + */ + + @Override + public void repaintLines() { + + display.write(ESCPOS.SELECT_DISPLAY); + display.write(ESCPOS.VISOR_CLEAR); + display.write(ESCPOS.VISOR_HOME); + display.write(trans.transString(DeviceTicket.alignLeft(m_displaylines.getLine1(), 20))); + display.write(trans.transString(DeviceTicket.alignLeft(m_displaylines.getLine2(), 20))); + display.flush(); + } +} diff --git a/src/main/java/com/unicenta/pos/printer/escpos/DeviceDisplaySerial.java b/src/main/java/com/unicenta/pos/printer/escpos/DeviceDisplaySerial.java new file mode 100644 index 0000000..842a6a7 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/escpos/DeviceDisplaySerial.java @@ -0,0 +1,121 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.escpos; + +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.printer.DeviceDisplay; +import com.unicenta.pos.printer.DeviceDisplayBase; +import com.unicenta.pos.printer.DeviceDisplayImpl; +/** + * + * @author adrianromero + */ +public abstract class DeviceDisplaySerial implements DeviceDisplay, DeviceDisplayImpl { + + private String m_sName; + + /** + * + */ + protected PrinterWritter display; + + /** + * + */ + protected DeviceDisplayBase m_displaylines; + + /** + * + */ + public DeviceDisplaySerial() { + m_displaylines = new DeviceDisplayBase(this); + } + + /** + * + * @param display + */ + protected void init(PrinterWritter display) { + m_sName = AppLocal.getIntString("printer.serial"); + this.display = display; + initVisor(); + } + + /** + * + * @return + */ + @Override + public String getDisplayName() { + return m_sName; + } + + /** + * + * @return + */ + @Override + public String getDisplayDescription() { + return null; + } + + /** + * + * @return + */ + @Override + public javax.swing.JComponent getDisplayComponent() { + return null; + } + + /** + * + * @param animation + * @param sLine1 + * @param sLine2 + */ + @Override + public void writeVisor(int animation, String sLine1, String sLine2) { + m_displaylines.writeVisor(animation, sLine1, sLine2); + } + + /** + * + * @param sLine1 + * @param sLine2 + */ + @Override + public void writeVisor(String sLine1, String sLine2) { + m_displaylines.writeVisor(sLine1, sLine2); + } + + /** + * + */ + @Override + public void clearVisor() { + m_displaylines.clearVisor(); + } + + /** + * + */ + public abstract void initVisor(); +} diff --git a/src/main/java/com/unicenta/pos/printer/escpos/DeviceDisplaySurePOS.java b/src/main/java/com/unicenta/pos/printer/escpos/DeviceDisplaySurePOS.java new file mode 100644 index 0000000..7c12414 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/escpos/DeviceDisplaySurePOS.java @@ -0,0 +1,66 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.escpos; + +import com.unicenta.pos.printer.DeviceTicket; + +/** + * + * @author adrianromero + */ +public class DeviceDisplaySurePOS extends DeviceDisplaySerial { + + private UnicodeTranslator trans; + + /** + * + * @param display + */ + public DeviceDisplaySurePOS(PrinterWritter display) { + trans = new UnicodeTranslatorSurePOS(); + init(display); + } + + /** + * + */ + @Override + public void initVisor() { + display.write(new byte[]{0x00, 0x01}); // IBM Mode + display.write(new byte[]{0x02}); // Set the code page + display.write(trans.getCodeTable()); + display.write(new byte[]{0x11}); // HIDE CURSOR + display.write(new byte[]{0x14}); // HIDE CURSOR + display.write(new byte[]{0x10, 0x00}); // VISOR HOME + display.flush(); + } + + /** + * + */ + @Override + public void repaintLines() { + display.write(new byte[]{0x10, 0x00}); // VISOR HOME + display.write(trans.transString(DeviceTicket.alignLeft(m_displaylines.getLine1(), 20))); + display.write(new byte[]{0x10, 0x14}); + display.write(trans.transString(DeviceTicket.alignLeft(m_displaylines.getLine2(), 20))); + display.flush(); + } +} diff --git a/src/main/java/com/unicenta/pos/printer/escpos/DevicePrinterESCPOS.java b/src/main/java/com/unicenta/pos/printer/escpos/DevicePrinterESCPOS.java new file mode 100644 index 0000000..a4e3912 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/escpos/DevicePrinterESCPOS.java @@ -0,0 +1,227 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.escpos; + +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.printer.DevicePrinter; +import com.unicenta.pos.printer.TicketPrinterException; +import java.awt.image.BufferedImage; +import javax.swing.JComponent; + +/** + * + * @author JG uniCenta + */ +public class DevicePrinterESCPOS implements DevicePrinter { + + private PrinterWritter m_CommOutputPrinter; + private Codes m_codes; + private UnicodeTranslator m_trans; + +// private boolean m_bInline; + private String m_sName; + + + // Creates new TicketPrinter + + /** + * + * @param CommOutputPrinter + * @param codes + * @param trans + * @throws TicketPrinterException + */ + public DevicePrinterESCPOS(PrinterWritter CommOutputPrinter, Codes codes, UnicodeTranslator trans) throws TicketPrinterException { + + m_sName = AppLocal.getIntString("printer.serial"); + m_CommOutputPrinter = CommOutputPrinter; + m_codes = codes; + m_trans = trans; + + // Inicializamos la impresora + m_CommOutputPrinter.init(ESCPOS.INIT); + + m_CommOutputPrinter.write(ESCPOS.SELECT_PRINTER); // A la impresora + m_CommOutputPrinter.init(m_codes.getInitSequence()); + m_CommOutputPrinter.write(m_trans.getCodeTable()); + + m_CommOutputPrinter.flush(); + } + + /** + * + * @return + */ + @Override + public String getPrinterName() { + return m_sName; + } + + /** + * + * @return + */ + @Override + public String getPrinterDescription() { + return null; + } + + /** + * + * @return + */ + @Override + public JComponent getPrinterComponent() { + return null; + } + + /** + * + */ + @Override + public void reset() { + } + + /** + * + */ + @Override + public void beginReceipt() { + } + + /** + * + * @param image + */ + @Override + public void printImage(BufferedImage image) { + + m_CommOutputPrinter.write(ESCPOS.SELECT_PRINTER); + m_CommOutputPrinter.write(m_codes.transImage(image)); + } + + /** + * + */ + @Override + public void printLogo() { + m_CommOutputPrinter.write(ESCPOS.SELECT_PRINTER); + m_CommOutputPrinter.write(m_codes.getImageLogo()); + } + + /** + * + * @param type + * @param position + * @param code + */ + @Override + public void printBarCode(String type, String position, String code) { + + m_CommOutputPrinter.write(ESCPOS.SELECT_PRINTER); + m_codes.printBarcode(m_CommOutputPrinter, type, position, code); + } + + /** + * + * @param iTextSize + */ + @Override + public void beginLine(int iTextSize) { + + m_CommOutputPrinter.write(ESCPOS.SELECT_PRINTER); + + if (iTextSize == DevicePrinter.SIZE_0) { + m_CommOutputPrinter.write(m_codes.getSize0()); + } else if (iTextSize == DevicePrinter.SIZE_1) { + m_CommOutputPrinter.write(m_codes.getSize1()); + } else if (iTextSize == DevicePrinter.SIZE_2) { + m_CommOutputPrinter.write(m_codes.getSize2()); + } else if (iTextSize == DevicePrinter.SIZE_3) { + m_CommOutputPrinter.write(m_codes.getSize3()); + } else { + m_CommOutputPrinter.write(m_codes.getSize0()); + } + } + + /** + * + * @param iStyle + * @param sText + */ + @Override + public void printText(int iStyle, String sText) { + + m_CommOutputPrinter.write(ESCPOS.SELECT_PRINTER); + + if ((iStyle & DevicePrinter.STYLE_BOLD) != 0) { + m_CommOutputPrinter.write(m_codes.getBoldSet()); + } + if ((iStyle & DevicePrinter.STYLE_UNDERLINE) != 0) { + m_CommOutputPrinter.write(m_codes.getUnderlineSet()); + } + m_CommOutputPrinter.write(m_trans.transString(sText)); + if ((iStyle & DevicePrinter.STYLE_UNDERLINE) != 0) { + m_CommOutputPrinter.write(m_codes.getUnderlineReset()); + } + if ((iStyle & DevicePrinter.STYLE_BOLD) != 0) { + m_CommOutputPrinter.write(m_codes.getBoldReset()); + } + } + + /** + * + */ + @Override + public void endLine() { + m_CommOutputPrinter.write(ESCPOS.SELECT_PRINTER); + m_CommOutputPrinter.write(m_codes.getNewLine()); + } + + /** + * + */ + @Override + public void endReceipt() { + m_CommOutputPrinter.write(ESCPOS.SELECT_PRINTER); + + m_CommOutputPrinter.write(m_codes.getNewLine()); + m_CommOutputPrinter.write(m_codes.getNewLine()); + m_CommOutputPrinter.write(m_codes.getNewLine()); + m_CommOutputPrinter.write(m_codes.getNewLine()); + m_CommOutputPrinter.write(m_codes.getNewLine()); + + m_CommOutputPrinter.write(m_codes.getCutReceipt()); + m_CommOutputPrinter.flush(); + } + + /** + * + */ + public void openDrawer() { + + m_CommOutputPrinter.write(ESCPOS.SELECT_PRINTER); +System.out.print(m_codes.getOpenDrawer()); + +m_CommOutputPrinter.write(m_codes.getOpenDrawer()); + m_CommOutputPrinter.flush(); + } +} + diff --git a/src/main/java/com/unicenta/pos/printer/escpos/DevicePrinterPlain.java b/src/main/java/com/unicenta/pos/printer/escpos/DevicePrinterPlain.java new file mode 100644 index 0000000..24ec481 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/escpos/DevicePrinterPlain.java @@ -0,0 +1,168 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.escpos; + +import com.unicenta.pos.printer.DevicePrinter; +import com.unicenta.pos.printer.TicketPrinterException; +import java.awt.image.BufferedImage; +import javax.swing.JComponent; + +/** + * + * @author JG uniCenta + */ +public class DevicePrinterPlain implements DevicePrinter { + + private static final byte[] NEW_LINE = {0x0D, 0x0A}; // Print and carriage return + + private final PrinterWritter out; + private final UnicodeTranslator trans; + + // Creates new TicketPrinter + + /** + * + * @param CommOutputPrinter + * @throws TicketPrinterException + */ + public DevicePrinterPlain(PrinterWritter CommOutputPrinter) throws TicketPrinterException { + + out = CommOutputPrinter; + trans = new UnicodeTranslatorStar(); // The star translator stands for the 437 int char page + } + + /** + * + * @return + */ + @Override + public String getPrinterName() { + return "Plain"; + } + + /** + * + * @return + */ + @Override + public String getPrinterDescription() { + return null; + } + + /** + * + * @return + */ + @Override + public JComponent getPrinterComponent() { + return null; + } + + /** + * + */ + @Override + public void reset() { + } + + /** + * + */ + @Override + public void beginReceipt() { + } + + /** + * + * @param image + */ + @Override + public void printImage(BufferedImage image) { + } + + /** + * + */ + @Override + public void printLogo(){ + + } + + /** + * + * @param type + * @param position + * @param code + */ + @Override + public void printBarCode(String type, String position, String code) { + if (! DevicePrinter.POSITION_NONE.equals(position)) { + out.write(code); + out.write(NEW_LINE); + } + } + + /** + * + * @param iTextSize + */ + @Override + public void beginLine(int iTextSize) { + } + + /** + * + * @param iStyle + * @param sText + */ + @Override + public void printText(int iStyle, String sText) { + out.write(trans.transString(sText)); + } + + /** + * + */ + @Override + public void endLine() { + out.write(NEW_LINE); + } + + /** + * + */ + @Override + public void endReceipt() { + out.write(NEW_LINE); + out.write(NEW_LINE); + out.write(NEW_LINE); + out.write(NEW_LINE); + out.write(NEW_LINE); + out.flush(); + } + + /** + * + */ + @Override + public void openDrawer() { + } +} + diff --git a/src/main/java/com/unicenta/pos/printer/escpos/ESCPOS.java b/src/main/java/com/unicenta/pos/printer/escpos/ESCPOS.java new file mode 100644 index 0000000..2bef2e7 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/escpos/ESCPOS.java @@ -0,0 +1,55 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.escpos; + +/** + * + * @author JG uniCenta + */ +public class ESCPOS { + + /** + * + */ + public static final byte[] INIT = {0x1B, 0x40}; + public static final byte[] SELECT_PRINTER = {0x1B, 0x3D, 0x01}; + public static final byte[] SELECT_DISPLAY = {0x1B, 0x3D, 0x02}; + public static final byte[] HT = {0x09}; // Horizontal Tab +// public static final byte[] LF = {0x0A}; // Print and line feed + public static final byte[] FF = {0x0C}; // +// public static final byte[] CR = {0x0D}; // Print and carriage return + public static final byte[] CHAR_FONT_0 = {0x1B, 0x4D, 0x00}; + public static final byte[] CHAR_FONT_1 = {0x1B, 0x4D, 0x01}; + public static final byte[] CHAR_FONT_2 = {0x1B, 0x4D, 0x30}; + public static final byte[] CHAR_FONT_3 = {0x1B, 0x4D, 0x31}; + public static final byte[] BAR_HEIGHT = {0x1D, 0x68, 0x40}; + public static final byte[] BAR_POSITIONDOWN = {0x1D, 0x48, 0x02}; + public static final byte[] BAR_POSITIONNONE = {0x1D, 0x48, 0x00}; + public static final byte[] BAR_HRIFONT1 = {0x1D, 0x66, 0x01}; + public static final byte[] BAR_CODE02 = {0x1D, 0x6B, 0x02}; // 12 numeros fijos + public static final byte[] VISOR_HIDE_CURSOR = {0x1F, 0x43, 0x00}; + public static final byte[] VISOR_SHOW_CURSOR = {0x1F, 0x43, 0x01}; + public static final byte[] VISOR_HOME = {0x0B}; + public static final byte[] VISOR_CLEAR = {0x0C}; + public static final byte[] CODE_TABLE_00 = {0x1B, 0x74, 0x00}; + public static final byte[] CODE_TABLE_13 = {0x1B, 0x74, 0x13}; + private ESCPOS() { + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/printer/escpos/PrinterWritter.java b/src/main/java/com/unicenta/pos/printer/escpos/PrinterWritter.java new file mode 100644 index 0000000..3e253f8 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/escpos/PrinterWritter.java @@ -0,0 +1,114 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.escpos; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * + * @author JG uniCenta + */ +public abstract class PrinterWritter { + + private boolean initialized = false; + + private ExecutorService exec; + + /** + * + */ + public PrinterWritter() { + exec = Executors.newSingleThreadExecutor(); + } + + /** + * + * @param data + */ + protected abstract void internalWrite(byte[] data); + + /** + * + */ + protected abstract void internalFlush(); + + /** + * + */ + protected abstract void internalClose(); + + /** + * + * @param data + */ + public void init(final byte[] data) { + if (!initialized) { + write(data); + initialized = true; + } + } + + /** + * + * @param sValue + */ + public void write(String sValue) { + write(sValue.getBytes()); + } + + /** + * + * @param data + */ + public void write(final byte[] data) { + exec.execute(new Runnable() { + @Override + public void run() { + internalWrite(data); + } + }); + } + + /** + * + */ + public void flush() { + exec.execute(new Runnable() { + @Override + public void run() { + internalFlush(); + } + }); + } + + /** + * + */ + public void close() { + exec.execute(new Runnable() { + @Override + public void run() { + internalClose(); + } + }); + exec.shutdown(); + } +} diff --git a/src/main/java/com/unicenta/pos/printer/escpos/PrinterWritterFile.java b/src/main/java/com/unicenta/pos/printer/escpos/PrinterWritterFile.java new file mode 100644 index 0000000..a9c7b91 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/escpos/PrinterWritterFile.java @@ -0,0 +1,91 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.escpos; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * + * @author JG uniCenta + */ +public class PrinterWritterFile extends PrinterWritter { + + private String m_sFilePrinter; + private OutputStream m_out; + + /** + * + * @param sFilePrinter + */ + public PrinterWritterFile(String sFilePrinter) { + m_sFilePrinter = sFilePrinter; + m_out = null; + } + + /** + * + * @param data + */ + @Override + protected void internalWrite(byte[] data) { + try { + if (m_out == null) { + m_out = new FileOutputStream(m_sFilePrinter); // No poner append = true. + } + m_out.write(data); + } catch (IOException e) { + System.err.println(e); + } + } + + /** + * + */ + @Override + protected void internalFlush() { + try { + if (m_out != null) { + m_out.flush(); + m_out.close(); + m_out = null; + } + } catch (IOException e) { + System.err.println(e); + } + } + + /** + * + */ + @Override + protected void internalClose() { + try { + if (m_out != null) { + m_out.flush(); + m_out.close(); + m_out = null; + } + } catch (IOException e) { + System.err.println(e); + } + } +} diff --git a/src/main/java/com/unicenta/pos/printer/escpos/PrinterWritterRXTX.java b/src/main/java/com/unicenta/pos/printer/escpos/PrinterWritterRXTX.java new file mode 100644 index 0000000..fb2bc5e --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/escpos/PrinterWritterRXTX.java @@ -0,0 +1,111 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.escpos; + +// import javax.comm.*; // Java comm library +import com.unicenta.pos.printer.TicketPrinterException; +import gnu.io.*; +import java.io.IOException; +import java.io.OutputStream; + +/** + * + * @author JG uniCenta + */ +public class PrinterWritterRXTX extends PrinterWritter /* implements SerialPortEventListener */ { + + private CommPortIdentifier m_PortIdPrinter; + private CommPort m_CommPortPrinter; + + private String m_sPortPrinter; + private OutputStream m_out; + + /** Creates a new instance of PrinterWritterComm + * @param sPortPrinter + * @throws com.unicenta.pos.printer.TicketPrinterException */ + public PrinterWritterRXTX(String sPortPrinter) throws TicketPrinterException { + m_sPortPrinter = sPortPrinter; + m_out = null; + } + + /** + * + * @param data + */ + @Override + protected void internalWrite(byte[] data) { + try { + if (m_out == null) { + m_PortIdPrinter = CommPortIdentifier.getPortIdentifier(m_sPortPrinter); // Tomamos el puerto + m_CommPortPrinter = m_PortIdPrinter.open("PORTID", 2000); // Abrimos el puerto + + m_out = m_CommPortPrinter.getOutputStream(); // Tomamos el chorro de escritura + + if (m_PortIdPrinter.getPortType() == CommPortIdentifier.PORT_SERIAL) { + ((SerialPort)m_CommPortPrinter).setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); // Configuramos el puerto + ((SerialPort)m_CommPortPrinter).setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN); // this line prevents the printer tmu220 to stop printing after +-18 lines printed + // this line prevents the printer tmu220 to stop printing after +-18 lines printed. Bug 8324 + // But if added a regression error appears. Bug 9417, Better to keep it commented. + // ((SerialPort)m_CommPortPrinter).setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN); + // Not needed to set parallel properties + // } else if (m_PortIdPrinter.getPortType() == CommPortIdentifier.PORT_PARALLEL) { + // ((ParallelPort)m_CommPortPrinter).setMode(1); + + } + } + m_out.write(data); +// JG 16 May 12 use multicatch + } catch (NoSuchPortException | PortInUseException | UnsupportedCommOperationException | IOException e) { + System.err.println(e); + } + } + + /** + * + */ + @Override + protected void internalFlush() { + try { + if (m_out != null) { + m_out.flush(); + } + } catch (IOException e) { + System.err.println(e); + } + } + + /** + * + */ + @Override + protected void internalClose() { + try { + if (m_out != null) { + m_out.flush(); + m_out.close(); + m_out = null; + m_CommPortPrinter = null; + m_PortIdPrinter = null; + } + } catch (IOException e) { + System.err.println(e); + } + } +} diff --git a/src/main/java/com/unicenta/pos/printer/escpos/PrinterWritterRaw.java b/src/main/java/com/unicenta/pos/printer/escpos/PrinterWritterRaw.java new file mode 100644 index 0000000..dd50c45 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/escpos/PrinterWritterRaw.java @@ -0,0 +1,167 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Adrian Romero Corchado. +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.escpos; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.LinkedList; +import java.util.Locale; +import javax.print.Doc; +import javax.print.DocFlavor; +import javax.print.DocPrintJob; +import javax.print.PrintException; +import javax.print.PrintService; +import javax.print.PrintServiceLookup; +import javax.print.SimpleDoc; +import javax.print.attribute.DocAttributeSet; +import javax.print.attribute.HashDocAttributeSet; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.print.attribute.standard.DocumentName; +import javax.print.attribute.standard.JobName; + +public final class PrinterWritterRaw extends PrinterWritter { + + private byte[] m_printData; + private PrintService m_printService; + private final DocFlavor m_docFlavor; + private PrinterBuffer m_buff = null; + private OutputStream m_out; + + public PrinterWritterRaw(String sRawPrinter) { + m_printData = null; + m_docFlavor = DocFlavor.BYTE_ARRAY.AUTOSENSE; + m_buff = new PrinterBuffer(); + + init(); + + PrintService[] services = PrintServiceLookup.lookupPrintServices(m_docFlavor, null); + for (PrintService ps : services) { + if (ps.getName().contains(sRawPrinter)) { + // if we have found the prineter the start our print routine + m_printService = ps; + write(ESCPOS.INIT); + return; + } + } + } + + public void init() { + byte[] inicode = concatByteArrays(ESCPOS.SELECT_PRINTER, new UnicodeTranslatorInt().getCodeTable()); + m_printData = concatByteArrays(inicode, m_printData); + } + + @Override + public void write(byte[] data) { + m_printData = concatByteArrays(m_printData, data); + } + + @Override + public void write(String sValue) { + m_buff.putData(sValue.getBytes()); + } + + @Override + protected void internalWrite(byte[] data) { + } + + @Override + protected void internalClose() { + try { + if (m_out != null) { + m_out.flush(); + m_out.close(); + m_out = null; + } + } catch (IOException e) { + System.err.println(e); + } + } + + @Override + protected void internalFlush() { + } + + + @Override + public void flush() { + printJob(); + } + + private byte[] concatByteArrays(byte[] a, byte[] b) { + if (a == null) { + return b; + } + if (b == null) { + return a; + } + byte[] concat = new byte[a.length + b.length]; + System.arraycopy(a, 0, concat, 0, a.length); + System.arraycopy(b, 0, concat, a.length, b.length); + return concat; + } + + private void printJob() { + if (null != m_printService) { + try { + DocPrintJob pj = m_printService.createPrintJob(); + DocAttributeSet docattributes = new HashDocAttributeSet(); + + docattributes.add(new DocumentName("Ticket", Locale.getDefault())); + PrintRequestAttributeSet jobattributes = new HashPrintRequestAttributeSet(); + + jobattributes.add(new JobName("unicenta", Locale.getDefault())); + Doc doc = new SimpleDoc(m_printData, m_docFlavor, docattributes); + pj.print(doc, jobattributes); + } catch (PrintException ex) { + } finally { + m_printData = null; + } + } + } + + private class PrinterBuffer { + + private final LinkedList m_list; + + /** + * Creates a new instance of PrinterBuffer + */ + public PrinterBuffer() { + m_list = new LinkedList(); + } + + public synchronized void putData(Object data) { + m_list.addFirst(data); + notifyAll(); + } + + public synchronized Object getData() { + while (m_list.isEmpty()) { + try { + wait(); + } catch (InterruptedException e) { + } + } + notifyAll(); + return m_list.removeLast(); + } + } +} diff --git a/src/main/java/com/unicenta/pos/printer/escpos/UnicodeTranslator.java b/src/main/java/com/unicenta/pos/printer/escpos/UnicodeTranslator.java new file mode 100644 index 0000000..80ab2de --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/escpos/UnicodeTranslator.java @@ -0,0 +1,188 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.escpos; + +/** + * + * @author JG uniCenta + */ +public abstract class UnicodeTranslator { + + /** + * + * @return + */ + public abstract byte[] getCodeTable(); + + /** + * + * @param sCad + * @return + */ + public final byte[] transString(String sCad) { + + if (sCad == null) { + return null; + } else { + byte bAux[] = new byte[sCad.length()]; + for( int i = 0; i < sCad.length(); i++) { + bAux[i] = transChar(sCad.charAt(i)); + } + return bAux; + } + } + + /** + * + * @param sChar + * @return + */ + public abstract byte transChar(char sChar); + +// case '\u0000': return -0x80; // 0x80 : +// case '\u0000': return -0x7F; // 0x81 : +// case '\u0000': return -0x7E; // 0x82 : +// case '\u0000': return -0x7D; // 0x83 : +// case '\u0000': return -0x7C; // 0x84 : +// case '\u0000': return -0x7B; // 0x85 : +// case '\u0000': return -0x7A; // 0x86 : +// case '\u0000': return -0x79; // 0x87 : +// case '\u0000': return -0x78; // 0x88 : +// case '\u0000': return -0x77; // 0x89 : +// case '\u0000': return -0x76; // 0x8A : +// case '\u0000': return -0x75; // 0x8B : +// case '\u0000': return -0x74; // 0x8C : +// case '\u0000': return -0x73; // 0x8D : +// case '\u0000': return -0x72; // 0x8E : +// case '\u0000': return -0x71; // 0x8F : +// case '\u0000': return -0x70; // 0x90 : +// case '\u0000': return -0x6F; // 0x91 : +// case '\u0000': return -0x6E; // 0x92 : +// case '\u0000': return -0x6D; // 0x93 : +// case '\u0000': return -0x6C; // 0x94 : +// case '\u0000': return -0x6B; // 0x95 : +// case '\u0000': return -0x6A; // 0x96 : +// case '\u0000': return -0x69; // 0x97 : +// case '\u0000': return -0x68; // 0x98 : +// case '\u0000': return -0x67; // 0x99 : +// case '\u0000': return -0x66; // 0x9A : +// case '\u0000': return -0x65; // 0x9B : +// case '\u0000': return -0x64; // 0x9C : +// case '\u0000': return -0x63; // 0x9D : +// case '\u0000': return -0x62; // 0x9E : +// case '\u0000': return -0x61; // 0x9F : +// case '\u0000': return -0x60; // 0xA0 : +// case '\u0000': return -0x5F; // 0xA1 : +// case '\u0000': return -0x5E; // 0xA2 : +// case '\u0000': return -0x5D; // 0xA3 : +// case '\u0000': return -0x5C; // 0xA4 : +// case '\u0000': return -0x5B; // 0xA5 : +// case '\u0000': return -0x5A; // 0xA6 : +// case '\u0000': return -0x59; // 0xA7 : +// case '\u0000': return -0x58; // 0xA8 : +// case '\u0000': return -0x57; // 0xA9 : +// case '\u0000': return -0x56; // 0xAA : +// case '\u0000': return -0x55; // 0xAB : +// case '\u0000': return -0x54; // 0xAC : +// case '\u0000': return -0x53; // 0xAD : +// case '\u0000': return -0x52; // 0xAE : +// case '\u0000': return -0x51; // 0xAF : +// case '\u0000': return -0x50; // 0xB0 : +// case '\u0000': return -0x4F; // 0xB1 : +// case '\u0000': return -0x4E; // 0xB2 : +// case '\u0000': return -0x4D; // 0xB3 : +// case '\u0000': return -0x4C; // 0xB4 : +// case '\u0000': return -0x4B; // 0xB5 : +// case '\u0000': return -0x4A; // 0xB6 : +// case '\u0000': return -0x49; // 0xB7 : +// case '\u0000': return -0x48; // 0xB8 : +// case '\u0000': return -0x47; // 0xB9 : +// case '\u0000': return -0x46; // 0xBA : +// case '\u0000': return -0x45; // 0xBB : +// case '\u0000': return -0x44; // 0xBC : +// case '\u0000': return -0x43; // 0xBD : +// case '\u0000': return -0x42; // 0xBE : +// case '\u0000': return -0x41; // 0xBF : +// case '\u0000': return -0x40; // 0xC0 : +// case '\u0000': return -0x3F; // 0xC1 : +// case '\u0000': return -0x3E; // 0xC2 : +// case '\u0000': return -0x3D; // 0xC3 : +// case '\u0000': return -0x3C; // 0xC4 : +// case '\u0000': return -0x3B; // 0xC5 : +// case '\u0000': return -0x3A; // 0xC6 : +// case '\u0000': return -0x39; // 0xC7 : +// case '\u0000': return -0x38; // 0xC8 : +// case '\u0000': return -0x37; // 0xC9 : +// case '\u0000': return -0x36; // 0xCA : +// case '\u0000': return -0x35; // 0xCB : +// case '\u0000': return -0x34; // 0xCC : +// case '\u0000': return -0x33; // 0xCD : +// case '\u0000': return -0x32; // 0xCE : +// case '\u0000': return -0x31; // 0xCF : +// case '\u0000': return -0x30; // 0xD0 : +// case '\u0000': return -0x2F; // 0xD1 : +// case '\u0000': return -0x2E; // 0xD2 : +// case '\u0000': return -0x2D; // 0xD3 : +// case '\u0000': return -0x2C; // 0xD4 : +// case '\u0000': return -0x2B; // 0xD5 : +// case '\u0000': return -0x2A; // 0xD6 : +// case '\u0000': return -0x29; // 0xD7 : +// case '\u0000': return -0x28; // 0xD8 : +// case '\u0000': return -0x27; // 0xD9 : +// case '\u0000': return -0x26; // 0xDA : +// case '\u0000': return -0x25; // 0xDB : +// case '\u0000': return -0x24; // 0xDC : +// case '\u0000': return -0x23; // 0xDD : +// case '\u0000': return -0x22; // 0xDE : +// case '\u0000': return -0x21; // 0xDF : +// case '\u0000': return -0x20; // 0xE0 : +// case '\u0000': return -0x2F; // 0xE1 : +// case '\u0000': return -0x1E; // 0xE2 : +// case '\u0000': return -0x1D; // 0xE3 : +// case '\u0000': return -0x1C; // 0xE4 : +// case '\u0000': return -0x1B; // 0xE5 : +// case '\u0000': return -0x1A; // 0xE6 : +// case '\u0000': return -0x19; // 0xE7 : +// case '\u0000': return -0x18; // 0xE8 : +// case '\u0000': return -0x17; // 0xE9 : +// case '\u0000': return -0x16; // 0xEA : +// case '\u0000': return -0x15; // 0xEB : +// case '\u0000': return -0x14; // 0xEC : +// case '\u0000': return -0x13; // 0xED : +// case '\u0000': return -0x12; // 0xEE : +// case '\u0000': return -0x11; // 0xEF : +// case '\u0000': return -0x10; // 0xF0 : +// case '\u0000': return -0x0F; // 0xF1 : +// case '\u0000': return -0x0E; // 0xF2 : +// case '\u0000': return -0x0D; // 0xF3 : +// case '\u0000': return -0x0C; // 0xF4 : +// case '\u0000': return -0x0B; // 0xF5 : +// case '\u0000': return -0x0A; // 0xF6 : +// case '\u0000': return -0x09; // 0xF7 : +// case '\u0000': return -0x08; // 0xF8 : +// case '\u0000': return -0x07; // 0xF9 : +// case '\u0000': return -0x06; // 0xFA : +// case '\u0000': return -0x05; // 0xFB : +// case '\u0000': return -0x04; // 0xFC : +// case '\u0000': return -0x03; // 0xFD : +// case '\u0000': return -0x02; // 0xFE : +// case '\u0000': return -0x01; // 0xFF : + +} diff --git a/src/main/java/com/unicenta/pos/printer/escpos/UnicodeTranslatorEur.java b/src/main/java/com/unicenta/pos/printer/escpos/UnicodeTranslatorEur.java new file mode 100644 index 0000000..c45f24e --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/escpos/UnicodeTranslatorEur.java @@ -0,0 +1,76 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.escpos; + +/** + * + * @author JG uniCenta + */ +public class UnicodeTranslatorEur extends UnicodeTranslator { + + /** Creates a new instance of UnicodeTranslatorEur */ + public UnicodeTranslatorEur() { + } + + /** + * + * @return + */ + @Override + public byte[] getCodeTable() { + return ESCPOS.CODE_TABLE_13; + } + + /** + * + * @param sChar + * @return + */ + @Override + public byte transChar(char sChar) { + if ((sChar >= 0x0000) && (sChar < 0x0080)) { + return (byte) sChar; + } else { + switch (sChar) { + case '\u00e1': return -0x60; // a acute + case '\u00e9': return -0x7E; // e acute + case '\u00ed': return -0x5F; // i acute + case '\u00f3': return -0x5E; // o acute + case '\u00fa': return -0x5D; // u acute + case '\u00fc': return -0x7F; // u dieresis + case '\u00f1': return -0x5C; // n tilde + case '\u00d1': return -0x5B; // N tilde + + case '\u00c1': return 0x41; // A acute + case '\u00c9': return 0x45; // E acute + case '\u00cd': return 0x49; // I acute + case '\u00d3': return 0x4F; // O acute + case '\u00da': return 0x55; // U acute + case '\u00dc': return -0x66; // U dieresis + case '\u00bf': return -0x58; // abrir interrogacion + case '\u00a1': return -0x53; // abrir admiracion + case '\u20ac': return -0x12; // Euro Sign + + + default: return 0x3F; // ? Not valid character. + } + } + } +} diff --git a/src/main/java/com/unicenta/pos/printer/escpos/UnicodeTranslatorInt.java b/src/main/java/com/unicenta/pos/printer/escpos/UnicodeTranslatorInt.java new file mode 100644 index 0000000..aee9eec --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/escpos/UnicodeTranslatorInt.java @@ -0,0 +1,214 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.escpos; + +/** + * + * @author JG uniCenta + */ +public class UnicodeTranslatorInt extends UnicodeTranslator { + + /** Creates a new instance of UnicodeTranslatorInt */ + public UnicodeTranslatorInt() { + } + + /** + * + * @return + */ + @Override + public byte[] getCodeTable() { + return ESCPOS.CODE_TABLE_13; + } + + /** + * + * @param sChar + * @return + */ + @Override + public byte transChar(char sChar) { + if ((sChar >= 0x0000) && (sChar < 0x0080)) { + return (byte) sChar; + } else { + switch (sChar) { + case '\u00c7': return -0x80; + case '\u00fc': return -0x7F; // u dieresis + case '\u00e2': return -0x7D; + case '\u00e4': return -0x7C; + case '\u00e0': return -0x7B; + case '\u00E5': return -0x7A; // ao + case '\u00e7': return -0x79; + case '\u00ea': return -0x78; + case '\u00eb': return -0x77; + case '\u00e8': return -0x76; + case '\u00ef': return -0x75; + case '\u00ee': return -0x74; + case '\u00ec': return -0x73; + case '\u00c4': return -0x72; + case '\u00C5': return -0x71; // Ao + + case '\u00c9': return -0x70; // E acute + case '\u00E6': return -0x6F; // ae + case '\u00C6': return -0x6E; // AE + case '\u00f4': return -0x6D; + case '\u00f6': return -0x6C; + case '\u00f2': return -0x6B; + case '\u00fb': return -0x6A; + case '\u00f9': return -0x69; + case '\u00ff': return -0x68; + case '\u00d6': return -0x67; + case '\u00dc': return -0x66; // U dieresis + case '\u00F8': return -0x65; // o/ + case '\u00A3': return -0x64; // L- Libra esterlina + case '\u00D8': return -0x63; // O/ + case '\u00D7': return -0x62; // X +// case '': return -0x61; // f + + case '\u00e1': return -0x60; // a acute + case '\u00e9': return -0x7E; // e acute + case '\u00ed': return -0x5F; // i acute + case '\u00f3': return -0x5E; // o acute + case '\u00fa': return -0x5D; // u acute + case '\u00f1': return -0x5C; // n tilde + case '\u00d1': return -0x5B; // N tilde + case '\u00aa': return -0x5A; + case '\u00ba': return -0x59; + case '\u00bf': return -0x58; // abrir interrogacion + case '\u00AE': return -0x57; // (R) Registrado + case '\u00ac': return -0x56; // Not sign + case '\u00BD': return -0x55; // 1/2 + case '\u00BC': return -0x54; // 1/4 + case '\u00a1': return -0x53; // abrir admiracion + case '\u00AB': return -0x52; // << + case '\u00BB': return -0x51; // >> + + case '\u2591': return -0x50; // Light shade + case '\u2592': return -0x4F; // Medium shade + case '\u2593': return -0x4E; // Dark shade + case '\u2502': return -0x4D; // BOX DRAWINGS LIGHT VERTICAL + case '\u2524': return -0x4C; // BOX DRAWINGS LIGHT VERTICAL AND LEFT + case '\u00c1': return -0x4B; // A acute + case '\u00c2': return -0x4A; + case '\u00c0': return -0x49; + case '\u00A9': return -0x48; // (c) Copyright + case '\u2563': return -0x47; // BOX DRAWINGS DOUBLE VERTICAL AND LEFT + case '\u2551': return -0x46; // BOX DRAWINGS DOUBLE VERTICAL + case '\u2557': return -0x45; // BOX DRAWINGS DOUBLE DOWN AND LEFT + case '\u255D': return -0x44; // BOX DRAWINGS DOUBLE UP AND LEFT + case '\u00A2': return -0x43; // Cent Sign + case '\u00A5': return -0x42; // Yen Sign + case '\u2510': return -0x41; // BOX DRAWINGS LIGHT DOWN AND LEFT + + case '\u2514': return -0x40; // BOX DRAWINGS LIGHT UP ANDRIGHT +// case '': return -0x3F; // +// case '': return -0x3E; // +// case '': return -0x3D; // +// case '': return -0x3C; // +// case '': return -0x3B; // +// case '': return -0x3A; // +// case '': return -0x39; // +// case '': return -0x38; // +// case '': return -0x37; // +// case '': return -0x36; // +// case '': return -0x35; // +// case '': return -0x34; // +// case '': return -0x33; // +// case '': return -0x32; // +// case '': return -0x31; // + +// case '': return -0x30; // +// case '': return -0x2F; // + case '\u00ca': return -0x2E; // + case '\u00cb': return -0x2D; // + case '\u00c8': return -0x2C; // + case '\u20ac': return -0x2B; // Euro Sign + case '\u00cd': return -0x2A; // I acute + case '\u00ce': return -0x29; // + case '\u00cf': return -0x28; // +// case '': return -0x27; // +// case '': return -0x26; // +// case '': return -0x25; // +// case '': return -0x24; // + case '|': return -0x23; // + case '\u00cc': return -0x22; // +// case '': return -0x21; // + + case '\u00d3': return -0x20; // O acute +// case '': return -0x1F; // + case '\u00d4': return -0x1E; // + case '\u00d2': return -0x1D; // +// case '': return -0x1C; // +// case '': return -0x1B; // +// case '': return -0x1A; // +// case '': return -0x19; // +// case '': return -0x18; // + case '\u00da': return -0x17; // U acute + case '\u00db': return -0x16; // + case '\u00d9': return -0x15; // + case '\u00fd': return -0x14; // + case '\u00dd': return -0x13; // +// case '': return -0x12; // + case '\u00b4': return -0x11; // + +// case '': return -0x10; // +// case '': return -0x0F; // +// case '': return -0x0E; // +// case '': return -0x0D; // +// case '': return -0x0C; // +// case '': return -0x0B; // +// case '': return -0x0A; // +// case '': return -0x09; // +// case '': return -0x08; // + case '\u00a8': return -0x07; // +// case '': return -0x06; // +// case '': return -0x05; // +// case '': return -0x04; // +// case '': return -0x03; // +// case '': return -0x02; // + // case ' ': return -0x01; // SP + + default: return 0x3F; // ? Not valid character. + +// Old translation +// case '\u00aa' : return (byte) 0xA6; +// case '\u00ba' : return (byte) 0xA7; +// case '\u00a1' : return (byte) 0xAD; +// case '\u00bf' : return (byte) 0xA8; +// case '\u00b7' : return (byte) 0xF9; +// case '\u00f1' : return (byte) 0xA4; +// case '\u00d1' : return (byte) 0xA5; +// case '\u00e1' : return (byte) 0xA0; +// case '\u00c1' : return (byte) 0x86; +// case '\u00e9' : return (byte) 0x82; +// case '\u00c9' : return (byte) 0x90; +// case '\u00ed' : return (byte) 0xA1; +// case '\u00cd' : return (byte) 0x8B; +// case '\u00f3' : return (byte) 0xA2; +// case '\u00d3' : return (byte) 0x9F; +// case '\u00fa' : return (byte) 0xA3; +// case '\u00da' : return (byte) 0x96; +// case '\u00fc' : return (byte) 0x81; +// case '\u00dc' : return (byte) 0x9A; +// default: return (byte) sChar; + } + } + } +} diff --git a/src/main/java/com/unicenta/pos/printer/escpos/UnicodeTranslatorStar.java b/src/main/java/com/unicenta/pos/printer/escpos/UnicodeTranslatorStar.java new file mode 100644 index 0000000..fb7b144 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/escpos/UnicodeTranslatorStar.java @@ -0,0 +1,192 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.escpos; + +/** + * + * @author JG uniCenta + */ +public class UnicodeTranslatorStar extends UnicodeTranslator { + + /** Creates a UnicodeTranslatorStar instance of UnicodeTranslatorInt */ + public UnicodeTranslatorStar() { + } + + /** + * + * @return + */ + @Override + public byte[] getCodeTable() { + return new byte[] {0x1B, 0x1D, 0x74, 0x01}; // Select code page 437 + } + + /** + * + * @param sChar + * @return + */ + @Override + public byte transChar(char sChar) { + if ((sChar >= 0x0000) && (sChar < 0x0080)) { + return (byte) sChar; + } else { + switch (sChar) { + case '\u00c1': return 0x41; // A acute + case '\u00c9': return 0x45; // E acute + case '\u00cd': return 0x49; // I acute + case '\u00d3': return 0x4F; // O acute + case '\u00da': return 0x55; // U acute + + + case '\u00C7': return -0x80; // 0x80 : C cedilla + case '\u00FC': return -0x7F; // 0x81 : u dieresis + case '\u00E9': return -0x7E; // 0x82 : e acute +// case '\u0000': return -0x7D; // 0x83 : + case '\u00E4': return -0x7C; // 0x84 : a dieresis +// case '\u0000': return -0x7B; // 0x85 : + case '\u00E5': return -0x7A; // 0x86 : a circle + case '\u00E7': return -0x79; // 0x87 : c cedilla +// case '\u0000': return -0x78; // 0x88 : +// case '\u0000': return -0x77; // 0x89 : +// case '\u0000': return -0x76; // 0x8A : +// case '\u0000': return -0x75; // 0x8B : +// case '\u0000': return -0x74; // 0x8C :dieresis +// case '\u0000': return -0x73; // 0x8D : + case '\u00C4': return -0x72; // 0x8E : A dieresis + case '\u00C5': return -0x71; // 0x8F : A circle +// case '\u0000': return -0x70; // 0x90 : +// case '\u0000': return -0x6F; // 0x91 : +// case '\u0000': return -0x6E; // 0x92 : +// case '\u0000': return -0x6D; // 0x93 : + case '\u00F6': return -0x6C; // 0x94 : o dieresis +// case '\u0000': return -0x6B; // 0x95 : +// case '\u0000': return -0x6A; // 0x96 : +// case '\u0000': return -0x69; // 0x97 : +// case '\u0000': return -0x68; // 0x98 : + case '\u00D6': return -0x67; // 0x99 : O dieresis + case '\u00DC': return -0x66; // 0x9A : U dieresesis +// case '\u0000': return -0x65; // 0x9B : + case '\u00A3': return -0x64; // 0x9C : Pound currency + case '\u00A5': return -0x63; // 0x9D : Yen currency +// case '\u0000': return -0x62; // 0x9E : +// case '\u0000': return -0x61; // 0x9F : + case '\u00E1': return -0x60; // 0xA0 : a acute + case '\u00ED': return -0x5F; // 0xA1 : i acute + case '\u00F3': return -0x5E; // 0xA2 : o acute + case '\u00FA': return -0x5D; // 0xA3 : u acute + case '\u00F1': return -0x5C; // 0xA4 : n tilde + case '\u00D1': return -0x5B; // 0xA5 : N tilde +// case '\u0000': return -0x5A; // 0xA6 : +// case '\u0000': return -0x59; // 0xA7 : + case '\u00BF': return -0x58; // 0xA8 : open ? +// case '\u0000': return -0x57; // 0xA9 : +// case '\u0000': return -0x56; // 0xAA : +// case '\u0000': return -0x55; // 0xAB : +// case '\u0000': return -0x54; // 0xAC : + case '\u00A1': return -0x53; // 0xAD : open ! +// case '\u0000': return -0x52; // 0xAE : +// case '\u0000': return -0x51; // 0xAF : +// case '\u0000': return -0x50; // 0xB0 : +// case '\u0000': return -0x4F; // 0xB1 : +// case '\u0000': return -0x4E; // 0xB2 : +// case '\u0000': return -0x4D; // 0xB3 : +// case '\u0000': return -0x4C; // 0xB4 : +// case '\u0000': return -0x4B; // 0xB5 : +// case '\u0000': return -0x4A; // 0xB6 : +// case '\u0000': return -0x49; // 0xB7 : +// case '\u0000': return -0x48; // 0xB8 : +// case '\u0000': return -0x47; // 0xB9 : +// case '\u0000': return -0x46; // 0xBA : +// case '\u0000': return -0x45; // 0xBB : +// case '\u0000': return -0x44; // 0xBC : +// case '\u0000': return -0x43; // 0xBD : +// case '\u0000': return -0x42; // 0xBE : +// case '\u0000': return -0x41; // 0xBF : +// case '\u0000': return -0x40; // 0xC0 : +// case '\u0000': return -0x3F; // 0xC1 : +// case '\u0000': return -0x3E; // 0xC2 : +// case '\u0000': return -0x3D; // 0xC3 : +// case '\u0000': return -0x3C; // 0xC4 : +// case '\u0000': return -0x3B; // 0xC5 : +// case '\u0000': return -0x3A; // 0xC6 : +// case '\u0000': return -0x39; // 0xC7 : +// case '\u0000': return -0x38; // 0xC8 : +// case '\u0000': return -0x37; // 0xC9 : +// case '\u0000': return -0x36; // 0xCA : +// case '\u0000': return -0x35; // 0xCB : +// case '\u0000': return -0x34; // 0xCC : +// case '\u0000': return -0x33; // 0xCD : +// case '\u0000': return -0x32; // 0xCE : +// case '\u0000': return -0x31; // 0xCF : +// case '\u0000': return -0x30; // 0xD0 : +// case '\u0000': return -0x2F; // 0xD1 : +// case '\u0000': return -0x2E; // 0xD2 : +// case '\u0000': return -0x2D; // 0xD3 : +// case '\u0000': return -0x2C; // 0xD4 : +// case '\u0000': return -0x2B; // 0xD5 : +// case '\u0000': return -0x2A; // 0xD6 : +// case '\u0000': return -0x29; // 0xD7 : +// case '\u0000': return -0x28; // 0xD8 : +// case '\u0000': return -0x27; // 0xD9 : +// case '\u0000': return -0x26; // 0xDA : +// case '\u0000': return -0x25; // 0xDB : +// case '\u0000': return -0x24; // 0xDC : +// case '\u0000': return -0x23; // 0xDD : +// case '\u0000': return -0x22; // 0xDE : +// case '\u0000': return -0x21; // 0xDF : +// case '\u0000': return -0x20; // 0xE0 : +// case '\u0000': return -0x2F; // 0xE1 : +// case '\u0000': return -0x1E; // 0xE2 : +// case '\u0000': return -0x1D; // 0xE3 : +// case '\u0000': return -0x1C; // 0xE4 : +// case '\u0000': return -0x1B; // 0xE5 : +// case '\u0000': return -0x1A; // 0xE6 : +// case '\u0000': return -0x19; // 0xE7 : +// case '\u0000': return -0x18; // 0xE8 : +// case '\u0000': return -0x17; // 0xE9 : +// case '\u0000': return -0x16; // 0xEA : +// case '\u0000': return -0x15; // 0xEB : +// case '\u0000': return -0x14; // 0xEC : +// case '\u0000': return -0x13; // 0xED : + case '\u20AC': return -0x12; // 0xEE : euro sign +// case '\u0000': return -0x11; // 0xEF : +// case '\u0000': return -0x10; // 0xF0 : +// case '\u0000': return -0x0F; // 0xF1 : +// case '\u0000': return -0x0E; // 0xF2 : +// case '\u0000': return -0x0D; // 0xF3 : +// case '\u0000': return -0x0C; // 0xF4 : +// case '\u0000': return -0x0B; // 0xF5 : +// case '\u0000': return -0x0A; // 0xF6 : +// case '\u0000': return -0x09; // 0xF7 : +// case '\u0000': return -0x08; // 0xF8 : +// case '\u0000': return -0x07; // 0xF9 : +// case '\u0000': return -0x06; // 0xFA : +// case '\u0000': return -0x05; // 0xFB : +// case '\u0000': return -0x04; // 0xFC : +// case '\u0000': return -0x03; // 0xFD : +// case '\u0000': return -0x02; // 0xFE : +// case '\u0000': return -0x01; // 0xFF : + default: return 0x3F; // ? Not valid character. + + } + } + } +} diff --git a/src/main/java/com/unicenta/pos/printer/escpos/UnicodeTranslatorSurePOS.java b/src/main/java/com/unicenta/pos/printer/escpos/UnicodeTranslatorSurePOS.java new file mode 100644 index 0000000..f078930 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/escpos/UnicodeTranslatorSurePOS.java @@ -0,0 +1,214 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.escpos; + +/** + * + * @author JG uniCenta + */ +public class UnicodeTranslatorSurePOS extends UnicodeTranslator { + + /** Creates a new instance of UnicodeTranslatorInt */ + public UnicodeTranslatorSurePOS() { + } + + /** + * + * @return + */ + @Override + public byte[] getCodeTable() { + return new byte[] {0x02}; // Multilingual International 858 + } + + /** + * + * @param sChar + * @return + */ + @Override + public byte transChar(char sChar) { + if ((sChar >= 0x0000) && (sChar < 0x0080)) { + return (byte) sChar; + } else { + switch (sChar) { + case '\u00c7': return -0x80; + case '\u00fc': return -0x7F; // u dieresis + case '\u00e2': return -0x7D; + case '\u00e4': return -0x7C; + case '\u00e0': return -0x7B; + case '\u00E5': return -0x7A; // ao + case '\u00e7': return -0x79; + case '\u00ea': return -0x78; + case '\u00eb': return -0x77; + case '\u00e8': return -0x76; + case '\u00ef': return -0x75; + case '\u00ee': return -0x74; + case '\u00ec': return -0x73; + case '\u00c4': return -0x72; + case '\u00C5': return -0x71; // Ao + + case '\u00c9': return -0x70; // E acute + case '\u00E6': return -0x6F; // ae + case '\u00C6': return -0x6E; // AE + case '\u00f4': return -0x6D; + case '\u00f6': return -0x6C; + case '\u00f2': return -0x6B; + case '\u00fb': return -0x6A; + case '\u00f9': return -0x69; + case '\u00ff': return -0x68; + case '\u00d6': return -0x67; + case '\u00dc': return -0x66; // U dieresis + case '\u00F8': return -0x65; // o/ + case '\u00A3': return -0x64; // L- Libra esterlina + case '\u00D8': return -0x63; // O/ + case '\u00D7': return -0x62; // X +// case '': return -0x61; // f + + case '\u00e1': return -0x60; // a acute + case '\u00e9': return -0x7E; // e acute + case '\u00ed': return -0x5F; // i acute + case '\u00f3': return -0x5E; // o acute + case '\u00fa': return -0x5D; // u acute + case '\u00f1': return -0x5C; // n tilde + case '\u00d1': return -0x5B; // N tilde + case '\u00aa': return -0x5A; + case '\u00ba': return -0x59; + case '\u00bf': return -0x58; // abrir interrogacion + case '\u00AE': return -0x57; // (R) Registrado + case '\u00ac': return -0x56; // Not sign + case '\u00BD': return -0x55; // 1/2 + case '\u00BC': return -0x54; // 1/4 + case '\u00a1': return -0x53; // abrir admiracion + case '\u00AB': return -0x52; // << + case '\u00BB': return -0x51; // >> + + case '\u2591': return -0x50; // Light shade + case '\u2592': return -0x4F; // Medium shade + case '\u2593': return -0x4E; // Dark shade + case '\u2502': return -0x4D; // BOX DRAWINGS LIGHT VERTICAL + case '\u2524': return -0x4C; // BOX DRAWINGS LIGHT VERTICAL AND LEFT + case '\u00c1': return -0x4B; // A acute + case '\u00c2': return -0x4A; + case '\u00c0': return -0x49; + case '\u00A9': return -0x48; // (c) Copyright + case '\u2563': return -0x47; // BOX DRAWINGS DOUBLE VERTICAL AND LEFT + case '\u2551': return -0x46; // BOX DRAWINGS DOUBLE VERTICAL + case '\u2557': return -0x45; // BOX DRAWINGS DOUBLE DOWN AND LEFT + case '\u255D': return -0x44; // BOX DRAWINGS DOUBLE UP AND LEFT + case '\u00A2': return -0x43; // Cent Sign + case '\u00A5': return -0x42; // Yen Sign + case '\u2510': return -0x41; // BOX DRAWINGS LIGHT DOWN AND LEFT + + case '\u2514': return -0x40; // BOX DRAWINGS LIGHT UP ANDRIGHT +// case '': return -0x3F; // +// case '': return -0x3E; // +// case '': return -0x3D; // +// case '': return -0x3C; // +// case '': return -0x3B; // +// case '': return -0x3A; // +// case '': return -0x39; // +// case '': return -0x38; // +// case '': return -0x37; // +// case '': return -0x36; // +// case '': return -0x35; // +// case '': return -0x34; // +// case '': return -0x33; // +// case '': return -0x32; // +// case '': return -0x31; // + +// case '': return -0x30; // +// case '': return -0x2F; // + case '\u00ca': return -0x2E; // + case '\u00cb': return -0x2D; // + case '\u00c8': return -0x2C; // + case '\u20ac': return (byte) 0xD5; // Euro Sign + case '\u00cd': return -0x2A; // I acute + case '\u00ce': return -0x29; // + case '\u00cf': return -0x28; // +// case '': return -0x27; // +// case '': return -0x26; // +// case '': return -0x25; // +// case '': return -0x24; // + case '|': return -0x23; // + case '\u00cc': return -0x22; // +// case '': return -0x21; // + + case '\u00d3': return -0x20; // O acute +// case '': return -0x1F; // + case '\u00d4': return -0x1E; // + case '\u00d2': return -0x1D; // +// case '': return -0x1C; // +// case '': return -0x1B; // +// case '': return -0x1A; // +// case '': return -0x19; // +// case '': return -0x18; // + case '\u00da': return -0x17; // U acute + case '\u00db': return -0x16; // + case '\u00d9': return -0x15; // + case '\u00fd': return -0x14; // + case '\u00dd': return -0x13; // +// case '': return -0x12; // + case '\u00b4': return -0x11; // + +// case '': return -0x10; // +// case '': return -0x0F; // +// case '': return -0x0E; // +// case '': return -0x0D; // +// case '': return -0x0C; // +// case '': return -0x0B; // +// case '': return -0x0A; // +// case '': return -0x09; // +// case '': return -0x08; // + case '\u00a8': return -0x07; // +// case '': return -0x06; // +// case '': return -0x05; // +// case '': return -0x04; // +// case '': return -0x03; // +// case '': return -0x02; // + // case ' ': return -0x01; // SP + + default: return 0x3F; // ? Not valid character. + +// Old translation +// case '\u00aa' : return (byte) 0xA6; +// case '\u00ba' : return (byte) 0xA7; +// case '\u00a1' : return (byte) 0xAD; +// case '\u00bf' : return (byte) 0xA8; +// case '\u00b7' : return (byte) 0xF9; +// case '\u00f1' : return (byte) 0xA4; +// case '\u00d1' : return (byte) 0xA5; +// case '\u00e1' : return (byte) 0xA0; +// case '\u00c1' : return (byte) 0x86; +// case '\u00e9' : return (byte) 0x82; +// case '\u00c9' : return (byte) 0x90; +// case '\u00ed' : return (byte) 0xA1; +// case '\u00cd' : return (byte) 0x8B; +// case '\u00f3' : return (byte) 0xA2; +// case '\u00d3' : return (byte) 0x9F; +// case '\u00fa' : return (byte) 0xA3; +// case '\u00da' : return (byte) 0x96; +// case '\u00fc' : return (byte) 0x81; +// case '\u00dc' : return (byte) 0x9A; +// default: return (byte) sChar; + } + } + } +} diff --git a/src/main/java/com/unicenta/pos/printer/javapos/DeviceDisplayJavaPOS.java b/src/main/java/com/unicenta/pos/printer/javapos/DeviceDisplayJavaPOS.java new file mode 100644 index 0000000..dab9c64 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/javapos/DeviceDisplayJavaPOS.java @@ -0,0 +1,136 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.javapos; + +import com.unicenta.pos.printer.DeviceDisplay; +import com.unicenta.pos.printer.DeviceDisplayBase; +import com.unicenta.pos.printer.DeviceDisplayImpl; +import com.unicenta.pos.printer.TicketPrinterException; +import jpos.JposException; +import jpos.LineDisplay; +import jpos.LineDisplayConst; + +/** + * + * @author JG uniCenta + */ +public class DeviceDisplayJavaPOS implements DeviceDisplay, DeviceDisplayImpl { + + private String m_sName; + private LineDisplay m_ld; + + private DeviceDisplayBase m_displaylines; + + /** Creates a new instance of DeviceDisplayJavaPOS + * @param sDeviceName + * @throws com.unicenta.pos.printer.TicketPrinterException */ + public DeviceDisplayJavaPOS(String sDeviceName) throws TicketPrinterException { + m_sName = sDeviceName; + + m_ld = new LineDisplay(); + try { + m_ld.open(m_sName); + m_ld.claim(10000); + m_ld.setDeviceEnabled(true); + } catch (JposException e) { + throw new TicketPrinterException(e.getMessage(), e); + } + + m_displaylines = new DeviceDisplayBase(this); + } + + /** + * + * @return + */ + @Override + public String getDisplayName() { + return m_sName; + } + + /** + * + * @return + */ + @Override + public String getDisplayDescription() { + return null; + } + + /** + * + * @return + */ + @Override + public javax.swing.JComponent getDisplayComponent() { + return null; + } + + /** + * + * @param animation + * @param sLine1 + * @param sLine2 + */ + @Override + public void writeVisor(int animation, String sLine1, String sLine2) { + m_displaylines.writeVisor(animation, sLine1, sLine2); + } + + /** + * + * @param sLine1 + * @param sLine2 + */ + @Override + public void writeVisor(String sLine1, String sLine2) { + m_displaylines.writeVisor(sLine1, sLine2); + } + + /** + * + */ + @Override + public void clearVisor() { + m_displaylines.clearVisor(); + } + + /** + * + */ + @Override + public void repaintLines() { + try { + m_ld.displayTextAt(0, 0, m_displaylines.getLine1(), LineDisplayConst.DISP_DT_NORMAL); + m_ld.displayTextAt(1, 0, m_displaylines.getLine2(), LineDisplayConst.DISP_DT_NORMAL); + } catch (JposException e) { + } + } + + @Override + public void finalize() throws Throwable { + + m_ld.setDeviceEnabled(false); + m_ld.release(); + m_ld.close(); + + super.finalize(); + } +} diff --git a/src/main/java/com/unicenta/pos/printer/javapos/DeviceFiscalPrinterJavaPOS.form b/src/main/java/com/unicenta/pos/printer/javapos/DeviceFiscalPrinterJavaPOS.form new file mode 100644 index 0000000..d5d6060 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/javapos/DeviceFiscalPrinterJavaPOS.form @@ -0,0 +1,246 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,73,0,0,2,15"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout"> + <Property name="useNullLayout" type="boolean" value="true"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="jButton1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="*X Report"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton1ActionPerformed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="30" y="10" width="130" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder title="*Receipt Title"/> + </Border> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="10" y="60" width="470" height="260"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout"> + <Property name="useNullLayout" type="boolean" value="true"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JTextField" name="jTextField1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="jTextField1"/> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="20" y="30" width="260" height="25"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JCheckBox" name="jCheckBox1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="jCheckBox1"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="0" left="0" right="0" top="0"/> + </Border> + </Property> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 0, 0, 0]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="290" y="30" width="110" height="25"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="jTextField2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="jTextField2"/> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="20" y="60" width="260" height="25"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JCheckBox" name="jCheckBox2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="jCheckBox2"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="0" left="0" right="0" top="0"/> + </Border> + </Property> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 0, 0, 0]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="290" y="60" width="110" height="25"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="jTextField3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="jTextField3"/> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="20" y="90" width="260" height="25"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="jTextField4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="jTextField4"/> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="20" y="120" width="260" height="25"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="jTextField5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="jTextField5"/> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="20" y="150" width="260" height="25"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JCheckBox" name="jCheckBox3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="jCheckBox3"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="0" left="0" right="0" top="0"/> + </Border> + </Property> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 0, 0, 0]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="290" y="90" width="110" height="25"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JCheckBox" name="jCheckBox4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="jCheckBox4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="0" left="0" right="0" top="0"/> + </Border> + </Property> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 0, 0, 0]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="290" y="120" width="110" height="25"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JCheckBox" name="jCheckBox5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="jCheckBox5"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="0" left="0" right="0" top="0"/> + </Border> + </Property> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 0, 0, 0]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="290" y="150" width="110" height="25"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JButton" name="jButton2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="*Z Report"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton2ActionPerformed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="20" y="220" width="130" height="-1"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/printer/javapos/DeviceFiscalPrinterJavaPOS.java b/src/main/java/com/unicenta/pos/printer/javapos/DeviceFiscalPrinterJavaPOS.java new file mode 100644 index 0000000..444ce64 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/javapos/DeviceFiscalPrinterJavaPOS.java @@ -0,0 +1,323 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.javapos; + +import com.unicenta.pos.printer.DeviceFiscalPrinter; +import com.unicenta.pos.printer.TicketPrinterException; +import com.unicenta.pos.util.RoundUtils; +import javax.swing.JComponent; +import jpos.FiscalPrinter; +import jpos.JposException; + +/** + * + * @author JG uniCenta + */ +public class DeviceFiscalPrinterJavaPOS extends javax.swing.JPanel implements DeviceFiscalPrinter { + + private String m_sName; + + private FiscalPrinter m_fiscal; + + /** Creates new form DeviceFiscalPrinterJavaPOSPanel + * @param sDeviceFiscalPrinterName + * @throws com.unicenta.pos.printer.TicketPrinterException */ + public DeviceFiscalPrinterJavaPOS(String sDeviceFiscalPrinterName) throws TicketPrinterException { + m_sName = sDeviceFiscalPrinterName; + + + m_fiscal = new FiscalPrinter(); + try { + m_fiscal.open(m_sName); + m_fiscal.claim(10000); + m_fiscal.setDeviceEnabled(true); + // m_printer.setMapMode(POSPrinterConst.PTR_MM_METRIC); // unit = 1/100 mm - i.e. 1 cm = 10 mm = 10 * 100 units + + m_fiscal.setCheckTotal(false); + + } catch (JposException e) { + throw new TicketPrinterException(e.getMessage(), e); + } + + initComponents(); + + + } + + /** + * + * @return + */ + @Override + public String getFiscalName() { + return m_sName; + } + + /** + * + * @return + */ + @Override + public JComponent getFiscalComponent() { + return this; + } + + /** + * + */ + @Override + public void beginReceipt() { + try { + m_fiscal.beginFiscalReceipt(true); + } catch (JposException e) { + } + } + + /** + * + */ + @Override + public void endReceipt() { + try { + m_fiscal.endFiscalReceipt(false); + } catch (JposException e) { + } + } + + /** + * + * @param sproduct + * @param dprice + * @param dunits + * @param taxinfo + */ + @Override + public void printLine(String sproduct, double dprice, double dunits, int taxinfo) { + try { + m_fiscal.printRecItem(sproduct, roundFiscal(dprice * dunits), (int)(dunits * 1000), taxinfo, roundFiscal(dprice), ""); + } catch (JposException e) { + } + } + + /** + * + * @param smessage + */ + @Override + public void printMessage(String smessage) { + try { + m_fiscal.printRecMessage(smessage); + } catch (JposException e) { + } + } + + /** + * + * @param sPayment + * @param dpaid + */ + @Override + public void printTotal(String sPayment, double dpaid) { + try { + // el primer valor es el total calculado por la aplicacion. + // al poner 0 no se debe chequear: CAPCHECKTOTAL = false. + m_fiscal.printRecTotal(0, roundFiscal(dpaid), sPayment); + } catch (JposException e) { + } + } + + /** + * + */ + @Override + public void printZReport() { + try { + m_fiscal.printZReport(); + } catch (JposException e) { + } + } + + /** + * + */ + @Override + public void printXReport() { + try { + m_fiscal.printXReport(); + } catch (JposException e) { + } + } + + @Override + public void finalize() throws Throwable { + + m_fiscal.setDeviceEnabled(false); + m_fiscal.release(); + m_fiscal.close(); + + super.finalize(); + } + + private int roundFiscal(double value) { + return (int) Math.floor(RoundUtils.round(value) * 10000.0 + 0.5); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jButton1 = new javax.swing.JButton(); + jPanel1 = new javax.swing.JPanel(); + jTextField1 = new javax.swing.JTextField(); + jCheckBox1 = new javax.swing.JCheckBox(); + jTextField2 = new javax.swing.JTextField(); + jCheckBox2 = new javax.swing.JCheckBox(); + jTextField3 = new javax.swing.JTextField(); + jTextField4 = new javax.swing.JTextField(); + jTextField5 = new javax.swing.JTextField(); + jCheckBox3 = new javax.swing.JCheckBox(); + jCheckBox4 = new javax.swing.JCheckBox(); + jCheckBox5 = new javax.swing.JCheckBox(); + jButton2 = new javax.swing.JButton(); + + setLayout(null); + + jButton1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jButton1.setText("*X Report"); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + add(jButton1); + jButton1.setBounds(30, 10, 130, 23); + + jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("*Receipt Title")); + jPanel1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel1.setLayout(null); + + jTextField1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jTextField1.setText("jTextField1"); + jPanel1.add(jTextField1); + jTextField1.setBounds(20, 30, 260, 25); + + jCheckBox1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jCheckBox1.setText("jCheckBox1"); + jCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0)); + jCheckBox1.setMargin(new java.awt.Insets(0, 0, 0, 0)); + jPanel1.add(jCheckBox1); + jCheckBox1.setBounds(290, 30, 110, 25); + + jTextField2.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jTextField2.setText("jTextField2"); + jPanel1.add(jTextField2); + jTextField2.setBounds(20, 60, 260, 25); + + jCheckBox2.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jCheckBox2.setText("jCheckBox2"); + jCheckBox2.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0)); + jCheckBox2.setMargin(new java.awt.Insets(0, 0, 0, 0)); + jPanel1.add(jCheckBox2); + jCheckBox2.setBounds(290, 60, 110, 25); + + jTextField3.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jTextField3.setText("jTextField3"); + jPanel1.add(jTextField3); + jTextField3.setBounds(20, 90, 260, 25); + + jTextField4.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jTextField4.setText("jTextField4"); + jPanel1.add(jTextField4); + jTextField4.setBounds(20, 120, 260, 25); + + jTextField5.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jTextField5.setText("jTextField5"); + jPanel1.add(jTextField5); + jTextField5.setBounds(20, 150, 260, 25); + + jCheckBox3.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jCheckBox3.setText("jCheckBox3"); + jCheckBox3.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0)); + jCheckBox3.setMargin(new java.awt.Insets(0, 0, 0, 0)); + jPanel1.add(jCheckBox3); + jCheckBox3.setBounds(290, 90, 110, 25); + + jCheckBox4.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jCheckBox4.setText("jCheckBox4"); + jCheckBox4.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0)); + jCheckBox4.setMargin(new java.awt.Insets(0, 0, 0, 0)); + jPanel1.add(jCheckBox4); + jCheckBox4.setBounds(290, 120, 110, 25); + + jCheckBox5.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jCheckBox5.setText("jCheckBox5"); + jCheckBox5.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0)); + jCheckBox5.setMargin(new java.awt.Insets(0, 0, 0, 0)); + jPanel1.add(jCheckBox5); + jCheckBox5.setBounds(290, 150, 110, 25); + + jButton2.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jButton2.setText("*Z Report"); + jButton2.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton2ActionPerformed(evt); + } + }); + jPanel1.add(jButton2); + jButton2.setBounds(20, 220, 130, 23); + + add(jPanel1); + jPanel1.setBounds(10, 60, 470, 260); + }// </editor-fold>//GEN-END:initComponents + + private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed + + printZReport(); + + }//GEN-LAST:event_jButton2ActionPerformed + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + + printXReport(); + + }//GEN-LAST:event_jButton1ActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + private javax.swing.JButton jButton2; + private javax.swing.JCheckBox jCheckBox1; + private javax.swing.JCheckBox jCheckBox2; + private javax.swing.JCheckBox jCheckBox3; + private javax.swing.JCheckBox jCheckBox4; + private javax.swing.JCheckBox jCheckBox5; + private javax.swing.JPanel jPanel1; + private javax.swing.JTextField jTextField1; + private javax.swing.JTextField jTextField2; + private javax.swing.JTextField jTextField3; + private javax.swing.JTextField jTextField4; + private javax.swing.JTextField jTextField5; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/printer/javapos/DevicePrinterJavaPOS.java b/src/main/java/com/unicenta/pos/printer/javapos/DevicePrinterJavaPOS.java new file mode 100644 index 0000000..842afaf --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/javapos/DevicePrinterJavaPOS.java @@ -0,0 +1,280 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.javapos; + +import com.unicenta.data.loader.ImageUtils; +import com.unicenta.pos.printer.DevicePrinter; +import com.unicenta.pos.printer.TicketPrinterException; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import javax.swing.JComponent; +import jpos.CashDrawer; +import jpos.JposException; +import jpos.POSPrinter; +import jpos.POSPrinterConst; + +/** + * + * @author JG uniCenta + */ +public class DevicePrinterJavaPOS implements DevicePrinter { + + private static final String JPOS_SIZE0 = "\u001b|1C"; + private static final String JPOS_SIZE1 = "\u001b|2C"; + private static final String JPOS_SIZE2 = "\u001b|3C"; + private static final String JPOS_SIZE3 = "\u001b|4C"; + private static final String JPOS_LF = "\n"; + private static final String JPOS_BOLD = "\u001b|bC"; + private static final String JPOS_UNDERLINE = "\u001b|uC"; + private static final String JPOS_CUT = "\u001b|100fP"; + + private String m_sName; + + private POSPrinter m_printer = null; + private CashDrawer m_drawer = null; + + private StringBuilder m_sline; + + /** Creates a new instance of DevicePrinterJavaPOS + * @param sDevicePrinterName + * @param sDeviceDrawerName + * @throws com.unicenta.pos.printer.TicketPrinterException */ + public DevicePrinterJavaPOS(String sDevicePrinterName, String sDeviceDrawerName) throws TicketPrinterException { + + m_sName = sDevicePrinterName; + if (sDeviceDrawerName != null && !sDeviceDrawerName.equals("")) { + m_sName += " - " + sDeviceDrawerName; + } + + try { + m_printer = new POSPrinter(); + m_printer.open(sDevicePrinterName); + m_printer.claim(10000); + m_printer.setDeviceEnabled(true); + m_printer.setMapMode(POSPrinterConst.PTR_MM_METRIC); // unit = 1/100 mm - i.e. 1 cm = 10 mm = 10 * 100 units + } catch (JposException e) { + // cannot live without the printer. + throw new TicketPrinterException(e.getMessage(), e); + } + + try { + m_drawer = new CashDrawer(); + m_drawer.open(sDeviceDrawerName); + m_drawer.claim(10000); + m_drawer.setDeviceEnabled(true); + } catch (JposException e) { + // can live without the drawer; + m_drawer = null; + } + } + + /** + * + * @return + */ + @Override + public String getPrinterName() { + return m_sName; + } + + /** + * + * @return + */ + @Override + public String getPrinterDescription() { + return null; + } + + /** + * + * @return + */ + @Override + public JComponent getPrinterComponent() { + return null; + } + + /** + * + */ + @Override + public void reset() { + } + + /** + * + */ + @Override + public void beginReceipt() { + try { + m_printer.transactionPrint(POSPrinterConst.PTR_S_RECEIPT, POSPrinterConst.PTR_TP_TRANSACTION); + } catch (JposException e) { + } + } + + /** + * + * @param image + */ + @Override + public void printImage(BufferedImage image) { + try { + if (m_printer.getCapRecBitmap()) { // si podemos imprimir bitmaps. + + File f = File.createTempFile("jposimg", ".png"); + try (OutputStream out = new FileOutputStream(f)) { + out.write(ImageUtils.writeImage(image)); + } + + m_printer.printBitmap(POSPrinterConst.PTR_S_RECEIPT, f.getAbsolutePath(), POSPrinterConst.PTR_BM_ASIS, POSPrinterConst.PTR_BM_CENTER); + } +// JG 16 May 12 use multicatch + } catch (IOException | JposException eIO) { + } + } + + /** + * + */ + @Override + public void printLogo(){ + } + + /** + * + * @param type + * @param position + * @param code + */ + @Override + public void printBarCode(String type, String position, String code) { + try { + if (m_printer.getCapRecBarCode()) { // si podemos imprimir codigos de barras + if (DevicePrinter.POSITION_NONE.equals(position)) { + m_printer.printBarCode(POSPrinterConst.PTR_S_RECEIPT, code, POSPrinterConst.PTR_BCS_EAN13, 10 * 100, 60 * 100, POSPrinterConst.PTR_BC_CENTER, POSPrinterConst.PTR_BC_TEXT_NONE); + } else { + m_printer.printBarCode(POSPrinterConst.PTR_S_RECEIPT, code, POSPrinterConst.PTR_BCS_EAN13, 10 * 100, 60 * 100, POSPrinterConst.PTR_BC_CENTER, POSPrinterConst.PTR_BC_TEXT_BELOW); + } + } + } catch (JposException e) { + } + } + + /** + * + * @param iTextSize + */ + @Override + public void beginLine(int iTextSize) { + m_sline = new StringBuilder(); + if (iTextSize == DevicePrinter.SIZE_0) { + m_sline.append(JPOS_SIZE0); + } else if (iTextSize == DevicePrinter.SIZE_1) { + m_sline.append(JPOS_SIZE1); + } else if (iTextSize == DevicePrinter.SIZE_2) { + m_sline.append(JPOS_SIZE2); + } else if (iTextSize == DevicePrinter.SIZE_3) { + m_sline.append(JPOS_SIZE3); + } else { + m_sline.append(JPOS_SIZE0); + } + } + + /** + * + * @param iStyle + * @param sText + */ + @Override + public void printText(int iStyle, String sText) { + + if ((iStyle & DevicePrinter.STYLE_BOLD) != 0) { + m_sline.append(JPOS_BOLD); + } + if ((iStyle & DevicePrinter.STYLE_UNDERLINE) != 0) { + m_sline.append(JPOS_UNDERLINE); + } + m_sline.append(sText); + } + + /** + * + */ + @Override + public void endLine() { + + m_sline.append(JPOS_LF); + try { + m_printer.printNormal(POSPrinterConst.PTR_S_RECEIPT, m_sline.toString()); + } catch (JposException e) { + } + m_sline = null; + } + + /** + * + */ + @Override + public void endReceipt() { + try { + // cut the receipt + m_printer.printNormal(POSPrinterConst.PTR_S_RECEIPT, JPOS_CUT); + + // end of the transaction + m_printer.transactionPrint(POSPrinterConst.PTR_S_RECEIPT, POSPrinterConst.PTR_TP_NORMAL); + } catch (JposException e) { + } + } + + /** + * + */ + + @Override + public void openDrawer() { + + if (m_drawer != null) { + try { + m_drawer.openDrawer(); + } catch (JposException e) { + } + } + } + + @Override + public void finalize() throws Throwable { + + m_printer.setDeviceEnabled(false); + m_printer.release(); + m_printer.close(); + + if (m_drawer != null) { + m_drawer.setDeviceEnabled(false); + m_drawer.release(); + m_drawer.close(); + } + + super.finalize(); + } +} diff --git a/src/main/java/com/unicenta/pos/printer/printer/DevicePrinterPrinter.java b/src/main/java/com/unicenta/pos/printer/printer/DevicePrinterPrinter.java new file mode 100644 index 0000000..30d3987 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/printer/DevicePrinterPrinter.java @@ -0,0 +1,362 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.printer; + +import com.unicenta.data.gui.JMessageDialog; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.printer.DevicePrinter; +import com.unicenta.pos.printer.ticket.BasicTicket; +import com.unicenta.pos.printer.ticket.BasicTicketForPrinter; +import com.unicenta.pos.util.ReportUtils; +import com.unicenta.pos.util.SelectPrinter; +import lombok.extern.slf4j.Slf4j; + +import javax.print.*; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.print.attribute.standard.JobName; +import javax.print.attribute.standard.Media; +import javax.print.attribute.standard.MediaSizeName; +import javax.print.attribute.standard.OrientationRequested; +import javax.swing.*; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.HashMap; + +/** + * Class DevicePrinterPrinter is responsible for printing tickets using system <br> + * printers. It takes into consideration if a user set a printer as a receipt <br> + * printer or not. + * <p>For receipt printers lenght of a receipt must be calculated in this class.</p> + * <p>For normal printers number of pages must be calculated dynamically in the <br> + * class PrintableTicket @see com.unicenta.pos.printer.printer.PrintableTicket + * + * @author jaroslawwozniak + */ +@Slf4j +public class DevicePrinterPrinter implements DevicePrinter { + + private Component parent; + /*name of a printer*/ + private String m_sName; + /*a ticket to print*/ +// private BasicTicketForPrinter m_ticketcurrent; + private BasicTicket m_ticketcurrent; + /*system printer*/ + private PrintService printservice; + +// // For Page Size 72mm x 200mm && MediaSizeName A4. +// private static final int imageable_width = 190; +// private static final int imageable_height = 546; +// private static final int imageable_x = 10; +// private static final int imageable_y = 287; +// private static final Media media = MediaSizeName.ISO_A4; + +// // For Page Size A4 && MediaSizeName A4. +// private static final int imageable_width = 451; +// private static final int imageable_height = 698; +// private static final int imageable_x = 72; +// private static final int imageable_y = 72; +// private static final Media media = MediaSizeName.ISO_A4; + + private int imageable_width; + private int imageable_height; + private int imageable_x; + private int imageable_y; + private Media media; + + // JG 16 May 12 use multicatch + private static final HashMap<String, MediaSizeName> mediasizenamemap = new HashMap<>(); + + /** + * Creates a new instance of DevicePrinterPrinter + * + * @param parent + * @param printername - name of printer that will be called in the system + * @param imageable_x + * @param imageable_y + * @param imageable_height + * @param imageable_width + * @param mediasizename + */ + public DevicePrinterPrinter(Component parent, String printername, int imageable_x, int imageable_y, int imageable_width, int imageable_height, String mediasizename) { + + this.parent = parent; + m_sName = "Printer"; // "AppLocal.getIntString("printer.screen"); + m_ticketcurrent = null; + printservice = ReportUtils.getPrintService(printername); + + this.imageable_x = imageable_x; + this.imageable_y = imageable_y; + this.imageable_width = imageable_width; + this.imageable_height = imageable_height; + this.media = getMedia(mediasizename); + } + + /** + * Getter that returns the name of a printer + * + * @return m_sName a name of a printer + */ + @Override + public String getPrinterName() { + return m_sName; + } + + /** + * Getter that returns the description of a printer + * + * @return description of a printer + */ + @Override + public String getPrinterDescription() { + return null; + } + + /** + * Getter that returns the printer's component + * + * @return printer's component + */ + @Override + public JComponent getPrinterComponent() { + return null; + } + + /** + * Method that sets the current ticket as a null + */ + @Override + public void reset() { + m_ticketcurrent = null; + } + + /** + * Method that is responsible for start a new ticket + */ + @Override + public void beginReceipt() { + m_ticketcurrent = new BasicTicketForPrinter(); + } + + /** + * Method that is responsible for printing an image + * + * @param image a buffered image object + */ + @Override + public void printImage(BufferedImage image) { + m_ticketcurrent.printImage(image); + } + + @Override + public void printLogo() { + } + + /** + * @param type + * @param position + * @param code + */ + @Override + public void printBarCode(String type, String position, String code) { + m_ticketcurrent.printBarCode(type, position, code); + } + + /** + * Method that is responsible for starting a new line on a receipt + * + * @param iTextSize a size of text in the line + */ + @Override + public void beginLine(int iTextSize) { + m_ticketcurrent.beginLine(iTextSize); + } + + /** + * Method that is responsible for printing text + * + * @param iStyle style of text + * @param sText text to print + */ + @Override + public void printText(int iStyle, String sText) { + m_ticketcurrent.printText(iStyle, sText); + } + + /** + * Method that is responsible for ending a line + */ + @Override + public void endLine() { + m_ticketcurrent.endLine(); + } + + /** + * Method that is responsible for ending and printing a ticket<br> + * It manages to get a printerJob, set the name of the job, get a Book object<br> + * and print the receipt + */ + @Override + public void endReceipt() { + + try { + + PrintService ps; + + if (printservice == null) { + String[] printers = ReportUtils.getPrintNames(); + if (printers.length == 0) { + log.error(AppLocal.getIntString("message.noprinters")); + ps = null; + } else { + SelectPrinter selectprinter = SelectPrinter.getSelectPrinter(parent, printers); + selectprinter.setVisible(true); + if (selectprinter.isOK()) { + ps = ReportUtils.getPrintService(selectprinter.getPrintService()); + } else { + ps = null; + } + } + } else { + ps = printservice; + } + + if (ps != null) { + + PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); + aset.add(OrientationRequested.PORTRAIT); + aset.add(new JobName(AppLocal.APP_NAME + " - Document", null)); + aset.add(media); + + DocPrintJob printjob = ps.createPrintJob(); + Doc doc = new SimpleDoc(new PrintableBasicTicket(m_ticketcurrent, imageable_x, imageable_y, imageable_width, imageable_height), DocFlavor.SERVICE_FORMATTED.PRINTABLE, null); + + printjob.print(doc, aset); + } + + } catch (PrintException ex) { + log.error(ex.getMessage()); + JMessageDialog.showMessage(parent, new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.printererror"), ex)); + } + + //ticket is not needed any more + m_ticketcurrent = null; + } + + /** + * Method that is responsible for opening a drawer + */ + + @Override + public void openDrawer() { + // Una simulacion + Toolkit.getDefaultToolkit().beep(); + } + + private static MediaSizeName getMedia(String mediasizename) { + return mediasizenamemap.get(mediasizename); + } + + static { + mediasizenamemap.put("Postcard", MediaSizeName.JAPANESE_POSTCARD); + mediasizenamemap.put("Statement", MediaSizeName.INVOICE); + + mediasizenamemap.put("Letter", MediaSizeName.NA_LETTER); + mediasizenamemap.put("Executive", MediaSizeName.EXECUTIVE); + mediasizenamemap.put("Legal", MediaSizeName.NA_LEGAL); + + mediasizenamemap.put("A0", MediaSizeName.ISO_A0); + mediasizenamemap.put("A1", MediaSizeName.ISO_A1); + mediasizenamemap.put("A2", MediaSizeName.ISO_A2); + mediasizenamemap.put("A3", MediaSizeName.ISO_A3); + mediasizenamemap.put("A4", MediaSizeName.ISO_A4); + mediasizenamemap.put("A5", MediaSizeName.ISO_A5); + mediasizenamemap.put("A6", MediaSizeName.ISO_A6); + mediasizenamemap.put("A7", MediaSizeName.ISO_A7); + mediasizenamemap.put("A8", MediaSizeName.ISO_A8); + mediasizenamemap.put("A9", MediaSizeName.ISO_A9); + mediasizenamemap.put("A10", MediaSizeName.ISO_A10); + + mediasizenamemap.put("B0", MediaSizeName.JIS_B0); + mediasizenamemap.put("B1", MediaSizeName.JIS_B1); + mediasizenamemap.put("B2", MediaSizeName.JIS_B2); + mediasizenamemap.put("B3", MediaSizeName.JIS_B3); + mediasizenamemap.put("B4", MediaSizeName.JIS_B4); + mediasizenamemap.put("B5", MediaSizeName.JIS_B5); + mediasizenamemap.put("B6", MediaSizeName.JIS_B6); + mediasizenamemap.put("B7", MediaSizeName.JIS_B7); + mediasizenamemap.put("B8", MediaSizeName.JIS_B8); + mediasizenamemap.put("B9", MediaSizeName.JIS_B9); + mediasizenamemap.put("B10", MediaSizeName.JIS_B10); + + mediasizenamemap.put("ISOB0", MediaSizeName.ISO_B0); + mediasizenamemap.put("ISOB1", MediaSizeName.ISO_B1); + mediasizenamemap.put("ISOB2", MediaSizeName.ISO_B2); + mediasizenamemap.put("ISOB3", MediaSizeName.ISO_B3); + mediasizenamemap.put("ISOB4", MediaSizeName.ISO_B4); + mediasizenamemap.put("ISOB5", MediaSizeName.ISO_B5); + mediasizenamemap.put("ISOB6", MediaSizeName.ISO_B6); + mediasizenamemap.put("ISOB7", MediaSizeName.ISO_B7); + mediasizenamemap.put("ISOB8", MediaSizeName.ISO_B8); + mediasizenamemap.put("ISOB9", MediaSizeName.ISO_B9); + mediasizenamemap.put("ISOB10", MediaSizeName.ISO_B10); + mediasizenamemap.put("EnvISOB0", MediaSizeName.ISO_B0); + mediasizenamemap.put("EnvISOB1", MediaSizeName.ISO_B1); + mediasizenamemap.put("EnvISOB2", MediaSizeName.ISO_B2); + mediasizenamemap.put("EnvISOB3", MediaSizeName.ISO_B3); + mediasizenamemap.put("EnvISOB4", MediaSizeName.ISO_B4); + mediasizenamemap.put("EnvISOB5", MediaSizeName.ISO_B5); + mediasizenamemap.put("EnvISOB6", MediaSizeName.ISO_B6); + mediasizenamemap.put("EnvISOB7", MediaSizeName.ISO_B7); + mediasizenamemap.put("EnvISOB8", MediaSizeName.ISO_B8); + mediasizenamemap.put("EnvISOB9", MediaSizeName.ISO_B9); + mediasizenamemap.put("EnvISOB10", MediaSizeName.ISO_B10); + + mediasizenamemap.put("C0", MediaSizeName.ISO_C0); + mediasizenamemap.put("C1", MediaSizeName.ISO_C1); + mediasizenamemap.put("C2", MediaSizeName.ISO_C2); + mediasizenamemap.put("C3", MediaSizeName.ISO_C3); + mediasizenamemap.put("C4", MediaSizeName.ISO_C4); + mediasizenamemap.put("C5", MediaSizeName.ISO_C5); + mediasizenamemap.put("C6", MediaSizeName.ISO_C6); + + mediasizenamemap.put("EnvPersonal", MediaSizeName.PERSONAL_ENVELOPE); + mediasizenamemap.put("EnvMonarch", MediaSizeName.MONARCH_ENVELOPE); + mediasizenamemap.put("Monarch", MediaSizeName.MONARCH_ENVELOPE); + mediasizenamemap.put("Env9", MediaSizeName.NA_NUMBER_9_ENVELOPE); + mediasizenamemap.put("Env10", MediaSizeName.NA_NUMBER_10_ENVELOPE); + mediasizenamemap.put("Env11", MediaSizeName.NA_NUMBER_11_ENVELOPE); + mediasizenamemap.put("Env12", MediaSizeName.NA_NUMBER_12_ENVELOPE); + mediasizenamemap.put("Env14", MediaSizeName.NA_NUMBER_14_ENVELOPE); + mediasizenamemap.put("c8x10", MediaSizeName.NA_8X10); + + mediasizenamemap.put("EnvDL", MediaSizeName.ISO_DESIGNATED_LONG); + mediasizenamemap.put("DL", MediaSizeName.ISO_DESIGNATED_LONG); + mediasizenamemap.put("EnvC0", MediaSizeName.ISO_C0); + mediasizenamemap.put("EnvC1", MediaSizeName.ISO_C1); + mediasizenamemap.put("EnvC2", MediaSizeName.ISO_C2); + mediasizenamemap.put("EnvC3", MediaSizeName.ISO_C3); + mediasizenamemap.put("EnvC4", MediaSizeName.ISO_C4); + mediasizenamemap.put("EnvC5", MediaSizeName.ISO_C5); + mediasizenamemap.put("EnvC6", MediaSizeName.ISO_C6); + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/printer/printer/PrintableBasicTicket.java b/src/main/java/com/unicenta/pos/printer/printer/PrintableBasicTicket.java new file mode 100644 index 0000000..d179256 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/printer/PrintableBasicTicket.java @@ -0,0 +1,100 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-20162009 Openbravo, S.L. +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.printer; + +import com.unicenta.pos.printer.ticket.BasicTicket; +import com.unicenta.pos.printer.ticket.PrintItem; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; + +/** + * + * @author adrianromero + */ +public class PrintableBasicTicket implements Printable { + + private int imageable_width; + private int imageable_height; + private int imageable_x; + private int imageable_y; + + private BasicTicket ticket; + + /** + * + * @param ticket + * @param imageable_x + * @param imageable_y + * @param imageable_width + * @param imageable_height + */ + public PrintableBasicTicket(BasicTicket ticket, int imageable_x, int imageable_y, int imageable_width, int imageable_height) { + this.ticket = ticket; + this.imageable_x = imageable_x; + this.imageable_y = imageable_y; + this.imageable_width = imageable_width; + this.imageable_height = imageable_height; + } + + @Override + public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { + + Graphics2D g2d = (Graphics2D) graphics; + + int line = 0; + int currentpage = 0; + int currentpagey = 0; + boolean printed = false; + + g2d.translate(imageable_x, imageable_y); + + java.util.List<PrintItem> commands = ticket.getCommands(); + + while (line < commands.size()) { + + int itemheight = commands.get(line).getHeight(); + + if (currentpagey + itemheight <= imageable_height) { + currentpagey += itemheight; + } else { + currentpage ++; + currentpagey = itemheight; + } + + if (currentpage < pageIndex) { + line ++; + } else if (currentpage == pageIndex) { + printed = true; + commands.get(line).draw(g2d, 0, currentpagey - itemheight, imageable_width); + + line ++; + } else if (currentpage > pageIndex) { + line ++; + } + } + + return printed + ? Printable.PAGE_EXISTS + : Printable.NO_SUCH_PAGE; + } +} diff --git a/src/main/java/com/unicenta/pos/printer/screen/DeviceDisplayPanel.form b/src/main/java/com/unicenta/pos/printer/screen/DeviceDisplayPanel.form new file mode 100644 index 0000000..1868195 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/screen/DeviceDisplayPanel.form @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" id="window" palette="3" red="ff" type="palette"/> + </Property> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder/> + </Border> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-127,0,0,1,126"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="16" left="16" right="16" top="16"/> + </Border> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="opaque" type="boolean" value="false"/> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> + <SubComponents> + <Component class="javax.swing.JLabel" name="jline1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="jline1"/> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="jline2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="jline2"/> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/printer/screen/DeviceDisplayPanel.java b/src/main/java/com/unicenta/pos/printer/screen/DeviceDisplayPanel.java new file mode 100644 index 0000000..413dab4 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/screen/DeviceDisplayPanel.java @@ -0,0 +1,200 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.screen; + +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.printer.DeviceDisplay; +import com.unicenta.pos.printer.DeviceDisplayBase; +import com.unicenta.pos.printer.DeviceDisplayImpl; +import java.awt.*; +import javax.swing.JComponent; +import javax.swing.JPanel; + +/** + * + * @author adrianromero + */ +public class DeviceDisplayPanel extends JPanel implements DeviceDisplay, DeviceDisplayImpl { + + private String m_sName; + + private DeviceDisplayBase m_displaylines; + + /** Creates new form JVisor */ + public DeviceDisplayPanel() { + this(1.0); + } + + /** + * + * @param dZoom + */ + public DeviceDisplayPanel(double dZoom) { + + initComponents(); + + m_sName = AppLocal.getIntString("display.screen"); + + jline1.setFont(new Font("Monospaced", Font.BOLD, (int)(16 * dZoom))); + jline2.setFont(new Font("Monospaced", Font.BOLD, (int)(16 * dZoom))); +// JG Feb' 16 - Revert +// Consolas intro'd in v4.1 but causes issue in RightToLeft languages i.e.: Arabic +// jline1.setFont(new Font("Consolas", Font.BOLD, (int)(16 * dZoom))); +// jline2.setFont(new Font("Consolas", Font.BOLD, (int)(16 * dZoom))); + + m_displaylines = new DeviceDisplayBase(this); + } + + /** + * + * @return + */ + @Override + public String getDisplayName() { + return m_sName; + } + + /** + * + * @return + */ + @Override + public String getDisplayDescription() { + return null; + } + + /** + * + * @return + */ + @Override + public JComponent getDisplayComponent() { + return this; + } + + /** + * + * @param animation + * @param sLine1 + * @param sLine2 + */ + @Override + public void writeVisor(int animation, String sLine1, String sLine2) { + + m_displaylines.writeVisor(animation, sLine1, sLine2); + } + + /** + * + * @param sLine1 + * @param sLine2 + */ + @Override + public void writeVisor(String sLine1, String sLine2) { + + m_displaylines.writeVisor(sLine1, sLine2); + } + + /** + * + */ + @Override + public void clearVisor() { + m_displaylines.clearVisor(); + } + + /** + * + */ + @Override + public void repaintLines() { + jline1.setText(m_displaylines.getLine1()); + jline2.setText(m_displaylines.getLine2()); + } + + @Override + protected void paintComponent(Graphics g) { + + paintBorder(g); + + Graphics2D g2d = (Graphics2D) g; + + Insets i = getInsets(); + + //g.setColor(getBackground()); + g2d.setPaint(new GradientPaint(getWidth() - i.left - i.right - 50, + getHeight() - i.top - i.bottom - 50, + getBackground(), + getWidth() - i.left - i.right, + getHeight() - i.top - i.bottom, + new Color(0xf0f0f0), true)); + g2d.fillRect(i.left, i.top, + getWidth() - i.left - i.right, + getHeight() - i.top - i.bottom); + + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + jPanel1 = new javax.swing.JPanel(); + jline1 = new javax.swing.JLabel(); + jline2 = new javax.swing.JLabel(); + + setBackground(javax.swing.UIManager.getDefaults().getColor("window")); + setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); + setLayout(new java.awt.BorderLayout()); + + jPanel1.setBorder(javax.swing.BorderFactory.createEmptyBorder(16, 16, 16, 16)); + jPanel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanel1.setOpaque(false); + jPanel1.setLayout(new java.awt.GridBagLayout()); + + jline1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jline1.setText("jline1"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + jPanel1.add(jline1, gridBagConstraints); + + jline2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jline2.setText("jline2"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + jPanel1.add(jline2, gridBagConstraints); + + add(jPanel1, java.awt.BorderLayout.CENTER); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JLabel jline1; + private javax.swing.JLabel jline2; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/printer/screen/DeviceDisplayWindow.form b/src/main/java/com/unicenta/pos/printer/screen/DeviceDisplayWindow.form new file mode 100644 index 0000000..c9a61fe --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/screen/DeviceDisplayWindow.form @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JFrameFormInfo"> + <Properties> + <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="Display.Window" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-11,0,0,2,-1"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generatePosition" type="boolean" value="false"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="false"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="m_jContainer"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="11" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/printer/screen/DeviceDisplayWindow.java b/src/main/java/com/unicenta/pos/printer/screen/DeviceDisplayWindow.java new file mode 100644 index 0000000..d542de3 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/screen/DeviceDisplayWindow.java @@ -0,0 +1,134 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.screen; + +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.printer.DeviceDisplay; +import java.io.IOException; +import javax.imageio.ImageIO; +import javax.swing.JComponent; + +/** + * + * @author adrian + */ +public class DeviceDisplayWindow extends javax.swing.JFrame implements DeviceDisplay { + + private final String m_sName; + private final DeviceDisplayPanel m_display; + + /** Creates new form DeviceDisplayWindow */ + public DeviceDisplayWindow() { + initComponents(); + + m_sName = AppLocal.getIntString("display.window"); + m_display = new DeviceDisplayPanel(3.0); + + m_jContainer.add(m_display.getDisplayComponent()); + try { + this.setIconImage(ImageIO.read(DeviceDisplayWindow.class.getResourceAsStream("/com/unicenta/images/favicon.png"))); + } catch (IOException e) { + } + + setVisible(true); + } + + /** + * + * @return + */ + @Override + public String getDisplayName() { + return m_sName; + } + + /** + * + * @return + */ + @Override + public String getDisplayDescription() { + return null; + } + + /** + * + * @return + */ + @Override + public JComponent getDisplayComponent() { + return null; + } + + /** + * + * @param animation + * @param sLine1 + * @param sLine2 + */ + @Override + public void writeVisor(int animation, String sLine1, String sLine2) { + m_display.writeVisor(animation, sLine1, sLine2); + } + + /** + * + * @param sLine1 + * @param sLine2 + */ + @Override + public void writeVisor(String sLine1, String sLine2) { + m_display.writeVisor(sLine1, sLine2); + } + + /** + * + */ + @Override + public void clearVisor() { + m_display.clearVisor(); + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jContainer = new javax.swing.JPanel(); + + setTitle(AppLocal.getIntString("display.window")); // NOI18N + + m_jContainer.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + m_jContainer.setFont(new java.awt.Font("Arial", 0, 11)); // NOI18N + m_jContainer.setLayout(new java.awt.BorderLayout()); + getContentPane().add(m_jContainer, java.awt.BorderLayout.CENTER); + + setSize(new java.awt.Dimension(767, 245)); + }// </editor-fold>//GEN-END:initComponents + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel m_jContainer; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/printer/screen/DevicePrinterPanel.form b/src/main/java/com/unicenta/pos/printer/screen/DevicePrinterPanel.form new file mode 100644 index 0000000..ce94b4f --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/screen/DevicePrinterPanel.form @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JScrollPane" name="m_jScrollView"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/printer/screen/DevicePrinterPanel.java b/src/main/java/com/unicenta/pos/printer/screen/DevicePrinterPanel.java new file mode 100644 index 0000000..c67c16b --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/screen/DevicePrinterPanel.java @@ -0,0 +1,188 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.screen; + +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.printer.DevicePrinter; +import com.unicenta.pos.printer.ticket.BasicTicket; +import com.unicenta.pos.printer.ticket.BasicTicketForScreen; +import java.awt.Toolkit; +import java.awt.image.BufferedImage; +import javax.swing.JComponent; + +/** + * + * @author JG uniCenta + */ +public class DevicePrinterPanel extends javax.swing.JPanel implements DevicePrinter { + + private final String m_sName; + + private final JTicketContainer m_jTicketContainer; + private BasicTicket m_ticketcurrent; + + /** Creates new form JPrinterScreen2 */ + public DevicePrinterPanel() { + initComponents(); + + m_sName = AppLocal.getIntString("printer.screen"); + + m_ticketcurrent = null; + + m_jTicketContainer = new JTicketContainer(); + m_jScrollView.setViewportView(m_jTicketContainer); + } + + /** + * + * @return + */ + @Override + public String getPrinterName() { + return m_sName; + } + + /** + * + */ + @Override + public void printLogo(){ + } + + /** + * + * @return + */ + @Override + public String getPrinterDescription() { + return null; + } + + /** + * + * @return + */ + @Override + public JComponent getPrinterComponent() { + return this; + } + + /** + * + */ + @Override + public void reset() { + m_ticketcurrent = null; + m_jTicketContainer.removeAllTickets(); + m_jTicketContainer.repaint(); + } + + @Override + public void beginReceipt() { + m_ticketcurrent = new BasicTicketForScreen(); + + } + + /** + * + * @param image + */ + @Override + public void printImage(BufferedImage image) { + m_ticketcurrent.printImage(image); + } + + /** + * + * @param type + * @param position + * @param code + */ + @Override + public void printBarCode(String type, String position, String code) { + m_ticketcurrent.printBarCode(type, position, code); + } + + /** + * + * @param iTextSize + */ + @Override + public void beginLine(int iTextSize) { + m_ticketcurrent.beginLine(iTextSize); + } + + /** + * + * @param iStyle + * @param sText + */ + @Override + public void printText(int iStyle, String sText) { + m_ticketcurrent.printText(iStyle, sText); + } + + /** + * + */ + @Override + public void endLine() { + m_ticketcurrent.endLine(); + } + + /** + * + */ + @Override + public void endReceipt() { + m_jTicketContainer.addTicket(new JTicket(m_ticketcurrent)); + m_ticketcurrent = null; + } + + /** + * + */ + @Override + public void openDrawer() { + Toolkit.getDefaultToolkit().beep(); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jScrollView = new javax.swing.JScrollPane(); + + setLayout(new java.awt.BorderLayout()); + + m_jScrollView.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + add(m_jScrollView, java.awt.BorderLayout.CENTER); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JScrollPane m_jScrollView; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/printer/screen/JTicket.form b/src/main/java/com/unicenta/pos/printer/screen/JTicket.form new file mode 100644 index 0000000..5218648 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/screen/JTicket.form @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" red="ff" type="rgb"/> + </Property> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder/> + </Border> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-93,0,0,0,-103"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> +</Form> diff --git a/src/main/java/com/unicenta/pos/printer/screen/JTicket.java b/src/main/java/com/unicenta/pos/printer/screen/JTicket.java new file mode 100644 index 0000000..b75c21b --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/screen/JTicket.java @@ -0,0 +1,107 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.screen; + +import com.unicenta.pos.printer.ticket.BasicTicket; +import java.awt.*; +import java.util.Map; + +class JTicket extends javax.swing.JPanel { + + private static final int H_GAP = 8; + private static final int V_GAP = 8; + private static final int COLUMNS = 42; + private static final int LINEWIDTH = COLUMNS * 7; + + private final BasicTicket basict; + private final Map desktophints; + + /** Creates new form JTicket */ + public JTicket(BasicTicket t) { + + basict = t; + desktophints = (Map) Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"); + initComponents(); + } + + @Override + protected void paintComponent(Graphics g) { + paintBorder(g); + + Graphics2D g2d = (Graphics2D) g; + + if (desktophints != null) { + g2d.addRenderingHints(desktophints); + } + + Insets i = getInsets(); + g2d.setPaint(new GradientPaint( + getWidth() - i.left - i.right - 100, + getHeight() - i.top - i.bottom - 100, + getBackground(), + getWidth() - i.left - i.right, + getHeight() - i.top - i.bottom, + new Color(0xf0f0f0), true)); + g2d.fillRect(i.left, i.top, + getWidth() - i.left - i.right, + getHeight() - i.top - i.bottom); + + g.setColor(getForeground()); + basict.draw(g2d, i.left + H_GAP, i.top + V_GAP, LINEWIDTH); + } + + + @Override + public Dimension getPreferredSize() { + Insets ins = getInsets(); + return new Dimension((int) ( + LINEWIDTH + 2 * H_GAP) + ins.left + ins.right + , (int) (basict.getHeight() + 2 * V_GAP) + ins.top + ins.bottom); + } + + @Override + public Dimension getMaximumSize() { + return getPreferredSize(); + } + + @Override + public Dimension getMinimumSize() { + return getPreferredSize(); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + setBackground(new java.awt.Color(255, 255, 255)); + setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + setLayout(new java.awt.BorderLayout()); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/printer/screen/JTicketContainer.form b/src/main/java/com/unicenta/pos/printer/screen/JTicketContainer.form new file mode 100644 index 0000000..cccf762 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/screen/JTicketContainer.form @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[700, 600]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-114,0,0,2,122"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> +</Form> diff --git a/src/main/java/com/unicenta/pos/printer/screen/JTicketContainer.java b/src/main/java/com/unicenta/pos/printer/screen/JTicketContainer.java new file mode 100644 index 0000000..5e09aeb --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/screen/JTicketContainer.java @@ -0,0 +1,133 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.screen; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Insets; +import java.awt.Rectangle; + +// JG 16 May 12 replace +// import java.awt.*; +// import java.awt.event.*; +// import java.awt.image.*; +// import java.util.*; +// import java.awt.print.*; + +// import javax.swing.*; +// import javax.swing.border.*; +// import javax.swing.event.*; + +/** + * + * @author Adrian + */ +class JTicketContainer extends javax.swing.JPanel { + + protected int H_GAP = 8; + protected int V_GAP = 8; + + /** Creates new form JTicketContainer */ + public JTicketContainer() { + initComponents(); + setLayout(null); + } + + @Override + public Dimension getPreferredSize() { + + Insets ins = getInsets(); + int iMaxx = 0; + int iMaxy = ins.top + V_GAP; + int n = getComponentCount(); + for(int i = 0; i < n; i++) { + Component comp = getComponent(i); + Dimension dc = comp.getPreferredSize(); + if (dc.width > iMaxx) { + iMaxx = dc.width; + } + iMaxy += V_GAP + dc.height; + } + + return new Dimension(iMaxx + 2 * H_GAP + ins.left + ins.right, iMaxy + ins.bottom); + } + + @Override + public Dimension getMaximumSize() { + return getPreferredSize(); + } + + @Override + public Dimension getMinimumSize() { + return getPreferredSize(); + } + + @Override + public void doLayout() { + Insets ins = getInsets(); + int x = ins.left + H_GAP; + int y = ins.top + V_GAP; + + int n = getComponentCount(); + for(int i = 0; i < n; i++) { + Component comp = getComponent(i); + Dimension dc = comp.getPreferredSize(); + + comp.setBounds(x, y, dc.width, dc.height); + y += V_GAP + dc.height; + } + } + + public void addTicket(JTicket ticket) { + + add(ticket); + + doLayout(); + revalidate(); + scrollRectToVisible(new Rectangle(0, getPreferredSize().height - 1, 1, 1)); + } + + public void removeAllTickets() { + + removeAll(); + + doLayout(); + revalidate(); + scrollRectToVisible(new Rectangle(0, 0, 1, 1)); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setPreferredSize(new java.awt.Dimension(700, 600)); + setLayout(new java.awt.BorderLayout()); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/printer/ticket.dtd b/src/main/java/com/unicenta/pos/printer/ticket.dtd new file mode 100644 index 0000000..7c4687b --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/ticket.dtd @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + uniCenta oPOS - Touch Friendly Point Of Sale + Copyright (c) 2009-2016 uniCenta & previous Openbravo POS works + http://sourceforge.net/projects/unicentaopos + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +--> + +<!ELEMENT output (ticket | display | opendrawer | play | )*> + +<!ELEMENT ticket (line | image | barcode | cut)*> +<!ATTLIST ticket printer CDATA "0"> + +<!ELEMENT line (text)*> +<!ATTLIST line size (0 | 1 | 2 | 3) "0"> + +<!ELEMENT text (#PCDATA)> +<!ATTLIST text align (left | right | center) "left"> +<!ATTLIST text length CDATA #IMPLIED> +<!ATTLIST text bold (true | false) "false"> +<!ATTLIST text underline (true | false) "false"> + +<!ELEMENT image (#PCDATA)> + +<!ELEMENT barcode (#PCDATA)> +<!ATTLIST barcode type (EAN13 | CODE128) "EAN13"> + +<!ELEMENT display (line)*> +<!ATTLIST display animation (scroll | flyer | blink | curtain | none) "none"> + +<!ELEMENT play (#PCDATA)> + +<!ELEMENT opendrawer EMPTY> +<!ATTLIST opendrawer printer CDATA "0"> \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/printer/ticket/BasicTicket.java b/src/main/java/com/unicenta/pos/printer/ticket/BasicTicket.java new file mode 100644 index 0000000..aa4ab1b --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/ticket/BasicTicket.java @@ -0,0 +1,169 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.ticket; + +import lombok.extern.log4j.Log4j2; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; + +/** + * + * @author JG uniCenta + */ +@Slf4j +public abstract class BasicTicket implements PrintItem { + + /** + * + */ + protected java.util.List<PrintItem> m_aCommands; + + /** + * + */ + protected PrintItemLine pil; + + /** + * + */ + protected int m_iBodyHeight; + + /** Creates a new instance of AbstractTicket */ + public BasicTicket() { +// JG 16 May 12 use diamond inference + m_aCommands = new ArrayList<>(); + pil = null; + m_iBodyHeight = 0; + } + + /** + * + * @return + */ + protected abstract Font getBaseFont(); + + /** + * + * @return + */ + protected abstract int getFontHeight(); + + /** + * + * @return + */ + protected abstract double getImageScale(); + + /** + * + * @return + */ + @Override + public int getHeight() { + return m_iBodyHeight; + } + + /** + * + * @param g2d + * @param x + * @param y + * @param width + */ + @Override + public void draw(Graphics2D g2d, int x, int y, int width) { + + int currenty = y; + for (PrintItem pi : m_aCommands) { + pi.draw(g2d, x, currenty, width); + currenty += pi.getHeight(); + } + } + + /** + * + * @return + */ + public java.util.List<PrintItem> getCommands() { + return m_aCommands; + } + + // INTERFAZ PRINTER 2 + + /** + * + * @param image + */ + public void printImage(BufferedImage image) { + + PrintItem pi = new PrintItemImage(image, getImageScale()); + m_aCommands.add(pi); + m_iBodyHeight += pi.getHeight(); + } + + /** + * + * @param type + * @param position + * @param code + */ + public void printBarCode(String type, String position, String code) { + + PrintItem pi = new PrintItemBarcode(type, position, code, getImageScale()); + m_aCommands.add(pi); + m_iBodyHeight += pi.getHeight(); + } + + /** + * + * @param iTextSize + */ + public void beginLine(int iTextSize) { + pil = new PrintItemLine(iTextSize, getBaseFont(), getFontHeight()); + } + + /** + * + * @param iStyle + * @param sText + */ + public void printText(int iStyle, String sText) { + if (pil != null) { + pil.addText(iStyle, sText); + } + } + + /** + * + */ + public void endLine() { + if (pil != null) { + m_aCommands.add(pil); + m_iBodyHeight += pil.getHeight(); + pil = null; + } + } + } \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/printer/ticket/BasicTicketForPrinter.java b/src/main/java/com/unicenta/pos/printer/ticket/BasicTicketForPrinter.java new file mode 100644 index 0000000..90f5669 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/ticket/BasicTicketForPrinter.java @@ -0,0 +1,73 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.ticket; + +import java.awt.Font; +import java.awt.geom.AffineTransform; + +/** + * + * @author jaroslawwozniak + * @author adrianromero + + */ +public class BasicTicketForPrinter extends BasicTicket { + +// private static final Font BASEFONT = new Font("Monospaced", + private static final Font BASEFONT = new Font("Courier New", + Font.PLAIN, 7).deriveFont(AffineTransform.getScaleInstance(1.0, 1.50)); + private static final int FONTHEIGHT = 12; + +// private static Font BASEFONT = new Font("Monospaced", + // Font.PLAIN, 7).deriveFont(AffineTransform.getScaleInstance(1.0, 1.40)); + +// JG Feb' 16 - Revert +// Consolas intro'd in v4.1 but causes issue in RightToLeft languages i.e.: Arabic +// private static Font BASEFONT = new Font("Consolas", Font.PLAIN,8).deriveFont(AffineTransform.getScaleInstance(1.0, 1.40)); +// private static int FONTHEIGHT = 12; + + private static final double IMAGE_SCALE = 0.65; + + /** + * + * @return + */ + @Override + protected Font getBaseFont() { + return BASEFONT; + } + + /** + * + * @return + */ + @Override + protected int getFontHeight() { + return FONTHEIGHT; + } + + /** + * + * @return + */ + @Override protected double getImageScale() { + return IMAGE_SCALE; + } + } \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/printer/ticket/BasicTicketForScreen.java b/src/main/java/com/unicenta/pos/printer/ticket/BasicTicketForScreen.java new file mode 100644 index 0000000..dce5fb6 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/ticket/BasicTicketForScreen.java @@ -0,0 +1,68 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + + +package com.unicenta.pos.printer.ticket; + +import java.awt.Font; +import java.awt.geom.AffineTransform; + +/** + * + * @author JG uniCenta + */ +public class BasicTicketForScreen extends BasicTicket { + +// private static Font BASEFONT = new Font("Monospaced", + private static Font BASEFONT = new Font("Courier New", + Font.PLAIN, 12).deriveFont(AffineTransform.getScaleInstance(1.0, 1.40)); +// JG Feb' 16 - Revert +// Consolas intro'd in v4.1 but causes issue in RightToLeft languages i.e.: Arabic +// private static Font BASEFONT = new Font("Consolas", Font.PLAIN, 12).deriveFont(AffineTransform.getScaleInstance(1.0, 1.40)); + + private static int FONTHEIGHT = 20; + private static double IMAGE_SCALE = 1.0; + + /** + * + * @return + */ + @Override + protected Font getBaseFont() { + return BASEFONT; + } + + /** + * + * @return + */ + @Override + protected int getFontHeight() { + return FONTHEIGHT; + } + + /** + * + * @return + */ + @Override + protected double getImageScale() { + return IMAGE_SCALE; + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/printer/ticket/MyPrinterState.java b/src/main/java/com/unicenta/pos/printer/ticket/MyPrinterState.java new file mode 100644 index 0000000..36fed3d --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/ticket/MyPrinterState.java @@ -0,0 +1,103 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.ticket; + +import com.unicenta.pos.printer.DevicePrinter; +import java.awt.Font; +import java.awt.geom.AffineTransform; + +/** + * + * @author JG uniCenta + */ +public class MyPrinterState { + + private int m_iSize; + + /** Creates a new instance of PrinterState + * @param iSize */ + public MyPrinterState(int iSize) { + m_iSize = iSize; + } + + /** + * + * @return + */ + public int getLineMult() { + return getLineMult(m_iSize); + } + + /** + * + * @param iSize + * @return + */ + public static int getLineMult(int iSize) { + switch (iSize) { + case 0: + case 2: + return 1; + case 1: + case 3: + return 2; + default: + return 1; + } + } + + /** + * + * @param baseFont + * @param iStyle + * @return + */ + public Font getFont(Font baseFont, int iStyle) { + + Font f; + AffineTransform a; + switch (m_iSize) { + case 0: + f = baseFont; + break; + case 2: + a = AffineTransform.getScaleInstance(2.0, 1.0); + a.preConcatenate(baseFont.getTransform()); + f = baseFont.deriveFont(a); + break; + case 1: + a = AffineTransform.getScaleInstance(1.0, 2.0); + a.preConcatenate(baseFont.getTransform()); + f = baseFont.deriveFont(a); + break; + case 3: + a = AffineTransform.getScaleInstance(2.0, 2.0); + a.preConcatenate(baseFont.getTransform()); + f = baseFont.deriveFont(a); + break; + default: + f = baseFont; + break; + } + f = f.deriveFont((iStyle & DevicePrinter.STYLE_BOLD) != 0 ? Font.BOLD : baseFont.getStyle()); + // Falta aplicar el subrayado + return f; + } +} diff --git a/src/main/java/com/unicenta/pos/printer/ticket/PrintItem.java b/src/main/java/com/unicenta/pos/printer/ticket/PrintItem.java new file mode 100644 index 0000000..917844c --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/ticket/PrintItem.java @@ -0,0 +1,44 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.ticket; + +import java.awt.Graphics2D; + +/** + * + * @author JG uniCenta + */ +public interface PrintItem { + + /** + * + * @return + */ + public int getHeight(); + + /** + * + * @param g + * @param x + * @param y + * @param width + */ + public void draw(Graphics2D g, int x, int y, int width); +} diff --git a/src/main/java/com/unicenta/pos/printer/ticket/PrintItemBarcode.java b/src/main/java/com/unicenta/pos/printer/ticket/PrintItemBarcode.java new file mode 100644 index 0000000..8e7136c --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/ticket/PrintItemBarcode.java @@ -0,0 +1,118 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.ticket; + +import com.unicenta.pos.printer.DevicePrinter; +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import org.krysalis.barcode4j.BarcodeDimension; +import org.krysalis.barcode4j.HumanReadablePlacement; +import org.krysalis.barcode4j.impl.AbstractBarcodeBean; +import org.krysalis.barcode4j.impl.code128.Code128Bean; +import org.krysalis.barcode4j.impl.upcean.*; +import org.krysalis.barcode4j.output.java2d.Java2DCanvasProvider; + +/** + * + * @author JG uniCenta + */ +public class PrintItemBarcode implements PrintItem { + + /** + * + */ + protected AbstractBarcodeBean m_barcode; + protected String m_sCode; + protected int m_iWidth; + protected int m_iHeight; + protected double scale; + + /** Creates a new instance of PrinterItemBarcode + * @param type + * @param position + * @param code + * @param scale */ + public PrintItemBarcode(String type, String position, String code, double scale) { + + m_sCode = code; + this.scale = scale; + + if (DevicePrinter.BARCODE_CODE128.equals(type)) { + m_barcode = new Code128Bean(); + } else { + m_barcode = new EAN13Bean(); + } + + if (m_barcode != null) { + m_barcode.setModuleWidth(1.0); + m_barcode.setBarHeight(40.0); + m_barcode.setFontSize(10.0); + m_barcode.setQuietZone(10.0); + m_barcode.doQuietZone(true); + if (DevicePrinter.POSITION_NONE.equals(position)) { + m_barcode.setMsgPosition(HumanReadablePlacement.HRP_NONE); + } else { + m_barcode.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM); + } + BarcodeDimension dim = m_barcode.calcDimensions(m_sCode); + m_iWidth = (int) dim.getWidth(0); + m_iHeight = (int) dim.getHeight(0); + } + } + + /** + * + * @param g + * @param x + * @param y + * @param width + */ + @Override + public void draw(Graphics2D g, int x, int y, int width) { + + if (m_barcode != null) { + Graphics2D g2d = (Graphics2D) g; + + AffineTransform oldt = g2d.getTransform(); + + g2d.translate(x - 10 + (width - (int)(m_iWidth * scale)) / 2, y + 10); + g2d.scale(scale, scale); + + try { + m_barcode.generateBarcode(new Java2DCanvasProvider(g2d, 0), m_sCode); + } catch (IllegalArgumentException e) { + g2d.drawRect(0, 0, m_iWidth, m_iHeight); + g2d.drawLine(0, 0, m_iWidth, m_iHeight); + g2d.drawLine(m_iWidth, 0, 0, m_iHeight); + } + + g2d.setTransform(oldt); + } + } + + /** + * + * @return + */ + @Override + public int getHeight() { + return (int) (m_iHeight * scale) + 20; + } +} diff --git a/src/main/java/com/unicenta/pos/printer/ticket/PrintItemImage.java b/src/main/java/com/unicenta/pos/printer/ticket/PrintItemImage.java new file mode 100644 index 0000000..5201b1f --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/ticket/PrintItemImage.java @@ -0,0 +1,73 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.ticket; + +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +/** + * + * @author JG uniCenta + */ +public class PrintItemImage implements PrintItem { + + /** + * + */ + protected BufferedImage image; + + /** + * + */ + protected double scale; + + /** Creates a new instance of PrintItemImage + * @param image + * @param scale + */ + public PrintItemImage(BufferedImage image, double scale) { + this.image = image; + this.scale = scale; + } + + /** + * + * @param g + * @param x + * @param y + * @param width + */ + @Override + public void draw(Graphics2D g, int x, int y, int width) { + g.drawImage(image, x + (width - (int)(image.getWidth() * scale)) / 2, y, + (int)(image.getWidth() * scale), + (int)(image.getHeight() * scale) + , null); + } + + /** + * + * @return + */ + @Override + public int getHeight() { + return (int) (image.getHeight() * scale); + } +} diff --git a/src/main/java/com/unicenta/pos/printer/ticket/PrintItemLine.java b/src/main/java/com/unicenta/pos/printer/ticket/PrintItemLine.java new file mode 100644 index 0000000..db58c84 --- /dev/null +++ b/src/main/java/com/unicenta/pos/printer/ticket/PrintItemLine.java @@ -0,0 +1,129 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.printer.ticket; + +import java.awt.Font; +import java.awt.Graphics2D; +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author JG uniCenta + */ +public class PrintItemLine implements PrintItem { + + /** + * + */ + protected Font font; + + /** + * + */ + protected int fontheight; + + /** + * + */ + protected int textsize; + + /** + * + */ + protected List<StyledText> m_atext; + + /** Creates a new instance of PrinterItemLine + * @param textsize + * @param font + * @param fontheight */ + public PrintItemLine(int textsize, Font font, int fontheight) { + this.textsize = textsize; + this.font = font; + this.fontheight = fontheight; + +// JG 16 May 12 use diamond inference + m_atext = new ArrayList<>(); + } + + /** + * + * @param style + * @param text + */ + public void addText(int style, String text) { + m_atext.add(new StyledText(style, text)); + } + + /** + * + * @param g + * @param x + * @param y + * @param width + */ + @Override + public void draw(Graphics2D g, int x, int y, int width) { + + MyPrinterState ps = new MyPrinterState(textsize); + float left = x; + for (int i = 0; i < m_atext.size(); i++) { + StyledText t = m_atext.get(i); + g.setFont(ps.getFont(font, t.style)); + g.drawString(t.text, left, (float) y); + left += g.getFontMetrics().getStringBounds(t.text, g).getWidth(); + } + } + + /** + * + * @return + */ + @Override + public int getHeight() { + return fontheight * MyPrinterState.getLineMult(textsize); + } + + /** + * + */ + protected static class StyledText { + + /** + * + * @param style + * @param text + */ + public StyledText(int style, String text) { + this.style = style; + this.text = text; + } + + /** + * + */ + public int style; + + /** + * + */ + public String text; + } +} diff --git a/src/main/java/com/unicenta/pos/reports/JPanelReport.form b/src/main/java/com/unicenta/pos/reports/JPanelReport.form new file mode 100644 index 0000000..e364854 --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/JPanelReport.form @@ -0,0 +1,100 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanelHeader"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanelFilter"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + </Container> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="2"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JToggleButton" name="jToggleFilter"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/1downarrow.png"/> + </Property> + <Property name="selected" type="boolean" value="true"/> + <Property name="toolTipText" type="java.lang.String" value="Hide/Show Filter"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="selectedIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/1uparrow.png"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jToggleFilterActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jButton1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.executereport" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Execute Report"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton1ActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/reports/JPanelReport.java b/src/main/java/com/unicenta/pos/reports/JPanelReport.java new file mode 100644 index 0000000..3f24800 --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/JPanelReport.java @@ -0,0 +1,330 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.reports; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.loader.BaseSentence; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.loader.Session; +import com.unicenta.data.user.EditorCreator; +import com.unicenta.pos.forms.*; +import com.unicenta.pos.sales.TaxesLogic; +import com.unicenta.pos.util.JRViewer400; +import java.awt.BorderLayout; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.sql.Connection; +import java.util.HashMap; +import java.util.Map; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import javax.swing.JComponent; +import javax.swing.JPanel; +import net.sf.jasperreports.engine.*; +import net.sf.jasperreports.engine.design.JasperDesign; +import net.sf.jasperreports.engine.xml.JRXmlLoader; + +/** + * + * @author JG uniCenta + */ +public abstract class JPanelReport extends JPanel implements JPanelView, BeanFactoryApp { + + private JRViewer400 reportviewer = null; + private JasperReport jr = null; + private EditorCreator editor = null; + + /** + * + */ + protected AppView m_App; + private Session s; + private Connection con; + + /** + * + */ + protected SentenceList taxsent; + + /** + * + */ + protected TaxesLogic taxeslogic; + + /** Creates new form JPanelReport */ + public JPanelReport() { + + initComponents(); + } + + /** + * + * @param app + * @throws BeanFactoryException + */ + @Override + public void init(AppView app) throws BeanFactoryException { + + m_App = app; + + DataLogicSales dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + taxsent = dlSales.getTaxList(); + + editor = getEditorCreator(); + if (editor instanceof ReportEditorCreator) { + jPanelFilter.add(((ReportEditorCreator) editor).getComponent(), BorderLayout.CENTER); + } + + reportviewer = new JRViewer400(null); + + add(reportviewer, BorderLayout.CENTER); + + try { + + InputStream in = getClass().getResourceAsStream(getReport() + ".ser"); + if (in == null) { + // read and compile the report + JasperDesign jd = JRXmlLoader.load(getClass().getResourceAsStream(getReport() + ".jrxml")); + jr = JasperCompileManager.compileReport(jd); + } else { +// JG 16 May 12 use try-with-resources + try (ObjectInputStream oin = new ObjectInputStream(in)) { + jr = (JasperReport) oin.readObject(); + } + } +// JG 16 May 12 use multicatch + } catch (JRException | IOException | ClassNotFoundException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotloadreport"), e); + msg.show(this); + jr = null; + } + } + + /** + * + * @return + */ + @Override + public Object getBean() { + return this; + } + + /** + * + * @return + */ + protected abstract String getReport(); + + /** + * + * @return + */ + protected abstract String getResourceBundle(); + + /** + * + * @return + */ + protected abstract BaseSentence getSentence(); + + /** + * + * @return + */ + protected abstract ReportFields getReportFields(); + + /** + * + * @return + */ + protected EditorCreator getEditorCreator() { + return null; + } + + /** + * + * @return + */ + @Override + public JComponent getComponent() { + return this; + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + + setVisibleFilter(true); + taxeslogic = new TaxesLogic(taxsent.list()); + } + + /** + * + * @return + */ + @Override + public boolean deactivate() { + + reportviewer.loadJasperPrint(null); + return true; + } + + /** + * + * @param value + */ + protected void setVisibleButtonFilter(boolean value) { + jToggleFilter.setVisible(value); + } + + /** + * + * @param value + */ + protected void setVisibleFilter(boolean value) { + jToggleFilter.setSelected(value); + jToggleFilterActionPerformed(null); + } + + private void launchreport() { + + m_App.waitCursorBegin(); + + if (jr != null) { + try { + + // Archivo de recursos + String res = getResourceBundle(); + + // Parametros y los datos + Object params = (editor == null) ? null : editor.createValue(); + JRDataSource data = new JRDataSourceBasic(getSentence(), getReportFields(), params); + + // Construyo el mapa de los parametros. + Map reportparams = new HashMap(); + reportparams.put("ARG", params); + if (res != null) { + reportparams.put("REPORT_RESOURCE_BUNDLE", ResourceBundle.getBundle(res)); + } + reportparams.put("TAXESLOGIC", taxeslogic); + + JasperPrint jp = JasperFillManager.fillReport(jr, reportparams, data); + + reportviewer.loadJasperPrint(jp); + + setVisibleFilter(false); + + } catch (MissingResourceException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotloadresourcedata"), e); + msg.show(this); + } catch (JRException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotfillreport"), e); + msg.show(this); + } catch (BasicException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotloadreportdata"), e); + msg.show(this); + } + } + + m_App.waitCursorEnd(); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanelHeader = new javax.swing.JPanel(); + jPanelFilter = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + jToggleFilter = new javax.swing.JToggleButton(); + jButton1 = new javax.swing.JButton(); + + setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setLayout(new java.awt.BorderLayout()); + + jPanelHeader.setLayout(new java.awt.BorderLayout()); + + jPanelFilter.setLayout(new java.awt.BorderLayout()); + jPanelHeader.add(jPanelFilter, java.awt.BorderLayout.CENTER); + + jPanel1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT)); + + jToggleFilter.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/1downarrow.png"))); // NOI18N + jToggleFilter.setSelected(true); + jToggleFilter.setToolTipText("Hide/Show Filter"); + jToggleFilter.setPreferredSize(new java.awt.Dimension(80, 45)); + jToggleFilter.setSelectedIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/1uparrow.png"))); // NOI18N + jToggleFilter.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jToggleFilterActionPerformed(evt); + } + }); + jPanel1.add(jToggleFilter); + + jButton1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jButton1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jButton1.setText(AppLocal.getIntString("button.executereport")); // NOI18N + jButton1.setToolTipText("Execute Report"); + jButton1.setPreferredSize(new java.awt.Dimension(150, 45)); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + jPanel1.add(jButton1); + + jPanelHeader.add(jPanel1, java.awt.BorderLayout.SOUTH); + + add(jPanelHeader, java.awt.BorderLayout.NORTH); + }// </editor-fold>//GEN-END:initComponents + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + + launchreport(); + + }//GEN-LAST:event_jButton1ActionPerformed + + private void jToggleFilterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jToggleFilterActionPerformed + + jPanelFilter.setVisible(jToggleFilter.isSelected()); + + }//GEN-LAST:event_jToggleFilterActionPerformed + + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanelFilter; + private javax.swing.JPanel jPanelHeader; + private javax.swing.JToggleButton jToggleFilter; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/reports/JParamsComposed.form b/src/main/java/com/unicenta/pos/reports/JParamsComposed.form new file mode 100644 index 0000000..7dc1eb1 --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/JParamsComposed.form @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,111,0,0,1,-124"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="1"/> + </Layout> +</Form> diff --git a/src/main/java/com/unicenta/pos/reports/JParamsComposed.java b/src/main/java/com/unicenta/pos/reports/JParamsComposed.java new file mode 100644 index 0000000..013a31b --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/JParamsComposed.java @@ -0,0 +1,142 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.reports; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.SerializerWrite; +import com.unicenta.data.loader.SerializerWriteComposed; +import com.unicenta.pos.forms.AppView; +import java.awt.Component; +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author JG uniCenta + */ +public class JParamsComposed extends javax.swing.JPanel implements ReportEditorCreator { + +// JG 16 May 12 use diamond inference + private List<ReportEditorCreator> editors = new ArrayList<>(); + + /** Creates new form JParamsComposed */ + public JParamsComposed() { + initComponents(); + } + + /** + * + * @param app + */ + @Override + public void init(AppView app) { + for (ReportEditorCreator qbff : editors) { + qbff.init(app); + } + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + for (ReportEditorCreator qbff : editors) { + qbff.activate(); + } + } + + /** + * + * @return + */ + @Override + public SerializerWrite getSerializerWrite() { + + SerializerWriteComposed sw = new SerializerWriteComposed(); + + for (ReportEditorCreator qbff : editors) { + sw.add(qbff.getSerializerWrite()); + } + + return sw; + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + Object[] value = new Object[editors.size()]; + + for(int i = 0; i < editors.size(); i++) { + value[i] = editors.get(i).createValue(); + } + + return value; + } + + /** + * + * @param c + */ + public void addEditor(ReportEditorCreator c) { + editors.add(c); + add(c.getComponent()); + } + + /** + * + * @return + */ + public boolean isEmpty() { + + return editors.isEmpty(); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.Y_AXIS)); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/reports/JParamsCustomer.form b/src/main/java/com/unicenta/pos/reports/JParamsCustomer.form new file mode 100644 index 0000000..c1ced7d --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/JParamsCustomer.form @@ -0,0 +1,98 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[550, 50]"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.bycustomer" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + </AccessibilityProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jTextField1" min="-2" pref="300" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="btnCustomer" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jTextField1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="btnCustomer" pref="0" max="32767" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JTextField" name="jTextField1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="btnCustomer"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/customer_sml.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Get Customers"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnCustomerActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.customer" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/reports/JParamsCustomer.java b/src/main/java/com/unicenta/pos/reports/JParamsCustomer.java new file mode 100644 index 0000000..dbbd05e --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/JParamsCustomer.java @@ -0,0 +1,204 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.reports; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.loader.QBFCompareEnum; +import com.unicenta.data.loader.SerializerWrite; +import com.unicenta.data.loader.SerializerWriteBasic; +import com.unicenta.pos.customers.CustomerInfo; +import com.unicenta.pos.customers.DataLogicCustomers; +import com.unicenta.pos.customers.JCustomerFinder; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import java.awt.Component; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +/** + * + * @author adrianromero + */ +public class JParamsCustomer extends javax.swing.JPanel implements ReportEditorCreator { + + private DataLogicCustomers dlCustomers; + private CustomerInfo currentcustomer; + + /** Creates new form JParamsCustomer */ + public JParamsCustomer() { + + initComponents(); + + jTextField1.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + currentcustomer = null; + } + @Override + public void removeUpdate(DocumentEvent e) { + currentcustomer = null; + } + @Override + public void changedUpdate(DocumentEvent e) { + currentcustomer = null; + } + }); + } + + /** + * + * @param app + */ + @Override + public void init(AppView app) { + dlCustomers = (DataLogicCustomers) app.getBean("com.unicenta.pos.customers.DataLogicCustomers"); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + + currentcustomer = null; + jTextField1.setText(null); + } + + /** + * + * @return + */ + @Override + public SerializerWrite getSerializerWrite() { + return new SerializerWriteBasic(new Datas[] {Datas.OBJECT, Datas.STRING, Datas.OBJECT, Datas.STRING}); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + if (currentcustomer == null) { + if (jTextField1.getText() == null || jTextField1.getText().equals("")) { + return new Object[] {QBFCompareEnum.COMP_NONE, null, QBFCompareEnum.COMP_NONE, null}; + } else { + return new Object[] {QBFCompareEnum.COMP_NONE, null, QBFCompareEnum.COMP_RE, jTextField1.getText()}; + } + } else { + return new Object[] {QBFCompareEnum.COMP_EQUALS, currentcustomer.getId(), QBFCompareEnum.COMP_NONE, null}; + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jTextField1 = new javax.swing.JTextField(); + btnCustomer = new javax.swing.JButton(); + jLabel2 = new javax.swing.JLabel(); + + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + setPreferredSize(new java.awt.Dimension(550, 50)); + + jTextField1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTextField1.setPreferredSize(new java.awt.Dimension(250, 30)); + + btnCustomer.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/customer_sml.png"))); // NOI18N + btnCustomer.setToolTipText("Get Customers"); + btnCustomer.setPreferredSize(new java.awt.Dimension(80, 45)); + btnCustomer.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnCustomerActionPerformed(evt); + } + }); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.customer")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(110, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 300, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnCustomer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(btnCustomer, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) + .addContainerGap()) + ); + + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + getAccessibleContext().setAccessibleName(bundle.getString("label.bycustomer")); // NOI18N + }// </editor-fold>//GEN-END:initComponents + + private void btnCustomerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCustomerActionPerformed + + JCustomerFinder finder = JCustomerFinder.getCustomerFinder(this, dlCustomers); + finder.search(currentcustomer); + finder.setVisible(true); + currentcustomer = finder.getSelectedCustomer(); + if (currentcustomer == null) { + jTextField1.setText(null); + } else { + jTextField1.setText(currentcustomer.getName()); + } + + }//GEN-LAST:event_btnCustomerActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btnCustomer; + private javax.swing.JLabel jLabel2; + private javax.swing.JTextField jTextField1; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/reports/JParamsDatesInterval.form b/src/main/java/com/unicenta/pos/reports/JParamsDatesInterval.form new file mode 100644 index 0000000..6754958 --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/JParamsDatesInterval.form @@ -0,0 +1,156 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[750, 50]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jTxtStartDate" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="btnDateStart" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jTxtEndDate" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="btnDateEnd" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Group type="103" alignment="0" groupAlignment="3" attributes="0"> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jTxtEndDate" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="btnDateStart" alignment="0" pref="0" max="32767" attributes="0"/> + <Group type="103" alignment="1" groupAlignment="3" attributes="0"> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jTxtStartDate" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="btnDateEnd" alignment="0" pref="0" max="32767" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.StartDate" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTxtStartDate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 30]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="JParamsDatesInterval_jTxtStartDate"/> + </AuxValues> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.EndDate" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTxtEndDate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="btnDateStart"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/date.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Open Calendar"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 33]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 33]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnDateStartActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="btnDateEnd"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/date.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Open Calendar"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 33]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 33]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnDateEndActionPerformed"/> + </Events> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/reports/JParamsDatesInterval.java b/src/main/java/com/unicenta/pos/reports/JParamsDatesInterval.java new file mode 100644 index 0000000..17dd0c7 --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/JParamsDatesInterval.java @@ -0,0 +1,242 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.reports; + +import com.unicenta.basic.BasicException; +import com.unicenta.beans.JCalendarDialog; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.loader.QBFCompareEnum; +import com.unicenta.data.loader.SerializerWrite; +import com.unicenta.data.loader.SerializerWriteBasic; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import java.awt.Component; +import java.util.Date; + +/** + * + * @author JG uniCenta + */ +public class JParamsDatesInterval extends javax.swing.JPanel implements ReportEditorCreator { + + /** Creates new form JParamsClosedPos */ + public JParamsDatesInterval() { + initComponents(); + } + + /** + * + * @param d + */ + public void setStartDate(Date d) { + jTxtStartDate.setText(Formats.TIMESTAMP.formatValue(d)); + } + + /** + * + * @param d + */ + public void setEndDate(Date d) { + jTxtEndDate.setText(Formats.TIMESTAMP.formatValue(d)); + } + + /** + * + * @param app + */ + @Override + public void init(AppView app) { + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + } + + /** + * + * @return + */ + @Override + public SerializerWrite getSerializerWrite() { + return new SerializerWriteBasic(new Datas[] {Datas.OBJECT, Datas.TIMESTAMP, Datas.OBJECT, Datas.TIMESTAMP}); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + Object startdate = Formats.TIMESTAMP.parseValue(jTxtStartDate.getText()); + Object enddate = Formats.TIMESTAMP.parseValue(jTxtEndDate.getText()); + + return new Object[] { + startdate == null ? QBFCompareEnum.COMP_NONE : QBFCompareEnum.COMP_GREATEROREQUALS, + startdate, + enddate == null ? QBFCompareEnum.COMP_NONE : QBFCompareEnum.COMP_LESS, + enddate + }; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel1 = new javax.swing.JLabel(); + jTxtStartDate = new javax.swing.JTextField(); + jLabel2 = new javax.swing.JLabel(); + jTxtEndDate = new javax.swing.JTextField(); + btnDateStart = new javax.swing.JButton(); + btnDateEnd = new javax.swing.JButton(); + + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + setPreferredSize(new java.awt.Dimension(750, 50)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.StartDate")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(110, 30)); + + jTxtStartDate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTxtStartDate.setPreferredSize(new java.awt.Dimension(160, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.EndDate")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(110, 30)); + + jTxtEndDate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTxtEndDate.setPreferredSize(new java.awt.Dimension(160, 30)); + + btnDateStart.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/date.png"))); // NOI18N + btnDateStart.setToolTipText("Open Calendar"); + btnDateStart.setMaximumSize(new java.awt.Dimension(40, 33)); + btnDateStart.setMinimumSize(new java.awt.Dimension(40, 33)); + btnDateStart.setPreferredSize(new java.awt.Dimension(80, 45)); + btnDateStart.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnDateStartActionPerformed(evt); + } + }); + + btnDateEnd.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/date.png"))); // NOI18N + btnDateEnd.setToolTipText("Open Calendar"); + btnDateEnd.setMaximumSize(new java.awt.Dimension(40, 33)); + btnDateEnd.setMinimumSize(new java.awt.Dimension(40, 33)); + btnDateEnd.setPreferredSize(new java.awt.Dimension(80, 45)); + btnDateEnd.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnDateEndActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jTxtStartDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnDateStart, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jTxtEndDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnDateEnd, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTxtEndDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(btnDateStart, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTxtStartDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(btnDateEnd, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + private void btnDateStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDateStartActionPerformed + + Date date; + try { + date = (Date) Formats.TIMESTAMP.parseValue(jTxtStartDate.getText()); + } catch (BasicException e) { + date = null; + } + date = JCalendarDialog.showCalendarTimeHours(this, date); + if (date != null) { + jTxtStartDate.setText(Formats.TIMESTAMP.formatValue(date)); + } + }//GEN-LAST:event_btnDateStartActionPerformed + + private void btnDateEndActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDateEndActionPerformed + + Date date; + try { + date = (Date) Formats.TIMESTAMP.parseValue(jTxtEndDate.getText()); + } catch (BasicException e) { + date = null; + } + date = JCalendarDialog.showCalendarTimeHours(this, date); + if (date != null) { + jTxtEndDate.setText(Formats.TIMESTAMP.formatValue(date)); + } + }//GEN-LAST:event_btnDateEndActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btnDateEnd; + private javax.swing.JButton btnDateStart; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JTextField jTxtEndDate; + private javax.swing.JTextField jTxtStartDate; + // End of variables declaration//GEN-END:variables + +} + diff --git a/src/main/java/com/unicenta/pos/reports/JParamsLocation.form b/src/main/java/com/unicenta/pos/reports/JParamsLocation.form new file mode 100644 index 0000000..8713db6 --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/JParamsLocation.form @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[384, 50]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel8" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jLocation" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace min="-2" pref="11" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel8" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jLocation" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JComboBox" name="m_jLocation"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.warehouse" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/reports/JParamsLocation.java b/src/main/java/com/unicenta/pos/reports/JParamsLocation.java new file mode 100644 index 0000000..1c2185a --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/JParamsLocation.java @@ -0,0 +1,179 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.reports; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.loader.*; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import java.awt.Component; +import java.awt.event.ActionListener; +import java.util.List; + +/** + * + * @author adrianromero + */ +public class JParamsLocation extends javax.swing.JPanel implements ReportEditorCreator { + + private SentenceList m_sentlocations; + private ComboBoxValModel m_LocationsModel; + + /** Creates new form JParamsLocation */ + public JParamsLocation() { + initComponents(); + } + + /** + * + * @param app + */ + @Override + public void init(AppView app) { + + DataLogicSales dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + + // El modelo de locales + m_sentlocations = dlSales.getLocationsList(); + m_LocationsModel = new ComboBoxValModel(); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + List a = m_sentlocations.list(); + addFirst(a); + m_LocationsModel = new ComboBoxValModel(a); + m_LocationsModel.setSelectedFirst(); + m_jLocation.setModel(m_LocationsModel); // refresh model + } + + /** + * + * @return + */ + @Override + public SerializerWrite getSerializerWrite() { + return new SerializerWriteBasic(new Datas[] {Datas.OBJECT, Datas.STRING}); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @param a + */ + protected void addFirst(List a) { + a.add(0, null); + } + + /** + * + * @param l + */ + public void addActionListener(ActionListener l) { + m_jLocation.addActionListener(l); + } + + /** + * + * @param l + */ + public void removeActionListener(ActionListener l) { + m_jLocation.removeActionListener(l); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + return new Object[] { + m_LocationsModel.getSelectedKey() == null + ? QBFCompareEnum.COMP_NONE + : QBFCompareEnum.COMP_EQUALS, + m_LocationsModel.getSelectedKey() + }; + } + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jLocation = new javax.swing.JComboBox(); + jLabel8 = new javax.swing.JLabel(); + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setPreferredSize(new java.awt.Dimension(384, 50)); + + m_jLocation.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jLocation.setPreferredSize(new java.awt.Dimension(250, 30)); + + jLabel8.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel8.setText(AppLocal.getIntString("label.warehouse")); // NOI18N + jLabel8.setPreferredSize(new java.awt.Dimension(110, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jLocation, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(11, 11, 11) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jLocation, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel8; + private javax.swing.JComboBox m_jLocation; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/reports/JParamsLocationWithFirst.java b/src/main/java/com/unicenta/pos/reports/JParamsLocationWithFirst.java new file mode 100644 index 0000000..12769a0 --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/JParamsLocationWithFirst.java @@ -0,0 +1,43 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.reports; + +import java.util.List; + +/** + * + * @author adrian + */ +public class JParamsLocationWithFirst extends JParamsLocation { + + /** Creates a new instance of JParamsLocationWithFirst */ + public JParamsLocationWithFirst() { + super(); + } + + /** + * + * @param a + */ + @Override + protected void addFirst(List a) { + a.add(0, null); + } +} diff --git a/src/main/java/com/unicenta/pos/reports/JParamsReason.form b/src/main/java/com/unicenta/pos/reports/JParamsReason.form new file mode 100644 index 0000000..ab0e239 --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/JParamsReason.form @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[400, 50]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jreason" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jreason" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.stockreason" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jreason"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="maximumRowCount" type="int" value="12"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/reports/JParamsReason.java b/src/main/java/com/unicenta/pos/reports/JParamsReason.java new file mode 100644 index 0000000..6d5105c --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/JParamsReason.java @@ -0,0 +1,161 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.reports; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.loader.QBFCompareEnum; +import com.unicenta.data.loader.SerializerWrite; +import com.unicenta.data.loader.SerializerWriteBasic; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.inventory.MovementReason; +import java.awt.Component; + +/** + * + * @author JG uniCenta + */ +public class JParamsReason extends javax.swing.JPanel implements ReportEditorCreator { + + private ComboBoxValModel m_ReasonModel; + + /** Creates new form JParamsReason */ + public JParamsReason() { + initComponents(); + + m_ReasonModel = new ComboBoxValModel(); + m_ReasonModel.add(null); + m_ReasonModel.add(MovementReason.IN_PURCHASE); //Supplier Purchase + m_ReasonModel.add(MovementReason.OUT_SALE); //Sale + m_ReasonModel.add(MovementReason.IN_REFUND); //Customer Refund + m_ReasonModel.add(MovementReason.OUT_REFUND); //Supplier Return + m_ReasonModel.add(MovementReason.IN_MOVEMENT); //Adjust Add + m_ReasonModel.add(MovementReason.OUT_MOVEMENT); //Adjust Subtract + m_ReasonModel.add(MovementReason.OUT_SUBTRACT); //Rectify error per JM requirement + m_ReasonModel.add(MovementReason.OUT_BREAK); //Breakage + m_ReasonModel.add(MovementReason.OUT_FREE); //Given Free + m_ReasonModel.add(MovementReason.OUT_SAMPLE); //Given Sample + m_ReasonModel.add(MovementReason.OUT_USED); //Used item + m_ReasonModel.add(MovementReason.OUT_CROSSING); //Inter-Location move + + m_jreason.setModel(m_ReasonModel); + // m_jreason.setSelectedItem(null); + } + + /** + * + * @param app + */ + @Override + public void init(AppView app) { + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + } + + /** + * + * @return + */ + @Override + public SerializerWrite getSerializerWrite() { + return new SerializerWriteBasic(new Datas[] {Datas.OBJECT, Datas.INT}); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + return new Object[] { + m_ReasonModel.getSelectedItem() == null ? QBFCompareEnum.COMP_NONE : QBFCompareEnum.COMP_EQUALS, m_ReasonModel.getSelectedKey() + }; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel2 = new javax.swing.JLabel(); + m_jreason = new javax.swing.JComboBox(); + + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + setPreferredSize(new java.awt.Dimension(400, 50)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.stockreason")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jreason.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jreason.setMaximumRowCount(12); + m_jreason.setPreferredSize(new java.awt.Dimension(250, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jreason, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jreason, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel2; + private javax.swing.JComboBox m_jreason; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/reports/JParamsSuppliers.form b/src/main/java/com/unicenta/pos/reports/JParamsSuppliers.form new file mode 100644 index 0000000..cc5272d --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/JParamsSuppliers.form @@ -0,0 +1,103 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[550, 50]"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.bycustomer" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + </AccessibilityProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jTextField1" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="btnSupplier" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jTextField1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" pref="14" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="1" attributes="0"> + <Component id="btnSupplier" min="-2" pref="34" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JTextField" name="jTextField1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="btnSupplier"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/customer_sml.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Get Suppliers"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnSupplierActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.supplier" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/reports/JParamsSuppliers.java b/src/main/java/com/unicenta/pos/reports/JParamsSuppliers.java new file mode 100644 index 0000000..efc8e69 --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/JParamsSuppliers.java @@ -0,0 +1,207 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2016 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.reports; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.loader.QBFCompareEnum; +import com.unicenta.data.loader.SerializerWrite; +import com.unicenta.data.loader.SerializerWriteBasic; +import com.unicenta.pos.suppliers.SupplierInfo; +import com.unicenta.pos.suppliers.DataLogicSuppliers; +import com.unicenta.pos.suppliers.JSupplierFinder; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import java.awt.Component; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +/** + * + * @author Jack Gerrard + */ +public class JParamsSuppliers extends javax.swing.JPanel implements ReportEditorCreator { + + private DataLogicSuppliers dlSuppliers; + private SupplierInfo currentsupplier; + + /** Creates new form JParamsSupplier */ + public JParamsSuppliers() { + + initComponents(); + + jTextField1.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + currentsupplier = null; + } + @Override + public void removeUpdate(DocumentEvent e) { + currentsupplier = null; + } + @Override + public void changedUpdate(DocumentEvent e) { + currentsupplier = null; + } + }); + } + + /** + * + * @param app + */ + @Override + public void init(AppView app) { + dlSuppliers = (DataLogicSuppliers) app.getBean("com.unicenta.pos.suppliers.DataLogicSuppliers"); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + + currentsupplier = null; + jTextField1.setText(null); + } + + /** + * + * @return + */ + @Override + public SerializerWrite getSerializerWrite() { + return new SerializerWriteBasic(new Datas[] {Datas.OBJECT, Datas.STRING, Datas.OBJECT, Datas.STRING}); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + if (currentsupplier == null) { + if (jTextField1.getText() == null || jTextField1.getText().equals("")) { + return new Object[] {QBFCompareEnum.COMP_NONE, null, QBFCompareEnum.COMP_NONE, null}; + } else { + return new Object[] {QBFCompareEnum.COMP_NONE, null, QBFCompareEnum.COMP_RE, jTextField1.getText()}; + } + } else { + return new Object[] {QBFCompareEnum.COMP_EQUALS, currentsupplier.getID(), QBFCompareEnum.COMP_NONE, null}; + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jTextField1 = new javax.swing.JTextField(); + btnSupplier = new javax.swing.JButton(); + jLabel2 = new javax.swing.JLabel(); + + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + setPreferredSize(new java.awt.Dimension(550, 50)); + + jTextField1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTextField1.setPreferredSize(new java.awt.Dimension(300, 30)); + + btnSupplier.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/customer_sml.png"))); // NOI18N + btnSupplier.setToolTipText("Get Suppliers"); + btnSupplier.setPreferredSize(new java.awt.Dimension(80, 45)); + btnSupplier.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnSupplierActionPerformed(evt); + } + }); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.supplier")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(110, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnSupplier, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(14, 14, 14)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(btnSupplier, javax.swing.GroupLayout.PREFERRED_SIZE, 34, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()))) + ); + + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + getAccessibleContext().setAccessibleName(bundle.getString("label.bycustomer")); // NOI18N + }// </editor-fold>//GEN-END:initComponents + + private void btnSupplierActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSupplierActionPerformed + + JSupplierFinder finder = JSupplierFinder.getSupplierFinder(this, dlSuppliers); + finder.search(currentsupplier); + finder.setVisible(true); + currentsupplier = finder.getSelectedSupplier(); + if (currentsupplier == null) { + jTextField1.setText(null); + } else { + jTextField1.setText(currentsupplier.getName()); + } + + }//GEN-LAST:event_btnSupplierActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btnSupplier; + private javax.swing.JLabel jLabel2; + private javax.swing.JTextField jTextField1; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/reports/JParamsText.form b/src/main/java/com/unicenta/pos/reports/JParamsText.form new file mode 100644 index 0000000..f90777e --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/JParamsText.form @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,43,0,0,1,-64"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout"> + <Property name="useNullLayout" type="boolean" value="true"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="lblField"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="***"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="20" y="10" width="120" height="-1"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="txtField"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="140" y="10" width="200" height="-1"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/reports/JParamsText.java b/src/main/java/com/unicenta/pos/reports/JParamsText.java new file mode 100644 index 0000000..d181609 --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/JParamsText.java @@ -0,0 +1,234 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.reports; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.loader.QBFCompareEnum; +import com.unicenta.data.loader.SerializerWrite; +import com.unicenta.data.loader.SerializerWriteBasic; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import java.awt.Component; + +/** + * + * @author adrianromero + */ +public final class JParamsText extends javax.swing.JPanel implements ReportEditorCreator { + + private Datas datasvalue; + private Formats formatsvalue; + private QBFCompareEnum comparevalue; + + /** Creates new form JParamsText */ + public JParamsText() { + initComponents(); + + setLabel(AppLocal.getIntString("label.value")); + setType(Formats.STRING); + } + + /** + * + * @param label + */ + public JParamsText(String label) { + + initComponents(); + + setLabel(label); + setType(Formats.STRING); + } + + /** + * + * @param label + * @param format + */ + public JParamsText(String label, Formats format) { + + initComponents(); + + setLabel(label); + setType(format); + } + + /** + * + * @param label + * @param format + * @param data + */ + public JParamsText(String label, Formats format, Datas data) { + + initComponents(); + + setLabel(label); + setType(format, data); + } + + /** + * + * @param label + */ + public void setLabel(String label) { + lblField.setText(label); + } + + /** + * + * @param format + * @param data + */ + public void setType(Formats format, Datas data) { + formatsvalue = format; + datasvalue = data; + setDefaultCompare(); + } + + /** + * + * @param format + */ + public void setType(Formats format) { + + if (Formats.INT == format) { + setType(format, Datas.INT); + } else if (Formats.DOUBLE == format || Formats.CURRENCY == format || Formats.PERCENT == format) { + setType(format, Datas.DOUBLE); + } else if (Formats.DATE == format || Formats.TIME == format || Formats.TIMESTAMP == format) { + setType(format, Datas.TIMESTAMP); + } else if (Formats.BOOLEAN == format) { + setType(format, Datas.BOOLEAN); + } else { // if (Formats.STRING == format) { + setType(format, Datas.STRING); + } + } + + /** + * + * @param compare + */ + public void setCompare(QBFCompareEnum compare) { + comparevalue = compare; + } + + private void setDefaultCompare() { + if (Formats.INT == formatsvalue) { + comparevalue = QBFCompareEnum.COMP_LESSOREQUALS; + } else if (Formats.DOUBLE == formatsvalue || Formats.CURRENCY == formatsvalue || Formats.PERCENT == formatsvalue) { + comparevalue = QBFCompareEnum.COMP_LESSOREQUALS; + } else if (Formats.DATE == formatsvalue || Formats.TIME == formatsvalue || Formats.TIMESTAMP == formatsvalue) { + comparevalue = QBFCompareEnum.COMP_GREATEROREQUALS; + } else if (Formats.BOOLEAN == formatsvalue) { + comparevalue = QBFCompareEnum.COMP_EQUALS; + } else { // if (Formats.STRING == formatsvalue) { + comparevalue = QBFCompareEnum.COMP_RE; + } + } + + /** + * + * @param app + */ + @Override + public void init(AppView app) { + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + txtField.setText(null); + } + + /** + * + * @return + */ + @Override + public SerializerWrite getSerializerWrite() { + return new SerializerWriteBasic(new Datas[] {Datas.OBJECT, datasvalue}); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + Object value = formatsvalue.parseValue(txtField.getText()); + txtField.setText(formatsvalue.formatValue(value)); + + if (value == null) { + return new Object[] {QBFCompareEnum.COMP_NONE, null}; + } else { + return new Object[] {comparevalue, value}; + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + lblField = new javax.swing.JLabel(); + txtField = new javax.swing.JTextField(); + + setPreferredSize(new java.awt.Dimension(0, 30)); + setLayout(null); + + lblField.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + lblField.setText("***"); + lblField.setPreferredSize(new java.awt.Dimension(0, 30)); + add(lblField); + lblField.setBounds(20, 10, 120, 30); + + txtField.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtField.setPreferredSize(new java.awt.Dimension(0, 30)); + add(txtField); + txtField.setBounds(140, 10, 200, 30); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel lblField; + private javax.swing.JTextField txtField; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/reports/JParamsUser.form b/src/main/java/com/unicenta/pos/reports/JParamsUser.form new file mode 100644 index 0000000..1b67516 --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/JParamsUser.form @@ -0,0 +1,93 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[425, 50]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="6" max="-2" attributes="0"/> + <Component id="jTextField1" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="btnUser" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jTextField1" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="btnUser" pref="0" max="32767" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.user" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTextField1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="btnUser"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/customer_sml.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Get Customers"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnUserActionPerformed"/> + </Events> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/reports/JParamsUser.java b/src/main/java/com/unicenta/pos/reports/JParamsUser.java new file mode 100644 index 0000000..565359f --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/JParamsUser.java @@ -0,0 +1,201 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.reports; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.loader.QBFCompareEnum; +import com.unicenta.data.loader.SerializerWrite; +import com.unicenta.data.loader.SerializerWriteBasic; +import com.unicenta.pos.admin.PeopleInfo; +import com.unicenta.pos.admin.DataLogicAdmin; +import com.unicenta.pos.admin.JPeopleFinder; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import java.awt.Component; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +/** + * + * @author adrianromero + */ +public class JParamsUser extends javax.swing.JPanel implements ReportEditorCreator { + + private DataLogicAdmin dlPeople; + private PeopleInfo currentpeople; + + /** Creates new form JParamsUser */ + public JParamsUser() { + + initComponents(); + + jTextField1.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + currentpeople = null; + } + @Override + public void removeUpdate(DocumentEvent e) { + currentpeople = null; + } + @Override + public void changedUpdate(DocumentEvent e) { + currentpeople = null; + } + }); + } + + /** + * + * @param app + */ + @Override + public void init(AppView app) { + dlPeople = (DataLogicAdmin) app.getBean("com.unicenta.pos.admin.DataLogicAdmin"); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + + currentpeople = null; + jTextField1.setText(null); + } + + /** + * + * @return + */ + @Override + public SerializerWrite getSerializerWrite() { + return new SerializerWriteBasic(new Datas[] {Datas.OBJECT, Datas.STRING, Datas.OBJECT, Datas.STRING}); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + if (currentpeople == null) { + if (jTextField1.getText() == null || jTextField1.getText().equals("")) { + return new Object[] {QBFCompareEnum.COMP_NONE, null, QBFCompareEnum.COMP_NONE, null}; + } else { + return new Object[] {QBFCompareEnum.COMP_NONE, null, QBFCompareEnum.COMP_RE, jTextField1.getText()}; + } + } else { + return new Object[] {QBFCompareEnum.COMP_EQUALS, currentpeople.getID(), QBFCompareEnum.COMP_NONE, null}; + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel1 = new javax.swing.JLabel(); + jTextField1 = new javax.swing.JTextField(); + btnUser = new javax.swing.JButton(); + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setPreferredSize(new java.awt.Dimension(425, 50)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.user")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(110, 30)); + + jTextField1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTextField1.setPreferredSize(new java.awt.Dimension(200, 30)); + + btnUser.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/customer_sml.png"))); // NOI18N + btnUser.setToolTipText("Get Customers"); + btnUser.setPreferredSize(new java.awt.Dimension(80, 45)); + btnUser.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnUserActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(6, 6, 6) + .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnUser, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(btnUser, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + private void btnUserActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnUserActionPerformed + + JPeopleFinder finder = JPeopleFinder.getPeopleFinder(this, dlPeople); + finder.search(currentpeople); + finder.setVisible(true); + currentpeople = finder.getSelectedPeople(); + if (currentpeople == null) { + jTextField1.setText(null); + } else { + jTextField1.setText(currentpeople.getName()); + } + + }//GEN-LAST:event_btnUserActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btnUser; + private javax.swing.JLabel jLabel1; + private javax.swing.JTextField jTextField1; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/reports/JRDataSourceBasic.java b/src/main/java/com/unicenta/pos/reports/JRDataSourceBasic.java new file mode 100644 index 0000000..2bdccd6 --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/JRDataSourceBasic.java @@ -0,0 +1,97 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.reports; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.BaseSentence; +import com.unicenta.data.loader.DataResultSet; +import com.unicenta.pos.forms.AppLocal; +import net.sf.jasperreports.engine.JRDataSource; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JRField; + +/** + * + * @author JG uniCenta + */ +public class JRDataSourceBasic implements JRDataSource { + + private BaseSentence sent; + private DataResultSet SRS = null; + private Object current = null; + + private ReportFields m_fields = null; + + /** Creates a new instance of JRDataSourceBasic + * @param sent + * @param fields + * @param params + * @throws com.unicenta.basic.BasicException */ + public JRDataSourceBasic(BaseSentence sent, ReportFields fields, Object params) throws BasicException { + + this.sent = sent; + SRS = sent.openExec(params); + m_fields = fields; + } + + /** + * + * @param jrField + * @return + * @throws JRException + */ + @Override + public Object getFieldValue(JRField jrField) throws JRException { + + try { + return m_fields.getField(current, jrField.getName()); + } catch (ReportException er) { + throw new JRException(er); + } + } + + /** + * + * @return + * @throws JRException + */ + @Override + public boolean next() throws JRException { + + if (SRS == null) { + throw new JRException(AppLocal.getIntString("exception.unavailabledataset")); + } + + try { + if (SRS.next()) { + current = SRS.getCurrent(); + return true; + } else { + current = null; + SRS = null; + sent.closeExec(); + sent = null; + return false; + } + } catch (BasicException e) { + throw new JRException(e); + } + } +} diff --git a/src/main/java/com/unicenta/pos/reports/PanelReportBean.java b/src/main/java/com/unicenta/pos/reports/PanelReportBean.java new file mode 100644 index 0000000..c6f6abc --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/PanelReportBean.java @@ -0,0 +1,201 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.reports; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.*; +import com.unicenta.data.user.EditorCreator; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.BeanFactoryException; +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author adrianromero + */ +public class PanelReportBean extends JPanelReport { + + private String title; + private String report; + + private String resourcebundle = null; + + private String sentence; + + +// JG 16 May 12 use diamond inference + private List<Datas> fielddatas = new ArrayList<>(); + private List<String> fieldnames = new ArrayList<>(); + + private List<String> paramnames = new ArrayList<>(); + + private JParamsComposed qbffilter = new JParamsComposed(); + + /** + * + * @param app + * @throws BeanFactoryException + */ + @Override + public void init(AppView app) throws BeanFactoryException { + + qbffilter.init(app); + super.init(app); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + + qbffilter.activate(); + super.activate(); + + if (qbffilter.isEmpty()) { + setVisibleFilter(false); + setVisibleButtonFilter(false); + } + } + + /** + * + * @return + */ + @Override + protected EditorCreator getEditorCreator() { + + return qbffilter; + } + + /** + * + * @param title + */ + public void setTitle(String title) { + this.title = title; + } + + /** + * + * @param titlekey + */ + public void setTitleKey(String titlekey) { + title = AppLocal.getIntString(titlekey); + } + + /** + * + * @return + */ + public String getTitle() { + return title; + } + + /** + * + * @param report + */ + public void setReport(String report) { + this.report = report; + } + + /** + * + * @return + */ + protected String getReport() { + return report; + } + + /** + * + * @param resourcebundle + */ + public void setResourceBundle(String resourcebundle) { + this.resourcebundle = resourcebundle; + } + + /** + * + * @return + */ + protected String getResourceBundle() { + return resourcebundle == null + ? report + : resourcebundle; + } + + /** + * + * @param sentence + */ + public void setSentence(String sentence) { + this.sentence = sentence; + } + + /** + * + * @param name + * @param data + */ + public void addField(String name, Datas data) { + fieldnames.add(name); + fielddatas.add(data); + } + + /** + * + * @param name + */ + public void addParameter(String name) { + paramnames.add(name); + } + + /** + * + * @return + */ + protected BaseSentence getSentence() { + return new StaticSentence(m_App.getSession() + , new QBFBuilder(sentence, paramnames.toArray(new String[paramnames.size()])) + , qbffilter.getSerializerWrite() + , new SerializerReadBasic(fielddatas.toArray(new Datas[fielddatas.size()]))); + } + + /** + * + * @return + */ + protected ReportFields getReportFields() { + return new ReportFieldsArray(fieldnames.toArray(new String[fieldnames.size()])); + } + + /** + * + * @param qbff + */ + public void addQBFFilter(ReportEditorCreator qbff) { + qbffilter.addEditor(qbff); + } +} diff --git a/src/main/java/com/unicenta/pos/reports/ReportEditorCreator.java b/src/main/java/com/unicenta/pos/reports/ReportEditorCreator.java new file mode 100644 index 0000000..51ca132 --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/ReportEditorCreator.java @@ -0,0 +1,50 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.reports; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.user.FilterEditorCreator; +import com.unicenta.pos.forms.AppView; +import java.awt.Component; + +/** + * + * @author adrianromero + */ +public interface ReportEditorCreator extends FilterEditorCreator { + + /** + * + * @param app + */ + public void init(AppView app); + + /** + * + * @throws BasicException + */ + public void activate() throws BasicException; + + /** + * + * @return + */ + public Component getComponent(); +} diff --git a/src/main/java/com/unicenta/pos/reports/ReportException.java b/src/main/java/com/unicenta/pos/reports/ReportException.java new file mode 100644 index 0000000..65b213e --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/ReportException.java @@ -0,0 +1,49 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.reports; + +/** + * + * @author JG uniCenta + */ +public class ReportException extends Exception { + + /** + * + */ + public ReportException() { + } + + /** + * + * @param msg + */ + public ReportException(String msg) { + super(msg); + } + + /** + * + * @param e + */ + public ReportException(Exception e) { + super(e); + } +} diff --git a/src/main/java/com/unicenta/pos/reports/ReportFields.java b/src/main/java/com/unicenta/pos/reports/ReportFields.java new file mode 100644 index 0000000..1188893 --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/ReportFields.java @@ -0,0 +1,36 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.reports; + +/** + * + * @author JG uniCenta + */ +public interface ReportFields { + + /** + * + * @param record + * @param field + * @return + * @throws ReportException + */ + public Object getField(Object record, String field) throws ReportException; +} diff --git a/src/main/java/com/unicenta/pos/reports/ReportFieldsArray.java b/src/main/java/com/unicenta/pos/reports/ReportFieldsArray.java new file mode 100644 index 0000000..d4de182 --- /dev/null +++ b/src/main/java/com/unicenta/pos/reports/ReportFieldsArray.java @@ -0,0 +1,68 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.reports; + +import java.util.HashMap; +import java.util.Map; +import com.unicenta.pos.forms.AppLocal; + +/** + * + * @author JG uniCenta + */ +public class ReportFieldsArray implements ReportFields { + + private Map m_keys = null; + + /** Creates a new instance of ReportFieldsArray + * @param afields */ + public ReportFieldsArray(String[] afields) { + + // Creo el mapa de claves + m_keys = new HashMap(); + for (int i = 0; i < afields.length; i++) { + m_keys.put(afields[i], new Integer(i)); + } + } + + /** + * + * @param record + * @param field + * @return + * @throws ReportException + */ + @Override + public Object getField(Object record, String field) throws ReportException { + + Integer i = (Integer) m_keys.get(field); + if (i == null) { + throw new ReportException(AppLocal.getIntString("exception.unavailablefield", new Object[] {field})); + } else { + Object[] arecord = (Object[]) record; + if (arecord == null || i.intValue() < 0 + || i.intValue() >= arecord.length) { + throw new ReportException(AppLocal.getIntString("exception.unavailablefields")); + } else { + return arecord[i.intValue()]; + } + } + } +} diff --git a/src/main/java/com/unicenta/pos/resets/JPanelResets.form b/src/main/java/com/unicenta/pos/resets/JPanelResets.form new file mode 100644 index 0000000..86321ea --- /dev/null +++ b/src/main/java/com/unicenta/pos/resets/JPanelResets.form @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <EmptySpace min="0" pref="400" max="32767" attributes="0"/> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <EmptySpace min="0" pref="300" max="32767" attributes="0"/> + </Group> + </DimensionLayout> + </Layout> +</Form> diff --git a/src/main/java/com/unicenta/pos/resets/JPanelResets.java b/src/main/java/com/unicenta/pos/resets/JPanelResets.java new file mode 100644 index 0000000..cce1727 --- /dev/null +++ b/src/main/java/com/unicenta/pos/resets/JPanelResets.java @@ -0,0 +1,53 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2016 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +// CSV Import Panel added by JDL - February 2013 +// Additonal library required - javacsv + +package com.unicenta.pos.resets; + +public class JPanelResets extends javax.swing.JPanel { + + + public JPanelResets() { + initComponents(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 400, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 300, Short.MAX_VALUE) + ); + }// </editor-fold>//GEN-END:initComponents + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/resets/JResetPickupID.java b/src/main/java/com/unicenta/pos/resets/JResetPickupID.java new file mode 100644 index 0000000..a3c7059 --- /dev/null +++ b/src/main/java/com/unicenta/pos/resets/JResetPickupID.java @@ -0,0 +1,134 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2017 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.resets; + +import com.unicenta.basic.BasicException; +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppProperties; +import com.unicenta.pos.forms.JRootFrame; +import com.unicenta.pos.sales.JPanelResetPickupId; +import java.awt.BorderLayout; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.IOException; +import javax.imageio.ImageIO; +import javax.swing.LookAndFeel; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; + + +/** + * + * @author adrianromero + */ +public class JResetPickupID extends javax.swing.JFrame { + + private JPanelResetPickupId config; + + /** + * + * @param props + */ + public JResetPickupID(AppProperties props) { + + initComponents(); + + try { + this.setIconImage(ImageIO.read(JRootFrame.class.getResourceAsStream("/com/unicenta/images/favicon.png"))); + } catch (IOException e) { + } + setTitle(AppLocal.APP_NAME + " - " + AppLocal.APP_VERSION + " - " + AppLocal.getIntString("Menu.Resetpickup")); + + addWindowListener(new MyFrameListener()); + + config = new JPanelResetPickupId(props); + + getContentPane().add(config, BorderLayout.CENTER); + + try { + config.activate(); + } catch (BasicException e) { // never thrown ;-) + } + } + + private class MyFrameListener extends WindowAdapter{ + + @Override + public void windowClosing(WindowEvent evt) { + if (config.deactivate()) { + dispose(); + } + } + @Override + public void windowClosed(WindowEvent evt) { + System.exit(0); + } + } + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE); + + java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); + setBounds((screenSize.width-507)/2, (screenSize.height-304)/2, 507, 304); + }// </editor-fold>//GEN-END:initComponents + + /** + * @param args the command line arguments + */ + public static void main(final String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + + AppConfig config = new AppConfig(args); + config.load(); + +// Set the look and feel. +// JG 6 May 2013 to Multicatch + try { + Object laf = Class.forName(config.getProperty("swing.defaultlaf")).newInstance(); + if (laf instanceof LookAndFeel){ + UIManager.setLookAndFeel((LookAndFeel) laf); +// } else if (laf instanceof SubstanceSkin) { +// SubstanceLookAndFeel.setSkin((SubstanceSkin) laf); + } +// JG 6 May 2013 to multicatch + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) { + } + + JResetPickupID resetFrame = new JResetPickupID(config);// + resetFrame.setSize(360, 120); + resetFrame.setVisible(true); + + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/DataLogicReceipts.java b/src/main/java/com/unicenta/pos/sales/DataLogicReceipts.java new file mode 100644 index 0000000..1028db0 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/DataLogicReceipts.java @@ -0,0 +1,384 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.loader.PreparedSentence; +import com.unicenta.data.loader.SerializerReadBasic; +import com.unicenta.data.loader.SerializerReadClass; +import com.unicenta.data.loader.SerializerWriteBasicExt; +import com.unicenta.data.loader.SerializerWriteString; +import com.unicenta.data.loader.Session; +import com.unicenta.data.loader.StaticSentence; +import com.unicenta.pos.forms.BeanFactoryDataSingle; +import com.unicenta.pos.ticket.TicketInfo; +import java.util.List; + +/** + * + * @author adrianromero + */ +public class DataLogicReceipts extends BeanFactoryDataSingle { + + private Session s; + + /** Creates a new instance of DataLogicReceipts */ + public DataLogicReceipts() { + } + + /** + * + * @param s + */ + @Override + public void init(Session s){ + this.s = s; + } + + /** + * + * @param Id + * @return + * @throws BasicException + */ + public final TicketInfo getSharedTicket(String Id) throws BasicException { + + if (Id == null) { + return null; + } else { + Object[]record = (Object[]) new StaticSentence(s + , "SELECT CONTENT, LOCKED FROM sharedtickets WHERE ID = ?" + , SerializerWriteString.INSTANCE + , new SerializerReadBasic(new Datas[] { + Datas.SERIALIZABLE})).find(Id); + return record == null ? null : (TicketInfo) record[0]; + } + } + + /** + * + * @param pickupId + * @return + * @throws BasicException + */ + public final TicketInfo getSharedTicketPickupId(String pickupId) throws BasicException { + + if (pickupId == null) { + return null; + } else { + Object[]record = (Object[]) new StaticSentence(s + , "SELECT CONTENT, LOCKED FROM sharedtickets WHERE PICKUPID = ?" + , SerializerWriteString.INSTANCE + , new SerializerReadBasic(new Datas[] { + Datas.SERIALIZABLE})).find(pickupId); + return record == null ? null : (TicketInfo) record[0]; + } + } + + /** + * JG Dec 14 Administrator and Manager Roles always have access to ALL SHAREDtickets + * @return + * @throws BasicException + */ + public final List<SharedTicketInfo> getSharedTicketList() throws BasicException { + + return (List<SharedTicketInfo>) new StaticSentence(s +// , "SELECT ID, NAME, CONTENT, APPUSER, PICKUPID, LOCKED FROM sharedtickets ORDER BY ID" + , "SELECT ID, NAME, CONTENT, APPUSER, PICKUPID, LOCKED " + + "FROM sharedtickets ORDER BY PICKUPID" + , null + , new SerializerReadClass(SharedTicketInfo.class)).list(); + } + + /** + * Return only current APPUSER SHAREDtickets + * @param appuser + * @return + * @throws BasicException + */ + public final List<SharedTicketInfo> getUserSharedTicketList(String appuser) throws BasicException { + String sql = "SELECT ID, NAME, CONTENT, APPUSER, PICKUPID, LOCKED " + + "FROM sharedtickets " + + "WHERE APPUSER =\""+ appuser +"\" ORDER BY PICKUPID"; + + return (List<SharedTicketInfo>) new StaticSentence(s + , sql + , null + , new SerializerReadClass(SharedTicketInfo.class)).list(); + } + + /** + * For Standard View + * @param id + * @param ticket + * @param pickupid + * @throws BasicException + */ + public final void insertSharedTicket(final String id, final TicketInfo ticket, int pickupid) throws BasicException { + + Object[] values = new Object[] { + id, + ticket.getName(), + ticket, + ticket.getUser().getId(), + pickupid + + }; + Datas[] datas; + datas = new Datas[] { + Datas.STRING, + Datas.STRING, + Datas.SERIALIZABLE, + Datas.STRING, + Datas.INT + + }; + new PreparedSentence(s + , "INSERT INTO sharedtickets (" + + "ID, " + + "NAME, " + + "CONTENT, " + + "APPUSER, " + + "PICKUPID) " + + "VALUES (?, ?, ?, ?, ?)" + , new SerializerWriteBasicExt(datas, new int[] {0, 1, 2, 3, 4})).exec(values); + } + + /** + * + * @param id + * @param ticket + * @param pickupid + * @throws BasicException + */ + public final void updateSharedTicket(final String id, final TicketInfo ticket, int pickupid) throws BasicException { + + Object[] values = new Object[] { + id, + ticket.getName(), + ticket, + ticket.getUser().getId(), + pickupid + }; + Datas[] datas = new Datas[] { + Datas.STRING, + Datas.STRING, + Datas.SERIALIZABLE, + Datas.STRING, + Datas.INT + }; + new PreparedSentence(s + , "UPDATE sharedtickets SET " + + "NAME = ?, " + + "CONTENT = ?, " + + "APPUSER = ?, " + + "PICKUPID = ? " + + "WHERE ID = ?" + , new SerializerWriteBasicExt(datas, + new int[] { + 1, 2, 3, 4, 0})).exec(values); + } + + /** + * + * @param id + * @param ticket + * @param pickupid + * @throws BasicException + */ + public final void updateRSharedTicket( + final String id, + final TicketInfo ticket, + int pickupid) throws BasicException { + + Object[] values = new Object[] { + id, + ticket.getName(), + ticket, + pickupid + }; + Datas[] datas = new Datas[] { + Datas.STRING, + Datas.STRING, + Datas.SERIALIZABLE, + Datas.INT + }; + new PreparedSentence(s + , "UPDATE sharedtickets SET " + + "NAME = ?, " + + "CONTENT = ?, " + + "PICKUPID = ? " + + "WHERE ID = ?" + , new SerializerWriteBasicExt(datas, new int[] {1, 2, 3, 0})).exec(values); + } + + /** + * In place for multi-purposing like containing data from elsewhere and/or + * using Place and User for Notifications + * @param id + * @param locked + * @throws BasicException + */ + public final void lockSharedTicket(final String id, final String locked) throws BasicException { + + Object[] values = new Object[] { + id, + locked + }; + Datas[] datas = new Datas[] { + Datas.STRING, + Datas.STRING + }; + new PreparedSentence(s + , "UPDATE sharedtickets SET " + + "LOCKED = ? " + + "WHERE ID = ?" + , new SerializerWriteBasicExt(datas, new int[] {1, 0})).exec(values); + } + + /** + * In place for multi-purposing like flushing locks from elsewhere and/or + * using Place and User for Notifications + * @param id + * @param unlocked + * @throws BasicException + */ + public final void unlockSharedTicket(final String id, final String unlocked) throws BasicException { + + Object[] values = new Object[] { + id, + unlocked + }; + Datas[] datas = new Datas[] { + Datas.STRING, + Datas.STRING + }; + new PreparedSentence(s + , "UPDATE sharedtickets SET " + + "LOCKED = ? " + + "WHERE ID = ?" + , new SerializerWriteBasicExt(datas, new int[] {1, 0})).exec(values); + } + + /** + * For Restaurant View + * @param id + * @param ticket + * @param pickupid + * @throws BasicException + */ + public final void insertRSharedTicket( + final String id, + final TicketInfo ticket, + int pickupid) throws BasicException { + + Object[] values = new Object[] { + id, + ticket.getName(), + ticket, + ticket.getUser(), + ticket.getPickupId(), + ticket.getHost() + }; + Datas[] datas; + datas = new Datas[] { + Datas.STRING, + Datas.STRING, + Datas.SERIALIZABLE, + Datas.STRING, + Datas.INT + + }; + new PreparedSentence(s + , "INSERT INTO sharedtickets (" + + "ID, " + + "NAME, " + + "CONTENT, " + + "APPUSER, " + + "PICKUPID) " + + "VALUES (?, ?, ?, ?, ?)" + , new SerializerWriteBasicExt(datas, new int[] {0, 1, 2, 3, 4})).exec(values); + } + + /** + * + * @param id + * @throws BasicException + */ + public final void deleteSharedTicket(final String id) throws BasicException { + + new StaticSentence(s + , "DELETE FROM sharedtickets WHERE ID = ?" + , SerializerWriteString.INSTANCE).exec(id); + } + + /** + * + * @param Id + * @return + * @throws BasicException + */ + public final Integer getPickupId(String Id) throws BasicException { + + if (Id == null) { + return null; + } else { + Object[]record = (Object[]) new StaticSentence(s + , "SELECT PICKUPID FROM sharedtickets WHERE ID = ?" + , SerializerWriteString.INSTANCE + , new SerializerReadBasic(new Datas[] {Datas.INT})).find(Id); + return record == null ? 0 : (Integer)record[0]; + } + } + + + public final String getUserId(final String id) throws BasicException { + Object[] userID = (Object []) new StaticSentence(s + , "SELECT APPUSER FROM sharedtickets WHERE ID = ?" + , SerializerWriteString.INSTANCE + , new SerializerReadBasic(new Datas[] {Datas.STRING})).find(id); + if( userID == null ) { + return null; + } else { + return (String) userID[0]; + } + } + + public final String getLockState(final String id, String lockState) throws BasicException { + Object[] state = (Object[]) new StaticSentence(s + , "SELECT LOCKED FROM sharedtickets WHERE ID = ?" + , SerializerWriteString.INSTANCE + , new SerializerReadBasic(new Datas[] { + Datas.STRING + })).find(id); + return (String) state[0]; + } + + public final String getServer(final String id, String user) throws BasicException { + Object[] server = (Object[]) new StaticSentence(s + , "SELECT appuser FROM sharedtickets WHERE ID = ?" + , SerializerWriteString.INSTANCE + , new SerializerReadBasic(new Datas[] { + Datas.STRING + })).find(id); + return (String) server[0]; + } +} diff --git a/src/main/java/com/unicenta/pos/sales/JMooringDetails.form b/src/main/java/com/unicenta/pos/sales/JMooringDetails.form new file mode 100644 index 0000000..2dff394 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JMooringDetails.form @@ -0,0 +1,159 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.6" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,18,0,0,2,24"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jScrollPane2" pref="508" max="32767" attributes="0"/> + <Group type="102" attributes="0"> + <EmptySpace min="-2" pref="10" max="-2" attributes="0"/> + <Component id="jLabel1" min="-2" pref="107" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jText" min="-2" pref="222" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jbtnCreateTicket" min="-2" pref="150" max="-2" attributes="0"/> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Component id="jScrollPane2" min="-2" pref="179" max="-2" attributes="0"/> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jText" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jbtnCreateTicket" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="jbtnCreateTicket"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.mooringcreatebtn" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnCreateTicketActionPerformed"/> + </Events> + </Component> + <Container class="javax.swing.JScrollPane" name="jScrollPane2"> + <AuxValues> + <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JTable" name="jTableSelector"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor"> + <Table columnCount="4" rowCount="6"> + <Column editable="false" title="Vessel Name" type="java.lang.Object"/> + <Column editable="false" title="Size" type="java.lang.Object"/> + <Column editable="false" title="Days" type="java.lang.Object"/> + <Column editable="false" title="Power" type="java.lang.Object"/> + </Table> + </Property> + <Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor"> + <TableColumnModel selectionModel="0"> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="50" resizable="false"> + <Title/> + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="50" resizable="false"> + <Title/> + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="70" resizable="false"> + <Title/> + <Editor/> + <Renderer/> + </Column> + </TableColumnModel> + </Property> + <Property name="rowHeight" type="int" value="25"/> + <Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor"> + <TableHeader reorderingAllowed="true" resizingAllowed="true"/> + </Property> + </Properties> + <Events> + <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="jTableSelectorMouseClicked"/> + </Events> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JTextField" name="jText"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="disabledTextColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="0" green="0" red="0" type="rgb"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jTextActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.mooringscreatefor" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/JMooringDetails.java b/src/main/java/com/unicenta/pos/sales/JMooringDetails.java new file mode 100644 index 0000000..c91d286 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JMooringDetails.java @@ -0,0 +1,307 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.data.loader.Session; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.Window; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.Statement; +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; +import net.proteanit.sql.DbUtils; + +/** + * + * @author JG uniCenta + */ +public class JMooringDetails extends javax.swing.JDialog { + + private Connection con; + private ResultSet rs; + private Statement stmt; + private String ID; + private String SQL; + private String vesselName = ""; + private Integer vesselSize; + private Integer vesselDays; + private Boolean vesselPower; + private boolean create = false; + + + private JMooringDetails(java.awt.Frame parent, boolean modal) { + super(parent, modal); + } + + + private JMooringDetails(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + } + + private void init(Session s) { + + initComponents(); + setTitle("Select Vessel details"); + + try{ + con=s.getConnection(); + stmt = (Statement) con.createStatement(); + + SQL = "SELECT * FROM moorers"; + rs = stmt.executeQuery(SQL); + + jTableSelector.setModel(DbUtils.resultSetToTableModel(rs)); + jTableSelector.getColumnModel().getColumn(0).setPreferredWidth(200); + jTableSelector.getColumnModel().getColumn(1).setPreferredWidth(40); + jTableSelector.getColumnModel().getColumn(2).setPreferredWidth(40); + jTableSelector.getColumnModel().getColumn(3).setPreferredWidth(40); + jTableSelector.setRowSelectionAllowed(true); + jTableSelector.getTableHeader().setReorderingAllowed(true); + + + } catch (Exception e) { + } + + + } + + /** + * + * @param parent + * @param s + * @return + */ + public static JMooringDetails getMooringDetails(Component parent, Session s) { + Window window = SwingUtilities.getWindowAncestor(parent); + // m_oticket = new ticket(); + JMooringDetails myMsg; + if (window instanceof Frame) { + myMsg = new JMooringDetails((Frame) window, true); + } else { + myMsg = new JMooringDetails((Dialog) window, true); + } + myMsg.init(s); + myMsg.applyComponentOrientation(parent.getComponentOrientation()); + + + return myMsg; + } + + /** + * + * @return + */ + public boolean isCreate() { + return create; + } + + /** + * + * @return + */ + public String getVesselName() { + return vesselName; + } + + /** + * + * @return + */ + public Integer getVesselSize() { + return vesselSize; + } + + /** + * + * @return + */ + public Integer getVesselDays() { + return vesselDays; + } + + /** + * + * @return + */ + public Boolean getVesselPower() { + return vesselPower; + } + + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jbtnCreateTicket = new javax.swing.JButton(); + jScrollPane2 = new javax.swing.JScrollPane(); + jTableSelector = new javax.swing.JTable(); + jText = new javax.swing.JTextField(); + jLabel1 = new javax.swing.JLabel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + + jbtnCreateTicket.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnCreateTicket.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jbtnCreateTicket.setText(bundle.getString("label.mooringcreatebtn")); // NOI18N + jbtnCreateTicket.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnCreateTicketActionPerformed(evt); + } + }); + + jTableSelector.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jTableSelector.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + {null, null, null, null}, + {null, null, null, null}, + {null, null, null, null}, + {null, null, null, null}, + {null, null, null, null}, + {null, null, null, null} + }, + new String [] { + "Vessel Name", "Size", "Days", "Power" + } + ) { + boolean[] canEdit = new boolean [] { + false, false, false, false + }; + + public boolean isCellEditable(int rowIndex, int columnIndex) { + return canEdit [columnIndex]; + } + }); + jTableSelector.setRowHeight(25); + jTableSelector.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + jTableSelectorMouseClicked(evt); + } + }); + jScrollPane2.setViewportView(jTableSelector); + jTableSelector.getColumnModel().getColumn(1).setResizable(false); + jTableSelector.getColumnModel().getColumn(1).setPreferredWidth(50); + jTableSelector.getColumnModel().getColumn(2).setResizable(false); + jTableSelector.getColumnModel().getColumn(2).setPreferredWidth(50); + jTableSelector.getColumnModel().getColumn(3).setResizable(false); + jTableSelector.getColumnModel().getColumn(3).setPreferredWidth(70); + + jText.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jText.setDisabledTextColor(new java.awt.Color(0, 0, 0)); + jText.setEnabled(false); + jText.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jTextActionPerformed(evt); + } + }); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jLabel1.setText(bundle.getString("label.mooringscreatefor")); // NOI18N + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 508, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addGap(10, 10, 10) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jText, javax.swing.GroupLayout.PREFERRED_SIZE, 222, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jbtnCreateTicket, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 179, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1) + .addComponent(jbtnCreateTicket)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); + setBounds((screenSize.width-536)/2, (screenSize.height-274)/2, 536, 274); + }// </editor-fold>//GEN-END:initComponents + + private void jbtnCreateTicketActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnCreateTicketActionPerformed + // use the passed parameters to add line to the ticket + + if (vesselName.equals("")){ + this.create = false; + dispose(); + }else{ + this.create = true; + dispose(); + } + + }//GEN-LAST:event_jbtnCreateTicketActionPerformed + + private void jTableSelectorMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTableSelectorMouseClicked + + try{ + int row = jTableSelector.getSelectedRow(); + vesselName =(jTableSelector.getModel().getValueAt(row, 0).toString()); + SQL = "SELECT * FROM moorers WHERE VESSELNAME ='" + vesselName +"';"; + rs = stmt.executeQuery(SQL); + if (rs.next()){ + vesselDays=rs.getInt("DAYS"); + vesselSize=rs.getInt("SIZE"); + vesselPower=rs.getBoolean("POWER"); + jText.setText(vesselName); + } + }catch (Exception e){ + JOptionPane.showMessageDialog(null, e); + } + + + }//GEN-LAST:event_jTableSelectorMouseClicked + + private void jTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jTextActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JScrollPane jScrollPane2; + private javax.swing.JTable jTableSelector; + private javax.swing.JTextField jText; + private javax.swing.JButton jbtnCreateTicket; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/JPanelButtons.form b/src/main/java/com/unicenta/pos/sales/JPanelButtons.form new file mode 100644 index 0000000..92cafed --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JPanelButtons.form @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/JPanelButtons.java b/src/main/java/com/unicenta/pos/sales/JPanelButtons.java new file mode 100644 index 0000000..9414514 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JPanelButtons.java @@ -0,0 +1,221 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.data.loader.LocalRes; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppUser; +import com.unicenta.pos.util.ThumbNailBuilder; +import lombok.extern.slf4j.Slf4j; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import javax.swing.*; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.io.IOException; +import java.io.StringReader; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +/** + * + * @author JG uniCenta + */ +@Slf4j +public class JPanelButtons extends javax.swing.JPanel { + + private static SAXParser m_sp = null; + + private Properties props; + private Map<String, String> events; + + private ThumbNailBuilder tnbmacro; + + private JPanelTicket panelticket; + + /** Creates new form JPanelButtons + * @param sConfigKey + * @param panelticket */ + public JPanelButtons(String sConfigKey, JPanelTicket panelticket) { + initComponents(); + + // Load categories default thumbnail + tnbmacro = new ThumbNailBuilder(42, 36, "com/unicenta/images/run_script.png"); + + this.panelticket = panelticket; + + props = new Properties(); + events = new HashMap<>(); + + String sConfigRes = panelticket.getResourceAsXML(sConfigKey); + + if (sConfigRes != null) { + try { + if (m_sp == null) { + SAXParserFactory spf = SAXParserFactory.newInstance(); + m_sp = spf.newSAXParser(); + } + m_sp.parse(new InputSource(new StringReader(sConfigRes)), new ConfigurationHandler()); + + } catch (ParserConfigurationException ePC) { + log.error(LocalRes.getIntString("exception.parserconfig"), ePC.getMessage()); + } catch (SAXException eSAX) { + log.error(LocalRes.getIntString("exception.xmlfile"), eSAX.getMessage()); + } catch (IOException eIO) { + log.error(LocalRes.getIntString("exception.iofile"), eIO.getMessage()); + } + } + + } + + /** + * + * @param user + */ + public void setPermissions(AppUser user) { + for (Component c : this.getComponents()) { + String sKey = c.getName(); + if (sKey == null || sKey.equals("")) { + c.setEnabled(true); + } else { + c.setEnabled(user.hasPermission(c.getName())); + } + } + } + + /** + * + * @param key + * @return + */ + public String getProperty(String key) { + return props.getProperty(key); + } + + /** + * + * @param key + * @param defaultvalue + * @return + */ + public String getProperty(String key, String defaultvalue) { + return props.getProperty(key, defaultvalue); + } + + /** + * + * @param key + * @return + */ + public String getEvent(String key) { + return events.get(key); + } + + private class ConfigurationHandler extends DefaultHandler { + @Override + public void startDocument() throws SAXException {} + @Override + public void endDocument() throws SAXException {} + @Override + public void startElement(String uri, String localName, String qName, + Attributes attributes) throws SAXException{ + switch (qName) { + case "button": + // The button title text + String titlekey = attributes.getValue("titlekey"); + if (titlekey == null) { + titlekey = attributes.getValue("name"); + } + String title = titlekey == null + ? attributes.getValue("title") + : AppLocal.getIntString(titlekey); + // adding the button to the panel + JButton btn = new JButtonFunc(attributes.getValue("key"), + attributes.getValue("image"), + title); + // The template resource or the code resource + final String template = attributes.getValue("template"); + if (template == null) { + final String code = attributes.getValue("code"); + btn.addActionListener((ActionEvent evt) -> { + panelticket.evalScriptAndRefresh(code); + }); + } else { + btn.addActionListener((ActionEvent evt) -> { + panelticket.printTicket(template); + }); + } + add(btn); + break; + case "event": + events.put(attributes.getValue("key"), attributes.getValue("code")); + break; + default: + String value = attributes.getValue("value"); + if (value != null) { + props.setProperty(qName, attributes.getValue("value")); + } + break; + } + } + @Override + public void endElement(String uri, String localName, String qName) throws SAXException {} + @Override + public void characters(char[] ch, int start, int length) throws SAXException {} + } + + private class JButtonFunc extends JButton { + + public JButtonFunc(String sKey, String sImage, String title) { + + setName(sKey); + setText(title); + setIcon(new ImageIcon(tnbmacro.getThumbNail(panelticket.getResourceAsImage(sImage)))); + setFocusPainted(false); + setFocusable(false); + setRequestFocusEnabled(false); + setMargin(new Insets(8, 14, 8, 14)); + setPreferredSize(new Dimension(80,45)); + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/JPanelResetPickupId.form b/src/main/java/com/unicenta/pos/sales/JPanelResetPickupId.form new file mode 100644 index 0000000..20907e2 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JPanelResetPickupId.form @@ -0,0 +1,114 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 100]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jPanel1" alignment="1" max="32767" attributes="0"/> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jPanel1" min="-2" max="-2" attributes="0"/> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[342, 80]"/> + </Property> + </Properties> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="20" max="-2" attributes="0"/> + <Component id="jbtnUpdate" min="-2" pref="155" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="56" max="-2" attributes="0"/> + <Component id="jbtnExit" min="-2" pref="101" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="22" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jbtnUpdate" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jbtnExit" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace pref="25" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="jbtnUpdate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.resetpickup" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 33]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 33]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 33]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnUpdateActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jbtnExit"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="Button.Exit" replaceFormat="AppLocal.getIntString("Button.Exit")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 33]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 33]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 33]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnExitActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/JPanelResetPickupId.java b/src/main/java/com/unicenta/pos/sales/JPanelResetPickupId.java new file mode 100644 index 0000000..f7cb7c7 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JPanelResetPickupId.java @@ -0,0 +1,275 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.JMessageDialog; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.loader.Session; +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppProperties; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.AppViewConnection; +import com.unicenta.pos.forms.JPanelView; +import com.unicenta.pos.util.AltEncrypter; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; +import javax.swing.JComponent; +import javax.swing.JOptionPane; +import javax.swing.JPanel; + +/** + * + * @author JG uniCenta + */ +public class JPanelResetPickupId extends JPanel implements JPanelView { + + + private AppConfig config; + private Connection con; + private String sdbmanager; + private Session session; + private AppProperties m_props; + private String SQL; + private Statement stmt; + + /** Creates new form JPaneldbUpdate + * @param oApp */ + public JPanelResetPickupId(AppView oApp) { + this(oApp.getProperties()); + } + + /** + * + * @param props + */ + public JPanelResetPickupId(AppProperties props) { + + initComponents(); + config = new AppConfig(props.getConfigFile()); + m_props=props; + + + } + + /** + * + */ + public void performReset(){ + + if ("HSQL Database Engine".equals(sdbmanager)) { + SQL = "ALTER SEQUENCE pickup_number RESTART WITH 1"; + try { + stmt.executeUpdate(SQL); +// } catch (SQLException e){System.out.println(e.getMessage());} + } catch (SQLException e){} + } else if ("MySQL".equals(sdbmanager)) { + SQL = "UPDATE pickup_number SET ID=0"; + try { + stmt.executeUpdate(SQL); +// } catch (SQLException e){System.out.println(e.getMessage());} + } catch (SQLException e){} + } else if ("PostgreSQL".equals(sdbmanager)) { + SQL = "ALTER SEQUENCE pickup_number RESTART WITH 1"; + try { + stmt.executeUpdate(SQL); +// } catch (SQLException e){System.out.println(e.getMessage());} + } catch (SQLException e){} + } else if ("Oracle".equals(sdbmanager)) { + SQL = "ALTER SEQUENCE pickup_number RESTART WITH 1"; + try { + stmt.executeUpdate(SQL); +// } catch (SQLException e){System.out.println(e.getMessage());} + } catch (SQLException e){} + } else if ("Apache Derby".equals(sdbmanager)) { + SQL = "ALTER TABLE pickup_number ALTER COLUMN ID RESTART WITH 1"; + try { + stmt.executeUpdate(SQL); +// } catch (SQLException e){System.out.println(e.getMessage());} + } catch (SQLException e){} + } else if ("Derby".equals(sdbmanager)) { + SQL = "UPDATE pickup_number SET ID=0"; + try { + stmt.executeUpdate(SQL); +// } catch (SQLException e){System.out.println(e.getMessage());} + } catch (SQLException e){} + } else { + SQL = "ALTER SEQUENCE pickup_number RESTART WITH 1"; + try { + stmt.executeUpdate(SQL); +// } catch (SQLException e){System.out.println(e.getMessage());} + } catch (SQLException e){} + } + JOptionPane.showMessageDialog(this,"Reset complete."); + + } + + /** + * + * @return + */ + @Override + public JComponent getComponent() { + return this; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.Resetpickup"); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + + // connect to the database + String db_user =(m_props.getProperty("db.user")); + String db_url = (m_props.getProperty("db.URL")); + String db_password = (m_props.getProperty("db.password")); + + if (db_user != null && db_password != null && db_password.startsWith("crypt:")) { + // the password is encrypted + AltEncrypter cypher = new AltEncrypter("cypherkey" + db_user); + db_password = cypher.decrypt(db_password.substring(6)); + } + + try{ + session = AppViewConnection.createSession(m_props); + con = DriverManager.getConnection(db_url,db_user,db_password); + sdbmanager = con.getMetaData().getDatabaseProductName(); + stmt = (Statement) con.createStatement(); + } catch (BasicException | SQLException e) { + + JMessageDialog.showMessage(this, new MessageInf(MessageInf.SGN_DANGER, AppLocal.getIntString("database.UnableToConnect"), e)); + System.exit(0); + } + + } + + /** + * + * @return + */ + @Override + public boolean deactivate() { + return(true); + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jbtnUpdate = new javax.swing.JButton(); + jbtnExit = new javax.swing.JButton(); + + setPreferredSize(new java.awt.Dimension(200, 100)); + + jPanel1.setPreferredSize(new java.awt.Dimension(342, 80)); + + jbtnUpdate.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnUpdate.setText(AppLocal.getIntString("label.resetpickup")); // NOI18N + jbtnUpdate.setMaximumSize(new java.awt.Dimension(70, 33)); + jbtnUpdate.setMinimumSize(new java.awt.Dimension(70, 33)); + jbtnUpdate.setPreferredSize(new java.awt.Dimension(70, 33)); + jbtnUpdate.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnUpdateActionPerformed(evt); + } + }); + + jbtnExit.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnExit.setText(AppLocal.getIntString("button.exit")); // NOI18N + jbtnExit.setMaximumSize(new java.awt.Dimension(70, 33)); + jbtnExit.setMinimumSize(new java.awt.Dimension(70, 33)); + jbtnExit.setPreferredSize(new java.awt.Dimension(70, 33)); + jbtnExit.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnExitActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(20, 20, 20) + .addComponent(jbtnUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, 155, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(56, 56, 56) + .addComponent(jbtnExit, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(22, 22, 22) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jbtnUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jbtnExit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(25, Short.MAX_VALUE)) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + ); + }// </editor-fold>//GEN-END:initComponents + + private void jbtnUpdateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnUpdateActionPerformed + performReset(); + + }//GEN-LAST:event_jbtnUpdateActionPerformed + + private void jbtnExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnExitActionPerformed + deactivate(); + System.exit(0); + }//GEN-LAST:event_jbtnExitActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JButton jbtnExit; + private javax.swing.JButton jbtnUpdate; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/JPanelTicket.form b/src/main/java/com/unicenta/pos/sales/JPanelTicket.form new file mode 100644 index 0000000..4023123 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JPanelTicket.form @@ -0,0 +1,1072 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="99" green="cc" red="ff" type="rgb"/> + </Property> + <Property name="opaque" type="boolean" value="false"/> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-21,0,0,3,67"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignCardLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="m_jPanContainer"> + <Events> + <EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="m_jPanContainerFocusLost"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription"> + <CardConstraints cardName="ticket"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="m_jOptions"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="m_jPanelBag"> + <Properties> + <Property name="autoscrolls" type="boolean" value="true"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 10]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 60]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="First"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JToggleButton" name="jTBtnShow"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/resources.png"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jTBtnShowActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jbtnScale"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/scale.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.scale" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.scale" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[85, 44]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[85, 44]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[85, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jbtnScaleActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jbtnMooring"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.moorings" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnMooringActionPerformed"/> + </Events> + </Component> + <Container class="javax.swing.JPanel" name="m_jButtons"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[350, 55]"/> + </Property> + </Properties> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jBtnCustomer" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="btnSplit" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="j_btnRemotePrt" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="btnReprint1" min="-2" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="5" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="j_btnRemotePrt" max="32767" attributes="0"/> + <Component id="btnSplit" alignment="1" max="32767" attributes="0"/> + <Component id="btnReprint1" alignment="1" max="32767" attributes="0"/> + <Component id="jBtnCustomer" max="32767" attributes="0"/> + </Group> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="btnSplit"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/sale_split_sml.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.salesplit" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnSplitActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="btnReprint1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/reprint24.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.reprintLastTicket" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnReprint1ActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="j_btnRemotePrt"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/remote_print.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.sendorder" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.printtoremote" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 4, 0, 4]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="j_btnRemotePrtActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jBtnCustomer"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/customer.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.salescustomer" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnCustomerActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="m_jPanelScripts"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 60]"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" value=""/> + </AccessibilityProperties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="m_jButtonsExt"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[20, 60]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="First"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[235, 50]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 55]"/> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="m_jPanTicket"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[75, 270]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Before"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="0" left="5" right="5" top="0"/> + </Border> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 250]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> + <Property name="columns" type="int" value="1"/> + <Property name="horizontalGap" type="int" value="5"/> + <Property name="rows" type="int" value="0"/> + <Property name="verticalGap" type="int" value="5"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="m_jDelete"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/editdelete.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.saleremoveline" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[42, 36]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[42, 36]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jDeleteActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jList"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/search32.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.saleproductfind" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[42, 36]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[42, 36]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jListActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jEditLine"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/sale_editline.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.saleeditline" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[42, 36]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[42, 36]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jEditLineActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jEditAttributes"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/attributes.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.saleattributes" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[42, 36]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[42, 36]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jEditAttributesActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jCheckStock"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="1"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ed" green="c5" red="4c" type="rgb"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/info.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.salecheckstock" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="horizontalTextPosition" type="int" value="2"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 4, 8, 4]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[42, 36]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[42, 36]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + <Property name="verticalTextPosition" type="int" value="1"/> + </Properties> + <Events> + <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="jCheckStockMouseClicked"/> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jCheckStockActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="m_jPanelCentral"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[450, 240]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Component class="javax.swing.Box$Filler" name="filler2"> + <Properties> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[5, 32767]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[5, 0]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[5, 0]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.HorizontalStrut"/> + </AuxValues> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Before"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="m_jTicketId"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="1"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="verticalAlignment" type="int" value="1"/> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 40]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + <Property name="verticalTextPosition" type="int" value="1"/> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + </Component> + <Container class="javax.swing.JPanel" name="m_jPanTotals"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[375, 60]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="After"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> + <Property name="columns" type="int" value="3"/> + <Property name="horizontalGap" type="int" value="4"/> + <Property name="rows" type="int" value="2"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="m_jLblTotalEuros3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="1"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor"> + <ComponentRef name="m_jSubtotalEuros"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.subtotalcash" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jLblTotalEuros2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="1"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor"> + <ComponentRef name="m_jSubtotalEuros"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.taxcash" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jLblTotalEuros1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="1"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor"> + <ComponentRef name="m_jTotalEuros"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.totalcash" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jSubtotalEuros"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection component="m_jEditLine" name="background" type="property"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection component="m_jEditLine" name="foreground" type="property"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor"> + <ComponentRef name="m_jSubtotalEuros"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.salesubtotal" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder roundedCorners="true"> + <Color PropertyName="color" blue="99" green="99" red="99" type="rgb"/> + </LineBorder> + </Border> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[125, 25]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 25]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jTaxesEuros"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection component="m_jEditLine" name="background" type="property"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection component="m_jEditLine" name="foreground" type="property"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor"> + <ComponentRef name="m_jTaxesEuros"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.saletax" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder roundedCorners="true"> + <Color PropertyName="color" blue="99" green="99" red="99" type="rgb"/> + </LineBorder> + </Border> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[125, 25]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 25]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jTotalEuros"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection component="m_jEditLine" name="background" type="property"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="1"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection component="m_jEditLine" name="foreground" type="property"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor"> + <ComponentRef name="m_jTotalEuros"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.saletotal" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder roundedCorners="true"> + <Color PropertyName="color" blue="99" green="99" red="99" type="rgb"/> + </LineBorder> + </Border> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[125, 25]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 25]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="m_jContEntries"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 350]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="After"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="m_jPanEntries"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 350]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="1"/> + </Layout> + <SubComponents> + <Component class="com.unicenta.beans.JNumberKeys" name="m_jNumberKeys"> + <Properties> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 300]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 250]"/> + </Property> + </Properties> + <Events> + <EventHandler event="keyPerformed" listener="com.unicenta.beans.JNumberEventListener" parameters="com.unicenta.beans.JNumberEvent" handler="m_jNumberKeysKeyPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="JPanelTicket_m_jNumberKeys"/> + </AuxValues> + </Component> + <Container class="javax.swing.JPanel" name="jPanel9"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + </Properties> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="m_jPor" min="-2" max="-2" attributes="0"/> + <Component id="m_jKeyFactory" max="32767" attributes="0"/> + </Group> + <EmptySpace pref="7" max="32767" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="m_jaddtax" max="32767" attributes="0"/> + <EmptySpace min="-2" pref="7" max="-2" attributes="0"/> + <Component id="m_jTax" min="-2" pref="128" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="m_jPrice" max="32767" attributes="0"/> + <EmptySpace min="-2" pref="5" max="-2" attributes="0"/> + </Group> + </Group> + <Component id="m_jEnter" min="-2" pref="71" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="m_jEnter" min="-2" max="-2" attributes="0"/> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="m_jPrice" min="-2" pref="44" max="-2" attributes="0"/> + <EmptySpace pref="7" max="32767" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jTax" alignment="1" min="-2" pref="30" max="-2" attributes="0"/> + <Component id="m_jaddtax" alignment="1" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" alignment="1" attributes="0"> + <Component id="m_jPor" min="-2" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + <Component id="m_jKeyFactory" min="-2" pref="1" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="com.alee.extended.button.WebSwitch" name="m_jaddtax"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.switchtax" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jaddtaxActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="m_jPrice"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" id="white" palette="0" red="ff" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="16" style="1"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ed" green="c5" red="4c" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="ed" green="c5" red="4c" type="rgb"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 25]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jPor"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" id="white" palette="0" red="ff" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="m_jEnter"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/barcode.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.salebarcode" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jEnterActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="m_jTax"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.salestaxswitch" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusable" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[28, 25]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jKeyFactory"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="11" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ee" green="ee" id="Panel.background" palette="3" red="ee" type="palette"/> + </Property> + <Property name="autoscrolls" type="boolean" value="false"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="caretColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ee" green="ee" id="Panel.background" palette="3" red="ee" type="palette"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 0]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[1, 1]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + <Property name="verifyInputWhenFocusTarget" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="keyTyped" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="m_jKeyFactoryKeyTyped"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="m_jPanEntriesE"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="After"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="catcontainer"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/JPanelTicket.java b/src/main/java/com/unicenta/pos/sales/JPanelTicket.java new file mode 100644 index 0000000..def840d --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JPanelTicket.java @@ -0,0 +1,3515 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import bsh.EvalError; +import bsh.Interpreter; +import com.alee.extended.time.ClockType; +import com.alee.extended.time.WebClock; +import com.alee.managers.notification.NotificationIcon; +import com.alee.managers.notification.NotificationManager; +import com.alee.managers.notification.WebNotification; +import com.unicenta.basic.BasicException; +import com.unicenta.beans.JNumberPop; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.gui.ListKeyed; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.plugins.Application; +import com.unicenta.pos.catalog.JCatalog; +import com.unicenta.pos.customers.*; +import com.unicenta.pos.forms.*; +import com.unicenta.pos.inventory.ProductStock; +import com.unicenta.pos.inventory.TaxCategoryInfo; +import com.unicenta.pos.panels.JProductFinder; +import com.unicenta.pos.payment.JPaymentSelect; +import com.unicenta.pos.payment.JPaymentSelectReceipt; +import com.unicenta.pos.payment.JPaymentSelectRefund; +import com.unicenta.pos.printer.DeviceTicket; +import com.unicenta.pos.printer.TicketParser; +import com.unicenta.pos.printer.TicketPrinterException; +import com.unicenta.pos.sales.restaurant.RestaurantDBUtils; +import com.unicenta.pos.scale.ScaleException; +import com.unicenta.pos.scripting.ScriptEngine; +import com.unicenta.pos.scripting.ScriptException; +import com.unicenta.pos.scripting.ScriptFactory; +import com.unicenta.pos.ticket.*; +import com.unicenta.pos.util.AltEncrypter; +import com.unicenta.pos.util.InactivityListener; +import com.unicenta.pos.util.JRPrinterAWT300; +import com.unicenta.pos.util.ReportUtils; +import lombok.extern.slf4j.Slf4j; +import net.sf.jasperreports.engine.*; +import net.sf.jasperreports.engine.data.JRMapArrayDataSource; +import net.sf.jasperreports.engine.design.JasperDesign; +import net.sf.jasperreports.engine.xml.JRXmlLoader; + +import javax.print.PrintService; +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.FocusEvent; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.util.*; + +import static java.awt.Window.getWindows; + + +/** + * @author JG uniCenta + */ +@Slf4j +public abstract class JPanelTicket extends JPanel implements JPanelView, BeanFactoryApp, TicketsEditor { + + private final static int NUMBERZERO = 0; + private final static int NUMBERVALID = 1; + + private final static int NUMBER_INPUTZERO = 0; + private final static int NUMBER_INPUTZERODEC = 1; + private final static int NUMBER_INPUTINT = 2; + private final static int NUMBER_INPUTDEC = 3; + private final static int NUMBER_PORZERO = 4; + private final static int NUMBER_PORZERODEC = 5; + private final static int NUMBER_PORINT = 6; + private final static int NUMBER_PORDEC = 7; + + protected JTicketLines m_ticketlines; + + private TicketParser m_TTP; + + protected TicketInfo m_oTicket; + protected Object m_oTicketExt; + + private int m_iNumberStatus; + private int m_iNumberStatusInput; + private int m_iNumberStatusPor; + private StringBuffer m_sBarcode; + + private JTicketsBag m_ticketsbag; + + private SentenceList senttax; + private ListKeyed taxcollection; + + private SentenceList senttaxcategories; + private ListKeyed taxcategoriescollection; + private ComboBoxValModel taxcategoriesmodel; + + private TaxesLogic taxeslogic; + + protected JPanelButtons m_jbtnconfig; + protected AppView m_App; + + protected DataLogicSystem dlSystem; + protected DataLogicSales dlSales; + protected DataLogicCustomers dlCustomers; + + private JPaymentSelect paymentdialogreceipt; + private JPaymentSelect paymentdialogrefund; + + private JRootApp root; + private Object m_principalapp; + private Boolean restaurant; + private Boolean orderlistopen; + + private Action logout; + private InactivityListener listener; + private Integer delay = 0; + private final String m_sCurrentTicket = null; + + protected TicketsEditor m_panelticket; + private DataLogicReceipts dlReceipts = null; + private Boolean priceWith00; + private final String temp_jPrice = ""; + private String tableDetails; + private RestaurantDBUtils restDB; + private KitchenDisplay kitchenDisplay; + private String ticketPrintType; + + private Boolean warrantyPrint = false; + + private TicketInfo m_ticket; + private TicketInfo m_ticketCopy; + private AppConfig m_config; + + private Integer count = 0; + private Integer oCount = 0; + private Boolean pinOK; + + + /** + * Creates new form JTicketView + */ + public JPanelTicket() { + + initComponents(); + } + + /** + * @param app + * @throws BeanFactoryException + */ + @Override + public void init(AppView app) throws BeanFactoryException { + + m_config = new AppConfig(new File((System.getProperty("user.home")), AppLocal.APP_ID + ".properties")); + m_config.load(); + + m_App = app; + restDB = new RestaurantDBUtils(m_App); + + dlSystem = (DataLogicSystem) m_App.getBean("com.unicenta.pos.forms.DataLogicSystem"); + dlSales = (DataLogicSales) m_App.getBean("com.unicenta.pos.forms.DataLogicSales"); + dlCustomers = (DataLogicCustomers) m_App.getBean("com.unicenta.pos.customers.DataLogicCustomers"); + dlReceipts = (DataLogicReceipts) app.getBean("com.unicenta.pos.sales.DataLogicReceipts"); + + + /* uniCenta Feb 2018 + * Changed for 4.3 + * Set up main toolbar area with two rows to add cater for additional scripts + * else over-crowding and some dynamic buttons off screen/not visible + * m_jPanelScripts contains m_jButtonsExt panel for buttons Enabled/Disabled in + * Resources>Menu.Root + */ + +// Set Configuration>General>Tickets toolbar simple : standard : restaurant option + m_ticketsbag = getJTicketsBag(); + m_jPanelBag.add(m_ticketsbag.getBagComponent(), BorderLayout.LINE_START); + add(m_ticketsbag.getNullComponent(), "null"); + +// Script event buttons + m_jbtnconfig = new JPanelButtons("Ticket.Buttons", this); + m_jButtonsExt.add(m_jbtnconfig); + +// Configuration>Peripheral options + if (!m_App.getDeviceScale().existsScale()) { + m_jbtnScale.setVisible(false); + } + jbtnMooring.setVisible(Boolean.valueOf(m_App.getProperties().getProperty("till.marineoption"))); + m_jPanelScripts.setVisible(false); + m_jButtonsExt.setVisible(false); + jTBtnShow.setSelected(false); + + if (Boolean.valueOf(m_App.getProperties().getProperty("till.amountattop"))) { + m_jPanEntries.remove(jPanel9); + m_jPanEntries.remove(m_jNumberKeys); + m_jPanEntries.add(jPanel9); + m_jPanEntries.add(m_jNumberKeys); + } + + priceWith00 = ("true".equals(m_App.getProperties().getProperty("till.pricewith00"))); + + if (priceWith00) { + m_jNumberKeys.dotIs00(true); + } + + m_ticketlines = new JTicketLines(dlSystem.getResourceAsXML("Ticket.Line")); + m_jPanelCentral.add(m_ticketlines, java.awt.BorderLayout.CENTER); + m_TTP = new TicketParser(m_App.getDeviceTicket(), dlSystem); + catcontainer.add(getSouthComponent(), BorderLayout.CENTER); + + senttax = dlSales.getTaxList(); + senttaxcategories = dlSales.getTaxCategoriesList(); + taxcategoriesmodel = new ComboBoxValModel(); + + stateToZero(); + + m_oTicket = null; + m_oTicketExt = null; + jCheckStock.setText(AppLocal.getIntString("message.title.checkstock")); + + if (this instanceof JPanelTicketSales) { + // 2016-10-14 TJMChan - Sales screen Layout code starts here. + if (AppConfig.getInstance().getProperty("machine.saleslayout") != null) { + JSalesLayoutManager.createLayout(); + + if (AppConfig.getInstance().getProperty("machine.saleslayout").equals("Layout1")) { + Component southcomponent = getSouthComponent(); + catcontainer.add(southcomponent, BorderLayout.CENTER); + JPanel southpanel = (JPanel) southcomponent; + ((JPanel) southpanel.getComponent(0)).setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + + JPanel fpanel = new JPanel(new BorderLayout()); + fpanel.add(m_jPanEntries, BorderLayout.WEST); + if (southcomponent instanceof JCatalog) { + fpanel.add(((JCatalog) southpanel).getCatComponent(), BorderLayout.EAST); + } + + m_jPanEntriesE.add(jPanel5, BorderLayout.WEST); + m_jPanEntriesE.add(fpanel, BorderLayout.EAST); + + m_jTicketId.setPreferredSize(new Dimension(300, 16)); + m_jPanTicket.add(m_jTicketId, BorderLayout.BEFORE_FIRST_LINE); + jPanel2.setPreferredSize(new Dimension(90, 305)); + jPanel5.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + jPanel4.add(m_jPanTotals, BorderLayout.CENTER); + m_jContEntries.add(m_jPanEntriesE, BorderLayout.NORTH); + if (southcomponent instanceof JCatalog) { + JCatalog catpanel = (JCatalog) southpanel; + m_jContEntries.add(catpanel.getProductComponent(), BorderLayout.CENTER); + catpanel.setControls("south"); + catpanel.getCatComponent().setPreferredSize(new Dimension(230, 10)); + catpanel.getProductComponent().setPreferredSize(new Dimension(230, 350)); + } else { + m_jContEntries.add(southpanel, BorderLayout.CENTER); + } + southcomponent.setPreferredSize(new Dimension(0, 0)); + } else if (AppConfig.getInstance().getProperty("machine.saleslayout").equals("Layout2")) { + if (catcontainer.getComponent(0) instanceof JCatalog) { + JCatalog catpanel = (JCatalog) catcontainer.getComponent(0); + catpanel.setControls("south"); + catpanel.getCatComponent().setPreferredSize(new Dimension(230, 10)); + } + jPanel4.add(m_jPanTotals, BorderLayout.CENTER); + m_jPanContainer.add(m_jPanTicket, BorderLayout.EAST); + m_jPanContainer.add(catcontainer, BorderLayout.CENTER); + jPanel5.setPreferredSize(new Dimension(80, 0)); + jPanel2.setPreferredSize(new Dimension(90, 310)); + m_jPanEntriesE.add(jPanel5, BorderLayout.CENTER); + m_jPanEntriesE.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0)); + m_jContEntries.add(m_jPanEntries, BorderLayout.CENTER); + m_jPanEntries.setPreferredSize(new Dimension(250, 316)); + m_jTicketId.setPreferredSize(new Dimension(300, 16)); + m_jPanTicket.add(m_jTicketId, BorderLayout.BEFORE_FIRST_LINE); + m_jPanTicket.setPreferredSize(new Dimension(390, 316)); + m_jPanTicket.add(m_jContEntries, BorderLayout.SOUTH); + } else if (AppConfig.getInstance().getProperty("machine.saleslayout").equals("Layout3")) { + JPanel catPanel = null; + JPanel jpanelA = new JPanel(new BorderLayout()); + if (catcontainer.getComponent(0) instanceof JCatalog) { + JCatalog myCatpanel = (JCatalog) catcontainer.getComponent(0); + myCatpanel.setControls("south"); + myCatpanel.getCatComponent().setPreferredSize(new Dimension(230, 10)); + catPanel = (JPanel) myCatpanel.getCatComponent(); + catPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + m_jPanContainer.add(jpanelA, BorderLayout.EAST); + jpanelA.add(catPanel, BorderLayout.CENTER); + } + jPanel4.add(m_jPanTotals, BorderLayout.CENTER); + m_jPanContainer.add(m_jPanTicket, BorderLayout.EAST); + m_jPanContainer.add(catcontainer, BorderLayout.CENTER); + jPanel5.setPreferredSize(new Dimension(80, 0)); + jPanel2.setPreferredSize(new Dimension(90, 310)); + m_jPanEntriesE.add(jPanel5, BorderLayout.CENTER); + m_jPanEntriesE.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0)); + m_jContEntries.add(m_jPanEntries, BorderLayout.CENTER); + m_jPanEntries.setPreferredSize(new Dimension(250, 316)); + m_jTicketId.setPreferredSize(new Dimension(300, 16)); + m_jPanTicket.add(m_jTicketId, BorderLayout.BEFORE_FIRST_LINE); + if (catPanel != null) { + m_jPanTicket.setPreferredSize(new Dimension(500, 316)); + jpanelA.add(m_jContEntries, BorderLayout.EAST); + m_jPanTicket.add(jpanelA, BorderLayout.SOUTH); + } else { + m_jPanTicket.setPreferredSize(new Dimension(390, 316)); + m_jPanTicket.add(m_jContEntries, BorderLayout.SOUTH); + } + } + } + } + + + } + + @Override + public Object getBean() { + return this; + } + + @Override + public JComponent getComponent() { + return this; + } + + private void jPanContainerFocusLost(FocusEvent evt) { + System.out.println("PanelContainer : Focus Lost"); + } + + private class logout extends AbstractAction { + + public logout() { + } + + @Override + public void actionPerformed(ActionEvent ae) { + closeAllDialogs(); + switch (m_App.getProperties().getProperty("machine.ticketsbag")) { + case "restaurant": + if ("false".equals(m_App.getProperties().getProperty("till.autoLogoffrestaurant"))) { + deactivate(); + ((JRootApp) m_App).closeAppView(); + break; + } + + deactivate(); + setActiveTicket(null, null); + break; + + default: + deactivate(); + ((JRootApp) m_App).closeAppView(); + } + } + } + + private void closeAllDialogs() { + Window[] windows = getWindows(); + + for (Window window : windows) { + if (window instanceof JDialog) { + window.dispose(); + } + } + } + + private void saveCurrentTicket() { + String currentTicket = (String) m_oTicketExt; + if (currentTicket != null) { + try { + dlReceipts.updateSharedTicket(currentTicket, m_oTicket, m_oTicket.getPickupId()); +// } catch (BasicException e) { +// new MessageInf(e).show(this); +// } + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + } + } + + /** + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + + Action logout = new logout(); + String autoLogoff = (m_App.getProperties().getProperty("till.autoLogoff")); + + if (autoLogoff != null) { + if (autoLogoff.equals("true")) { + try { + delay = Integer.parseInt(m_App.getProperties().getProperty("till.autotimer")); + } catch (NumberFormatException e) { + delay = 0; + } + delay *= 1000; + } + } + + if (delay != 0) { + listener = new InactivityListener(logout, delay); + listener.start(); + } + + paymentdialogreceipt = JPaymentSelectReceipt.getDialog(this); + paymentdialogreceipt.init(m_App); + paymentdialogrefund = JPaymentSelectRefund.getDialog(this); + paymentdialogrefund.init(m_App); + + m_jaddtax.setSelected("true".equals(m_jbtnconfig.getProperty("taxesincluded"))); + + java.util.List<TaxInfo> taxlist = senttax.list(); + taxcollection = new ListKeyed<>(taxlist); + java.util.List<TaxCategoryInfo> taxcategorieslist = senttaxcategories.list(); + taxcategoriescollection = new ListKeyed<>(taxcategorieslist); + + taxcategoriesmodel = new ComboBoxValModel(taxcategorieslist); + m_jTax.setModel(taxcategoriesmodel); + + String taxesid = m_jbtnconfig.getProperty("taxcategoryid"); + + if (taxesid == null) { + if (m_jTax.getItemCount() > 0) { + m_jTax.setSelectedIndex(0); + } + } else { + taxcategoriesmodel.setSelectedKey(taxesid); + } + + taxeslogic = new TaxesLogic(taxlist); + m_jaddtax.setSelected((Boolean.parseBoolean(m_App.getProperties().getProperty("till.taxincluded")))); + + if (m_App.getAppUserView().getUser().hasPermission("sales.ChangeTaxOptions")) { + m_jTax.setVisible(true); + m_jaddtax.setVisible(true); + } else { + m_jTax.setVisible(false); + m_jaddtax.setVisible(false); + } + + m_jDelete.setEnabled(m_App.getAppUserView().getUser().hasPermission("sales.EditLines")); + m_jNumberKeys.setMinusEnabled(m_App.getAppUserView().getUser().hasPermission("sales.EditLines")); + m_jNumberKeys.setEqualsEnabled(m_App.getAppUserView().getUser().hasPermission("sales.Total")); + m_jbtnconfig.setPermissions(m_App.getAppUserView().getUser()); + + m_ticketsbag.setEnabled(false); + m_ticketsbag.activate(); + + CustomerInfoGlobal customerInfoGlobal = CustomerInfoGlobal.getInstance(); + + if (customerInfoGlobal.getCustomerInfoExt() != null) { + + if (m_oTicket != null) { + m_oTicket.setCustomer(customerInfoGlobal.getCustomerInfoExt()); + } + } + + refreshTicket(); + } + + @Override + public boolean deactivate() { + if (listener != null) { + listener.stop(); + } + + return m_ticketsbag.deactivate(); + } + + protected abstract JTicketsBag getJTicketsBag(); + + protected abstract Component getSouthComponent(); + + protected abstract void resetSouthComponent(); + + /** + * @param oTicket + * @param oTicketExt + */ + @SuppressWarnings("empty-statement") + @Override + public void setActiveTicket(TicketInfo oTicket, Object oTicketExt) { + + switch (m_App.getProperties().getProperty("machine.ticketsbag")) { + case "restaurant": + if ("true".equals(m_App.getProperties().getProperty("till.autoLogoffrestaurant"))) { + if (listener != null) { + listener.restart(); + } + } + } + + m_oTicket = oTicket; + m_oTicketExt = oTicketExt; + + if (m_oTicket != null) { + m_oTicket.setUser(m_App.getAppUserView().getUser().getUserInfo()); + m_oTicket.setActiveCash(m_App.getActiveCashIndex()); + m_oTicket.setDate(new Date()); + + if ("restaurant".equals(m_App.getProperties().getProperty("machine.ticketsbag")) + && !oTicket.getOldTicket()) { + if (restDB.getCustomerNameInTable(oTicketExt.toString()) == null) { + if (m_oTicket.getCustomer() != null) { + restDB.setCustomerNameInTable(m_oTicket.getCustomer().toString(), + oTicketExt.toString()); + } + } + if (restDB.getWaiterNameInTable(oTicketExt.toString()) == null + || "".equals(restDB.getWaiterNameInTable(oTicketExt.toString()))) { + restDB.setWaiterNameInTable(m_App.getAppUserView().getUser().getName(), + oTicketExt.toString()); + } + + restDB.setTicketIdInTable(m_oTicket.getId(), oTicketExt.toString()); + restDB.setGuestsInTable(restDB.getGuestsInTable(m_oTicket.getId()), m_oTicket.getId()); + restDB.setOccupied(m_oTicket.getId()); + } + } + + if ((m_oTicket != null) && (((Boolean.parseBoolean(m_App.getProperties() + .getProperty("table.showwaiterdetails"))) + || (Boolean.valueOf(m_App.getProperties().getProperty( + "table.showcustomerdetails")))))) { + } + + if ((m_oTicket != null) && (((Boolean.valueOf(m_App.getProperties() + .getProperty("table.showcustomerdetails"))) || + (Boolean.parseBoolean(m_App.getProperties().getProperty("table.showwaiterdetails")))))) { + if (restDB.getTableMovedFlag(m_oTicket.getId())) { + restDB.moveCustomer(oTicketExt.toString(), m_oTicket.getId()); + } + } + + executeEvent(m_oTicket, m_oTicketExt, "ticket.show"); + + if (m_App.getAppUserView().getUser().hasPermission("sales.PrintRemote")) { + j_btnRemotePrt.setEnabled(true); + + } else { + j_btnRemotePrt.setEnabled(false); + } + + refreshTicket(); + } + + /** + * @return + */ + @Override + public TicketInfo getActiveTicket() { + return m_oTicket; + } + + private void refreshTicket() { + + CardLayout cl = (CardLayout) (getLayout()); + + if (m_oTicket == null) { + m_jTicketId.setText(null); + m_ticketlines.clearTicketLines(); + + m_jSubtotalEuros.setText(null); + m_jTaxesEuros.setText(null); + m_jTotalEuros.setText(null); + jCheckStock.setText(null); + + checkStock(); + stateToZero(); + repaint(); + + cl.show(this, "null"); + + if ((m_oTicket != null) && (m_oTicket.getLinesCount() == 0)) { + resetSouthComponent(); + } + } else { + if (m_oTicket.getTicketType() == TicketInfo.RECEIPT_REFUND) { + m_jEditLine.setVisible(false); + m_jList.setVisible(false); + } + + m_oTicket.getLines().forEach((line) -> { + line.setTaxInfo(taxeslogic.getTaxInfo(line + .getProductTaxCategoryID(), m_oTicket.getCustomer())); + }); + + m_jTicketId.setText(m_oTicket.getName(m_oTicketExt)); + m_ticketlines.clearTicketLines(); + + for (int i = 0; i < m_oTicket.getLinesCount(); i++) { + m_ticketlines.addTicketLine(m_oTicket.getLine(i)); + } +// set line here? + + countArticles(); + printPartialTotals(); + stateToZero(); + + cl.show(this, "ticket"); + + if (m_oTicket.getLinesCount() == 0) { + resetSouthComponent(); + } + + m_jKeyFactory.setText(null); + java.awt.EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + m_jKeyFactory.requestFocus(); + } + }); + } + } + + private void countArticles() { + oCount = count; // existing line before change + count = (int) m_oTicket.getArticlesCount(); //existing line after change + + if (m_oTicket != null) { + for (int i = 0; i < m_oTicket.getLinesCount(); i++) { + if (m_App.getAppUserView().getUser().hasPermission("sales.Total") + && m_oTicket.getArticlesCount() > 1) { + btnSplit.setEnabled(true); + } else { + btnSplit.setEnabled(false); + } + } + } + } + + private boolean changeCount(boolean pinOK) { + + pinOK = false; + + if (m_oTicket != null) { + + if (m_App.getProperties().getProperty("override.check").equals("true")) { + Integer secret = Integer.parseInt(m_App.getProperties().getProperty("override.pin")); + Integer iValue = JNumberPop.showEditNumber(this, AppLocal.getIntString("title.override.enterpin")); + + if (iValue == null ? secret == null : iValue.equals(secret)) { + pinOK = true; + JOptionPane.showMessageDialog(this, "Units changed from " + + count + " to " + oCount); + return pinOK; + + } else { + pinOK = false; + JOptionPane.showMessageDialog(this, AppLocal.getIntString("message.override.badpin")); + return pinOK; + } + } + } + return pinOK; + } + + private void printPartialTotals() { + + if (m_oTicket.getLinesCount() == 0) { + m_jSubtotalEuros.setText(null); + m_jTaxesEuros.setText(null); + m_jTotalEuros.setText(null); + } else { + m_jSubtotalEuros.setText(m_oTicket.printSubTotal()); + m_jTaxesEuros.setText(m_oTicket.printTax()); + m_jTotalEuros.setText(m_oTicket.printTotal()); + } + repaint(); + } + + private void paintTicketLine(int index, TicketLineInfo oLine) { + if (executeEventAndRefresh("ticket.setline", + new ScriptArg("index", index), new ScriptArg("line", oLine)) == null) { + + m_oTicket.setLine(index, oLine); + m_ticketlines.setTicketLine(index, oLine); + m_ticketlines.setSelectedIndex(index); + + oCount = count; // pass line old multiplier value + + countArticles(); + visorTicketLine(oLine); + printPartialTotals(); + stateToZero(); + + executeEventAndRefresh("ticket.change"); + } + } + + private void addTicketLine(ProductInfoExt oProduct, double dMul, double dPrice) { + +// if (oProduct.isVprice() || oProduct.getID().equals("xxx999_999xxx_x9x9x9")){ + if (oProduct.isVprice()) { + TaxInfo tax = taxeslogic.getTaxInfo(oProduct.getTaxCategoryID(), m_oTicket.getCustomer()); + + if (m_jaddtax.isSelected()) { + dPrice /= (1 + tax.getRate()); + } + + addTicketLine(new TicketLineInfo(oProduct, dMul, dPrice, tax, + (java.util.Properties) (oProduct.getProperties().clone()))); + + } else if (oProduct.getID().equals("xxx998_998xxx_x8x8x8")) { + + if (m_App.getProperties().getProperty("till.SCOnOff").equals("true")) { + TaxInfo tax = taxeslogic.getTaxInfo(oProduct.getTaxCategoryID(), + m_oTicket.getCustomer()); + String SCRate = (m_App.getProperties().getProperty("till.SCRate")); + + double scharge; + scharge = Double.parseDouble(SCRate); + scharge = m_oTicket.getTotal() * (scharge / 100); + + addTicketLine(new TicketLineInfo(oProduct, 1, scharge, tax, + (java.util.Properties) (oProduct.getProperties().clone()))); + + } else { + JOptionPane.showMessageDialog(this, "Service Charge Not Enabled"); + } + + } else { +// get the line product tax + TaxInfo tax = taxeslogic.getTaxInfo(oProduct.getTaxCategoryID(), m_oTicket.getCustomer()); + + addTicketLine(new TicketLineInfo(oProduct, dMul, dPrice, tax, + (java.util.Properties) (oProduct.getProperties().clone()))); + +// if (oProduct.getID().equals("xxx999_999xxx_x9x9x9")){ +// m_jEditLine.doClick(); +// } + refreshTicket(); + + } + + j_btnRemotePrt.setEnabled(true); + + } + + /** + * @param oLine + */ + protected void addTicketLine(TicketLineInfo oLine) { + if (executeEventAndRefresh("ticket.addline", new ScriptArg("line", oLine)) == null) { + if (oLine.isProductCom()) { + int i = m_ticketlines.getSelectedIndex(); + + if (i >= 0 && !m_oTicket.getLine(i).isProductCom()) { + i++; + } + + while (i >= 0 && i < m_oTicket.getLinesCount() && m_oTicket.getLine(i).isProductCom()) { + i++; + } + + if (i >= 0) { + m_oTicket.insertLine(i, oLine); + m_ticketlines.insertTicketLine(i, oLine); + } else { + Toolkit.getDefaultToolkit().beep(); + } + } else { + m_oTicket.addLine(oLine); + m_ticketlines.addTicketLine(oLine); + + try { + int i = m_ticketlines.getSelectedIndex(); + TicketLineInfo line = m_oTicket.getLine(i); + + if (line.isProductVerpatrib()) { + JProductAttEdit2 attedit = JProductAttEdit2.getAttributesEditor(this, m_App.getSession()); + attedit.editAttributes(line.getProductAttSetId(), line.getProductAttSetInstId()); + attedit.setVisible(true); + + if (attedit.isOK()) { + line.setProductAttSetInstId(attedit.getAttributeSetInst()); + line.setProductAttSetInstDesc(attedit.getAttributeSetInstDescription()); + paintTicketLine(i, line); + } + } + + } catch (BasicException ex) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.cannotfindattributes"), ex); + msg.show(this); + } + } + + visorTicketLine(oLine); + printPartialTotals(); + stateToZero(); + checkStock(); + countArticles(); + + executeEvent(m_oTicket, m_oTicketExt, "ticket.change"); + } + } + + private void removeTicketLine(int i) { + +// if (m_App.getProperties().getProperty("override.check").equals("true")) { + if (!m_oTicket.getLine(i).getUpdated()) { + JOptionPane.showMessageDialog(this + , AppLocal.getIntString("message.deletelinesent") + , AppLocal.getIntString("label.deleteline") + , JOptionPane.WARNING_MESSAGE); + } else { + if (executeEventAndRefresh("ticket.removeline", new ScriptArg("index", i)) == null) { + String ticketID = Integer.toString(m_oTicket.getTicketId()); + if (m_oTicket.getTicketId() == 0) { + ticketID = "Void"; + } + dlSystem.execLineRemoved( + new Object[]{ + m_App.getAppUserView().getUser().getName(), + ticketID, + m_oTicket.getLine(i).getProductID(), + m_oTicket.getLine(i).getProductName(), + m_oTicket.getLine(i).getMultiply() + } + ); + + if (m_oTicket.getLine(i).isProductCom()) { + m_oTicket.removeLine(i); + m_ticketlines.removeTicketLine(i); + } else { + if (i < 1) { + + if (m_App.getAppUserView().getUser().hasPermission("sales.DeleteLines")) { + int input = JOptionPane.showConfirmDialog(this, + AppLocal.getIntString("message.deletelineyes") + , AppLocal.getIntString("label.deleteline"), JOptionPane.YES_NO_OPTION); + + if (input == 0) { + m_oTicket.removeLine(i); + m_ticketlines.removeTicketLine(i); + } + } else { + JOptionPane.showMessageDialog(this, + AppLocal.getIntString("message.deletelineno") + , AppLocal.getIntString("label.deleteline"), JOptionPane.WARNING_MESSAGE); + } + } else { + m_oTicket.removeLine(i); + m_ticketlines.removeTicketLine(i); + + while (i < m_oTicket.getLinesCount() && m_oTicket.getLine(i).isProductCom()) { + m_oTicket.removeLine(i); + m_ticketlines.removeTicketLine(i); + } + } + } + + visorTicketLine(null); + printPartialTotals(); + stateToZero(); + checkStock(); + countArticles(); + + executeEventAndRefresh("ticket.change"); + } + } +// } + } + + private ProductInfoExt getInputProduct() { + ProductInfoExt oProduct = new ProductInfoExt(); +// Always add Default Prod ID + Add Name to Misc. if empty + oProduct.setID("xxx999_999xxx_x9x9x9"); + oProduct.setReference("xxx999"); + oProduct.setCode("xxx999"); + oProduct.setName("***"); + oProduct.setTaxCategoryID(((TaxCategoryInfo) taxcategoriesmodel + .getSelectedItem()).getID()); + oProduct.setPriceSell(includeTaxes(oProduct.getTaxCategoryID(), getInputValue())); + + return oProduct; + } + + private double includeTaxes(String tcid, double dValue) { + if (m_jaddtax.isSelected()) { + TaxInfo tax = taxeslogic.getTaxInfo(tcid, m_oTicket.getCustomer()); + double dTaxRate = tax == null ? 0.0 : tax.getRate(); + return dValue / (1.0 + dTaxRate); + } else { + return dValue; + } + } + + private double excludeTaxes(String tcid, double dValue) { + TaxInfo tax = taxeslogic.getTaxInfo(tcid, m_oTicket.getCustomer()); + double dTaxRate = tax == null ? 0.0 : tax.getRate(); + return dValue / (1.0 + dTaxRate); + } + + + private double getInputValue() { + try { + return Double.parseDouble(m_jPrice.getText()); + } catch (NumberFormatException e) { + return 0.0; + } + } + + private double getPorValue() { + try { + return Double.parseDouble(m_jPor.getText().substring(1)); + } catch (NumberFormatException | StringIndexOutOfBoundsException e) { + return 1.0; + } + } + + private void stateToZero() { + m_jPor.setText(""); + m_jPrice.setText(""); + m_sBarcode = new StringBuffer(); + + m_iNumberStatus = NUMBER_INPUTZERO; + m_iNumberStatusInput = NUMBERZERO; + m_iNumberStatusPor = NUMBERZERO; + repaint(); + } + + private void incProductByCode(String sCode) { + + try { + ProductInfoExt oProduct = dlSales.getProductInfoByCode(sCode); + + if (oProduct == null) { + Toolkit.getDefaultToolkit().beep(); + JOptionPane.showMessageDialog(null, + sCode + " - " + AppLocal.getIntString("message.noproduct"), + "Check", JOptionPane.WARNING_MESSAGE); + stateToZero(); + } else { + incProduct(oProduct); + } + } catch (BasicException eData) { + stateToZero(); + new MessageInf(eData).show(this); + } + } + + private void incProductByCodePrice(String sCode, double dPriceSell) { + + try { + ProductInfoExt oProduct = dlSales.getProductInfoByCode(sCode); + if (oProduct == null) { + Toolkit.getDefaultToolkit().beep(); + new MessageInf(MessageInf.SGN_WARNING, AppLocal + .getIntString("message.noproduct")).show(this); + stateToZero(); + } else { + if (m_jaddtax.isSelected()) { + TaxInfo tax = taxeslogic.getTaxInfo(oProduct.getTaxCategoryID(), m_oTicket.getCustomer()); + addTicketLine(oProduct, 1.0, dPriceSell / (1.0 + tax.getRate())); + } else { + addTicketLine(oProduct, 1.0, dPriceSell); + } + } + } catch (BasicException eData) { + stateToZero(); + new MessageInf(eData).show(this); + } + } + + private void incProduct(ProductInfoExt prod) { + + if (prod.isScale() && m_App.getDeviceScale().existsScale()) { + try { + Double value = m_App.getDeviceScale().readWeight(); + if (value != null) { + incProduct(value, prod); + } + } catch (ScaleException e) { + Toolkit.getDefaultToolkit().beep(); + new MessageInf(MessageInf.SGN_WARNING, AppLocal + .getIntString("message.noweight"), e).show(this); + stateToZero(); + } + } else { + if (!prod.isVprice()) { + incProduct(1.0, prod); + } else { + Toolkit.getDefaultToolkit().beep(); + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.novprice")); + } + } + } + + private void incProduct(double dPor, ProductInfoExt prod) { + + if (prod.isVprice()) { + addTicketLine(prod, getPorValue(), getInputValue()); + } else { + addTicketLine(prod, dPor, prod.getPriceSell()); + } + } + + /** + * @param prod + */ + protected void buttonTransition(ProductInfoExt prod) { + + if (m_iNumberStatusInput == NUMBERZERO && m_iNumberStatusPor == NUMBERZERO) { + incProduct(prod); + } else if (m_iNumberStatusInput == NUMBERVALID && m_iNumberStatusPor == NUMBERZERO) { + incProduct(getInputValue(), prod); + } else if (prod.isVprice()) { + addTicketLine(prod, getPorValue(), getInputValue()); + } else { + Toolkit.getDefaultToolkit().beep(); + } + } + + @SuppressWarnings("empty-statement") + private void stateTransition(char cTrans) { + + if ((cTrans == '\n') || (cTrans == '?')) { + + if (m_sBarcode.length() > 0) { + + String sCode = m_sBarcode.toString(); + String sCodetype = "EAN"; // Declare EAN. It's default + + if ("true".equals(m_App.getProperties() + .getProperty("machine.barcodetype"))) { + sCodetype = "UPC"; + } else { + sCodetype = "EAN"; // Ensure not null + } + + if (sCode.startsWith("C") + || sCode.startsWith("c")) { + try { + String card = sCode; + CustomerInfoExt newcustomer = dlSales.findCustomerExt(card); + + if (newcustomer == null) { + Toolkit.getDefaultToolkit().beep(); + new MessageInf(MessageInf.SGN_WARNING, AppLocal + .getIntString("message.nocustomer")).show(this); + } else { + m_oTicket.setCustomer(newcustomer); + m_jTicketId.setText(m_oTicket.getName(m_oTicketExt)); + } + } catch (BasicException e) { + Toolkit.getDefaultToolkit().beep(); + new MessageInf(MessageInf.SGN_WARNING, AppLocal + .getIntString("message.nocustomer"), e).show(this); + } + stateToZero(); + + } else if (sCode.startsWith(";")) { + stateToZero(); + + + // START OF BARCODE PARSING + /* This block is deliberately verbose and is base for future scanner handling + * Some scanners inject a CR+LF... some don't... + * stateTransition() must allow for this as these add characters to .length() + * First 3 digits are GS1 CountryCode OR Retailer internal use + * + * Prefix ManCodeProdCode CheckCode + * PPP MMMMMCCCCC K + * 012 3456789012 K + * Barcode CCCCC must be unique + * Notes: + * ManufacturerCode and ProductCode must be exactly 10 digits + * If code begins with 0 then is actually a UPC-A with prepended 0 + * + * uniCenta oPOS Retailer instore uses these RULES + * Prefixes 020 to 029 are set aside for Retailer internal use + * This means that CCCC becomes price/weight values + * Prefixes 978 and 979 are set aside for ISBN - Future use + * + * Prefix ManCode ProdCode CheckCode + * PPP MMMMM CCCCC K Format + * 012 34567 89012 K Human + * + */ + + } else if ("EAN".equals(sCodetype) + && ((sCode.startsWith("2")) || (sCode.startsWith("02"))) // check code prefix + && ((sCode.length() == 13) || (sCode.length() == 12))) { // check code length variances + + try { + ProductInfoExt oProduct // get product(s) with PMMMMM + = dlSales.getProductInfoByShortCode(sCode); + + if (oProduct == null) { // nothing returned so display message to user + Toolkit.getDefaultToolkit().beep(); + JOptionPane.showMessageDialog(null, + sCode + " - " + + AppLocal.getIntString("message.noproduct"), + "Check", JOptionPane.WARNING_MESSAGE); + stateToZero(); // clear the user input + + } else if ("EAN-13".equals(oProduct.getCodetype())) { // have a valid barcode + oProduct.setProperty("product.barcode", sCode); // set the screen's barcode from input + double dPriceSell = oProduct.getPriceSell(); // default price for product + double weight = 0; // used if barcode includes weight of product + double dUnits = 0; // used for pro-rata unit + String sVariableTypePrefix = sCode.substring(0, 2); // get first two PPP digits + String sVariableNum; // CCCCC variable value of barcode + + if (sCode.length() == 13) { // full barcode from scanner + sVariableNum = sCode.substring(8, 12); // get the 5 CCCCC digits + } else { // barcode can be any length + sVariableNum = sCode.substring(7, 11); // get the 5 CCCCC digits + } // scanner has dropped 1st digit so shift get to left + +// PRICE - SET value decimals + switch (sVariableTypePrefix) { // Use CCCCC value of 01049 as example + case "02": // first 2 PPP digits determine decimal position + dUnits = (Double.parseDouble(sVariableNum) // position decimal in CCC.CC + / 100) / oProduct.getPriceSell(); // 2 decimal = 010.49 + break; + case "20": + dUnits = (Double.parseDouble(sVariableNum) // position decimal in CCC.CC + / 100) / oProduct.getPriceSell(); // 2 decimal = 010.49 + break; + case "21": + dUnits = (Double.parseDouble(sVariableNum) // position decimal in CC.CCC + / 10) / oProduct.getPriceSell(); // 2 decimal = 0104.9 + break; + case "22": + dUnits = Double.parseDouble(sVariableNum) // position decimal in CCCC.C + / oProduct.getPriceSell(); // Price = 01049. + break; + +// WEIGHT - SET value decimals + case "23": // Use CCCCC 01049kg as example + weight = Double.parseDouble(sVariableNum) + / 1000; // Weight = 01.049 + dUnits = weight; // set Units for price calculation + break; + case "24": + weight = Double.parseDouble(sVariableNum) + / 100; // Weight = 010.49 + dUnits = weight; // set Units for price calculation + break; + case "25": + weight = Double.parseDouble(sVariableNum) + / 10; // Weight = 0104.9 + dUnits = weight; // set Units for price calculation + break; + default: + break; + } + + TaxInfo tax = taxeslogic // get the TaxRate for the product + .getTaxInfo(oProduct.getTaxCategoryID() + , m_oTicket.getCustomer()); // calculate if ticket has a Customer + + switch (sVariableTypePrefix) { +// PRICE - Assign var's + case "02": // now we need to calculate some values + dPriceSell = oProduct.getPriceSellTax(tax) + / (1.0 + tax.getRate()); // selling price with tax + dUnits = (Double.parseDouble(sVariableNum) + / 100) / oProduct.getPriceSellTax(tax); // Units as proportion of selling price + oProduct.setProperty("product.price" + , Double.toString(oProduct.getPriceSell())); // push to screen + break; + case "20": // as above + dPriceSell = oProduct.getPriceSellTax(tax) + / (1.0 + tax.getRate()); + dUnits = (Double.parseDouble(sVariableNum) + / 100) / oProduct.getPriceSellTax(tax); + oProduct.setProperty("product.price" + , Double.toString(oProduct.getPriceSellTax(tax))); + break; + case "21": + dPriceSell = oProduct.getPriceSellTax(tax) + / (1.0 + tax.getRate()); + dUnits = (Double.parseDouble(sVariableNum) + / 10) / oProduct.getPriceSellTax(tax); + oProduct.setProperty("product.price" + , Double.toString(oProduct.getPriceSell())); + break; + case "22": + dPriceSell = oProduct.getPriceSellTax(tax) + / (1.0 + tax.getRate()); + dUnits = (Double.parseDouble(sVariableNum) + / 1) / oProduct.getPriceSellTax(tax); + oProduct.setProperty("product.price" + , Double.toString(oProduct.getPriceSell())); + break; + +// WEIGHT - Assign variable to Unit + case "23": + weight = Double.parseDouble(sVariableNum) + / 1000; // 3 decimals = 01.049 kg + dUnits = weight; // which represents 1gramme Units + oProduct.setProperty("product.weight" + , Double.toString(weight)); + oProduct.setProperty("product.price" + , Double.toString(dPriceSell)); + break; + case "24": + weight = Double.parseDouble(sVariableNum) + / 100; // 2 decimals = 010.49 kg + dUnits = weight; // which represents 10gramme Units + oProduct.setProperty("product.weight" + , Double.toString(weight)); + oProduct.setProperty("product.price" + , Double.toString(dPriceSell)); + break; + case "25": + weight = Double.parseDouble(sVariableNum) + / 10; // 1 decimal = 0104.9 kg + dUnits = weight; // which represents 100gramme Units + oProduct.setProperty("product.weight" + , Double.toString(weight)); + oProduct.setProperty("product.price" + , Double.toString(dPriceSell)); + break; + +/* + * Some countries use different barcode prefix 26-29 or 250 etc. + * Use this section to add more case statements but these are not mandatory + * If you have your own internal or other barcode schema then... + * Example: + case "28": + { + // price has tax. Remove it from sPriceSell + TaxInfo tax = taxeslogic.getTaxInfo(oProduct.getTaxCategoryID(), m_oTicket.getCustomer()); + dPriceSell /= (1.0 + tax.getRate()); + oProduct.setProperty("product.price", Double.toString(dPriceSell)); + weight = -1.0; + break; +*/ + default: + break; + } + + if (m_jaddtax.isSelected()) { + addTicketLine(oProduct + , dUnits //weight + , dPriceSell = oProduct.getPriceSellTax(tax)); + } else { + addTicketLine(oProduct + , dUnits + , dPriceSell); + } + } + } catch (BasicException eData) { + stateToZero(); + new MessageInf(eData).show(this); + } + +// UPC-A +/* Note: if begins 02 then its a standard +// UPC-A max value limitation is 4 digit price +// UPC-A Extended uses State digit to give 5 digit price +// uniCenta oPOS does not support UPC-A Extended at this time +// Identifier Prod State Cost CheckCode +// I PPPPP S CCCC K +// 1 23456 7 8901 2 + + * 0 = Standard UPC number (must have a zero to do zero-suppressed numbers) + * 1 = Reserved + * 2 = Random-weight items (fruits, vegetables, meats, etc.) + * 3 = Pharmaceuticals + * 4 = In-store marketing for retailers (Other stores will not understand) + * 5 = Coupons + * 6 = Standard UPC number + * 7 = Standard UPC number + * 8 = Reserved + * 9 = Reserved +*/ + + } else if ("UPC".equals(sCodetype) + && (sCode.startsWith("2")) + && (sCode.length() == 12)) { + + try { + ProductInfoExt oProduct + = dlSales.getProductInfoByUShortCode(sCode); // Return only UPC product + + if (oProduct == null) { + Toolkit.getDefaultToolkit().beep(); + JOptionPane.showMessageDialog(null, + sCode + " - " + + AppLocal.getIntString("message.noproduct"), + "Check", JOptionPane.WARNING_MESSAGE); + stateToZero(); + } else if ("Upc-A".equals(oProduct.getCodetype())) { + oProduct.setProperty("product.barcode", sCode); + double dPriceSell = oProduct.getPriceSell(); // default price for product + double weight = 0; // used if barcode includes weight of product + double dUnits = 0; // used for pro-rata unit + String sVariableNum = sCode.substring(7, 11); // grab the value from the code only using 4 digit price + + TaxInfo tax = taxeslogic // get the TaxRate for the product + .getTaxInfo(oProduct.getTaxCategoryID() + , m_oTicket.getCustomer()); + + if (oProduct.getPriceSell() != 0.0) { // we have a weight barcode + weight = Double.parseDouble(sVariableNum) / 100; // 2 decimals (e.g. 10.49 kg) + dUnits = weight; // Units is now transformed to weight + + oProduct.setProperty("product.weight" // catch-all for weight + , Double.toString(weight)); + oProduct.setProperty("product.price" // get the prod sellprice + , Double.toString(oProduct.getPriceSell())); + dPriceSell = oProduct.getPriceSellTax(tax); // calculate the tax on sellprice + dUnits = (Double.parseDouble(sVariableNum) // calculate Units in sellprice with Tax + / 100) + / oProduct.getPriceSellTax(tax); + + } else { // no sellprice so we have a price barcode + dPriceSell = (Double.parseDouble(sVariableNum) // calculate Units in sellprice with Tax + / 100); + dUnits = 1; // no sellprice to calculate so must be 1 Unit + } + + if (m_jaddtax.isSelected()) { + addTicketLine(oProduct + , dUnits + , dPriceSell); + } else { + addTicketLine(oProduct + , dUnits + , dPriceSell / (1.0 + tax.getRate())); + } + } + } catch (BasicException eData) { + stateToZero(); + new MessageInf(eData).show(this); + } + + } else { + incProductByCode(sCode); // returned is standard so go get it + } +// END OF BARCODE + + } else { + Toolkit.getDefaultToolkit().beep(); + } + + } else { + + m_sBarcode.append(cTrans); + + if (cTrans == '\u007f') { + stateToZero(); + + } else if ((cTrans == '0') && (m_iNumberStatus == NUMBER_INPUTZERO)) { + m_jPrice.setText(Character.toString('0')); + + } else if ((cTrans == '1' || cTrans == '2' || cTrans == '3' + || cTrans == '4' || cTrans == '5' || cTrans == '6' + || cTrans == '7' || cTrans == '8' || cTrans == '9') + && (m_iNumberStatus == NUMBER_INPUTZERO)) { + + if (!priceWith00) { + m_jPrice.setText(m_jPrice.getText() + cTrans); + } else { + m_jPrice.setText(setTempjPrice(m_jPrice.getText() + cTrans)); + } + + m_iNumberStatus = NUMBER_INPUTINT; + m_iNumberStatusInput = NUMBERVALID; + + } else if ((cTrans == '0' || cTrans == '1' || cTrans == '2' + || cTrans == '3' || cTrans == '4' || cTrans == '5' + || cTrans == '6' || cTrans == '7' || cTrans == '8' + || cTrans == '9') + && (m_iNumberStatus == NUMBER_INPUTINT)) { + + if (!priceWith00) { + m_jPrice.setText(m_jPrice.getText() + cTrans); + } else { + m_jPrice.setText(setTempjPrice(m_jPrice.getText() + cTrans)); + } + + + } else if (cTrans == '.' + && m_iNumberStatus == NUMBER_INPUTZERO && !priceWith00) { + m_jPrice.setText("0."); + m_iNumberStatus = NUMBER_INPUTZERODEC; + } else if (cTrans == '.' + && m_iNumberStatus == NUMBER_INPUTZERO) { + m_jPrice.setText(""); + m_iNumberStatus = NUMBER_INPUTZERO; + } else if (cTrans == '.' + && m_iNumberStatus == NUMBER_INPUTINT && !priceWith00) { + m_jPrice.setText(m_jPrice.getText() + "."); + m_iNumberStatus = NUMBER_INPUTDEC; + } else if (cTrans == '.' + && m_iNumberStatus == NUMBER_INPUTINT) { + + if (!priceWith00) { + m_jPrice.setText(m_jPrice.getText() + "00"); + } else { + m_jPrice.setText(setTempjPrice(m_jPrice.getText() + "00")); + } + + m_iNumberStatus = NUMBER_INPUTINT; + + } else if ((cTrans == '0') + && (m_iNumberStatus == NUMBER_INPUTZERODEC + || m_iNumberStatus == NUMBER_INPUTDEC)) { + + if (!priceWith00) { + m_jPrice.setText(m_jPrice.getText() + cTrans); + } else { + m_jPrice.setText(setTempjPrice(m_jPrice.getText() + cTrans)); + } + + } else if ((cTrans == '1' || cTrans == '2' || cTrans == '3' + || cTrans == '4' || cTrans == '5' || cTrans == '6' + || cTrans == '7' || cTrans == '8' || cTrans == '9') + && (m_iNumberStatus == NUMBER_INPUTZERODEC + || m_iNumberStatus == NUMBER_INPUTDEC)) { + + m_jPrice.setText(m_jPrice.getText() + cTrans); + m_iNumberStatus = NUMBER_INPUTDEC; + m_iNumberStatusInput = NUMBERVALID; + + } else if (cTrans == '*' + && (m_iNumberStatus == NUMBER_INPUTINT + || m_iNumberStatus == NUMBER_INPUTDEC)) { + m_jPor.setText("x"); + m_iNumberStatus = NUMBER_PORZERO; + } else if (cTrans == '*' + && (m_iNumberStatus == NUMBER_INPUTZERO + || m_iNumberStatus == NUMBER_INPUTZERODEC)) { + m_jPrice.setText("0"); + m_jPor.setText("x"); + m_iNumberStatus = NUMBER_PORZERO; + + } else if ((cTrans == '0') + && (m_iNumberStatus == NUMBER_PORZERO)) { + m_jPor.setText("x0"); + } else if ((cTrans == '1' || cTrans == '2' || cTrans == '3' + || cTrans == '4' || cTrans == '5' || cTrans == '6' + || cTrans == '7' || cTrans == '8' || cTrans == '9') + && (m_iNumberStatus == NUMBER_PORZERO)) { + + m_jPor.setText("x" + Character.toString(cTrans)); + m_iNumberStatus = NUMBER_PORINT; + m_iNumberStatusPor = NUMBERVALID; + } else if ((cTrans == '0' || cTrans == '1' || cTrans == '2' + || cTrans == '3' || cTrans == '4' || cTrans == '5' + || cTrans == '6' || cTrans == '7' || cTrans == '8' + || cTrans == '9') && (m_iNumberStatus == NUMBER_PORINT)) { + + m_jPor.setText(m_jPor.getText() + cTrans); + + } else if (cTrans == '.' + && m_iNumberStatus == NUMBER_PORZERO && !priceWith00) { + m_jPor.setText("x0."); + m_iNumberStatus = NUMBER_PORZERODEC; + } else if (cTrans == '.' + && m_iNumberStatus == NUMBER_PORZERO) { + m_jPor.setText("x"); + m_iNumberStatus = NUMBERVALID; + } else if (cTrans == '.' + && m_iNumberStatus == NUMBER_PORINT && !priceWith00) { + m_jPor.setText(m_jPor.getText() + "."); + m_iNumberStatus = NUMBER_PORDEC; + } else if (cTrans == '.' + && m_iNumberStatus == NUMBER_PORINT) { + m_jPor.setText(m_jPor.getText() + "00"); + m_iNumberStatus = NUMBERVALID; + + } else if ((cTrans == '0') + && (m_iNumberStatus == NUMBER_PORZERODEC + || m_iNumberStatus == NUMBER_PORDEC)) { + m_jPor.setText(m_jPor.getText() + cTrans); + } else if ((cTrans == '1' || cTrans == '2' || cTrans == '3' + || cTrans == '4' || cTrans == '5' || cTrans == '6' + || cTrans == '7' || cTrans == '8' || cTrans == '9') + && (m_iNumberStatus == NUMBER_PORZERODEC || m_iNumberStatus == NUMBER_PORDEC)) { + + m_jPor.setText(m_jPor.getText() + cTrans); + m_iNumberStatus = NUMBER_PORDEC; + m_iNumberStatusPor = NUMBERVALID; + + } else if (cTrans == '\u00a7' + && m_iNumberStatusInput == NUMBERVALID + && m_iNumberStatusPor == NUMBERZERO) { + + if (m_App.getDeviceScale().existsScale() + && m_App.getAppUserView().getUser().hasPermission("sales.EditLines")) { + try { + Double value = m_App.getDeviceScale().readWeight(); + if (value != null) { + ProductInfoExt product = getInputProduct(); + addTicketLine(product, value, product.getPriceSell()); + } + } catch (ScaleException e) { + Toolkit.getDefaultToolkit().beep(); + new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.noweight"), e).show(this); + stateToZero(); + } + } else { + + Toolkit.getDefaultToolkit().beep(); + } + } else if (cTrans == '\u00a7' + && m_iNumberStatusInput == NUMBERZERO + && m_iNumberStatusPor == NUMBERZERO) { + + int i = m_ticketlines.getSelectedIndex(); + if (i < 0) { + Toolkit.getDefaultToolkit().beep(); + } else if (m_App.getDeviceScale().existsScale()) { + try { + Double value = m_App.getDeviceScale().readWeight(); + if (value != null) { + TicketLineInfo newline = new TicketLineInfo(m_oTicket.getLine(i)); + newline.setMultiply(value); + newline.setPrice(Math.abs(newline.getPrice())); + paintTicketLine(i, newline); + } + } catch (ScaleException e) { + Toolkit.getDefaultToolkit().beep(); + new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.noweight"), e).show(this); + stateToZero(); + } + } else { + + Toolkit.getDefaultToolkit().beep(); + } + + } else if (cTrans == '+' + && m_iNumberStatusInput == NUMBERZERO + && m_iNumberStatusPor == NUMBERZERO) { + int i = m_ticketlines.getSelectedIndex(); + + if (i < 0) { + Toolkit.getDefaultToolkit().beep(); + } else { + TicketLineInfo newline = new TicketLineInfo(m_oTicket.getLine(i)); + //If it's a refund + button means one unit less + if (m_oTicket.getTicketType() == TicketInfo.RECEIPT_REFUND) { + if (m_App.getProperties().getProperty("override.check").equals("true")) { + oCount = count - 1; //increment existing line + pinOK = false; + changeCount(pinOK); + newline.setMultiply(newline.getMultiply() - 1.0); + newline.setProperty("ticket.updated", "true"); + paintTicketLine(i, newline); + } else { + newline.setMultiply(newline.getMultiply() - 1.0); + newline.setProperty("ticket.updated", "true"); + paintTicketLine(i, newline); + } + } else { + if (m_App.getProperties().getProperty("override.check").equals("true")) { + oCount = count + 1; //increment existing line + pinOK = false; + if (changeCount(pinOK)) { + newline.setMultiply(newline.getMultiply() + 1.0); + newline.setProperty("ticket.updated", "true"); + paintTicketLine(i, newline); + } + } else { + newline.setMultiply(newline.getMultiply() + 1.0); + newline.setProperty("ticket.updated", "true"); + paintTicketLine(i, newline); + } + } + } + } else if (cTrans == '-' + && m_iNumberStatusInput == NUMBERZERO + && m_iNumberStatusPor == NUMBERZERO + && m_App.getAppUserView().getUser().hasPermission("sales.EditLines")) { + + int i = m_ticketlines.getSelectedIndex(); + if (i < 0) { + Toolkit.getDefaultToolkit().beep(); + } else { + TicketLineInfo newline = new TicketLineInfo(m_oTicket.getLine(i)); + + if (m_oTicket.getTicketType() == TicketInfo.RECEIPT_REFUND) { + if (m_App.getProperties().getProperty("override.check").equals("true")) { + oCount = count - 1; //increment existing line + pinOK = false; + changeCount(pinOK); + newline.setMultiply(newline.getMultiply() - 1.0); + newline.setProperty("ticket.updated", "true"); + paintTicketLine(i, newline); + } else { + newline.setMultiply(newline.getMultiply() - 1.0); + newline.setProperty("ticket.updated", "true"); + paintTicketLine(i, newline); + } + + if (newline.getMultiply() >= 0) { + removeTicketLine(i); + } else { + paintTicketLine(i, newline); + } + } else { + if (m_App.getProperties().getProperty("override.check").equals("true")) { + oCount = count - 1; //increment existing line + pinOK = false; + if (changeCount(pinOK)) { + newline.setMultiply(newline.getMultiply() - 1.0); + newline.setProperty("ticket.updated", "true"); + paintTicketLine(i, newline); + } + } else { + newline.setMultiply(newline.getMultiply() - 1.0); + newline.setProperty("ticket.updated", "true"); + paintTicketLine(i, newline); + } + + if (newline.getMultiply() <= 0.0) { + removeTicketLine(i); + } else { + paintTicketLine(i, newline); + } + } + } + + } else if (cTrans == '+' + && m_iNumberStatusInput == NUMBERZERO + && m_iNumberStatusPor == NUMBERVALID) { + int i = m_ticketlines.getSelectedIndex(); + + if (i < 0) { + Toolkit.getDefaultToolkit().beep(); + } else { + double dPor = getPorValue(); + TicketLineInfo newline = new TicketLineInfo(m_oTicket.getLine(i)); + + if (m_oTicket.getTicketType() == TicketInfo.RECEIPT_REFUND) { + if (m_App.getProperties().getProperty("override.check").equals("true")) { + oCount = count - 1; //increment existing line + pinOK = false; + changeCount(pinOK); + newline.setMultiply(-dPor); + newline.setProperty("ticket.updated", "true"); + newline.setPrice(Math.abs(newline.getPrice())); + paintTicketLine(i, newline); + } else { + newline.setMultiply(-dPor); + newline.setProperty("ticket.updated", "true"); + newline.setPrice(Math.abs(newline.getPrice())); + paintTicketLine(i, newline); + } + } else { + if (m_App.getProperties().getProperty("override.check").equals("true")) { + oCount = count + 1; //increment existing line + pinOK = false; + if (changeCount(pinOK)) { + newline.setMultiply(dPor); + newline.setProperty("ticket.updated", "true"); + newline.setPrice(Math.abs(newline.getPrice())); + paintTicketLine(i, newline); + } + } else { + newline.setMultiply(dPor); + newline.setProperty("ticket.updated", "true"); + newline.setPrice(Math.abs(newline.getPrice())); + paintTicketLine(i, newline); + } + } + } + } else if (cTrans == '-' + && m_iNumberStatusInput == NUMBERZERO + && m_iNumberStatusPor == NUMBERVALID + && m_App.getAppUserView().getUser().hasPermission("sales.EditLines")) { + int i = m_ticketlines.getSelectedIndex(); + + if (i < 0) { + Toolkit.getDefaultToolkit().beep(); + } else { + double dPor = getPorValue(); + TicketLineInfo newline = new TicketLineInfo(m_oTicket.getLine(i)); + + if (m_oTicket.getTicketType() == TicketInfo.RECEIPT_REFUND) { + if (m_App.getProperties().getProperty("override.check").equals("true")) { + oCount = count - 1; //increment existing line + pinOK = false; + changeCount(pinOK); + newline.setMultiply(-dPor); + newline.setProperty("ticket.updated", "true"); + newline.setPrice(Math.abs(newline.getPrice())); + paintTicketLine(i, newline); + } else { + newline.setMultiply(-dPor); + newline.setProperty("ticket.updated", "true"); + newline.setPrice(Math.abs(newline.getPrice())); + paintTicketLine(i, newline); + } + } else { + if (m_App.getProperties().getProperty("override.check").equals("true")) { + oCount = count - 1; //increment existing line + pinOK = false; + if (changeCount(pinOK)) { + newline.setMultiply(dPor); + newline.setProperty("ticket.updated", "true"); + newline.setPrice(Math.abs(newline.getPrice())); + paintTicketLine(i, newline); + } + } else { + newline.setMultiply(dPor); + newline.setProperty("ticket.updated", "true"); + newline.setPrice(Math.abs(newline.getPrice())); + paintTicketLine(i, newline); + } + } + } + } else if (cTrans == '+' + && m_iNumberStatusInput == NUMBERVALID + && m_iNumberStatusPor == NUMBERZERO + && m_App.getAppUserView().getUser().hasPermission("sales.EditLines")) { + ProductInfoExt product = getInputProduct(); + addTicketLine(product, 1.0, product.getPriceSell()); + m_jEditLine.doClick(); + + } else if (cTrans == '-' + && m_iNumberStatusInput == NUMBERVALID + && m_iNumberStatusPor == NUMBERZERO + && m_App.getAppUserView().getUser().hasPermission("sales.EditLines")) { + ProductInfoExt product = getInputProduct(); + addTicketLine(product, 1.0, -product.getPriceSell()); + m_jEditLine.doClick(); + + } else if (cTrans == '+' + && m_iNumberStatusInput == NUMBERVALID + && m_iNumberStatusPor == NUMBERVALID + && m_App.getAppUserView().getUser().hasPermission("sales.EditLines")) { + ProductInfoExt product = getInputProduct(); + addTicketLine(product, getPorValue(), product.getPriceSell()); + + } else if (cTrans == '-' + && m_iNumberStatusInput == NUMBERVALID + && m_iNumberStatusPor == NUMBERVALID + && m_App.getAppUserView().getUser().hasPermission("sales.EditLines")) { + ProductInfoExt product = getInputProduct(); + addTicketLine(product, getPorValue(), -product.getPriceSell()); + + } else if (cTrans == ' ' || cTrans == '=') { + if (m_oTicket.getLinesCount() > 0) { + if (closeTicket(m_oTicket, m_oTicketExt)) { + m_ticketsbag.deleteTicket(); + String autoLogoff = (m_App.getProperties().getProperty("till.autoLogoff")); + if (autoLogoff != null) { + if (autoLogoff.equals("true")) { + if ("restaurant".equals( + m_App.getProperties().getProperty("machine.ticketsbag")) + && ("true".equals(m_App.getProperties().getProperty("till.autoLogoffrestaurant")))) { + deactivate(); + setActiveTicket(null, null); + } else { + ((JRootApp) m_App).closeAppView(); + } + } + } + ; + } else { + refreshTicket(); + } + } else { + Toolkit.getDefaultToolkit().beep(); + } + } + } + } + + + private Window getActiveWindow() { + for (Window window: getWindows()) { + if (window instanceof JRootFrame) { + return window; + } + } + return null; + } + + private boolean closeTicket(TicketInfo ticket, Object ticketext) { + if (listener != null) { + listener.stop(); + } + boolean resultok = false; + + if (m_App.getAppUserView().getUser().hasPermission("sales.Total")) { + + warrantyCheck(ticket); + + try { + + taxeslogic.calculateTaxes(ticket); + if (ticket.getTotal() >= 0.0) { + ticket.resetPayments(); + } + + if (executeEvent(ticket, ticketext, "ticket.total") == null) { + if (listener != null) { + listener.stop(); + } + + printTicket("Printer.TicketTotal", ticket, ticketext); + + JPaymentSelect paymentdialog = ticket.getTicketType() == TicketInfo.RECEIPT_NORMAL + ? paymentdialogreceipt + : paymentdialogrefund; + paymentdialog.setPrintSelected("true".equals(m_jbtnconfig.getProperty("printselected", "true"))); + + paymentdialog.setTransactionID(ticket.getTransactionID()); + + if (paymentdialog.showDialog(ticket.getTotal(), ticket.getCustomer())) { + + ticket.setPayments(paymentdialog.getSelectedPayments()); + + ticket.setUser(m_App.getAppUserView().getUser().getUserInfo()); + ticket.setActiveCash(m_App.getActiveCashIndex()); + ticket.setDate(new Date()); + + if (executeEvent(ticket, ticketext, "ticket.save") == null) { + + try { + dlSales.saveTicket(ticket, m_App.getInventoryLocation()); + m_config.setProperty("lastticket.number", Integer.toString(ticket.getTicketId())); + m_config.setProperty("lastticket.type", Integer.toString(ticket.getTicketType())); + m_config.saveWithExistingProperties(); + + } catch (BasicException eData) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, AppLocal.getIntString("message.nosaveticket"), eData); + msg.show(this); + } catch (IOException ex) { + log.error(ex.getMessage()); + } + + if (m_config.getProperty("till.digital-receipt") != null && m_config.getProperty("till.digital-receipt").equals("true")){ + log.debug("Send digital receipt"); + String xml = dlSystem.getResourceAsXML("Printer.Ticket"); + new Application().sendReceipt(ticket, xml, getActiveWindow()); + } + + executeEvent(ticket, ticketext, "ticket.close", + new ScriptArg("print", paymentdialog.isPrintSelected())); + + printTicket(paymentdialog.isPrintSelected() || warrantyPrint + ? "Printer.Ticket" + : "Printer.Ticket2", ticket, ticketext); + Notify(AppLocal.getIntString("notify.printing")); + + resultok = true; + + if ("restaurant".equals(m_App.getProperties() + .getProperty("machine.ticketsbag")) && !ticket.getOldTicket()) { + /* Deliberately Explicit to allow for reassignments - future + * even though we could do a single SQL statment sweep for reset + */ + restDB.clearCustomerNameInTable(ticketext.toString()); + restDB.clearWaiterNameInTable(ticketext.toString()); + restDB.clearTicketIdInTable(ticketext.toString()); + } + } + } + } + } catch (TaxesException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.cannotcalculatetaxes")); + msg.show(this); + resultok = false; + } + + m_oTicket.resetTaxes(); + m_oTicket.resetPayments(); + + jCheckStock.setText(""); + + } + + return resultok; + } + + private boolean warrantyCheck(TicketInfo ticket) { + warrantyPrint = false; + int lines = 0; + while (lines < ticket.getLinesCount()) { + if (!warrantyPrint) { + warrantyPrint = ticket.getLine(lines).isProductWarranty(); + return (true); + } + lines++; + } + return false; + } + + /** + * @param pTicket + * @return + */ + public String getPickupString(TicketInfo pTicket) { + if (pTicket == null) { + return ("0"); + } + String tmpPickupId = Integer.toString(pTicket.getPickupId()); + String pickupSize = (m_App.getProperties().getProperty("till.pickupsize")); + if (pickupSize != null && (Integer.parseInt(pickupSize) >= tmpPickupId.length())) { + while (tmpPickupId.length() < (Integer.parseInt(pickupSize))) { + tmpPickupId = "0" + tmpPickupId; + } + } + return (tmpPickupId); + } + + + private void printTicket(String sresourcename, TicketInfo ticket, Object ticketext) { + + String sresource = dlSystem.getResourceAsXML(sresourcename); + if (sresource == null) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotprintticket")); + msg.show(JPanelTicket.this); + } else { + if (ticket.getPickupId() == 0) { + try { + ticket.setPickupId(dlSales.getNextPickupIndex()); + } catch (BasicException e) { + ticket.setPickupId(0); + } + } + try { + ScriptEngine script = ScriptFactory.getScriptEngine(ScriptFactory.VELOCITY); + + if (Boolean.parseBoolean(m_App.getProperties().getProperty("receipt.newlayout"))) { + script.put("taxes", ticket.getTaxLines()); + } else { + script.put("taxes", taxcollection); + } + + script.put("taxeslogic", taxeslogic); + script.put("ticket", ticket); + script.put("place", ticketext); + script.put("warranty", warrantyPrint); + script.put("pickupid", getPickupString(ticket)); + + refreshTicket(); + + m_TTP.printTicket(script.eval(sresource).toString(), ticket); + + } catch (ScriptException | TicketPrinterException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotprintticket"), e); + msg.show(JPanelTicket.this); + } + } + } + + public void printTicket(String resource) { +// this method is intended to be called only from JPanelButtons. + + if (resource == null) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotexecute")); + msg.show(this); + } else { +// JG 5 Jul 17 calculate taxes disabled as causing incorrect tax recalc +// taxeslogic.calculateTaxes(m_oTicket); + printTicket(resource, m_oTicket, m_oTicketExt); + } + + Notify(AppLocal.getIntString("notify.printed")); + j_btnRemotePrt.setEnabled(false); + } + + public void customerAdd(String resource) { + Notify(AppLocal.getIntString("notify.customeradd")); + } + + public void customerRemove(String resource) { + Notify(AppLocal.getIntString("notify.customerremove")); + } + + public void customerChange(String resource) { + Notify(AppLocal.getIntString("notify.customerchange")); + } + + public void Notify(String msg) { + final WebNotification notification = new WebNotification(); + notification.setIcon(NotificationIcon.information); + notification.setDisplayTime(4000); + + final WebClock clock = new WebClock(); + clock.setClockType(ClockType.timer); + clock.setTimeLeft(5000); + notification.setContent(msg); + + NotificationManager.showNotification(notification); + clock.start(); + } + + private void printReport(String resourcefile, TicketInfo ticket, Object ticketext) { + + try { + + JasperReport jr; + + InputStream in = getClass().getResourceAsStream(resourcefile + ".ser"); + if (in == null) { + // read and compile the report + JasperDesign jd = JRXmlLoader.load(getClass().getResourceAsStream(resourcefile + ".jrxml")); + jr = JasperCompileManager.compileReport(jd); + } else { + try (ObjectInputStream oin = new ObjectInputStream(in)) { + jr = (JasperReport) oin.readObject(); + } + } + + + Map reportparams = new HashMap(); + + try { + reportparams.put("REPORT_RESOURCE_BUNDLE", ResourceBundle.getBundle(resourcefile + ".properties")); + } catch (MissingResourceException e) { + } + reportparams.put("TAXESLOGIC", taxeslogic); + + Map reportfields = new HashMap(); + reportfields.put("TICKET", ticket); + reportfields.put("PLACE", ticketext); + + JasperPrint jp = JasperFillManager.fillReport(jr, reportparams, new JRMapArrayDataSource(new Object[]{reportfields})); + + PrintService service = ReportUtils.getPrintService(m_App.getProperties().getProperty("machine.printername")); + + JRPrinterAWT300.printPages(jp, 0, jp.getPages().size() - 1, service); + + } catch (JRException | IOException | ClassNotFoundException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotloadreport"), e); + msg.show(this); + } + } + + private void visorTicketLine(TicketLineInfo oLine) { + if (oLine == null) { + m_App.getDeviceTicket().getDeviceDisplay().clearVisor(); + } else { + try { + ScriptEngine script = ScriptFactory.getScriptEngine(ScriptFactory.VELOCITY); + script.put("ticketline", oLine); + m_TTP.printTicket(script.eval(dlSystem.getResourceAsXML("Printer.TicketLine")).toString()); + + } catch (ScriptException | TicketPrinterException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotprintline"), e); + msg.show(JPanelTicket.this); + } + } + } + + private Object evalScript(ScriptObject scr, String resource, ScriptArg... args) { + + // resource here is guaranteed to be not null + try { + scr.setSelectedIndex(m_ticketlines.getSelectedIndex()); + return scr.evalScript(dlSystem.getResourceAsXML(resource), args); + } catch (ScriptException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotexecute"), e); + msg.show(this); + return msg; + } + } + + /** + * @param resource + * @param args + */ + public void evalScriptAndRefresh(String resource, ScriptArg... args) { + + if (resource == null) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotexecute")); + msg.show(this); + } else { + ScriptObject scr = new ScriptObject(m_oTicket, m_oTicketExt); + scr.setSelectedIndex(m_ticketlines.getSelectedIndex()); + evalScript(scr, resource, args); + refreshTicket(); + + setSelectedIndex(scr.getSelectedIndex()); + } + } + + /** + * + */ + private Object executeEventAndRefresh(String eventkey, ScriptArg... args) { + + String resource = m_jbtnconfig.getEvent(eventkey); + + if (resource == null) { + return null; + } else { + ScriptObject scr = new ScriptObject(m_oTicket, m_oTicketExt); + scr.setSelectedIndex(m_ticketlines.getSelectedIndex()); + Object result = evalScript(scr, resource, args); + refreshTicket(); + setSelectedIndex(scr.getSelectedIndex()); + return result; + } + } + + + private Object executeEvent(TicketInfo ticket, Object ticketext, String eventkey, ScriptArg... args) { + + String resource = m_jbtnconfig.getEvent(eventkey); + if (resource == null) { + return null; + } else { + ScriptObject scr = new ScriptObject(ticket, ticketext); + return evalScript(scr, resource, args); + } + } + + /** + * @param sresourcename + * @return + */ + public String getResourceAsXML(String sresourcename) { + return dlSystem.getResourceAsXML(sresourcename); + } + + /** + * @param sresourcename + * @return + */ + public BufferedImage getResourceAsImage(String sresourcename) { + return dlSystem.getResourceAsImage(sresourcename); + } + + private void setSelectedIndex(int i) { + + if (i >= 0 && i < m_oTicket.getLinesCount()) { + m_ticketlines.setSelectedIndex(i); + } else if (m_oTicket.getLinesCount() > 0) { + m_ticketlines.setSelectedIndex(m_oTicket.getLinesCount() - 1); + } + } + + /** + * + */ + public static class ScriptArg { + private final String key; + private final Object value; + + /** + * @param key + * @param value + */ + public ScriptArg(String key, Object value) { + this.key = key; + this.value = value; + } + + /** + * @return + */ + public String getKey() { + return key; + } + + /** + * @return + */ + public Object getValue() { + return value; + } + } + + private String setTempjPrice(String jPrice) { + jPrice = jPrice.replace(".", ""); +// remove all leading zeros from the string + long tempL = Long.parseLong(jPrice); + jPrice = Long.toString(tempL); + + while (jPrice.length() < 3) { + jPrice = "0" + jPrice; + } + return (jPrice.length() <= 2) ? jPrice : (new StringBuffer(jPrice).insert(jPrice.length() - 2, ".").toString()); + } + + public void checkStock() { + int i = m_ticketlines.getSelectedIndex(); + + if (i < 0) { + } else { + try { + TicketLineInfo line = m_oTicket.getLine(i); + String pId = line.getProductID(); + + String lName = (m_App.getProperties().getProperty("machine.department")); + lName = "'" + lName + "'"; + ProductStock checkProduct; + String location = m_App.getInventoryLocation(); + checkProduct = dlSales.getProductStockState(pId, location); + + if (checkProduct != null) { + + if (checkProduct.getUnits() <= 0) { + jCheckStock.setForeground(Color.magenta); + } else { + jCheckStock.setForeground(Color.darkGray); + } + + double dUnits = checkProduct.getUnits(); + int iUnits; + iUnits = (int) dUnits; + jCheckStock.setText(Integer.toString(iUnits)); + } else { + jCheckStock.setText(null); + } + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + } + } + + public void checkCustomer() { + if (m_oTicket.getCustomer().isVIP() == true) { + + String content; + String vip; + String discount; + + if (m_oTicket.getCustomer().isVIP() == true) { + vip = AppLocal.getIntString("message.vipyes"); + } else { + vip = AppLocal.getIntString("message.vipno"); + } + if (m_oTicket.getCustomer().getDiscount() > 0) { + discount = AppLocal.getIntString("message.discyes") + m_oTicket.getCustomer().getDiscount() + "%"; + } else { + discount = AppLocal.getIntString("message.discno"); + } + + content = "<html>" + + "<b>" + AppLocal.getIntString("label.vip") + " : " + "</b>" + vip + "<br>" + + "<b>" + AppLocal.getIntString("label.discount") + " : " + "</b>" + discount + "<br>"; + + + JFrame frame = new JFrame(); + JOptionPane.showMessageDialog(frame, + content, + "Info", + JOptionPane.WARNING_MESSAGE); + } + } + + /** + * + */ + public class ScriptObject { + + private final TicketInfo ticket; + private final Object ticketext; + + private int selectedindex; + + private ScriptObject(TicketInfo ticket, Object ticketext) { + this.ticket = ticket; + this.ticketext = ticketext; + } + + /** + * @return + */ + public double getInputValue() { + if (m_iNumberStatusInput == NUMBERVALID && m_iNumberStatusPor == NUMBERZERO) { + return JPanelTicket.this.getInputValue(); + } else { + return 0.0; + } + } + + /** + * @return + */ + public int getSelectedIndex() { + return selectedindex; + } + + /** + * @param i + */ + public void setSelectedIndex(int i) { + selectedindex = i; + } + + /** + * @param resourcefile + */ + public void printReport(String resourcefile) { + JPanelTicket.this.printReport(resourcefile, ticket, ticketext); + } + + /** + * @param sresourcename + */ + public void printTicket(String sresourcename) { + JPanelTicket.this.printTicket(sresourcename, ticket, ticketext); + j_btnRemotePrt.setEnabled(false); + } + + /** + * @param code + * @param args + * @return Script object and value + * @throws ScriptException + */ + public Object evalScript(String code, ScriptArg... args) throws ScriptException { + + ScriptEngine script = ScriptFactory.getScriptEngine(ScriptFactory.BEANSHELL); + + String sDBUser = m_App.getProperties().getProperty("db.user"); + String sDBPassword = m_App.getProperties().getProperty("db.password"); + + if (sDBUser != null && sDBPassword != null && sDBPassword.startsWith("crypt:")) { + AltEncrypter cypher = new AltEncrypter("cypherkey" + sDBUser); + sDBPassword = cypher.decrypt(sDBPassword.substring(6)); + } + script.put("hostname", m_App.getProperties().getProperty("machine.hostname")); + script.put("dbURL", m_App.getProperties().getProperty("db.URL") + m_App.getProperties().getProperty("db.schema")); + script.put("dbUser", sDBUser); + script.put("dbPassword", sDBPassword); + + script.put("ticket", ticket); + script.put("place", ticketext); + script.put("taxes", taxcollection); + script.put("taxeslogic", taxeslogic); + script.put("user", m_App.getAppUserView().getUser()); + script.put("sales", this); + script.put("taxesinc", m_jaddtax.isSelected()); + script.put("warranty", warrantyPrint); + script.put("pickupid", getPickupString(ticket)); + + for (ScriptArg arg : args) { + script.put(arg.getKey(), arg.getValue()); + } + + return script.eval(code); + } + } + + + /** + * This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the FormEditor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jPanContainer = new javax.swing.JPanel(); + m_jOptions = new javax.swing.JPanel(); + m_jPanelBag = new javax.swing.JPanel(); + jTBtnShow = new javax.swing.JToggleButton(); + m_jbtnScale = new javax.swing.JButton(); + jbtnMooring = new javax.swing.JButton(); + m_jButtons = new javax.swing.JPanel(); + btnSplit = new javax.swing.JButton(); + btnReprint1 = new javax.swing.JButton(); + j_btnRemotePrt = new javax.swing.JButton(); + jBtnCustomer = new javax.swing.JButton(); + m_jPanelScripts = new javax.swing.JPanel(); + m_jButtonsExt = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + m_jPanTicket = new javax.swing.JPanel(); + jPanel5 = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + m_jDelete = new javax.swing.JButton(); + m_jList = new javax.swing.JButton(); + m_jEditLine = new javax.swing.JButton(); + jEditAttributes = new javax.swing.JButton(); + jCheckStock = new javax.swing.JButton(); + m_jPanelCentral = new javax.swing.JPanel(); + jPanel4 = new javax.swing.JPanel(); + filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767)); + m_jTicketId = new javax.swing.JLabel(); + m_jPanTotals = new javax.swing.JPanel(); + m_jLblTotalEuros3 = new javax.swing.JLabel(); + m_jLblTotalEuros2 = new javax.swing.JLabel(); + m_jLblTotalEuros1 = new javax.swing.JLabel(); + m_jSubtotalEuros = new javax.swing.JLabel(); + m_jTaxesEuros = new javax.swing.JLabel(); + m_jTotalEuros = new javax.swing.JLabel(); + m_jContEntries = new javax.swing.JPanel(); + m_jPanEntries = new javax.swing.JPanel(); + m_jNumberKeys = new com.unicenta.beans.JNumberKeys(); + jPanel9 = new javax.swing.JPanel(); + m_jaddtax = new com.alee.extended.button.WebSwitch(); + m_jPrice = new javax.swing.JLabel(); + m_jPor = new javax.swing.JLabel(); + m_jEnter = new javax.swing.JButton(); + m_jTax = new javax.swing.JComboBox(); + m_jKeyFactory = new javax.swing.JTextField(); + m_jPanEntriesE = new javax.swing.JPanel(); + catcontainer = new javax.swing.JPanel(); + + setBackground(new java.awt.Color(255, 204, 153)); + setOpaque(false); + setLayout(new java.awt.CardLayout()); + + m_jPanContainer.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusLost(java.awt.event.FocusEvent evt) { + m_jPanContainerFocusLost(evt); + } + }); + m_jPanContainer.setLayout(new java.awt.BorderLayout()); + + m_jOptions.setLayout(new java.awt.BorderLayout()); + + m_jPanelBag.setAutoscrolls(true); + m_jPanelBag.setMaximumSize(new java.awt.Dimension(10, 10)); + m_jPanelBag.setPreferredSize(new java.awt.Dimension(0, 60)); + + jTBtnShow.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTBtnShow.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/resources.png"))); // NOI18N + jTBtnShow.setPreferredSize(new java.awt.Dimension(80, 45)); + jTBtnShow.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jTBtnShowActionPerformed(evt); + } + }); + m_jPanelBag.add(jTBtnShow); + + m_jbtnScale.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jbtnScale.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/scale.png"))); // NOI18N + m_jbtnScale.setText(AppLocal.getIntString("button.scale")); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + m_jbtnScale.setToolTipText(bundle.getString("tooltip.scale")); // NOI18N + m_jbtnScale.setFocusPainted(false); + m_jbtnScale.setFocusable(false); + m_jbtnScale.setMargin(new java.awt.Insets(8, 14, 8, 14)); + m_jbtnScale.setMaximumSize(new java.awt.Dimension(85, 44)); + m_jbtnScale.setMinimumSize(new java.awt.Dimension(85, 44)); + m_jbtnScale.setPreferredSize(new java.awt.Dimension(85, 45)); + m_jbtnScale.setRequestFocusEnabled(false); + m_jbtnScale.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtnScaleActionPerformed(evt); + } + }); + m_jPanelBag.add(m_jbtnScale); + + jbtnMooring.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnMooring.setText(bundle.getString("button.moorings")); // NOI18N + jbtnMooring.setMargin(new java.awt.Insets(8, 14, 8, 14)); + jbtnMooring.setMaximumSize(new java.awt.Dimension(80, 40)); + jbtnMooring.setMinimumSize(new java.awt.Dimension(80, 40)); + jbtnMooring.setPreferredSize(new java.awt.Dimension(80, 45)); + jbtnMooring.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnMooringActionPerformed(evt); + } + }); + m_jPanelBag.add(jbtnMooring); + + m_jButtons.setPreferredSize(new java.awt.Dimension(350, 55)); + + btnSplit.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/sale_split_sml.png"))); // NOI18N + btnSplit.setToolTipText(bundle.getString("tooltip.salesplit")); // NOI18N + btnSplit.setEnabled(false); + btnSplit.setFocusPainted(false); + btnSplit.setFocusable(false); + btnSplit.setMargin(new java.awt.Insets(8, 14, 8, 14)); + btnSplit.setMaximumSize(new java.awt.Dimension(50, 40)); + btnSplit.setMinimumSize(new java.awt.Dimension(50, 40)); + btnSplit.setPreferredSize(new java.awt.Dimension(80, 45)); + btnSplit.setRequestFocusEnabled(false); + btnSplit.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnSplitActionPerformed(evt); + } + }); + + btnReprint1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + btnReprint1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reprint24.png"))); // NOI18N + btnReprint1.setToolTipText(bundle.getString("tooltip.reprintLastTicket")); // NOI18N + btnReprint1.setFocusPainted(false); + btnReprint1.setFocusable(false); + btnReprint1.setMargin(new java.awt.Insets(8, 14, 8, 14)); + btnReprint1.setMaximumSize(new java.awt.Dimension(50, 40)); + btnReprint1.setMinimumSize(new java.awt.Dimension(50, 40)); + btnReprint1.setPreferredSize(new java.awt.Dimension(80, 45)); + btnReprint1.setRequestFocusEnabled(false); + btnReprint1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnReprint1ActionPerformed(evt); + } + }); + + j_btnRemotePrt.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N + j_btnRemotePrt.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/remote_print.png"))); // NOI18N + j_btnRemotePrt.setText(bundle.getString("button.sendorder")); // NOI18N + j_btnRemotePrt.setToolTipText(bundle.getString("tooltip.printtoremote")); // NOI18N + j_btnRemotePrt.setMargin(new java.awt.Insets(0, 4, 0, 4)); + j_btnRemotePrt.setMaximumSize(new java.awt.Dimension(50, 40)); + j_btnRemotePrt.setMinimumSize(new java.awt.Dimension(50, 40)); + j_btnRemotePrt.setPreferredSize(new java.awt.Dimension(80, 45)); + j_btnRemotePrt.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + j_btnRemotePrtActionPerformed(evt); + } + }); + + jBtnCustomer.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jBtnCustomer.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/customer.png"))); // NOI18N + jBtnCustomer.setToolTipText(bundle.getString("tooltip.salescustomer")); // NOI18N + jBtnCustomer.setPreferredSize(new java.awt.Dimension(80, 45)); + jBtnCustomer.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnCustomerActionPerformed(evt); + } + }); + + javax.swing.GroupLayout m_jButtonsLayout = new javax.swing.GroupLayout(m_jButtons); + m_jButtons.setLayout(m_jButtonsLayout); + m_jButtonsLayout.setHorizontalGroup( + m_jButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(m_jButtonsLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jBtnCustomer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnSplit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(j_btnRemotePrt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnReprint1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + m_jButtonsLayout.setVerticalGroup( + m_jButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(m_jButtonsLayout.createSequentialGroup() + .addGap(5, 5, 5) + .addGroup(m_jButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(j_btnRemotePrt, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnSplit, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnReprint1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jBtnCustomer, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + m_jPanelBag.add(m_jButtons); + + m_jOptions.add(m_jPanelBag, java.awt.BorderLayout.PAGE_START); + + m_jPanelScripts.setPreferredSize(new java.awt.Dimension(200, 60)); + m_jPanelScripts.setLayout(new java.awt.BorderLayout()); + + m_jButtonsExt.setPreferredSize(new java.awt.Dimension(20, 60)); + + jPanel1.setMinimumSize(new java.awt.Dimension(235, 50)); + jPanel1.setPreferredSize(new java.awt.Dimension(10, 55)); + m_jButtonsExt.add(jPanel1); + + m_jPanelScripts.add(m_jButtonsExt, java.awt.BorderLayout.PAGE_START); + + m_jOptions.add(m_jPanelScripts, java.awt.BorderLayout.CENTER); + m_jPanelScripts.getAccessibleContext().setAccessibleDescription(""); + + m_jPanContainer.add(m_jOptions, java.awt.BorderLayout.NORTH); + + m_jPanTicket.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + m_jPanTicket.setLayout(new java.awt.BorderLayout()); + + jPanel5.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel5.setPreferredSize(new java.awt.Dimension(75, 270)); + jPanel5.setLayout(new java.awt.BorderLayout()); + + jPanel2.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 5, 0, 5)); + jPanel2.setPreferredSize(new java.awt.Dimension(70, 250)); + jPanel2.setLayout(new java.awt.GridLayout(0, 1, 5, 5)); + + m_jDelete.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/editdelete.png"))); // NOI18N + m_jDelete.setToolTipText(bundle.getString("tooltip.saleremoveline")); // NOI18N + m_jDelete.setFocusPainted(false); + m_jDelete.setFocusable(false); + m_jDelete.setMargin(new java.awt.Insets(8, 14, 8, 14)); + m_jDelete.setMaximumSize(new java.awt.Dimension(42, 36)); + m_jDelete.setMinimumSize(new java.awt.Dimension(42, 36)); + m_jDelete.setPreferredSize(new java.awt.Dimension(50, 45)); + m_jDelete.setRequestFocusEnabled(false); + m_jDelete.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jDeleteActionPerformed(evt); + } + }); + jPanel2.add(m_jDelete); + + m_jList.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/search32.png"))); // NOI18N + m_jList.setToolTipText(bundle.getString("tooltip.saleproductfind")); // NOI18N + m_jList.setFocusPainted(false); + m_jList.setFocusable(false); + m_jList.setMargin(new java.awt.Insets(8, 14, 8, 14)); + m_jList.setMaximumSize(new java.awt.Dimension(42, 36)); + m_jList.setMinimumSize(new java.awt.Dimension(42, 36)); + m_jList.setPreferredSize(new java.awt.Dimension(50, 45)); + m_jList.setRequestFocusEnabled(false); + m_jList.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jListActionPerformed(evt); + } + }); + jPanel2.add(m_jList); + + m_jEditLine.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/sale_editline.png"))); // NOI18N + m_jEditLine.setToolTipText(bundle.getString("tooltip.saleeditline")); // NOI18N + m_jEditLine.setFocusPainted(false); + m_jEditLine.setFocusable(false); + m_jEditLine.setMargin(new java.awt.Insets(8, 14, 8, 14)); + m_jEditLine.setMaximumSize(new java.awt.Dimension(42, 36)); + m_jEditLine.setMinimumSize(new java.awt.Dimension(42, 36)); + m_jEditLine.setPreferredSize(new java.awt.Dimension(50, 45)); + m_jEditLine.setRequestFocusEnabled(false); + m_jEditLine.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jEditLineActionPerformed(evt); + } + }); + jPanel2.add(m_jEditLine); + + jEditAttributes.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/attributes.png"))); // NOI18N + jEditAttributes.setToolTipText(bundle.getString("tooltip.saleattributes")); // NOI18N + jEditAttributes.setFocusPainted(false); + jEditAttributes.setFocusable(false); + jEditAttributes.setMargin(new java.awt.Insets(8, 14, 8, 14)); + jEditAttributes.setMaximumSize(new java.awt.Dimension(42, 36)); + jEditAttributes.setMinimumSize(new java.awt.Dimension(42, 36)); + jEditAttributes.setPreferredSize(new java.awt.Dimension(50, 45)); + jEditAttributes.setRequestFocusEnabled(false); + jEditAttributes.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jEditAttributesActionPerformed(evt); + } + }); + jPanel2.add(jEditAttributes); + + jCheckStock.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + jCheckStock.setForeground(new java.awt.Color(76, 197, 237)); + jCheckStock.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/info.png"))); // NOI18N + jCheckStock.setToolTipText(bundle.getString("tooltip.salecheckstock")); // NOI18N + jCheckStock.setFocusPainted(false); + jCheckStock.setFocusable(false); + jCheckStock.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jCheckStock.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT); + jCheckStock.setMargin(new java.awt.Insets(8, 4, 8, 4)); + jCheckStock.setMaximumSize(new java.awt.Dimension(42, 36)); + jCheckStock.setMinimumSize(new java.awt.Dimension(42, 36)); + jCheckStock.setPreferredSize(new java.awt.Dimension(80, 45)); + jCheckStock.setRequestFocusEnabled(false); + jCheckStock.setVerticalTextPosition(javax.swing.SwingConstants.TOP); + jCheckStock.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + jCheckStockMouseClicked(evt); + } + }); + jCheckStock.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jCheckStockActionPerformed(evt); + } + }); + jPanel2.add(jCheckStock); + + jPanel5.add(jPanel2, java.awt.BorderLayout.NORTH); + + m_jPanTicket.add(jPanel5, java.awt.BorderLayout.LINE_START); + + m_jPanelCentral.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPanelCentral.setPreferredSize(new java.awt.Dimension(450, 240)); + m_jPanelCentral.setLayout(new java.awt.BorderLayout()); + + jPanel4.setLayout(new java.awt.BorderLayout()); + jPanel4.add(filler2, java.awt.BorderLayout.LINE_START); + + m_jTicketId.setFont(new java.awt.Font("Arial", 1, 12)); // NOI18N + m_jTicketId.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + m_jTicketId.setVerticalAlignment(javax.swing.SwingConstants.TOP); + m_jTicketId.setOpaque(true); + m_jTicketId.setPreferredSize(new java.awt.Dimension(300, 40)); + m_jTicketId.setRequestFocusEnabled(false); + m_jTicketId.setVerticalTextPosition(javax.swing.SwingConstants.TOP); + jPanel4.add(m_jTicketId, java.awt.BorderLayout.CENTER); + + m_jPanTotals.setPreferredSize(new java.awt.Dimension(375, 60)); + m_jPanTotals.setLayout(new java.awt.GridLayout(2, 3, 4, 0)); + + m_jLblTotalEuros3.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + m_jLblTotalEuros3.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + m_jLblTotalEuros3.setLabelFor(m_jSubtotalEuros); + m_jLblTotalEuros3.setText(AppLocal.getIntString("label.subtotalcash")); // NOI18N + m_jPanTotals.add(m_jLblTotalEuros3); + + m_jLblTotalEuros2.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + m_jLblTotalEuros2.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + m_jLblTotalEuros2.setLabelFor(m_jSubtotalEuros); + m_jLblTotalEuros2.setText(AppLocal.getIntString("label.taxcash")); // NOI18N + m_jPanTotals.add(m_jLblTotalEuros2); + + m_jLblTotalEuros1.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + m_jLblTotalEuros1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + m_jLblTotalEuros1.setLabelFor(m_jTotalEuros); + m_jLblTotalEuros1.setText(AppLocal.getIntString("label.totalcash")); // NOI18N + m_jPanTotals.add(m_jLblTotalEuros1); + + m_jSubtotalEuros.setBackground(m_jEditLine.getBackground()); + m_jSubtotalEuros.setFont(new java.awt.Font("Arial", 0, 18)); // NOI18N + m_jSubtotalEuros.setForeground(m_jEditLine.getForeground()); + m_jSubtotalEuros.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + m_jSubtotalEuros.setLabelFor(m_jSubtotalEuros); + m_jSubtotalEuros.setToolTipText(bundle.getString("tooltip.salesubtotal")); // NOI18N + m_jSubtotalEuros.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(153, 153, 153), 1, true)); + m_jSubtotalEuros.setMaximumSize(new java.awt.Dimension(125, 25)); + m_jSubtotalEuros.setMinimumSize(new java.awt.Dimension(80, 25)); + m_jSubtotalEuros.setPreferredSize(new java.awt.Dimension(80, 25)); + m_jSubtotalEuros.setRequestFocusEnabled(false); + m_jPanTotals.add(m_jSubtotalEuros); + + m_jTaxesEuros.setBackground(m_jEditLine.getBackground()); + m_jTaxesEuros.setFont(new java.awt.Font("Arial", 0, 18)); // NOI18N + m_jTaxesEuros.setForeground(m_jEditLine.getForeground()); + m_jTaxesEuros.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + m_jTaxesEuros.setLabelFor(m_jTaxesEuros); + m_jTaxesEuros.setToolTipText(bundle.getString("tooltip.saletax")); // NOI18N + m_jTaxesEuros.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(153, 153, 153), 1, true)); + m_jTaxesEuros.setMaximumSize(new java.awt.Dimension(125, 25)); + m_jTaxesEuros.setMinimumSize(new java.awt.Dimension(80, 25)); + m_jTaxesEuros.setPreferredSize(new java.awt.Dimension(80, 25)); + m_jTaxesEuros.setRequestFocusEnabled(false); + m_jPanTotals.add(m_jTaxesEuros); + + m_jTotalEuros.setBackground(m_jEditLine.getBackground()); + m_jTotalEuros.setFont(new java.awt.Font("Arial", 1, 18)); // NOI18N + m_jTotalEuros.setForeground(m_jEditLine.getForeground()); + m_jTotalEuros.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + m_jTotalEuros.setLabelFor(m_jTotalEuros); + m_jTotalEuros.setToolTipText(bundle.getString("tooltip.saletotal")); // NOI18N + m_jTotalEuros.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(153, 153, 153), 1, true)); + m_jTotalEuros.setMaximumSize(new java.awt.Dimension(125, 25)); + m_jTotalEuros.setMinimumSize(new java.awt.Dimension(80, 25)); + m_jTotalEuros.setPreferredSize(new java.awt.Dimension(100, 25)); + m_jTotalEuros.setRequestFocusEnabled(false); + m_jPanTotals.add(m_jTotalEuros); + + jPanel4.add(m_jPanTotals, java.awt.BorderLayout.LINE_END); + + m_jPanelCentral.add(jPanel4, java.awt.BorderLayout.SOUTH); + + m_jPanTicket.add(m_jPanelCentral, java.awt.BorderLayout.CENTER); + + m_jPanContainer.add(m_jPanTicket, java.awt.BorderLayout.CENTER); + + m_jContEntries.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jContEntries.setMinimumSize(new java.awt.Dimension(300, 350)); + m_jContEntries.setLayout(new java.awt.BorderLayout()); + + m_jPanEntries.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPanEntries.setPreferredSize(new java.awt.Dimension(300, 350)); + m_jPanEntries.setLayout(new javax.swing.BoxLayout(m_jPanEntries, javax.swing.BoxLayout.Y_AXIS)); + + m_jNumberKeys.setMinimumSize(new java.awt.Dimension(300, 300)); + m_jNumberKeys.setPreferredSize(new java.awt.Dimension(250, 250)); + m_jNumberKeys.addJNumberEventListener(new com.unicenta.beans.JNumberEventListener() { + public void keyPerformed(com.unicenta.beans.JNumberEvent evt) { + m_jNumberKeysKeyPerformed(evt); + } + }); + m_jPanEntries.add(m_jNumberKeys); + + jPanel9.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + + m_jaddtax.setBorder(null); + m_jaddtax.setToolTipText(bundle.getString("tooltip.switchtax")); // NOI18N + m_jaddtax.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jaddtax.setPreferredSize(new java.awt.Dimension(60, 30)); + m_jaddtax.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jaddtaxActionPerformed(evt); + } + }); + + m_jPrice.setFont(new java.awt.Font("Arial", 1, 16)); // NOI18N + m_jPrice.setForeground(new java.awt.Color(76, 197, 237)); + m_jPrice.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + m_jPrice.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(76, 197, 237)), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jPrice.setOpaque(true); + m_jPrice.setPreferredSize(new java.awt.Dimension(100, 25)); + m_jPrice.setRequestFocusEnabled(false); + + m_jPor.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jPor.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + m_jPor.setRequestFocusEnabled(false); + + m_jEnter.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/barcode.png"))); // NOI18N + m_jEnter.setToolTipText(bundle.getString("tooltip.salebarcode")); // NOI18N + m_jEnter.setFocusPainted(false); + m_jEnter.setFocusable(false); + m_jEnter.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jEnter.setRequestFocusEnabled(false); + m_jEnter.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jEnterActionPerformed(evt); + } + }); + + m_jTax.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jTax.setToolTipText(bundle.getString("tooltip.salestaxswitch")); // NOI18N + m_jTax.setFocusable(false); + m_jTax.setPreferredSize(new java.awt.Dimension(28, 25)); + m_jTax.setRequestFocusEnabled(false); + + m_jKeyFactory.setEditable(false); + m_jKeyFactory.setFont(new java.awt.Font("Arial", 0, 11)); // NOI18N + m_jKeyFactory.setForeground(javax.swing.UIManager.getDefaults().getColor("Panel.background")); + m_jKeyFactory.setAutoscrolls(false); + m_jKeyFactory.setBorder(null); + m_jKeyFactory.setCaretColor(javax.swing.UIManager.getDefaults().getColor("Panel.background")); + m_jKeyFactory.setMinimumSize(new java.awt.Dimension(0, 0)); + m_jKeyFactory.setPreferredSize(new java.awt.Dimension(1, 1)); + m_jKeyFactory.setRequestFocusEnabled(false); + m_jKeyFactory.setVerifyInputWhenFocusTarget(false); + m_jKeyFactory.addKeyListener(new java.awt.event.KeyAdapter() { + public void keyTyped(java.awt.event.KeyEvent evt) { + m_jKeyFactoryKeyTyped(evt); + } + }); + + javax.swing.GroupLayout jPanel9Layout = new javax.swing.GroupLayout(jPanel9); + jPanel9.setLayout(jPanel9Layout); + jPanel9Layout.setHorizontalGroup( + jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel9Layout.createSequentialGroup() + .addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(m_jPor) + .addComponent(m_jKeyFactory, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 7, Short.MAX_VALUE) + .addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel9Layout.createSequentialGroup() + .addComponent(m_jaddtax, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(7, 7, 7) + .addComponent(m_jTax, javax.swing.GroupLayout.PREFERRED_SIZE, 128, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)) + .addGroup(jPanel9Layout.createSequentialGroup() + .addComponent(m_jPrice, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(5, 5, 5))) + .addComponent(m_jEnter, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + jPanel9Layout.setVerticalGroup( + jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel9Layout.createSequentialGroup() + .addComponent(m_jEnter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(jPanel9Layout.createSequentialGroup() + .addComponent(m_jPrice, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 7, Short.MAX_VALUE) + .addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jTax, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jaddtax, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel9Layout.createSequentialGroup() + .addComponent(m_jPor) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(m_jKeyFactory, javax.swing.GroupLayout.PREFERRED_SIZE, 1, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + + m_jPanEntries.add(jPanel9); + + m_jContEntries.add(m_jPanEntries, java.awt.BorderLayout.NORTH); + + m_jPanEntriesE.setLayout(new java.awt.BorderLayout()); + m_jContEntries.add(m_jPanEntriesE, java.awt.BorderLayout.LINE_END); + + m_jPanContainer.add(m_jContEntries, java.awt.BorderLayout.LINE_END); + + catcontainer.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + catcontainer.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + catcontainer.setLayout(new java.awt.BorderLayout()); + m_jPanContainer.add(catcontainer, java.awt.BorderLayout.SOUTH); + + add(m_jPanContainer, "ticket"); + }// </editor-fold>//GEN-END:initComponents + + private void m_jbtnScaleActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtnScaleActionPerformed + + stateTransition('\u00a7'); + + }//GEN-LAST:event_m_jbtnScaleActionPerformed + + private void m_jEditLineActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jEditLineActionPerformed + + count = (int) m_oTicket.getArticlesCount(); // get existing line value + + int i = m_ticketlines.getSelectedIndex(); + + if (i < 0) { + Toolkit.getDefaultToolkit().beep(); // no line selected + } else { + try { + TicketLineInfo newline = JProductLineEdit.showMessage(this, m_App, m_oTicket.getLine(i)); + if (newline != null) { + paintTicketLine(i, newline); + } + + } catch (BasicException e) { + new MessageInf(e).show(this); + } + } + + }//GEN-LAST:event_m_jEditLineActionPerformed + + private void m_jEnterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jEnterActionPerformed + + stateTransition('\n'); + + }//GEN-LAST:event_m_jEnterActionPerformed + + private void m_jNumberKeysKeyPerformed(com.unicenta.beans.JNumberEvent evt) {//GEN-FIRST:event_m_jNumberKeysKeyPerformed + + stateTransition(evt.getKey()); + + j_btnRemotePrt.setEnabled(true); + j_btnRemotePrt.revalidate(); + + }//GEN-LAST:event_m_jNumberKeysKeyPerformed + + private void m_jKeyFactoryKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_m_jKeyFactoryKeyTyped + + m_jKeyFactory.setText(null); + + stateTransition(evt.getKeyChar()); + + }//GEN-LAST:event_m_jKeyFactoryKeyTyped + + private void m_jDeleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jDeleteActionPerformed + int i = m_ticketlines.getSelectedIndex(); + if (m_App.getProperties().getProperty("override.check").equals("true")) { + pinOK = false; + if (changeCount(pinOK)) { + if (i < 0) { + Toolkit.getDefaultToolkit().beep(); + } else { + removeTicketLine(i); + jCheckStock.setText(""); + } + } + } else { + if (i < 0) { + Toolkit.getDefaultToolkit().beep(); + } else { + removeTicketLine(i); + jCheckStock.setText(""); + } + } + }//GEN-LAST:event_m_jDeleteActionPerformed + + private void m_jListActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jListActionPerformed + + ProductInfoExt prod = JProductFinder.showMessage(JPanelTicket.this, dlSales); + if (prod != null) { + buttonTransition(prod); + } + + }//GEN-LAST:event_m_jListActionPerformed + + private void jEditAttributesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jEditAttributesActionPerformed + if (listener != null) { + listener.stop(); + } + int i = m_ticketlines.getSelectedIndex(); + if (i < 0) { + Toolkit.getDefaultToolkit().beep(); // no line selected + } else { + try { + TicketLineInfo line = m_oTicket.getLine(i); + JProductAttEdit2 attedit = JProductAttEdit2.getAttributesEditor(this, m_App.getSession()); + attedit.editAttributes(line.getProductAttSetId(), line.getProductAttSetInstId()); + attedit.setVisible(true); + if (attedit.isOK()) { + line.setProductAttSetInstId(attedit.getAttributeSetInst()); + line.setProductAttSetInstDesc(attedit.getAttributeSetInstDescription()); + paintTicketLine(i, line); + } + } catch (BasicException ex) { + JOptionPane.showMessageDialog(this, + AppLocal.getIntString("message.cannotfindattributes"), + AppLocal.getIntString("message.title"), + JOptionPane.INFORMATION_MESSAGE); + } + } + + if (listener != null) { + listener.restart(); + } + }//GEN-LAST:event_jEditAttributesActionPerformed + + private void jbtnMooringActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnMooringActionPerformed +// Display vessel selection box on screen if reply is good add to the ticket + if (listener != null) { + listener.stop(); + } + JMooringDetails mooring = JMooringDetails.getMooringDetails(this, m_App.getSession()); + mooring.setVisible(true); + if (mooring.isCreate()) { + if (((mooring.getVesselDays() > 0)) && ((mooring.getVesselSize() > 1))) { + try { + ProductInfoExt vProduct = dlSales.getProductInfoByCode("BFeesDay1"); + vProduct.setName("Berth Fees 1st Day " + mooring.getVesselName()); + addTicketLine(vProduct, mooring.getVesselSize(), vProduct.getPriceSell()); + + if (mooring.getVesselDays() > 1) { + vProduct = dlSales.getProductInfoByCode("BFeesDay2"); + vProduct.setName("Additional Days " + (mooring.getVesselDays() - 1)); + addTicketLine(vProduct, mooring.getVesselSize() * (mooring.getVesselDays() - 1), vProduct.getPriceSell()); + } + + if (mooring.getVesselPower()) { + vProduct = dlSales.getProductInfoByCode("PowerSupplied"); + addTicketLine(vProduct, mooring.getVesselDays(), vProduct.getPriceSell()); + } + } catch (BasicException e) { + } + } + } + refreshTicket(); + }//GEN-LAST:event_jbtnMooringActionPerformed + + private void j_btnRemotePrtActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_j_btnRemotePrtActionPerformed + + String rScript = (dlSystem.getResourceAsText("script.SendOrder")); + + Interpreter i = new Interpreter(); + try { + i.set("ticket", m_oTicket); + i.set("place", m_oTicketExt); + i.set("user", m_App.getAppUserView().getUser()); + i.set("sales", this); + i.set("pickupid", m_oTicket.getPickupId()); + + Object result; + result = i.eval(rScript); + + } catch (EvalError ex) { + log.error(ex.getMessage()); + } + + remoteOrderDisplay(); + + }//GEN-LAST:event_j_btnRemotePrtActionPerformed + + private void btnReprint1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnReprint1ActionPerformed + if (m_config.getProperty("lastticket.number") != null) { + try { + TicketInfo ticket = dlSales.loadTicket( + Integer.parseInt((m_config.getProperty("lastticket.type"))), + Integer.parseInt((m_config.getProperty("lastticket.number")))); + if (ticket == null) { + JFrame frame = new JFrame(); + JOptionPane.showMessageDialog(frame, + AppLocal.getIntString("message.notexiststicket"), + AppLocal.getIntString("message.notexiststickettitle"), + JOptionPane.WARNING_MESSAGE); + } else { + m_ticket = ticket; + m_ticketCopy = null; + try { + taxeslogic.calculateTaxes(m_ticket); + TicketTaxInfo[] taxlist = m_ticket.getTaxLines(); + } catch (TaxesException ex) { + } + printTicket("Printer.ReprintTicket", m_ticket, null); + Notify("'Printed'"); + } + } catch (BasicException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotloadticket"), e); + msg.show(this); + } + } + }//GEN-LAST:event_btnReprint1ActionPerformed + + private void btnSplitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSplitActionPerformed + + if (m_oTicket.getLinesCount() > 0) { + ReceiptSplit splitdialog = ReceiptSplit.getDialog(this, + dlSystem.getResourceAsXML("Ticket.Line"), dlSales, dlCustomers, taxeslogic); + + TicketInfo ticket1 = m_oTicket.copyTicket(); + TicketInfo ticket2 = new TicketInfo(); + ticket2.setCustomer(m_oTicket.getCustomer()); + + if (splitdialog.showDialog(ticket1, ticket2, m_oTicketExt)) { + if (closeTicket(ticket2, m_oTicketExt)) { // already checked that number of lines > 0 + setActiveTicket(ticket1, m_oTicketExt);// set result ticket + } + } + } + + }//GEN-LAST:event_btnSplitActionPerformed + + private void jCheckStockActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckStockActionPerformed + + if (listener != null) { + listener.stop(); + } + + int i = m_ticketlines.getSelectedIndex(); + if (i < 0) { + Toolkit.getDefaultToolkit().beep(); + } else { + try { + TicketLineInfo line = m_oTicket.getLine(i); + String pId = line.getProductID(); + String location = m_App.getInventoryLocation(); + ProductStock checkProduct; + checkProduct = dlSales.getProductStockState(pId, location); + + if (checkProduct != null) { + + if (checkProduct.getUnits() <= 0) { + jCheckStock.setForeground(Color.magenta); + } else { + jCheckStock.setForeground(Color.darkGray); + } + + String content; + + if (!location.equals(checkProduct.getLocation())) { + content = AppLocal.getIntString("message.location.current"); + JFrame frame = new JFrame(); + JOptionPane.showMessageDialog(frame, + content, + "Info", + JOptionPane.INFORMATION_MESSAGE); + } else { + double dUnits = checkProduct.getUnits(); + int iUnits; + iUnits = (int) dUnits; + + jCheckStock.setText(Integer.toString(iUnits)); + } + + } else { + jCheckStock.setText(null); + } + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + } + + if (listener != null) { + listener.restart(); + } + }//GEN-LAST:event_jCheckStockActionPerformed + + private void jCheckStockMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jCheckStockMouseClicked + if (evt.getClickCount() == 2) { + if (listener != null) { + listener.stop(); + } + + int i = m_ticketlines.getSelectedIndex(); + if (i < 0) { + Toolkit.getDefaultToolkit().beep(); + } else { + try { + TicketLineInfo line = m_oTicket.getLine(i); + String pId = line.getProductID(); + String location = m_App.getInventoryLocation(); + ProductStock checkProduct; + checkProduct = dlSales.getProductStockState(pId, location); + + Double pMin; + Double pMax; + Double pUnits; + Date pMemoDate; + String content; + + if (!location.equals(checkProduct.getLocation())) { + content = AppLocal.getIntString("message.location.current"); + JFrame frame = new JFrame(); + JOptionPane.showMessageDialog(frame, + content, + "Info", + JOptionPane.INFORMATION_MESSAGE); + } else { + if (checkProduct.getMinimum() != null) { + pMin = checkProduct.getMinimum(); + } else { + pMin = 0.; + } + if (checkProduct.getMaximum() != null) { + pMax = checkProduct.getMaximum(); + } else { + pMax = 0.; + } + if (checkProduct.getUnits() != null) { + pUnits = checkProduct.getUnits(); + } else { + pUnits = 0.; + } + if (checkProduct.getMemoDate() != null) { + pMemoDate = checkProduct.getMemoDate(); + } else { + pMemoDate = null; + } + + content = "<html>" + + "<b>" + AppLocal.getIntString("label.currentstock") + + " : " + "</b>" + checkProduct.getUnits() + "<br>" + + "<b>" + AppLocal.getIntString("label.maximum") + + " : " + "</b>" + pMax + "<br>" + + "<b>" + AppLocal.getIntString("label.minimum") + + " : " + "</b>" + pMin + "<br>" + + "<b>" + AppLocal.getIntString("label.proddate") + + " : " + "</b>" + pMemoDate + "<br>"; + + JFrame frame = new JFrame(); + JOptionPane.showMessageDialog(frame, + content, + "Info", + JOptionPane.INFORMATION_MESSAGE); + } + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + } + + if (listener != null) { + listener.restart(); + } + } + }//GEN-LAST:event_jCheckStockMouseClicked + + private void m_jaddtaxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jaddtaxActionPerformed + m_jKeyFactory.requestFocus(); + }//GEN-LAST:event_m_jaddtaxActionPerformed + + private void jTBtnShowActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTBtnShowActionPerformed + if (jTBtnShow.isSelected()) { + m_jPanelScripts.setVisible(true); + m_jButtonsExt.setVisible(true); + } else { + m_jPanelScripts.setVisible(false); + m_jButtonsExt.setVisible(false); + } + refreshTicket(); + m_jKeyFactory.requestFocus(); + }//GEN-LAST:event_jTBtnShowActionPerformed + + private void jBtnCustomerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnCustomerActionPerformed + if (listener != null) { + listener.stop(); + } + Object[] options = {"Create", "Find", "Cancel"}; + + int n = JOptionPane.showOptionDialog(null, + AppLocal.getIntString("message.customeradd"), + AppLocal.getIntString("label.customer"), + JOptionPane.YES_NO_CANCEL_OPTION, + JOptionPane.QUESTION_MESSAGE, + null, + options, + options[2]); + + if (n == 0) { + JDialogNewCustomer dialog = JDialogNewCustomer.getDialog(this, m_App); + dialog.setVisible(true); + + CustomerInfoExt m_customerInfo = dialog.getSelectedCustomer(); + if (dialog.getSelectedCustomer() != null) { + try { + m_oTicket.setCustomer(dlSales.loadCustomerExt + (dialog.getSelectedCustomer().getId())); + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + } + } + + if (n == 1) { + JCustomerFinder finder = JCustomerFinder.getCustomerFinder(this, dlCustomers); + + if (m_oTicket.getCustomerId() == null) { + finder.setAppView(m_App); + finder.search(m_oTicket.getCustomer()); + finder.executeSearch(); + finder.setVisible(true); + + if (finder.getSelectedCustomer() != null) { + try { + m_oTicket.setCustomer(dlSales.loadCustomerExt + (finder.getSelectedCustomer().getId())); + if ("restaurant".equals(m_App.getProperties().getProperty("machine.ticketsbag"))) { + restDB.setCustomerNameInTableByTicketId(dlSales.loadCustomerExt + (finder.getSelectedCustomer().getId()).toString(), m_oTicket.getId()); + } + + checkCustomer(); + + m_jTicketId.setText(m_oTicket.getName(m_oTicketExt)); + + } catch (BasicException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.cannotfindcustomer"), e); + msg.show(this); + } + } else { + restDB.setCustomerNameInTableByTicketId(null, m_oTicket.getId()); + m_oTicket.setCustomer(null); + Notify("notify.customerremove"); + } + + } else { + if (JOptionPane.showConfirmDialog(this, + AppLocal.getIntString("message.customerchange"), + AppLocal.getIntString("title.editor"), + JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { + + finder.setAppView(m_App); + finder.search(m_oTicket.getCustomer()); + finder.executeSearch(); + finder.setVisible(true); + + if (finder.getSelectedCustomer() != null) { + try { + m_oTicket.setCustomer(dlSales.loadCustomerExt + (finder.getSelectedCustomer().getId())); + if ("restaurant".equals(m_App.getProperties().getProperty("machine.ticketsbag"))) { + restDB.setCustomerNameInTableByTicketId(dlSales.loadCustomerExt + (finder.getSelectedCustomer().getId()).toString(), m_oTicket.getId()); + } + + checkCustomer(); + + m_jTicketId.setText(m_oTicket.getName()); + + } catch (BasicException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.cannotfindcustomer"), e); + msg.show(this); + } + } else { + restDB.setCustomerNameInTableByTicketId(null, m_oTicket.getId()); + m_oTicket.setCustomer(null); + } + } + } + } + + refreshTicket(); + + }//GEN-LAST:event_jBtnCustomerActionPerformed + + private void m_jPanContainerFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_m_jPanContainerFocusLost + jPanContainerFocusLost(evt); + }//GEN-LAST:event_m_jPanContainerFocusLost + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btnReprint1; + private javax.swing.JButton btnSplit; + private javax.swing.JPanel catcontainer; + private javax.swing.Box.Filler filler2; + private javax.swing.JButton jBtnCustomer; + private javax.swing.JButton jCheckStock; + private javax.swing.JButton jEditAttributes; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JPanel jPanel9; + private javax.swing.JToggleButton jTBtnShow; + private javax.swing.JButton j_btnRemotePrt; + private javax.swing.JButton jbtnMooring; + private javax.swing.JPanel m_jButtons; + private javax.swing.JPanel m_jButtonsExt; + private javax.swing.JPanel m_jContEntries; + private javax.swing.JButton m_jDelete; + private javax.swing.JButton m_jEditLine; + private javax.swing.JButton m_jEnter; + private javax.swing.JTextField m_jKeyFactory; + private javax.swing.JLabel m_jLblTotalEuros1; + private javax.swing.JLabel m_jLblTotalEuros2; + private javax.swing.JLabel m_jLblTotalEuros3; + private javax.swing.JButton m_jList; + private com.unicenta.beans.JNumberKeys m_jNumberKeys; + private javax.swing.JPanel m_jOptions; + private javax.swing.JPanel m_jPanContainer; + private javax.swing.JPanel m_jPanEntries; + private javax.swing.JPanel m_jPanEntriesE; + private javax.swing.JPanel m_jPanTicket; + private javax.swing.JPanel m_jPanTotals; + private javax.swing.JPanel m_jPanelBag; + private javax.swing.JPanel m_jPanelCentral; + private javax.swing.JPanel m_jPanelScripts; + private javax.swing.JLabel m_jPor; + private javax.swing.JLabel m_jPrice; + private javax.swing.JLabel m_jSubtotalEuros; + private javax.swing.JComboBox m_jTax; + private javax.swing.JLabel m_jTaxesEuros; + private javax.swing.JLabel m_jTicketId; + private javax.swing.JLabel m_jTotalEuros; + private com.alee.extended.button.WebSwitch m_jaddtax; + private javax.swing.JButton m_jbtnScale; + // End of variables declaration//GEN-END:variables + +/* Remote Orders Display + We only know about uniCenta oPOS orders and won't try and handle any + that are injected from an external source +*/ + + public void remoteOrderDisplay() { + remoteOrderDisplay(remoteOrderId(), 1, true); + } + + public void remoteOrderDisplay(String id) { + remoteOrderDisplay(id, 1, true); + } + + public void remoteOrderDisplay(Integer display) { + remoteOrderDisplay(remoteOrderId(), display, false); + } + + public String remoteOrderId() { + + String id = ""; + + if ((m_oTicket.getCustomer() != null)) { + return m_oTicket.getCustomer().getName(); + } else if (m_oTicketExt != null) { + return m_oTicketExt.toString(); + } else { + if (m_oTicket.getPickupId() == 0) { + try { + m_oTicket.setPickupId(dlSales.getNextPickupIndex()); + } catch (BasicException e) { + m_oTicket.setPickupId(0); + } + } + + return getPickupString(m_oTicket); + } + } + + public void remoteOrderDisplay(String id, Integer display, boolean primary) { + + try { + // may use later if/when external order injection + // String orderUUID = UUID.randomUUID().toString(); + + dlSystem.deleteOrder(id); + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + + for (int i = 0; i < m_oTicket.getLinesCount(); i++) { + try { + if (primary) { + if ((m_oTicket.getLine(i).getProperty("display") == null) + || ("".equals(m_oTicket.getLine(i).getProperty("display")))) { + display = 1; + } else { + display = Integer.parseInt(m_oTicket.getLine(i).getProperty("display")); + } + } + + dlSystem.addOrder(getPickupString(m_oTicket) + , (int) m_oTicket.getLine(i).getMultiply() + , m_oTicket.getLine(i).getProductName() + , m_oTicket.getLine(i).getProductAttSetInstDesc() + , m_oTicket.getLine(i).getProperty("notes") + , id + , null + , display + , null + , null); + +/* this block for future - right now we're deleting all ticketlines + and resending for consistency with actual ticketlines + dlSystem.updateOrder(getPickupString(m_oTicket) + , (int) m_oTicket.getLine(i).getMultiply() + , m_oTicket.getLine(i).getProductName() + , m_oTicket.getLine(i).getProductAttSetInstDesc() + , m_oTicket.getLine(i).getProperty("notes") + , id + , null + , display + , null + , null); +*/ + + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + } + } + +} diff --git a/src/main/java/com/unicenta/pos/sales/JPanelTicketEdits.java b/src/main/java/com/unicenta/pos/sales/JPanelTicketEdits.java new file mode 100644 index 0000000..31516cf --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JPanelTicketEdits.java @@ -0,0 +1,126 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + + +package com.unicenta.pos.sales; + +import com.unicenta.basic.BasicException; +import com.unicenta.pos.ticket.ProductInfoExt; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.List; + + +/** + * + * @author JG uniCenta + */ +public class JPanelTicketEdits extends JPanelTicket { + + private JTicketCatalogLines m_catandlines; + + /** Creates a new instance of JPanelTicketRefunds */ + public JPanelTicketEdits() { + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return null; + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + super.activate(); + m_catandlines.loadCatalog(); + } + + public void reLoadCatalog(){ + } + + /** + * + */ + public void showCatalog() { + m_jbtnconfig.setVisible(true); + m_catandlines.showCatalog(); + } + + /** + * + * @param aRefundLines + */ + public void showRefundLines(List aRefundLines) { + // anado las lineas de refund + // m_reflines.setLines(aRefundLines); + m_jbtnconfig.setVisible(false); + m_catandlines.showRefundLines(aRefundLines); + } + + /** + * + * @return + */ + @Override + protected JTicketsBag getJTicketsBag() { + return new JTicketsBagTicket(m_App, this); + } + + /** + * + * @return + */ + @Override + protected Component getSouthComponent() { + + m_catandlines = new JTicketCatalogLines(m_App, this, + "true".equals(m_jbtnconfig.getProperty("pricevisible")), + "true".equals(m_jbtnconfig.getProperty("taxesincluded")), + Integer.parseInt(m_jbtnconfig.getProperty("img-width", "64")), + Integer.parseInt(m_jbtnconfig.getProperty("img-height", "54"))); + m_catandlines.setPreferredSize(new Dimension(0, + Integer.parseInt(m_jbtnconfig.getProperty("cat-height", "245")))); + m_catandlines.addActionListener(new CatalogListener()); + return m_catandlines; + } + + /** + * + */ + @Override + protected void resetSouthComponent() { + } + + private class CatalogListener implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + buttonTransition((ProductInfoExt) e.getSource()); + } + } + +} diff --git a/src/main/java/com/unicenta/pos/sales/JPanelTicketSales.java b/src/main/java/com/unicenta/pos/sales/JPanelTicketSales.java new file mode 100644 index 0000000..4bf2af0 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JPanelTicketSales.java @@ -0,0 +1,150 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; +import com.unicenta.basic.BasicException; +import com.unicenta.pos.catalog.CatalogSelector; +import com.unicenta.pos.catalog.JCatalog; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.ticket.ProductInfoExt; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +/** + * + * @author JG uniCenta + */ +public class JPanelTicketSales extends JPanelTicket { + + private CatalogSelector m_cat; + + /** Creates a new instance of JPanelTicketSales */ + public JPanelTicketSales() { + } + + /** + * + * @param app + */ + @Override + public void init(AppView app) { + super.init(app); + m_ticketlines.addListSelectionListener(new CatalogSelectionListener()); + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return null; + } + + /** + * + * @return + */ + @Override + protected Component getSouthComponent() { + m_cat = new JCatalog(dlSales, + "true".equals(m_jbtnconfig.getProperty("pricevisible")), + "true".equals(m_jbtnconfig.getProperty("taxesincluded")), + Integer.parseInt(m_jbtnconfig.getProperty("img-width", "64")), + Integer.parseInt(m_jbtnconfig.getProperty("img-height", "54"))); + // Integer.parseInt(m_jbtnconfig.getProperty("img-width", "32")), + // Integer.parseInt(m_jbtnconfig.getProperty("img-height", "32"))); + m_cat.addActionListener(new CatalogListener()); + m_cat.getComponent().setPreferredSize(new Dimension( + 0, + Integer.parseInt(m_jbtnconfig.getProperty("cat-height", "245")))); + return m_cat.getComponent(); + } + + /** + * + */ + @Override + protected void resetSouthComponent() { + m_cat.showCatalogPanel(null); + } + + /** + * + * @return + */ + @Override + protected JTicketsBag getJTicketsBag() { + return JTicketsBag.createTicketsBag(m_App.getProperties().getProperty("machine.ticketsbag"), m_App, this); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + super.activate(); + m_cat.loadCatalog(); + } + + public void reLoadCatalog() { + try { + m_cat.loadCatalog(); + } catch (BasicException ex) { + } + + } + + private class CatalogListener implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + buttonTransition((ProductInfoExt) e.getSource()); + } + } + + private class CatalogSelectionListener implements ListSelectionListener { + @Override + public void valueChanged(ListSelectionEvent e) { + + if (!e.getValueIsAdjusting()) { + int i = m_ticketlines.getSelectedIndex(); + + if (i >= 0) { + // Look for the first non auxiliar product. + while (i >= 0 && m_oTicket.getLine(i).isProductCom()) { + i--; + } + + // Show the accurate catalog panel... + if (i >= 0) { + m_cat.showCatalogPanel(m_oTicket.getLine(i).getProductID()); + } else { + m_cat.showCatalogPanel(null); + } + } + } + } + } + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/sales/JProductAttEdit.form b/src/main/java/com/unicenta/pos/sales/JProductAttEdit.form new file mode 100644 index 0000000..fbed0be --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JProductAttEdit.form @@ -0,0 +1,149 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-124,0,0,2,-110"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="3"/> + </Layout> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="1"/> + </Layout> + <SubComponents> + <Component class="com.unicenta.editor.JEditorKeys" name="m_jKeys"> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Last"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="2"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="m_jButtonCancel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.cancel" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jButtonCancelActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jButtonOK"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.OK" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jButtonOKActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/JProductAttEdit.java b/src/main/java/com/unicenta/pos/sales/JProductAttEdit.java new file mode 100644 index 0000000..efb1a0f --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JProductAttEdit.java @@ -0,0 +1,426 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.*; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.inventory.AttributeSetInfo; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * @author adrianromero + */ +@Slf4j +public class JProductAttEdit extends javax.swing.JDialog { + + private SentenceFind attsetSent; + private SentenceList attvaluesSent; + private SentenceList attinstSent; + private SentenceList attinstSent2; + private SentenceFind attsetinstExistsSent; + + private SentenceExec attsetSave; + private SentenceExec attinstSave; + + private List<JProductAttEditI> itemslist; + private String attsetid; + private String attInstanceId; + private String attInstanceDescription; + + private boolean ok; + + /** + * Creates new form JProductAttEdit + */ + private JProductAttEdit(java.awt.Frame parent, boolean modal) { + super(parent, modal); + } + + /** + * Creates new form JProductAttEdit + */ + private JProductAttEdit(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + } + + private void init(Session s) { + + initComponents(); + + attsetSave = new PreparedSentence(s, + "INSERT INTO attributesetinstance (ID, ATTRIBUTESET_ID, DESCRIPTION) VALUES (?, ?, ?)", + new SerializerWriteBasic(Datas.STRING, Datas.STRING, Datas.STRING)); + attinstSave = new PreparedSentence(s, + "INSERT INTO attributeinstance(ID, ATTRIBUTESETINSTANCE_ID, ATTRIBUTE_ID, VALUE) VALUES (?, ?, ?, ?)", + new SerializerWriteBasic(Datas.STRING, Datas.STRING, Datas.STRING, Datas.STRING)); + + attsetSent = new PreparedSentence(s, + "SELECT ID, NAME FROM attributeset WHERE ID = ?", + SerializerWriteString.INSTANCE, + new SerializerRead() { + @Override + public Object readValues(DataRead dr) throws BasicException { + return new AttributeSetInfo(dr.getString(1), dr.getString(2)); + } + }); + attsetinstExistsSent = new PreparedSentence(s, + "SELECT ID FROM attributesetinstance WHERE ATTRIBUTESET_ID = ? AND DESCRIPTION = ?", + new SerializerWriteBasic(Datas.STRING, Datas.STRING), + SerializerReadString.INSTANCE); + + attinstSent = new PreparedSentence(s, "SELECT A.ID, A.NAME, " + s.DB.CHAR_NULL() + ", " + s.DB.CHAR_NULL() + " " + + "FROM attributeuse AU JOIN attribute A ON AU.ATTRIBUTE_ID = A.ID " + + "WHERE AU.ATTRIBUTESET_ID = ? " + + "ORDER BY AU.LINENO", + SerializerWriteString.INSTANCE, + new SerializerRead() { + @Override + public Object readValues(DataRead dr) throws BasicException { + return new AttributeInstInfo(dr.getString(1), dr.getString(2), dr.getString(3), dr.getString(4)); + } + }); + attinstSent2 = new PreparedSentence(s, "SELECT A.ID, A.NAME, AI.ID, AI.VALUE " + + "FROM attributeuse AU JOIN attribute A ON AU.ATTRIBUTE_ID = A.ID LEFT OUTER JOIN attributeinstance AI ON AI.ATTRIBUTE_ID = A.ID " + + "WHERE AU.ATTRIBUTESET_ID = ? AND AI.ATTRIBUTESETINSTANCE_ID = ?" + + "ORDER BY AU.LINENO", + new SerializerWriteBasic(Datas.STRING, Datas.STRING), + new SerializerRead() { + @Override + public Object readValues(DataRead dr) throws BasicException { + return new AttributeInstInfo(dr.getString(1), dr.getString(2), dr.getString(3), dr.getString(4)); + } + }); + attvaluesSent = new PreparedSentence(s, "SELECT VALUE FROM attributevalue WHERE ATTRIBUTE_ID = ? ORDER BY VALUE", + SerializerWriteString.INSTANCE, + SerializerReadString.INSTANCE); + + getRootPane().setDefaultButton(m_jButtonOK); + } + + /** + * @param parent + * @param s + * @return + */ + public static JProductAttEdit getAttributesEditor(Component parent, Session s) { + + Window window = SwingUtilities.getWindowAncestor(parent); + + JProductAttEdit myMsg; + if (window instanceof Frame) { + myMsg = new JProductAttEdit((Frame) window, true); + } else { + myMsg = new JProductAttEdit((Dialog) window, true); + } + myMsg.init(s); + myMsg.applyComponentOrientation(parent.getComponentOrientation()); + return myMsg; + } + + /** + * @param attsetid + * @param attsetinstid + * @throws BasicException + */ + public void editAttributes(String attsetid, String attsetinstid) throws BasicException { + + if (attsetid == null) { +// throw new BasicException(AppLocal.getIntString("message.attsetnotexists")); + throw new BasicException(AppLocal.getIntString("message.cannotfindattributes")); + } else { + + this.attsetid = attsetid; + this.attInstanceId = null; + this.attInstanceDescription = null; + + this.ok = false; + + // get attsetinst values + AttributeSetInfo asi = (AttributeSetInfo) attsetSent.find(attsetid); + + if (asi == null) { +// throw new BasicException(AppLocal.getIntString("message.attsetnotexists")); + throw new BasicException(AppLocal.getIntString("message.cannotfindattributes")); + } + + setTitle(asi.getName()); + + List<AttributeInstInfo> attinstinfo = attsetinstid == null + ? attinstSent.list(attsetid) + : attinstSent2.list(attsetid, attsetinstid); + + itemslist = new ArrayList<>(); + + for (AttributeInstInfo aii : attinstinfo) { + + JProductAttEditI item; + + List<String> values = attvaluesSent.list(aii.getAttid()); + if (values.isEmpty()) { + // Does not exist a list of values then a textfield + item = new JProductAttEditItem(aii.getAttid(), aii.getAttname(), aii.getValue(), m_jKeys); + } else { + // Does exist a list with the values + item = new JProductAttListItem(aii.getAttid(), aii.getAttname(), aii.getValue(), values); + } + + itemslist.add(item); + jPanel2.add(item.getComponent()); + } + + if (itemslist.size() > 0) { + itemslist.get(0).assignSelection(); + } + } + } + + /** + * @return + */ + public boolean isOK() { + return ok; + } + + /** + * @return + */ + public String getAttributeSetInst() { + return attInstanceId; + } + + /** + * @return + */ + public String getAttributeSetInstDescription() { + return attInstanceDescription; + } + + private static class AttributeInstInfo { + + private String attid; + private String attname; + private String id; + private String value; + + public AttributeInstInfo(String attid, String attname, String id, String value) { + this.attid = attid; + this.attname = attname; + this.id = id; + this.value = value; + } + + /** + * @return the attid + */ + public String getAttid() { + return attid; + } + + /** + * @return the attname + */ + public String getAttname() { + return attname; + } + + /** + * @return the id + */ + public String getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(String id) { + this.id = id; + } + + /** + * @return the value + */ + public String getValue() { + return value; + } + + /** + * @param value the value to set + */ + public void setValue(String value) { + this.value = value; + } + } + + /** + * This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel5 = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + jPanel3 = new javax.swing.JPanel(); + jPanel4 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel1 = new javax.swing.JPanel(); + m_jButtonCancel = new javax.swing.JButton(); + m_jButtonOK = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + + jPanel5.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel5.setLayout(new java.awt.BorderLayout()); + + jPanel2.setLayout(new javax.swing.BoxLayout(jPanel2, javax.swing.BoxLayout.PAGE_AXIS)); + jPanel5.add(jPanel2, java.awt.BorderLayout.NORTH); + + getContentPane().add(jPanel5, java.awt.BorderLayout.CENTER); + + jPanel3.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel3.setLayout(new java.awt.BorderLayout()); + + jPanel4.setLayout(new javax.swing.BoxLayout(jPanel4, javax.swing.BoxLayout.Y_AXIS)); + jPanel4.add(m_jKeys); + + jPanel3.add(jPanel4, java.awt.BorderLayout.NORTH); + + jPanel1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT)); + + m_jButtonCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jButtonCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + m_jButtonCancel.setText(AppLocal.getIntString("button.cancel")); // NOI18N + m_jButtonCancel.setFocusPainted(false); + m_jButtonCancel.setFocusable(false); + m_jButtonCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jButtonCancel.setPreferredSize(new java.awt.Dimension(110, 45)); + m_jButtonCancel.setRequestFocusEnabled(false); + m_jButtonCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jButtonCancelActionPerformed(evt); + } + }); + jPanel1.add(m_jButtonCancel); + + m_jButtonOK.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jButtonOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + m_jButtonOK.setText(AppLocal.getIntString("button.OK")); // NOI18N + m_jButtonOK.setFocusPainted(false); + m_jButtonOK.setFocusable(false); + m_jButtonOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jButtonOK.setPreferredSize(new java.awt.Dimension(110, 45)); + m_jButtonOK.setRequestFocusEnabled(false); + m_jButtonOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jButtonOKActionPerformed(evt); + } + }); + jPanel1.add(m_jButtonOK); + + jPanel3.add(jPanel1, java.awt.BorderLayout.PAGE_END); + + getContentPane().add(jPanel3, java.awt.BorderLayout.EAST); + + setSize(new java.awt.Dimension(658, 388)); + setLocationRelativeTo(null); + }// </editor-fold>//GEN-END:initComponents + + private void m_jButtonOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jButtonOKActionPerformed + + StringBuilder description = new StringBuilder(); + for (JProductAttEditI item : itemslist) { + String value = item.getValue(); + if (value != null && value.length() > 0) { + if (description.length() > 0) { + description.append(", "); + } + description.append(value); + } + } + + String id; + + if (description.length() == 0) { + // No values then id is null + id = null; + } else { + // Some values then an instance should exists. + try { + // Exist an attribute set instance with these values for the attributeset selected + id = (String) attsetinstExistsSent.find(attsetid, description.toString()); + } catch (BasicException ex) { + log.error(ex.getMessage()); + return; + } + + + if (id == null) { + // No, create a new ATTRIBUTESETINSTANCE and return the ID generated + // or return null... That means that that product does not exists.... + // Maybe these two modes must be supported one for selection and other for creation.... + id = UUID.randomUUID().toString(); + try { + attsetSave.exec(id, attsetid, description.toString()); + for (JProductAttEditI item : itemslist) { + attinstSave.exec(UUID.randomUUID().toString(), id, item.getAttribute(), item.getValue()); + } + + } catch (BasicException ex) { + log.error(ex.getMessage()); + return; + } + } + } + + ok = true; + attInstanceId = id; + attInstanceDescription = description.toString(); + + dispose(); + }//GEN-LAST:event_m_jButtonOKActionPerformed + + private void m_jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jButtonCancelActionPerformed + + dispose(); + }//GEN-LAST:event_m_jButtonCancelActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JButton m_jButtonCancel; + private javax.swing.JButton m_jButtonOK; + private com.unicenta.editor.JEditorKeys m_jKeys; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/JProductAttEdit1.form b/src/main/java/com/unicenta/pos/sales/JProductAttEdit1.form new file mode 100644 index 0000000..fbed0be --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JProductAttEdit1.form @@ -0,0 +1,149 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-124,0,0,2,-110"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="3"/> + </Layout> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="1"/> + </Layout> + <SubComponents> + <Component class="com.unicenta.editor.JEditorKeys" name="m_jKeys"> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Last"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="2"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="m_jButtonCancel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.cancel" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jButtonCancelActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jButtonOK"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.OK" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jButtonOKActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/JProductAttEdit1.java b/src/main/java/com/unicenta/pos/sales/JProductAttEdit1.java new file mode 100644 index 0000000..09ddfe7 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JProductAttEdit1.java @@ -0,0 +1,427 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.*; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.inventory.AttributeSetInfo; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * @author adrianromero + */ +@Slf4j +public class JProductAttEdit1 extends javax.swing.JDialog { + + private SentenceFind attsetSent; + private SentenceList attvaluesSent; + private SentenceList attinstSent; + private SentenceList attinstSent2; + private SentenceFind attsetinstExistsSent; + + private SentenceExec attsetSave; + private SentenceExec attinstSave; + + private List<JProductAttEditI> itemslist; + private String attsetid; + private String attInstanceId; + private String attInstanceDescription; + + private boolean ok; + + /** + * Creates new form JProductAttEdit + */ + private JProductAttEdit1(java.awt.Frame parent, boolean modal) { + super(parent, modal); + } + + /** + * Creates new form JProductAttEdit + */ + private JProductAttEdit1(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + } + + private void init(Session s) { + + initComponents(); + + attsetSave = new PreparedSentence(s, + "INSERT INTO attributesetinstance (ID, ATTRIBUTESET_ID, DESCRIPTION) VALUES (?, ?, ?)", + new SerializerWriteBasic(Datas.STRING, Datas.STRING, Datas.STRING)); + attinstSave = new PreparedSentence(s, + "INSERT INTO attributeinstance(ID, ATTRIBUTESETINSTANCE_ID, ATTRIBUTE_ID, VALUE) VALUES (?, ?, ?, ?)", + new SerializerWriteBasic(Datas.STRING, Datas.STRING, Datas.STRING, Datas.STRING)); + + attsetSent = new PreparedSentence(s, + "SELECT ID, NAME FROM attributeset WHERE ID = ?", + SerializerWriteString.INSTANCE, + new SerializerRead() { + @Override + public Object readValues(DataRead dr) throws BasicException { + return new AttributeSetInfo(dr.getString(1), dr.getString(2)); + } + }); + attsetinstExistsSent = new PreparedSentence(s, + "SELECT ID FROM attributesetinstance WHERE ATTRIBUTESET_ID = ? AND DESCRIPTION = ?", + new SerializerWriteBasic(Datas.STRING, Datas.STRING), + SerializerReadString.INSTANCE); + + attinstSent = new PreparedSentence(s, "SELECT A.ID, A.NAME, " + s.DB.CHAR_NULL() + ", " + s.DB.CHAR_NULL() + " " + + "FROM attributeuse AU JOIN ATTRIBUTE A ON AU.ATTRIBUTE_ID = A.ID " + + "WHERE AU.ATTRIBUTESET_ID = ? " + + "ORDER BY AU.LINENO", + SerializerWriteString.INSTANCE, + new SerializerRead() { + @Override + public Object readValues(DataRead dr) throws BasicException { + return new AttributeInstInfo(dr.getString(1), dr.getString(2), dr.getString(3), dr.getString(4)); + } + }); + attinstSent2 = new PreparedSentence(s, "SELECT A.ID, A.NAME, AI.ID, AI.VALUE " + + "FROM attributeuse AU JOIN ATTRIBUTE A ON AU.ATTRIBUTE_ID = A.ID LEFT OUTER JOIN attributeinstance AI ON AI.ATTRIBUTE_ID = A.ID " + + "WHERE AU.ATTRIBUTESET_ID = ? AND AI.ATTRIBUTESETINSTANCE_ID = ?" + + "ORDER BY AU.LINENO", + new SerializerWriteBasic(Datas.STRING, Datas.STRING), + new SerializerRead() { + @Override + public Object readValues(DataRead dr) throws BasicException { + return new AttributeInstInfo(dr.getString(1), dr.getString(2), dr.getString(3), dr.getString(4)); + } + }); + attvaluesSent = new PreparedSentence(s, "SELECT VALUE FROM attributevalue WHERE ATTRIBUTE_ID = ? ORDER BY VALUE", + SerializerWriteString.INSTANCE, + SerializerReadString.INSTANCE); + + getRootPane().setDefaultButton(m_jButtonOK); + } + + /** + * @param parent + * @param s + * @return + */ + public static JProductAttEdit1 getAttributesEditor(Component parent, Session s) { + + Window window = SwingUtilities.getWindowAncestor(parent); + + JProductAttEdit1 myMsg; + if (window instanceof Frame) { + myMsg = new JProductAttEdit1((Frame) window, true); + } else { + myMsg = new JProductAttEdit1((Dialog) window, true); + } + myMsg.init(s); + myMsg.applyComponentOrientation(parent.getComponentOrientation()); + return myMsg; + } + + /** + * @param attsetid + * @param attsetinstid + * @throws BasicException + */ + public void editAttributes(String attsetid, String attsetinstid) throws BasicException { + + if (attsetid == null) { +// throw new BasicException(AppLocal.getIntString("message.attsetnotexists")); + throw new BasicException(AppLocal.getIntString("message.cannotfindattributes")); + } else { + + this.attsetid = attsetid; + this.attInstanceId = null; + this.attInstanceDescription = null; + + this.ok = false; + + // get attsetinst values + AttributeSetInfo asi = (AttributeSetInfo) attsetSent.find(attsetid); + + if (asi == null) { +// throw new BasicException(AppLocal.getIntString("message.attsetnotexists")); + throw new BasicException(AppLocal.getIntString("message.cannotfindattributes")); + } + + setTitle(asi.getName()); + + List<AttributeInstInfo> attinstinfo = attsetinstid == null + ? attinstSent.list(attsetid) + : attinstSent2.list(attsetid, attsetinstid); + + itemslist = new ArrayList<>(); + + for (AttributeInstInfo aii : attinstinfo) { + + JProductAttEditI item; + + List<String> values = attvaluesSent.list(aii.getAttid()); + if (values.isEmpty()) { + // Does not exist a list of values then a textfield + item = new JProductAttEditItem(aii.getAttid(), aii.getAttname(), aii.getValue(), m_jKeys); + } else { + // Does exist a list with the values + item = new JProductAttListItem(aii.getAttid(), aii.getAttname(), aii.getValue(), values); + } + + itemslist.add(item); + jPanel2.add(item.getComponent()); + } + + if (itemslist.size() > 0) { + itemslist.get(0).assignSelection(); + } + } + } + + /** + * @return + */ + public boolean isOK() { + return ok; + } + + /** + * @return + */ + public String getAttributeSetInst() { + return attInstanceId; + } + + /** + * @return + */ + public String getAttributeSetInstDescription() { + return attInstanceDescription; + } + + private static class AttributeInstInfo { + + private String attid; + private String attname; + private String id; + private String value; + + public AttributeInstInfo(String attid, String attname, String id, String value) { + this.attid = attid; + this.attname = attname; + this.id = id; + this.value = value; + } + + /** + * @return the attid + */ + public String getAttid() { + return attid; + } + + /** + * @return the attname + */ + public String getAttname() { + return attname; + } + + /** + * @return the id + */ + public String getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(String id) { + this.id = id; + } + + /** + * @return the value + */ + public String getValue() { + return value; + } + + /** + * @param value the value to set + */ + public void setValue(String value) { + this.value = value; + } + } + + /** + * This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel5 = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + jPanel3 = new javax.swing.JPanel(); + jPanel4 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel1 = new javax.swing.JPanel(); + m_jButtonCancel = new javax.swing.JButton(); + m_jButtonOK = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + + jPanel5.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel5.setLayout(new java.awt.BorderLayout()); + + jPanel2.setLayout(new javax.swing.BoxLayout(jPanel2, javax.swing.BoxLayout.PAGE_AXIS)); + jPanel5.add(jPanel2, java.awt.BorderLayout.NORTH); + + getContentPane().add(jPanel5, java.awt.BorderLayout.CENTER); + + jPanel3.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel3.setLayout(new java.awt.BorderLayout()); + + jPanel4.setLayout(new javax.swing.BoxLayout(jPanel4, javax.swing.BoxLayout.Y_AXIS)); + jPanel4.add(m_jKeys); + + jPanel3.add(jPanel4, java.awt.BorderLayout.NORTH); + + jPanel1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT)); + + m_jButtonCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jButtonCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + m_jButtonCancel.setText(AppLocal.getIntString("button.cancel")); // NOI18N + m_jButtonCancel.setFocusPainted(false); + m_jButtonCancel.setFocusable(false); + m_jButtonCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jButtonCancel.setPreferredSize(new java.awt.Dimension(110, 45)); + m_jButtonCancel.setRequestFocusEnabled(false); + m_jButtonCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jButtonCancelActionPerformed(evt); + } + }); + jPanel1.add(m_jButtonCancel); + + m_jButtonOK.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jButtonOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + m_jButtonOK.setText(AppLocal.getIntString("button.OK")); // NOI18N + m_jButtonOK.setFocusPainted(false); + m_jButtonOK.setFocusable(false); + m_jButtonOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jButtonOK.setPreferredSize(new java.awt.Dimension(110, 45)); + m_jButtonOK.setRequestFocusEnabled(false); + m_jButtonOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jButtonOKActionPerformed(evt); + } + }); + jPanel1.add(m_jButtonOK); + + jPanel3.add(jPanel1, java.awt.BorderLayout.PAGE_END); + + getContentPane().add(jPanel3, java.awt.BorderLayout.EAST); + + setSize(new java.awt.Dimension(658, 388)); + setLocationRelativeTo(null); + }// </editor-fold>//GEN-END:initComponents + + private void m_jButtonOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jButtonOKActionPerformed + + StringBuilder description = new StringBuilder(); + for (JProductAttEditI item : itemslist) { + String value = item.getValue(); + if (value != null && value.length() > 0) { + if (description.length() > 0) { + description.append(", "); + } + description.append(value); + } + } + + + String id; + + if (description.length() == 0) { + // No values then id is null + id = null; + } else { + // Some values then an instance should exists. + try { + // Exist an attribute set instance with these values for the attributeset selected + id = (String) attsetinstExistsSent.find(attsetid, description.toString()); + } catch (BasicException ex) { + log.error(ex.getMessage()); + return; + } + + + if (id == null) { + // No, create a new ATTRIBUTESETINSTANCE and return the ID generated + // or return null... That means that that product does not exists.... + // Maybe these two modes must be supported one for selection and other for creation.... + id = UUID.randomUUID().toString(); + try { + attsetSave.exec(id, attsetid, description.toString()); + for (JProductAttEditI item : itemslist) { + attinstSave.exec(UUID.randomUUID().toString(), id, item.getAttribute(), item.getValue()); + } + + } catch (BasicException ex) { + log.error(ex.getMessage()); + return; + } + } + } + + ok = true; + attInstanceId = id; + attInstanceDescription = description.toString(); + + dispose(); + }//GEN-LAST:event_m_jButtonOKActionPerformed + + private void m_jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jButtonCancelActionPerformed + + dispose(); + }//GEN-LAST:event_m_jButtonCancelActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JButton m_jButtonCancel; + private javax.swing.JButton m_jButtonOK; + private com.unicenta.editor.JEditorKeys m_jKeys; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/JProductAttEdit2.form b/src/main/java/com/unicenta/pos/sales/JProductAttEdit2.form new file mode 100644 index 0000000..c92e874 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JProductAttEdit2.form @@ -0,0 +1,152 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 250]"/> + </Property> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-124,0,0,2,-112"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="3"/> + </Layout> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="1"/> + </Layout> + <SubComponents> + <Component class="com.unicenta.editor.JEditorKeys" name="m_jKeys"> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Last"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="2"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="m_jButtonCancel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.cancel" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jButtonCancelActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jButtonOK"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.OK" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jButtonOKActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/JProductAttEdit2.java b/src/main/java/com/unicenta/pos/sales/JProductAttEdit2.java new file mode 100644 index 0000000..39d5099 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JProductAttEdit2.java @@ -0,0 +1,426 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.loader.PreparedSentence; +import com.unicenta.data.loader.SentenceExec; +import com.unicenta.data.loader.SentenceFind; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.loader.SerializerRead; +import com.unicenta.data.loader.SerializerReadString; +import com.unicenta.data.loader.SerializerWriteBasic; +import com.unicenta.data.loader.SerializerWriteString; +import com.unicenta.data.loader.Session; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.inventory.AttributeSetInfo; +import lombok.extern.slf4j.Slf4j; + +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.Window; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import javax.swing.SwingUtilities; + +/** + * @author adrianromero + */ +@Slf4j +public class JProductAttEdit2 extends javax.swing.JDialog { + + private SentenceFind attsetSent; + private SentenceList attvaluesSent; + private SentenceList attinstSent; + private SentenceList attinstSent2; + private SentenceFind attsetinstExistsSent; + + private SentenceExec attsetSave; + private SentenceExec attinstSave; + + private List<JProductAttEditI> itemslist; + private String attsetid; + private String attInstanceId; + private String attInstanceDescription; + + private boolean ok; + + /** + * Creates new form JProductAttEdit + */ + private JProductAttEdit2(java.awt.Frame parent, boolean modal) { + super(parent, modal); + } + + /** + * Creates new form JProductAttEdit + */ + private JProductAttEdit2(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + } + + private void init(Session s) { + + initComponents(); + + attsetSave = new PreparedSentence(s, + "INSERT INTO attributesetinstance (ID, ATTRIBUTESET_ID, DESCRIPTION) VALUES (?, ?, ?)", + new SerializerWriteBasic(Datas.STRING, Datas.STRING, Datas.STRING)); + attinstSave = new PreparedSentence(s, + "INSERT INTO attributeinstance(ID, ATTRIBUTESETINSTANCE_ID, ATTRIBUTE_ID, VALUE) VALUES (?, ?, ?, ?)", + new SerializerWriteBasic(Datas.STRING, Datas.STRING, Datas.STRING, Datas.STRING)); + + attsetSent = new PreparedSentence(s, + "SELECT ID, NAME FROM attributeset WHERE ID = ?", + SerializerWriteString.INSTANCE, + (DataRead dr) -> new AttributeSetInfo(dr.getString(1), dr.getString(2))); + attsetinstExistsSent = new PreparedSentence(s, +// "SELECT ID FROM attributesetinstance WHERE ATTRIBUTESET_ID = ? AND DESCRIPTION = ?", + "SELECT ID, DESCRIPTION FROM attributesetinstance WHERE ATTRIBUTESET_ID = ? AND DESCRIPTION = ?", + new SerializerWriteBasic(Datas.STRING, Datas.STRING), + SerializerReadString.INSTANCE); + + attinstSent = new PreparedSentence(s, "SELECT A.ID, A.NAME, " + s.DB.CHAR_NULL() + ", " + s.DB.CHAR_NULL() + " " + + "FROM attributeuse AU JOIN attribute A ON AU.ATTRIBUTE_ID = A.ID " + + "WHERE AU.ATTRIBUTESET_ID = ? " + + "ORDER BY AU.LINENO", + SerializerWriteString.INSTANCE, + (DataRead dr) -> new AttributeInstInfo(dr.getString(1), dr.getString(2), dr.getString(3), dr.getString(4))); + attinstSent2 = new PreparedSentence(s, "SELECT A.ID, A.NAME, AI.ID, AI.VALUE " + + "FROM attributeuse AU JOIN attribute A ON AU.ATTRIBUTE_ID = A.ID LEFT OUTER JOIN attributeinstance AI ON AI.ATTRIBUTE_ID = A.ID " + + "WHERE AU.ATTRIBUTESET_ID = ? AND AI.ATTRIBUTESETINSTANCE_ID = ?" + + "ORDER BY AU.LINENO", + new SerializerWriteBasic(Datas.STRING, Datas.STRING), + (DataRead dr) -> new AttributeInstInfo(dr.getString(1), dr.getString(2), dr.getString(3), dr.getString(4))); + attvaluesSent = new PreparedSentence(s, "SELECT VALUE FROM attributevalue WHERE ATTRIBUTE_ID = ? ORDER BY VALUE", + SerializerWriteString.INSTANCE, + SerializerReadString.INSTANCE); + + getRootPane().setDefaultButton(m_jButtonOK); + } + + /** + * @param parent + * @param s + * @return + */ + public static JProductAttEdit2 getAttributesEditor(Component parent, Session s) { + + Window window = SwingUtilities.getWindowAncestor(parent); + + JProductAttEdit2 myMsg; + if (window instanceof Frame) { + myMsg = new JProductAttEdit2((Frame) window, true); + } else { + myMsg = new JProductAttEdit2((Dialog) window, true); + } + myMsg.init(s); + myMsg.applyComponentOrientation(parent.getComponentOrientation()); + return myMsg; + } + + /** + * @param attsetid + * @param attsetinstid + * @throws BasicException + */ + public void editAttributes(String attsetid, String attsetinstid) throws BasicException { + + if (attsetid == null) { +// throw new BasicException(AppLocal.getIntString("message.attsetnotexists")); + throw new BasicException(AppLocal.getIntString("message.cannotfindattributes")); + } else { + + this.attsetid = attsetid; + this.attInstanceId = null; + this.attInstanceDescription = null; + + this.ok = false; + + // get attsetinst values + AttributeSetInfo asi = (AttributeSetInfo) attsetSent.find(attsetid); + + if (asi == null) { +// throw new BasicException(AppLocal.getIntString("message.attsetnotexists")); + throw new BasicException(AppLocal.getIntString("message.cannotfindattributes")); + } + + setTitle(asi.getName()); + + List<AttributeInstInfo> attinstinfo = attsetinstid == null + ? attinstSent.list(attsetid) + : attinstSent2.list(attsetid, attsetinstid); + + itemslist = new ArrayList<>(); + + for (AttributeInstInfo aii : attinstinfo) { + + JProductAttEditI item; + + List<String> values = attvaluesSent.list(aii.getAttid()); + if (values.isEmpty()) { + // Does not exist a list of values then a textfield + item = new JProductAttEditItem(aii.getAttid(), aii.getAttname(), aii.getValue(), m_jKeys); + } else { + // Does exist a list with the values + item = new JProductAttListItem(aii.getAttid(), aii.getAttname(), aii.getValue(), values); + } + + itemslist.add(item); + jPanel2.add(item.getComponent()); + } + + if (itemslist.size() > 0) { + itemslist.get(0).assignSelection(); + } + } + } + + /** + * @return + */ + public boolean isOK() { + return ok; + } + + /** + * @return + */ + public String getAttributeSetInst() { + return attInstanceId; + } + + /** + * @return + */ + public String getAttributeSetInstDescription() { + return attInstanceDescription; + } + + private static class AttributeInstInfo { + + private final String attid; + private final String attname; + private String id; + private String value; + + public AttributeInstInfo(String attid, String attname, String id, String value) { + this.attid = attid; + this.attname = attname; + this.id = id; + this.value = value; + } + + /** + * @return the attid + */ + public String getAttid() { + return attid; + } + + /** + * @return the attname + */ + public String getAttname() { + return attname; + } + + /** + * @return the id + */ + public String getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(String id) { + this.id = id; + } + + /** + * @return the value + */ + public String getValue() { + return value; + } + + /** + * @param value the value to set + */ + public void setValue(String value) { + this.value = value; + } + } + + /** + * This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel5 = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + jPanel3 = new javax.swing.JPanel(); + jPanel4 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel1 = new javax.swing.JPanel(); + m_jButtonCancel = new javax.swing.JButton(); + m_jButtonOK = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setPreferredSize(new java.awt.Dimension(300, 250)); + + jPanel5.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel5.setLayout(new java.awt.BorderLayout()); + + jPanel2.setLayout(new javax.swing.BoxLayout(jPanel2, javax.swing.BoxLayout.PAGE_AXIS)); + jPanel5.add(jPanel2, java.awt.BorderLayout.NORTH); + + getContentPane().add(jPanel5, java.awt.BorderLayout.CENTER); + + jPanel3.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel3.setLayout(new java.awt.BorderLayout()); + + jPanel4.setLayout(new javax.swing.BoxLayout(jPanel4, javax.swing.BoxLayout.Y_AXIS)); + jPanel4.add(m_jKeys); + + jPanel3.add(jPanel4, java.awt.BorderLayout.NORTH); + + jPanel1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT)); + + m_jButtonCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jButtonCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + m_jButtonCancel.setText(AppLocal.getIntString("button.cancel")); // NOI18N + m_jButtonCancel.setFocusPainted(false); + m_jButtonCancel.setFocusable(false); + m_jButtonCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jButtonCancel.setPreferredSize(new java.awt.Dimension(110, 45)); + m_jButtonCancel.setRequestFocusEnabled(false); + m_jButtonCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jButtonCancelActionPerformed(evt); + } + }); + jPanel1.add(m_jButtonCancel); + + m_jButtonOK.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jButtonOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + m_jButtonOK.setText(AppLocal.getIntString("button.OK")); // NOI18N + m_jButtonOK.setFocusPainted(false); + m_jButtonOK.setFocusable(false); + m_jButtonOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jButtonOK.setPreferredSize(new java.awt.Dimension(110, 45)); + m_jButtonOK.setRequestFocusEnabled(false); + m_jButtonOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jButtonOKActionPerformed(evt); + } + }); + jPanel1.add(m_jButtonOK); + + jPanel3.add(jPanel1, java.awt.BorderLayout.PAGE_END); + + getContentPane().add(jPanel3, java.awt.BorderLayout.EAST); + + setSize(new java.awt.Dimension(656, 388)); + setLocationRelativeTo(null); + }// </editor-fold>//GEN-END:initComponents + + private void m_jButtonOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jButtonOKActionPerformed + + StringBuilder description = new StringBuilder(); + itemslist.stream().map((item) -> item.getValue()) + .filter((value) -> (value != null && value.length() > 0)) + .forEach((value) -> { + if (description.length() > 0) { + description.append(", "); + } + description.append(value); + }); + + String id; + + if (description.length() == 0) { + id = null; + } else { + + try { + + id = (String) attsetinstExistsSent.find(attsetid, description.toString()); + + } catch (BasicException ex) { + return; + } + + if (id == null) { +// if (id == null ? (String.valueOf(description)) != null : !id.equals(String.valueOf(description))) { + // Now creates a new ATTRIBUTESETINSTANCE and returns the ID generated + // to allow for ad-hoc user input i.e.: Serial No + + id = UUID.randomUUID().toString(); + + try { + attsetSave.exec(id, attsetid, description.toString()); + + for (JProductAttEditI item : itemslist) { + attinstSave.exec(UUID.randomUUID().toString(), id, item.getAttribute(), item.getValue()); + } + + } catch (BasicException ex) { + log.error(ex.getMessage()); + return; + } + } + } + + ok = true; + attInstanceId = id; + attInstanceDescription = description.toString(); + + dispose(); + }//GEN-LAST:event_m_jButtonOKActionPerformed + + private void m_jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jButtonCancelActionPerformed + + dispose(); + }//GEN-LAST:event_m_jButtonCancelActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JButton m_jButtonCancel; + private javax.swing.JButton m_jButtonOK; + private com.unicenta.editor.JEditorKeys m_jKeys; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/JProductAttEditI.java b/src/main/java/com/unicenta/pos/sales/JProductAttEditI.java new file mode 100644 index 0000000..9137942 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JProductAttEditI.java @@ -0,0 +1,52 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import java.awt.Component; + +/** + * + * @author adrianromero + */ +public interface JProductAttEditI { + + /** + * + * @return + */ + public String getAttribute(); + + /** + * + * @return + */ + public String getValue(); + + /** + * + * @return + */ + public Component getComponent(); + + /** + * + */ + public void assignSelection(); +} diff --git a/src/main/java/com/unicenta/pos/sales/JProductAttEditItem.form b/src/main/java/com/unicenta/pos/sales/JProductAttEditItem.form new file mode 100644 index 0000000..afe6b9f --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JProductAttEditItem.form @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jValue" min="-2" pref="224" max="-2" attributes="0"/> + <EmptySpace pref="56" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="jLabel1" alignment="1" max="32767" attributes="1"/> + <Component id="jValue" alignment="1" max="32767" attributes="1"/> + </Group> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="jLabel1"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="jValue"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/JProductAttEditItem.java b/src/main/java/com/unicenta/pos/sales/JProductAttEditItem.java new file mode 100644 index 0000000..ee953d3 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JProductAttEditItem.java @@ -0,0 +1,129 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.editor.JEditorKeys; +import java.awt.Component; + +/** + * + * @author adrian + */ +public class JProductAttEditItem extends javax.swing.JPanel implements JProductAttEditI { + + private String attid; + + /** Creates new form JProductAttEditItem + * @param attid + * @param label + * @param value + * @param keys */ + public JProductAttEditItem(String attid, String label, String value, JEditorKeys keys) { + + this.attid = attid; + + initComponents(); + + jLabel1.setText(label); + + jValue.addEditorKeys(keys); + jValue.setText(value); + } + + /** + * + */ + public void assignSelection() { + jValue.activate(); + } + + /** + * + * @return + */ + public String getAttribute() { + return attid; + } + + /** + * + * @return + */ + public String getValue() { + return jValue.getText(); + } + + /** + * + * @return + */ + public Component getComponent() { + return this; + } + + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel1 = new javax.swing.JLabel(); + jValue = new com.unicenta.editor.JEditorString(); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText("jLabel1"); + jLabel1.setPreferredSize(new java.awt.Dimension(110, 30)); + + jValue.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jValue.setPreferredSize(new java.awt.Dimension(0, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jValue, javax.swing.GroupLayout.PREFERRED_SIZE, 224, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(56, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jLabel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jValue, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + ); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private com.unicenta.editor.JEditorString jValue; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/JProductAttListItem.form b/src/main/java/com/unicenta/pos/sales/JProductAttListItem.form new file mode 100644 index 0000000..5dcf4f3 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JProductAttListItem.form @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jValues" min="-2" max="-2" attributes="0"/> + <EmptySpace pref="66" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="1"/> + <Component id="jValues" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="jLabel1"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="jValues"> + <Properties> + <Property name="editable" type="boolean" value="true"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jValuesActionPerformed"/> + </Events> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/JProductAttListItem.java b/src/main/java/com/unicenta/pos/sales/JProductAttListItem.java new file mode 100644 index 0000000..9cf7a17 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JProductAttListItem.java @@ -0,0 +1,151 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.data.gui.ComboBoxValModel; +import java.awt.Component; +import java.util.List; + +/** + * @author JG + * @author adrian + */ +public class JProductAttListItem extends javax.swing.JPanel implements JProductAttEditI { + + private final String attid; + private ComboBoxValModel model; + + /** Creates new form JProductAttListItem + * @param attid + * @param label + * @param value + * @param values */ + public JProductAttListItem(String attid, String label, String value, List<String> values) { + + this.attid = attid; + + initComponents(); + + jLabel1.setText(label); + + values.stream().forEach((item) -> { + jValues.addItem(item); + }); + jValues.setSelectedItem(value); + } + + /** + * + */ + @Override + public void assignSelection() { + java.awt.EventQueue.invokeLater(() -> { + jValues.requestFocus(); + }); + } + + /** + * + * @return + */ + @Override + public String getAttribute() { + return attid; + } + + /** + * + * @return + */ + @Override + public String getValue() { + if (jValues.getSelectedItem() == null) { + return (String) jValues.getEditor().getItem(); + } else { + return (String) jValues.getSelectedItem(); + } + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel1 = new javax.swing.JLabel(); + jValues = new javax.swing.JComboBox(); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText("jLabel1"); + jLabel1.setPreferredSize(new java.awt.Dimension(110, 30)); + + jValues.setEditable(true); + jValues.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jValues.setPreferredSize(new java.awt.Dimension(200, 30)); + jValues.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jValuesActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jValues, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(66, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jValues, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + ); + }// </editor-fold>//GEN-END:initComponents + + private void jValuesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jValuesActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jValuesActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JComboBox jValues; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/JProductLineEdit.form b/src/main/java/com/unicenta/pos/sales/JProductLineEdit.form new file mode 100644 index 0000000..9bcfb02 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JProductLineEdit.form @@ -0,0 +1,492 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.editline" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[650, 350]"/> + </Property> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-118,0,0,2,-60"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[400, 230]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="10" pref="10" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jUnits" min="-2" pref="100" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jPriceTax" min="-2" pref="150" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jPrice" min="-2" pref="150" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel5" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel7" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jSubtotal" min="-2" pref="120" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="116" max="-2" attributes="0"/> + <Component id="m_jTaxrate" min="-2" pref="120" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel6" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jBtnPriceUpdate" min="-2" max="-2" attributes="0"/> + <Component id="m_jTotal" min="-2" pref="120" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jName" min="-2" pref="354" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace min="-2" pref="60" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jName" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" attributes="0"> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + <Component id="m_jUnits" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jPrice" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + <Component id="m_jPriceTax" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" pref="9" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="1" pref="1" max="-2" attributes="0"/> + <Component id="jLabel5" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="1" attributes="0"> + <Component id="m_jTaxrate" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel7" min="-2" max="-2" attributes="0"/> + <Component id="m_jSubtotal" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jTotal" min="-2" max="-2" attributes="0"/> + <Component id="jLabel6" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace pref="19" max="32767" attributes="0"/> + <Component id="m_jBtnPriceUpdate" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.price" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.units" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.pricetax" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[132, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorDouble" name="m_jUnits"> + <Properties> + <Property name="enabled" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[132, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorCurrency" name="m_jPrice"> + <Properties> + <Property name="enabled" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[132, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorCurrency" name="m_jPriceTax"> + <Properties> + <Property name="enabled" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[132, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jTaxrate"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="e4" green="eb" id="TextField.disabledBackground" palette="3" red="eb" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 25]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.tax" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.totalcash" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jTotal"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="e4" green="eb" id="TextField.disabledBackground" palette="3" red="eb" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 25]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel7"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.subtotalcash" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jSubtotal"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="e4" green="eb" id="TextField.disabledBackground" palette="3" red="eb" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 25]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="m_jBtnPriceUpdate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/filesave.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.priceupdate" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jBtnPriceUpdateActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="1"/> + </Layout> + <SubComponents> + <Component class="com.unicenta.editor.JEditorKeys" name="m_jKeys"> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jKeysActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="2"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="m_jButtonCancel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.cancel" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jButtonCancelActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jButtonOK"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.OK" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jButtonOKActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/JProductLineEdit.java b/src/main/java/com/unicenta/pos/sales/JProductLineEdit.java new file mode 100644 index 0000000..a009f59 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JProductLineEdit.java @@ -0,0 +1,566 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.Session; +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.ticket.TicketLineInfo; +import com.unicenta.pos.util.AltEncrypter; + +import javax.swing.*; +import java.awt.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +/** + * + * @author adrianromero + */ +public class JProductLineEdit extends javax.swing.JDialog { + + private TicketLineInfo returnLine; + private TicketLineInfo m_oLine; + private boolean m_bunitsok; + private boolean m_bpriceok; + private String productID; + private Session s; + private Connection con; + private String SQL; + private PreparedStatement pstmt; + + /** Creates new form JProductLineEdit */ + private JProductLineEdit(java.awt.Frame parent, boolean modal) { + super(parent, modal); + } + /** Creates new form JProductLineEdit */ + private JProductLineEdit(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + } + + private TicketLineInfo init(AppView app, TicketLineInfo oLine) throws BasicException { + + initComponents(); + + productID = oLine.getProductID(); + + if (oLine.getTaxInfo() == null) { + throw new BasicException(AppLocal.getIntString("message.cannotcalculatetaxes")); + } + + if (!productID.equals("xxx999_999xxx_x9x9x9")) { + m_jBtnPriceUpdate.setVisible(AppConfig.getInstance().getBoolean("db.prodpriceupdate")); + }else{ + m_jBtnPriceUpdate.setVisible(false); + } + + m_jBtnPriceUpdate.setEnabled(false); + + m_oLine = new TicketLineInfo(oLine); + m_bunitsok = true; + m_bpriceok = true; + +// m_jName.setEnabled(app.getAppUserView().getUser().hasPermission("com.unicenta.pos.sales.JPanelTicketEdits")); + m_jUnits.setEnabled(app.getAppUserView().getUser().hasPermission("com.unicenta.pos.sales.JPanelTicketEdits")); + m_jPrice.setEnabled(app.getAppUserView().getUser().hasPermission("com.unicenta.pos.sales.JPanelTicketEdits")); + m_jPriceTax.setEnabled(app.getAppUserView().getUser().hasPermission("com.unicenta.pos.sales.JPanelTicketEdits")); + + m_jName.setText(oLine.getProductName()); + m_jUnits.setDoubleValue(oLine.getMultiply()); + m_jPrice.setDoubleValue(oLine.getPrice()); + m_jPriceTax.setDoubleValue(oLine.getPriceTax()); + m_jTaxrate.setText(oLine.getTaxInfo().getName()); + + m_jName.addPropertyChangeListener("Edition", new RecalculateName()); + m_jUnits.addPropertyChangeListener("Edition", new RecalculateUnits()); + m_jPrice.addPropertyChangeListener("Edition", new RecalculatePrice()); + m_jPriceTax.addPropertyChangeListener("Edition", new RecalculatePriceTax()); + + m_jName.addEditorKeys(m_jKeys); + m_jUnits.addEditorKeys(m_jKeys); + m_jPrice.addEditorKeys(m_jKeys); + m_jPriceTax.addEditorKeys(m_jKeys); + + if (m_jName.isEnabled()) { + m_jName.activate(); + } else { + m_jUnits.activate(); + } + + printTotals(); + + getRootPane().setDefaultButton(m_jButtonOK); + returnLine = null; + setVisible(true); + + return returnLine; + } + + private void printTotals() { + + if (m_bunitsok && m_bpriceok) { + m_jSubtotal.setText(m_oLine.printSubValue()); + m_jTotal.setText(m_oLine.printValue()); + m_jButtonOK.setEnabled(true); + } else { + m_jSubtotal.setText(null); + m_jTotal.setText(null); + m_jButtonOK.setEnabled(false); + } + } + + private class RecalculateUnits implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + Double value = m_jUnits.getDoubleValue(); + if (value == null || value == 0.0) { + m_bunitsok = false; + } else { + m_oLine.setMultiply(value); + m_bunitsok = true; + } + + printTotals(); + } + } + + private class RecalculatePrice implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + + Double value = m_jPrice.getDoubleValue(); + if (value == null || value == 0.0) { + m_bpriceok = false; + } else { + m_oLine.setPrice(value); + m_jPriceTax.setDoubleValue(m_oLine.getPriceTax()); + m_bpriceok = true; + m_jBtnPriceUpdate.setEnabled(AppConfig.getInstance().getBoolean("db.prodpriceupdate")); + } + + printTotals(); + } + } + + private class RecalculatePriceTax implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + + Double value = m_jPriceTax.getDoubleValue(); + if (value == null || value == 0.0) { + m_bpriceok = false; + } else { + m_oLine.setPriceTax(value); + m_jPrice.setDoubleValue(m_oLine.getPrice()); + m_bpriceok = true; + m_jBtnPriceUpdate.setEnabled(AppConfig.getInstance().getBoolean("db.prodpriceupdate")); + } + + printTotals(); + } + } + + private class RecalculateName implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + m_oLine.setProperty("product.name", m_jName.getText()); + } + } + + private static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window)parent; + } else { + return getWindow(parent.getParent()); + } + } + + /** + * + * @param parent + * @param app + * @param oLine + * @return + * @throws BasicException + */ + public static TicketLineInfo showMessage(Component parent + , AppView app + , TicketLineInfo oLine) throws BasicException { + + Window window = getWindow(parent); + + JProductLineEdit myMsg; + if (window instanceof Frame) { + myMsg = new JProductLineEdit((Frame) window, true); + } else { + myMsg = new JProductLineEdit((Dialog) window, true); + } + return myMsg.init(app, oLine); + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel5 = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + m_jName = new com.unicenta.editor.JEditorString(); + m_jUnits = new com.unicenta.editor.JEditorDouble(); + m_jPrice = new com.unicenta.editor.JEditorCurrency(); + m_jPriceTax = new com.unicenta.editor.JEditorCurrency(); + m_jTaxrate = new javax.swing.JLabel(); + jLabel5 = new javax.swing.JLabel(); + jLabel6 = new javax.swing.JLabel(); + m_jTotal = new javax.swing.JLabel(); + jLabel7 = new javax.swing.JLabel(); + m_jSubtotal = new javax.swing.JLabel(); + m_jBtnPriceUpdate = new javax.swing.JButton(); + jPanel3 = new javax.swing.JPanel(); + jPanel4 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel1 = new javax.swing.JPanel(); + m_jButtonCancel = new javax.swing.JButton(); + m_jButtonOK = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(AppLocal.getIntString("label.editline")); // NOI18N + setPreferredSize(new java.awt.Dimension(650, 350)); + + jPanel5.setLayout(new java.awt.BorderLayout()); + + jPanel2.setPreferredSize(new java.awt.Dimension(400, 230)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.price")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.units")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.pricetax")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(132, 30)); + + m_jUnits.setEnabled(false); + m_jUnits.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jUnits.setPreferredSize(new java.awt.Dimension(132, 30)); + + m_jPrice.setEnabled(false); + m_jPrice.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPrice.setPreferredSize(new java.awt.Dimension(132, 30)); + + m_jPriceTax.setEnabled(false); + m_jPriceTax.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPriceTax.setPreferredSize(new java.awt.Dimension(132, 30)); + + m_jTaxrate.setBackground(javax.swing.UIManager.getDefaults().getColor("TextField.disabledBackground")); + m_jTaxrate.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jTaxrate.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jTaxrate.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jTaxrate.setOpaque(true); + m_jTaxrate.setPreferredSize(new java.awt.Dimension(150, 25)); + m_jTaxrate.setRequestFocusEnabled(false); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.tax")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setText(AppLocal.getIntString("label.totalcash")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jTotal.setBackground(javax.swing.UIManager.getDefaults().getColor("TextField.disabledBackground")); + m_jTotal.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jTotal.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jTotal.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jTotal.setOpaque(true); + m_jTotal.setPreferredSize(new java.awt.Dimension(150, 25)); + m_jTotal.setRequestFocusEnabled(false); + + jLabel7.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel7.setText(AppLocal.getIntString("label.subtotalcash")); // NOI18N + jLabel7.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jSubtotal.setBackground(javax.swing.UIManager.getDefaults().getColor("TextField.disabledBackground")); + m_jSubtotal.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jSubtotal.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jSubtotal.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jSubtotal.setOpaque(true); + m_jSubtotal.setPreferredSize(new java.awt.Dimension(150, 25)); + m_jSubtotal.setRequestFocusEnabled(false); + + m_jBtnPriceUpdate.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jBtnPriceUpdate.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/filesave.png"))); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + m_jBtnPriceUpdate.setText(bundle.getString("button.priceupdate")); // NOI18N + m_jBtnPriceUpdate.setFocusPainted(false); + m_jBtnPriceUpdate.setFocusable(false); + m_jBtnPriceUpdate.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jBtnPriceUpdate.setPreferredSize(new java.awt.Dimension(110, 45)); + m_jBtnPriceUpdate.setRequestFocusEnabled(false); + m_jBtnPriceUpdate.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jBtnPriceUpdateActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(10, 10, 10) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jUnits, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jPriceTax, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jPrice, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jSubtotal, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(116, 116, 116) + .addComponent(m_jTaxrate, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jBtnPriceUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jTotal, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE))))) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, 354, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(60, 60, 60)) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jUnits, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jPrice, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jPriceTax, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(9, 9, 9) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(1, 1, 1) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addComponent(m_jTaxrate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED))) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jSubtotal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jTotal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 19, Short.MAX_VALUE) + .addComponent(m_jBtnPriceUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + + jPanel5.add(jPanel2, java.awt.BorderLayout.CENTER); + + getContentPane().add(jPanel5, java.awt.BorderLayout.CENTER); + + jPanel3.setLayout(new java.awt.BorderLayout()); + + jPanel4.setLayout(new javax.swing.BoxLayout(jPanel4, javax.swing.BoxLayout.Y_AXIS)); + + m_jKeys.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jKeysActionPerformed(evt); + } + }); + jPanel4.add(m_jKeys); + + jPanel3.add(jPanel4, java.awt.BorderLayout.NORTH); + + jPanel1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT)); + + m_jButtonCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jButtonCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + m_jButtonCancel.setText(AppLocal.getIntString("button.cancel")); // NOI18N + m_jButtonCancel.setFocusPainted(false); + m_jButtonCancel.setFocusable(false); + m_jButtonCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jButtonCancel.setPreferredSize(new java.awt.Dimension(110, 45)); + m_jButtonCancel.setRequestFocusEnabled(false); + m_jButtonCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jButtonCancelActionPerformed(evt); + } + }); + jPanel1.add(m_jButtonCancel); + + m_jButtonOK.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jButtonOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + m_jButtonOK.setText(AppLocal.getIntString("button.OK")); // NOI18N + m_jButtonOK.setFocusPainted(false); + m_jButtonOK.setFocusable(false); + m_jButtonOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jButtonOK.setPreferredSize(new java.awt.Dimension(110, 45)); + m_jButtonOK.setRequestFocusEnabled(false); + m_jButtonOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jButtonOKActionPerformed(evt); + } + }); + jPanel1.add(m_jButtonOK); + + jPanel3.add(jPanel1, java.awt.BorderLayout.SOUTH); + + getContentPane().add(jPanel3, java.awt.BorderLayout.EAST); + + setSize(new java.awt.Dimension(708, 394)); + setLocationRelativeTo(null); + }// </editor-fold>//GEN-END:initComponents + + private void m_jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jButtonCancelActionPerformed + + dispose(); + + }//GEN-LAST:event_m_jButtonCancelActionPerformed + + private void m_jButtonOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jButtonOKActionPerformed + + returnLine = m_oLine; + + dispose(); + + }//GEN-LAST:event_m_jButtonOKActionPerformed + + private void m_jKeysActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jKeysActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_m_jKeysActionPerformed + + private void m_jBtnPriceUpdateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jBtnPriceUpdateActionPerformed + + String db_password = (AppConfig.getInstance().getProperty("db.password")); + + if (AppConfig.getInstance().getProperty("db.user") != null + && db_password != null + && db_password.startsWith("crypt:")) { + AltEncrypter cypher = new AltEncrypter("cypherkey" + + AppConfig.getInstance().getProperty("db.user")); + db_password = cypher.decrypt(db_password.substring(6)); + } + + try { + +// s = AppViewConnection.createSession(); + con = DriverManager.getConnection( + AppConfig.getInstance().getProperty("db.URL") + + AppConfig.getInstance().getProperty("db.schema") + , AppConfig.getInstance().getProperty("db.user") + , db_password); + + pstmt = con.prepareStatement( + "UPDATE PRODUCTS SET PRICESELL = ? WHERE ID = ?"); + pstmt.setDouble(1, m_jPrice.getDoubleValue()); + pstmt.setString(2, productID); + System.out.println(pstmt); + + pstmt.executeUpdate(); + + m_jBtnPriceUpdate.setEnabled(false); + + con.close(); + + } catch (SQLException e) { + System.out.println(e); + + return; + } + + m_oLine.setUpdated(true); + }//GEN-LAST:event_m_jBtnPriceUpdateActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JButton m_jBtnPriceUpdate; + private javax.swing.JButton m_jButtonCancel; + private javax.swing.JButton m_jButtonOK; + private com.unicenta.editor.JEditorKeys m_jKeys; + private com.unicenta.editor.JEditorString m_jName; + private com.unicenta.editor.JEditorCurrency m_jPrice; + private com.unicenta.editor.JEditorCurrency m_jPriceTax; + private javax.swing.JLabel m_jSubtotal; + private javax.swing.JLabel m_jTaxrate; + private javax.swing.JLabel m_jTotal; + private com.unicenta.editor.JEditorDouble m_jUnits; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/JProductLineEditTax.form b/src/main/java/com/unicenta/pos/sales/JProductLineEditTax.form new file mode 100644 index 0000000..f5d9bff --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JProductLineEditTax.form @@ -0,0 +1,525 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.editline" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-118,0,0,2,-60"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[400, 230]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="10" pref="10" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jUnits" min="-2" pref="100" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jPriceTax" min="-2" pref="150" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jPrice" min="-2" pref="150" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel4" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jName" min="-2" pref="240" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel7" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jSubtotal" min="-2" pref="120" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel6" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jBtnPriceUpdate" min="-2" max="-2" attributes="0"/> + <Component id="m_jTotal" min="-2" pref="120" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel5" alignment="0" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="116" max="-2" attributes="0"/> + <Component id="m_jTaxrateOld" min="-2" pref="120" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="m_jTaxrate" min="-2" pref="100" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </Group> + <EmptySpace min="-2" pref="60" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jName" min="-2" max="-2" attributes="0"/> + <Component id="jLabel4" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" attributes="0"> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + <Component id="m_jUnits" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jPrice" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + <Component id="m_jPriceTax" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" attributes="0"> + <Group type="103" alignment="1" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="1" pref="1" max="-2" attributes="0"/> + <Component id="jLabel5" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="1" attributes="0"> + <Component id="m_jTaxrateOld" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" alignment="1" attributes="0"> + <Component id="m_jTaxrate" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="11" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel7" min="-2" max="-2" attributes="0"/> + <Component id="m_jSubtotal" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jTotal" min="-2" max="-2" attributes="0"/> + <Component id="jLabel6" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="32767" attributes="0"/> + <Component id="m_jBtnPriceUpdate" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.price" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.units" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.pricetax" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.item" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[132, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorDouble" name="m_jUnits"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[132, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorCurrency" name="m_jPrice"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[132, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorCurrency" name="m_jPriceTax"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[132, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jTaxrateOld"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="e4" green="eb" id="TextField.disabledBackground" palette="3" red="eb" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 25]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.tax" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.totalcash" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jTotal"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="e4" green="eb" id="TextField.disabledBackground" palette="3" red="eb" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 25]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel7"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.subtotalcash" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="m_jSubtotal"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="e4" green="eb" id="TextField.disabledBackground" palette="3" red="eb" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 25]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="m_jBtnPriceUpdate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/filesave.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.priceupdate" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jBtnPriceUpdateActionPerformed"/> + </Events> + </Component> + <Component class="com.unicenta.editor.JEditorDouble" name="m_jTaxrate"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[132, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="1"/> + </Layout> + <SubComponents> + <Component class="com.unicenta.editor.JEditorKeys" name="m_jKeys"> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jKeysActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="2"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="m_jButtonCancel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.cancel" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jButtonCancelActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jButtonOK"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.OK" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jButtonOKActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/JProductLineEditTax.java b/src/main/java/com/unicenta/pos/sales/JProductLineEditTax.java new file mode 100644 index 0000000..da7d8a5 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JProductLineEditTax.java @@ -0,0 +1,584 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.Session; +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.ticket.TicketLineInfo; +import com.unicenta.pos.util.AltEncrypter; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.*; +import java.awt.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +/** + * + * @author adrianromero + */ +@Slf4j +public class JProductLineEditTax extends javax.swing.JDialog { + + private TicketLineInfo returnLine; + private TicketLineInfo m_oLine; + private boolean m_bunitsok; + private boolean m_bpriceok; + private String productID; + private Session s; + private Connection con; + private String SQL; + private PreparedStatement pstmt; + + /** Creates new form JProductLineEdit */ + private JProductLineEditTax(java.awt.Frame parent, boolean modal) { + super(parent, modal); + } + /** Creates new form JProductLineEdit */ + private JProductLineEditTax(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + } + + private TicketLineInfo init(AppView app, TicketLineInfo oLine) throws BasicException { + + initComponents(); + + productID = oLine.getProductID(); + + if (oLine.getTaxInfo() == null) { + throw new BasicException(AppLocal.getIntString("message.cannotcalculatetaxes")); + } + + if (!productID.equals("xxx999_999xxx_x9x9x9")) { + m_jBtnPriceUpdate.setVisible(AppConfig.getInstance().getBoolean("db.prodpriceupdate")); + }else{ + m_jBtnPriceUpdate.setVisible(false); + } + + m_jBtnPriceUpdate.setEnabled(false); + + m_oLine = new TicketLineInfo(oLine); + m_bunitsok = true; + m_bpriceok = true; + + m_jName.setEnabled(app.getAppUserView().getUser().hasPermission("com.unicenta.pos.sales.JPanelTicketEdits")); + m_jPrice.setEnabled(app.getAppUserView().getUser().hasPermission("com.unicenta.pos.sales.JPanelTicketEdits")); + m_jPriceTax.setEnabled(app.getAppUserView().getUser().hasPermission("com.unicenta.pos.sales.JPanelTicketEdits")); + + m_jName.setText(oLine.getProductName()); + m_jUnits.setDoubleValue(oLine.getMultiply()); + m_jPrice.setDoubleValue(oLine.getPrice()); + m_jPriceTax.setDoubleValue(oLine.getPriceTax()); + m_jTaxrateOld.setText(oLine.getTaxInfo().getName()); + m_jTaxrate.setDoubleValue(oLine.getTaxRate()); + + m_jName.addPropertyChangeListener("Edition", new RecalculateName()); + m_jUnits.addPropertyChangeListener("Edition", new RecalculateUnits()); + m_jPrice.addPropertyChangeListener("Edition", new RecalculatePrice()); + m_jPriceTax.addPropertyChangeListener("Edition", new RecalculatePriceTax()); + + m_jName.addEditorKeys(m_jKeys); + m_jUnits.addEditorKeys(m_jKeys); + m_jPrice.addEditorKeys(m_jKeys); + m_jPriceTax.addEditorKeys(m_jKeys); + m_jTaxrate.addEditorKeys(m_jKeys); + + if (m_jName.isEnabled()) { + m_jName.activate(); + } else { + m_jUnits.activate(); + } + + printTotals(); + + getRootPane().setDefaultButton(m_jButtonOK); + returnLine = null; + setVisible(true); + + return returnLine; + } + + private void printTotals() { + + if (m_bunitsok && m_bpriceok) { + m_jSubtotal.setText(m_oLine.printSubValue()); + m_jTotal.setText(m_oLine.printValue()); + m_jButtonOK.setEnabled(true); + } else { + m_jSubtotal.setText(null); + m_jTotal.setText(null); + m_jButtonOK.setEnabled(false); + } + } + + private class RecalculateUnits implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + Double value = m_jUnits.getDoubleValue(); + if (value == null || value == 0.0) { + m_bunitsok = false; + } else { + m_oLine.setMultiply(value); + m_bunitsok = true; + } + + printTotals(); + } + } + + private class RecalculatePrice implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + + Double value = m_jPrice.getDoubleValue(); + if (value == null || value == 0.0) { + m_bpriceok = false; + } else { + m_oLine.setPrice(value); + m_jPriceTax.setDoubleValue(m_oLine.getPriceTax()); + m_bpriceok = true; + m_jBtnPriceUpdate.setEnabled(AppConfig.getInstance().getBoolean("db.prodpriceupdate")); + } + + printTotals(); + } + } + + private class RecalculatePriceTax implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + + Double value = m_jPriceTax.getDoubleValue(); + if (value == null || value == 0.0) { + m_bpriceok = false; + } else { + m_oLine.setPriceTax(value); + m_jPrice.setDoubleValue(m_oLine.getPrice()); + m_bpriceok = true; + m_jBtnPriceUpdate.setEnabled(AppConfig.getInstance().getBoolean("db.prodpriceupdate")); + } + + printTotals(); + } + } + + private class RecalculateName implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + m_oLine.setProperty("product.name", m_jName.getText()); + } + } + + private static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window)parent; + } else { + return getWindow(parent.getParent()); + } + } + + /** + * + * @param parent + * @param app + * @param oLine + * @return + * @throws BasicException + */ + public static TicketLineInfo showMessage(Component parent + , AppView app + , TicketLineInfo oLine) throws BasicException { + + Window window = getWindow(parent); + + JProductLineEditTax myMsg; + if (window instanceof Frame) { + myMsg = new JProductLineEditTax((Frame) window, true); + } else { + myMsg = new JProductLineEditTax((Dialog) window, true); + } + return myMsg.init(app, oLine); + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel5 = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + m_jName = new com.unicenta.editor.JEditorString(); + m_jUnits = new com.unicenta.editor.JEditorDouble(); + m_jPrice = new com.unicenta.editor.JEditorCurrency(); + m_jPriceTax = new com.unicenta.editor.JEditorCurrency(); + m_jTaxrateOld = new javax.swing.JLabel(); + jLabel5 = new javax.swing.JLabel(); + jLabel6 = new javax.swing.JLabel(); + m_jTotal = new javax.swing.JLabel(); + jLabel7 = new javax.swing.JLabel(); + m_jSubtotal = new javax.swing.JLabel(); + m_jBtnPriceUpdate = new javax.swing.JButton(); + m_jTaxrate = new com.unicenta.editor.JEditorDouble(); + jPanel3 = new javax.swing.JPanel(); + jPanel4 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel1 = new javax.swing.JPanel(); + m_jButtonCancel = new javax.swing.JButton(); + m_jButtonOK = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(AppLocal.getIntString("label.editline")); // NOI18N + + jPanel5.setLayout(new java.awt.BorderLayout()); + + jPanel2.setPreferredSize(new java.awt.Dimension(400, 230)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.price")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.units")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.pricetax")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.item")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(132, 30)); + + m_jUnits.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jUnits.setPreferredSize(new java.awt.Dimension(132, 30)); + + m_jPrice.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPrice.setPreferredSize(new java.awt.Dimension(132, 30)); + + m_jPriceTax.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPriceTax.setPreferredSize(new java.awt.Dimension(132, 30)); + + m_jTaxrateOld.setBackground(javax.swing.UIManager.getDefaults().getColor("TextField.disabledBackground")); + m_jTaxrateOld.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jTaxrateOld.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jTaxrateOld.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jTaxrateOld.setOpaque(true); + m_jTaxrateOld.setPreferredSize(new java.awt.Dimension(150, 25)); + m_jTaxrateOld.setRequestFocusEnabled(false); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.tax")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setText(AppLocal.getIntString("label.totalcash")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jTotal.setBackground(javax.swing.UIManager.getDefaults().getColor("TextField.disabledBackground")); + m_jTotal.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jTotal.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jTotal.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jTotal.setOpaque(true); + m_jTotal.setPreferredSize(new java.awt.Dimension(150, 25)); + m_jTotal.setRequestFocusEnabled(false); + + jLabel7.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel7.setText(AppLocal.getIntString("label.subtotalcash")); // NOI18N + jLabel7.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jSubtotal.setBackground(javax.swing.UIManager.getDefaults().getColor("TextField.disabledBackground")); + m_jSubtotal.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jSubtotal.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jSubtotal.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jSubtotal.setOpaque(true); + m_jSubtotal.setPreferredSize(new java.awt.Dimension(150, 25)); + m_jSubtotal.setRequestFocusEnabled(false); + + m_jBtnPriceUpdate.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jBtnPriceUpdate.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/filesave.png"))); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + m_jBtnPriceUpdate.setText(bundle.getString("button.priceupdate")); // NOI18N + m_jBtnPriceUpdate.setFocusPainted(false); + m_jBtnPriceUpdate.setFocusable(false); + m_jBtnPriceUpdate.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jBtnPriceUpdate.setPreferredSize(new java.awt.Dimension(110, 45)); + m_jBtnPriceUpdate.setRequestFocusEnabled(false); + m_jBtnPriceUpdate.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jBtnPriceUpdateActionPerformed(evt); + } + }); + + m_jTaxrate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jTaxrate.setPreferredSize(new java.awt.Dimension(132, 30)); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(10, 10, 10) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jUnits, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jPriceTax, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jPrice, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, 240, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jSubtotal, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jBtnPriceUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jTotal, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(116, 116, 116) + .addComponent(m_jTaxrateOld, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(18, 18, 18) + .addComponent(m_jTaxrate, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE))))) + .addGap(60, 60, 60)) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jUnits, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jPrice, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jPriceTax, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(1, 1, 1) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addComponent(m_jTaxrateOld, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED))) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(m_jTaxrate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(11, 11, 11))) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jSubtotal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jTotal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(m_jBtnPriceUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + + jPanel5.add(jPanel2, java.awt.BorderLayout.CENTER); + + getContentPane().add(jPanel5, java.awt.BorderLayout.CENTER); + + jPanel3.setLayout(new java.awt.BorderLayout()); + + jPanel4.setLayout(new javax.swing.BoxLayout(jPanel4, javax.swing.BoxLayout.Y_AXIS)); + + m_jKeys.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jKeysActionPerformed(evt); + } + }); + jPanel4.add(m_jKeys); + + jPanel3.add(jPanel4, java.awt.BorderLayout.NORTH); + + jPanel1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT)); + + m_jButtonCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jButtonCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + m_jButtonCancel.setText(AppLocal.getIntString("button.cancel")); // NOI18N + m_jButtonCancel.setFocusPainted(false); + m_jButtonCancel.setFocusable(false); + m_jButtonCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jButtonCancel.setPreferredSize(new java.awt.Dimension(110, 45)); + m_jButtonCancel.setRequestFocusEnabled(false); + m_jButtonCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jButtonCancelActionPerformed(evt); + } + }); + jPanel1.add(m_jButtonCancel); + + m_jButtonOK.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jButtonOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + m_jButtonOK.setText(AppLocal.getIntString("button.OK")); // NOI18N + m_jButtonOK.setFocusPainted(false); + m_jButtonOK.setFocusable(false); + m_jButtonOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jButtonOK.setPreferredSize(new java.awt.Dimension(110, 45)); + m_jButtonOK.setRequestFocusEnabled(false); + m_jButtonOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jButtonOKActionPerformed(evt); + } + }); + jPanel1.add(m_jButtonOK); + + jPanel3.add(jPanel1, java.awt.BorderLayout.SOUTH); + + getContentPane().add(jPanel3, java.awt.BorderLayout.EAST); + + setSize(new java.awt.Dimension(708, 394)); + setLocationRelativeTo(null); + }// </editor-fold>//GEN-END:initComponents + + private void m_jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jButtonCancelActionPerformed + + dispose(); + + }//GEN-LAST:event_m_jButtonCancelActionPerformed + + private void m_jButtonOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jButtonOKActionPerformed + + returnLine = m_oLine; + + dispose(); + + }//GEN-LAST:event_m_jButtonOKActionPerformed + + private void m_jKeysActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jKeysActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_m_jKeysActionPerformed + + private void m_jBtnPriceUpdateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jBtnPriceUpdateActionPerformed + + String db_password = (AppConfig.getInstance().getProperty("db.password")); + + if (AppConfig.getInstance().getProperty("db.user") != null + && db_password != null + && db_password.startsWith("crypt:")) { + AltEncrypter cypher = new AltEncrypter("cypherkey" + + AppConfig.getInstance().getProperty("db.user")); + db_password = cypher.decrypt(db_password.substring(6)); + } + + try { + +// s = AppViewConnection.createSession(); + con = DriverManager.getConnection( + AppConfig.getInstance().getProperty("db.URL") + + AppConfig.getInstance().getProperty("db.schema") + , AppConfig.getInstance().getProperty("db.user") + , db_password); + + pstmt = con.prepareStatement( + "UPDATE PRODUCTS SET PRICESELL = ? WHERE ID = ?"); + pstmt.setDouble(1, m_jPrice.getDoubleValue()); + pstmt.setString(2, productID); + pstmt.executeUpdate(); + + m_jBtnPriceUpdate.setEnabled(false); + + con.close(); + + } catch (SQLException e) { + + return; + } + + m_oLine.setUpdated(true); + }//GEN-LAST:event_m_jBtnPriceUpdateActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JButton m_jBtnPriceUpdate; + private javax.swing.JButton m_jButtonCancel; + private javax.swing.JButton m_jButtonOK; + private com.unicenta.editor.JEditorKeys m_jKeys; + private com.unicenta.editor.JEditorString m_jName; + private com.unicenta.editor.JEditorCurrency m_jPrice; + private com.unicenta.editor.JEditorCurrency m_jPriceTax; + private javax.swing.JLabel m_jSubtotal; + private com.unicenta.editor.JEditorDouble m_jTaxrate; + private javax.swing.JLabel m_jTaxrateOld; + private javax.swing.JLabel m_jTotal; + private com.unicenta.editor.JEditorDouble m_jUnits; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/JRefundLines.form b/src/main/java/com/unicenta/pos/sales/JRefundLines.form new file mode 100644 index 0000000..6992b01 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JRefundLines.form @@ -0,0 +1,177 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[15, 200]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-31,0,0,1,103"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="West"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="0" left="5" right="0" top="0"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="After"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="webLabel1" min="-2" pref="110" max="-2" attributes="0"/> + <Component id="m_jbtnAddOne" min="-2" max="-2" attributes="0"/> + <Component id="m_jbtnAddLine" min="-2" max="-2" attributes="0"/> + <Component id="m_jbtnAddAll" min="-2" max="-2" attributes="0"/> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="1" pref="1" max="-2" attributes="0"/> + <Component id="webLabel1" min="-2" pref="52" max="-2" attributes="0"/> + <EmptySpace min="5" pref="5" max="-2" attributes="0"/> + <Component id="m_jbtnAddOne" min="-2" max="-2" attributes="0"/> + <EmptySpace min="5" pref="5" max="-2" attributes="0"/> + <Component id="m_jbtnAddLine" min="-2" max="-2" attributes="0"/> + <EmptySpace min="5" pref="5" max="-2" attributes="0"/> + <Component id="m_jbtnAddAll" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="com.alee.laf.label.WebLabel" name="webLabel1"> + <Properties> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.refunds" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="1"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="m_jbtnAddOne"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.refundone" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.refunditem" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jbtnAddOneActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jbtnAddLine"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.refundline" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.refundline" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jbtnAddLineActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jbtnAddAll"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.refundall" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.refundticket" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jbtnAddAllActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/JRefundLines.java b/src/main/java/com/unicenta/pos/sales/JRefundLines.java new file mode 100644 index 0000000..23b0b2d --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JRefundLines.java @@ -0,0 +1,216 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSystem; +import com.unicenta.pos.ticket.TicketLineInfo; +import java.awt.BorderLayout; +import java.util.List; + +/** + * + * @author JG uniCenta + */ +public class JRefundLines extends javax.swing.JPanel { + + private JTicketLines ticketlines; + private List m_aLines; + + private JPanelTicketEdits m_jTicketEdit; + +/** Creates new form JRefundLines +* @param dlSystem +* @param jTicketEdit +*/ +public JRefundLines(DataLogicSystem dlSystem, JPanelTicketEdits jTicketEdit) { + + m_jTicketEdit = jTicketEdit; + + initComponents(); + + ticketlines = new JTicketLines(dlSystem.getResourceAsXML("Ticket.Line")); + + jPanel3.add(ticketlines, BorderLayout.CENTER); + } + + /** + * + * @param aRefundLines + */ + public void setLines(List aRefundLines) { + + m_aLines = aRefundLines; + ticketlines.clearTicketLines(); + + if (m_aLines != null) { + for (int i = 0; i < m_aLines.size(); i++) { + ticketlines.addTicketLine((TicketLineInfo) m_aLines.get(i)); + } + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel3 = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + webLabel1 = new com.alee.laf.label.WebLabel(); + m_jbtnAddOne = new javax.swing.JButton(); + m_jbtnAddLine = new javax.swing.JButton(); + m_jbtnAddAll = new javax.swing.JButton(); + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setPreferredSize(new java.awt.Dimension(15, 200)); + setLayout(new java.awt.BorderLayout()); + + jPanel3.setLayout(new java.awt.BorderLayout()); + + jPanel1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 5, 0, 0)); + jPanel1.setLayout(new java.awt.BorderLayout()); + + webLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + webLabel1.setText(bundle.getString("label.refunds")); // NOI18N + webLabel1.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + + m_jbtnAddOne.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jbtnAddOne.setText(AppLocal.getIntString("button.refundone")); // NOI18N + m_jbtnAddOne.setToolTipText(bundle.getString("tooltip.refunditem")); // NOI18N + m_jbtnAddOne.setFocusPainted(false); + m_jbtnAddOne.setFocusable(false); + m_jbtnAddOne.setMargin(new java.awt.Insets(8, 14, 8, 14)); + m_jbtnAddOne.setPreferredSize(new java.awt.Dimension(110, 45)); + m_jbtnAddOne.setRequestFocusEnabled(false); + m_jbtnAddOne.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtnAddOneActionPerformed(evt); + } + }); + + m_jbtnAddLine.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jbtnAddLine.setText(AppLocal.getIntString("button.refundline")); // NOI18N + m_jbtnAddLine.setToolTipText(bundle.getString("tooltip.refundline")); // NOI18N + m_jbtnAddLine.setFocusPainted(false); + m_jbtnAddLine.setFocusable(false); + m_jbtnAddLine.setMargin(new java.awt.Insets(8, 14, 8, 14)); + m_jbtnAddLine.setPreferredSize(new java.awt.Dimension(110, 45)); + m_jbtnAddLine.setRequestFocusEnabled(false); + m_jbtnAddLine.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtnAddLineActionPerformed(evt); + } + }); + + m_jbtnAddAll.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jbtnAddAll.setText(AppLocal.getIntString("button.refundall")); // NOI18N + m_jbtnAddAll.setToolTipText(bundle.getString("tooltip.refundticket")); // NOI18N + m_jbtnAddAll.setFocusPainted(false); + m_jbtnAddAll.setFocusable(false); + m_jbtnAddAll.setMargin(new java.awt.Insets(8, 14, 8, 14)); + m_jbtnAddAll.setPreferredSize(new java.awt.Dimension(110, 45)); + m_jbtnAddAll.setRequestFocusEnabled(false); + m_jbtnAddAll.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtnAddAllActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(webLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jbtnAddOne, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jbtnAddLine, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jbtnAddAll, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(1, 1, 1) + .addComponent(webLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(5, 5, 5) + .addComponent(m_jbtnAddOne, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(5, 5, 5) + .addComponent(m_jbtnAddLine, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(5, 5, 5) + .addComponent(m_jbtnAddAll, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + + jPanel1.add(jPanel2, java.awt.BorderLayout.LINE_END); + + jPanel3.add(jPanel1, java.awt.BorderLayout.EAST); + + add(jPanel3, java.awt.BorderLayout.WEST); + }// </editor-fold>//GEN-END:initComponents + + private void m_jbtnAddAllActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtnAddAllActionPerformed + + for (int i = 0; i < m_aLines.size(); i++) { + TicketLineInfo oLine = (TicketLineInfo) m_aLines.get(i); + TicketLineInfo oNewLine = new TicketLineInfo(oLine); + oNewLine.setMultiply(-oLine.getMultiply()); + m_jTicketEdit.addTicketLine(oNewLine); + } + + }//GEN-LAST:event_m_jbtnAddAllActionPerformed + + private void m_jbtnAddOneActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtnAddOneActionPerformed + + int index = ticketlines.getSelectedIndex(); + if (index >= 0) { + TicketLineInfo oLine = (TicketLineInfo) m_aLines.get(index); + TicketLineInfo oNewLine = new TicketLineInfo(oLine); + oNewLine.setMultiply(-1.0); + m_jTicketEdit.addTicketLine(oNewLine); + } + + }//GEN-LAST:event_m_jbtnAddOneActionPerformed + + private void m_jbtnAddLineActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtnAddLineActionPerformed + + int index = ticketlines.getSelectedIndex(); + if (index >= 0) { + TicketLineInfo oLine = (TicketLineInfo) m_aLines.get(index); + TicketLineInfo oNewLine = new TicketLineInfo(oLine); + oNewLine.setMultiply(-oLine.getMultiply()); + m_jTicketEdit.addTicketLine(oNewLine); + } + }//GEN-LAST:event_m_jbtnAddLineActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JButton m_jbtnAddAll; + private javax.swing.JButton m_jbtnAddLine; + private javax.swing.JButton m_jbtnAddOne; + private com.alee.laf.label.WebLabel webLabel1; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/JSalesLayoutManager.java b/src/main/java/com/unicenta/pos/sales/JSalesLayoutManager.java new file mode 100644 index 0000000..2b39f4b --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JSalesLayoutManager.java @@ -0,0 +1,10 @@ + +package com.unicenta.pos.sales; + +public class JSalesLayoutManager { + + public JSalesLayoutManager(){ } + + public static void createLayout(){ } + +} diff --git a/src/main/java/com/unicenta/pos/sales/JTicketCatalogLines.form b/src/main/java/com/unicenta/pos/sales/JTicketCatalogLines.form new file mode 100644 index 0000000..cd93fc2 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JTicketCatalogLines.form @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,18,0,0,1,-99"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignCardLayout"/> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/JTicketCatalogLines.java b/src/main/java/com/unicenta/pos/sales/JTicketCatalogLines.java new file mode 100644 index 0000000..b1eb1b3 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JTicketCatalogLines.java @@ -0,0 +1,129 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.basic.BasicException; +import com.unicenta.pos.catalog.CatalogSelector; +import com.unicenta.pos.catalog.JCatalog; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.forms.DataLogicSystem; +import java.awt.CardLayout; +import java.awt.Dimension; +import java.awt.event.ActionListener; +import java.util.List; + +/** + * + * @author JG uniCenta + */ +public class JTicketCatalogLines extends javax.swing.JPanel { + + private JRefundLines m_reflines; + private CatalogSelector m_catalog; + + /** Creates new form JTicketCatalogLines + * @param app + * @param jTicketEdit + * @param pricevisible + * @param taxesincluded + * @param width + * @param height */ + public JTicketCatalogLines(AppView app, JPanelTicketEdits jTicketEdit, boolean pricevisible, boolean taxesincluded, int width, int height) { + + DataLogicSystem dlSystem = null; + DataLogicSales dlSales = null; + dlSystem = (DataLogicSystem) app.getBean("com.unicenta.pos.forms.DataLogicSystem"); + dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + + initComponents(); + + m_reflines = new JRefundLines(dlSystem, jTicketEdit); + add(m_reflines, "reflines"); + + m_catalog = new JCatalog(dlSales, pricevisible, taxesincluded, width, height); + m_catalog.getComponent().setPreferredSize(new Dimension(0, 245)); + // m_catalog.addActionListener(new CatalogListener()); + add(m_catalog.getComponent(), "catalog"); + } + + /** + * + */ + public void showCatalog() { + showView("catalog"); + } + + /** + * + * @throws BasicException + */ + public void loadCatalog() throws BasicException { + m_catalog.loadCatalog(); + } + + /** + * + * @param l + */ + public void addActionListener(ActionListener l) { + m_catalog.addActionListener(l); + } + + /** + * + * @param l + */ + public void removeActionListener(ActionListener l) { + m_catalog.addActionListener(l); + } + + /** + * + * @param aRefundLines + */ + public void showRefundLines(List aRefundLines) { + // anado las lineas de refund + m_reflines.setLines(aRefundLines); + showView("reflines"); + } + + private void showView(String sView) { + CardLayout cl = (CardLayout)(this.getLayout()); + cl.show(this, sView); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setLayout(new java.awt.CardLayout()); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/JTicketLines.form b/src/main/java/com/unicenta/pos/sales/JTicketLines.form new file mode 100644 index 0000000..c200961 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JTicketLines.form @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-20,0,0,1,113"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JScrollPane" name="m_jScrollTableTicket"> + <Properties> + <Property name="horizontalScrollBarPolicy" type="int" value="31"/> + <Property name="verticalScrollBarPolicy" type="int" value="22"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JTable" name="m_jTicketTable"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="focusable" type="boolean" value="false"/> + <Property name="intercellSpacing" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 1]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + <Property name="showVerticalLines" type="boolean" value="false"/> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/JTicketLines.java b/src/main/java/com/unicenta/pos/sales/JTicketLines.java new file mode 100644 index 0000000..0e89b85 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JTicketLines.java @@ -0,0 +1,482 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.data.loader.LocalRes; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.scripting.ScriptEngine; +import com.unicenta.pos.scripting.ScriptException; +import com.unicenta.pos.scripting.ScriptFactory; +import com.unicenta.pos.ticket.TicketLineInfo; +import lombok.extern.slf4j.Slf4j; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import javax.swing.*; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.JTableHeader; +import javax.swing.table.TableColumnModel; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import java.awt.*; +import java.io.IOException; +import java.io.StringReader; +import java.util.ArrayList; + +/** + * + * @author JG uniCenta + */ +@Slf4j +public class JTicketLines extends javax.swing.JPanel { + + private static SAXParser m_sp = null; + + private final TicketTableModel m_jTableModel; + private Boolean sendStatus; + + /** Creates new form JLinesTicket + * @param ticketline */ + public JTicketLines(String ticketline) { + + initComponents(); + + ColumnTicket[] acolumns = new ColumnTicket[0]; + + if (ticketline != null) { + try { + if (m_sp == null) { + SAXParserFactory spf = SAXParserFactory.newInstance(); + m_sp = spf.newSAXParser(); + } + ColumnsHandler columnshandler = new ColumnsHandler(); + m_sp.parse(new InputSource(new StringReader(ticketline)), columnshandler); + acolumns = columnshandler.getColumns(); + + } catch (ParserConfigurationException ePC) { + log.error(LocalRes.getIntString("exception.parserconfig"), ePC.getMessage()); + } catch (SAXException eSAX) { + log.error(LocalRes.getIntString("exception.xmlfile"), eSAX.getMessage()); + } catch (IOException eIO) { + log.error(LocalRes.getIntString("exception.iofile"), eIO); + } + } + + m_jTableModel = new TicketTableModel(acolumns); + m_jTicketTable.setModel(m_jTableModel); + + TableColumnModel jColumns = m_jTicketTable.getColumnModel(); + for (int i = 0; i < acolumns.length; i++) { + jColumns.getColumn(i).setPreferredWidth(acolumns[i].width); + jColumns.getColumn(i).setResizable(false); + } + + m_jScrollTableTicket.getVerticalScrollBar().setPreferredSize(new Dimension(35, 35)); + + // set font for headers + Font f = new Font("Arial", Font.BOLD, 14); + JTableHeader header = m_jTicketTable.getTableHeader(); + header.setFont(f); + +/* + * Starting point for SORTING the current table model & view + * m_aLines + TicketLineInfo also has to be considered BECAUSE.... + * where ticket is open on another terminal it won't reflect change from + * other session once placed and opened from sharedticket table + * + * m_jTicketTable.setRowSorter(new TableRowSorter(m_jTableModel)); + * m_jTicketTable.getTableHeader().setReorderingAllowed(true); + * m_jTicketTable.setAutoCreateRowSorter(true); + * m_jTicketTable.getTableHeader().addMouseListener(new MouseAdapter() { + * @Override + * public void mouseClicked(MouseEvent e) { + * int col = m_jTicketTable.columnAtPoint(e.getPoint()); + * String name = m_jTicketTable.getColumnName(col); + * System.out.println("Column index selected " + col + " " + name); + * } + * }); +*/ + + m_jTicketTable.setDefaultRenderer(Object.class, new TicketCellRenderer(acolumns)); + + m_jTicketTable.setRowHeight(40); + m_jTicketTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + m_jTableModel.clear(); + } + + /** + * + * @param l + */ + public void addListSelectionListener(ListSelectionListener l) { + m_jTicketTable.getSelectionModel().addListSelectionListener(l); + } + + /** + * + * @param l + */ + public void removeListSelectionListener(ListSelectionListener l) { + m_jTicketTable.getSelectionModel().removeListSelectionListener(l); + } + + /** + * + */ + public void clearTicketLines() { + m_jTableModel.clear(); + } + + /** + * + * @param index + * @param oLine + */ + public void setTicketLine(int index, TicketLineInfo oLine){ + m_jTableModel.setRow(index, oLine); + } + + /** + * + * @param oLine + */ + public void addTicketLine(TicketLineInfo oLine) { + m_jTableModel.addRow(oLine); + setSelectedIndex(m_jTableModel.getRowCount() - 1); + } + + /** + * + * @param index + * @param oLine + */ + public void insertTicketLine(int index, TicketLineInfo oLine) { + m_jTableModel.insertRow(index, oLine); + setSelectedIndex(index); + } + + /** + * + * @param i + */ + public void removeTicketLine(int i){ + m_jTableModel.removeRow(i); + + if (i >= m_jTableModel.getRowCount()) { + i = m_jTableModel.getRowCount() - 1; + } + + if ((i >= 0) && (i < m_jTableModel.getRowCount())) { + setSelectedIndex(i); + } + } + + /** + * + * @param i + */ + public void setSelectedIndex(int i){ + m_jTicketTable.getSelectionModel().setSelectionInterval(i, i); + Rectangle oRect = m_jTicketTable.getCellRect(i, 0, true); + m_jTicketTable.scrollRectToVisible(oRect); + + } + + /** + * + * @return + */ + public int getSelectedIndex() { + return m_jTicketTable.getSelectionModel().getMinSelectionIndex(); // solo sera uno, luego no importa... + } + + public int sortIndex(int i) { + int[] selection = m_jTicketTable.getSelectedRows(); + for (i = 0; i < selection.length; i++) { + selection[i] = m_jTicketTable.convertRowIndexToModel(selection[i]); + } + return m_jTicketTable.getRowSorter().convertRowIndexToView(i); + } + + /** + * + */ + public void selectionDown() { + int i = m_jTicketTable.getSelectionModel().getMaxSelectionIndex(); + if (i < 0){ + i = 0; + } else { + i ++; + if (i >= m_jTableModel.getRowCount()) { + i = m_jTableModel.getRowCount() - 1; + } + } + + if ((i >= 0) && (i < m_jTableModel.getRowCount())) { + setSelectedIndex(i); + } + } + + /** + * + */ + public void selectionUp() { + int i = m_jTicketTable.getSelectionModel().getMinSelectionIndex(); + if (i < 0){ + i = m_jTableModel.getRowCount() - 1; // No hay ninguna seleccionada + } else { + i --; + if (i < 0) { + i = 0; + } + } + + if ((i >= 0) && (i < m_jTableModel.getRowCount())) { + setSelectedIndex(i); + } + } + + + private static class TicketCellRenderer extends DefaultTableCellRenderer { + + private final ColumnTicket[] m_acolumns; + + public TicketCellRenderer(ColumnTicket[] acolumns) { + m_acolumns = acolumns; + } + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, + boolean isSelected, boolean hasFocus, int row, int column){ + + JLabel aux = (JLabel) super.getTableCellRendererComponent(table, value, + isSelected, hasFocus, row, column); + aux.setVerticalAlignment(javax.swing.SwingConstants.TOP); + aux.setHorizontalAlignment(m_acolumns[column].align); + Font fName =aux.getFont(); + aux.setFont(new Font(fName.getName(),Font.PLAIN,14)); + + return aux; + } + } + + private static class TicketCellRendererSent extends DefaultTableCellRenderer { + + private final ColumnTicket[] m_acolumns; + + public TicketCellRendererSent(ColumnTicket[] acolumns) { + m_acolumns = acolumns; + } + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, + boolean isSelected, boolean hasFocus, int row, int column){ + + JLabel aux = (JLabel) super.getTableCellRendererComponent(table, + value, isSelected, hasFocus, row, column); + + aux.setVerticalAlignment(javax.swing.SwingConstants.TOP); + aux.setHorizontalAlignment(m_acolumns[column].align); + Font fName =aux.getFont(); + aux.setFont(new Font(fName.getName(),Font.PLAIN,12)); + aux.setBackground(Color.yellow); + return aux; + } + } + + private static class TicketTableModel extends AbstractTableModel { + + private final ColumnTicket[] m_acolumns; + private final ArrayList m_rows = new ArrayList(); + + public TicketTableModel(ColumnTicket[] acolumns) { + m_acolumns = acolumns; + } + @Override + public int getRowCount() { + return m_rows.size(); + } + @Override + public int getColumnCount() { + return m_acolumns.length; + } + @Override + public String getColumnName(int column) { + return AppLocal.getIntString(m_acolumns[column].name); + // return m_acolumns[column].name; + } + @Override + public Object getValueAt(int row, int column) { + return ((String[]) m_rows.get(row))[column]; + } + + @Override + public boolean isCellEditable(int row, int column) { + return false; + } + + public void clear() { + int old = getRowCount(); + if (old > 0) { + m_rows.clear(); + fireTableRowsDeleted(0, old - 1); + } + } + + public void setRow(int index, TicketLineInfo oLine){ + + String[] row = (String []) m_rows.get(index); + for (int i = 0; i < m_acolumns.length; i++) { + try { + ScriptEngine script = ScriptFactory.getScriptEngine(ScriptFactory.VELOCITY); + script.put("ticketline", oLine); + row[i] = script.eval(m_acolumns[i].value).toString(); + } catch (ScriptException e) { + row[i] = null; + } + fireTableCellUpdated(index, i); + } + } + + public void addRow(TicketLineInfo oLine) { + + insertRow(m_rows.size(), oLine); + } + + public void insertRow(int index, TicketLineInfo oLine) { + + String[] row = new String[m_acolumns.length]; + for (int i = 0; i < m_acolumns.length; i++) { + try { + ScriptEngine script = ScriptFactory.getScriptEngine(ScriptFactory.VELOCITY); + script.put("ticketline", oLine); + row[i] = script.eval(m_acolumns[i].value).toString(); + } catch (ScriptException e) { + row[i] = null; + } + } + + m_rows.add(index, row); + fireTableRowsInserted(index, index); + } + + public void removeRow(int row) { + m_rows.remove(row); + fireTableRowsDeleted(row, row); + } + } + + private static class ColumnsHandler extends DefaultHandler { + + private ArrayList m_columns = null; + + public ColumnTicket[] getColumns() { + return (ColumnTicket[]) m_columns.toArray(new ColumnTicket[m_columns.size()]); + } + @Override + public void startDocument() throws SAXException { + m_columns = new ArrayList(); + } + @Override + public void endDocument() throws SAXException {} + @Override + public void startElement(String uri, String localName, String qName, + Attributes attributes) throws SAXException{ + if ("column".equals(qName)){ + ColumnTicket c = new ColumnTicket(); + c.name = attributes.getValue("name"); + c.width = Integer.parseInt(attributes.getValue("width")); + String sAlign = attributes.getValue("align"); + switch (sAlign) { + case "right": + c.align = javax.swing.SwingConstants.RIGHT; + break; + case "center": + c.align = javax.swing.SwingConstants.CENTER; + break; + default: + c.align = javax.swing.SwingConstants.LEFT; + break; + } + c.value = attributes.getValue("value"); + m_columns.add(c); + } + } + @Override + public void endElement(String uri, String localName, String qName) throws SAXException {} + @Override + public void characters(char[] ch, int start, int length) throws SAXException {} + } + + /** + * + * @param state + */ + public void setSendStatus(Boolean state){ + sendStatus = state; + } + + private static class ColumnTicket { + public String name; + public int width; + public int align; + public String value; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jScrollTableTicket = new javax.swing.JScrollPane(); + m_jTicketTable = new javax.swing.JTable(); + + setLayout(new java.awt.BorderLayout()); + + m_jScrollTableTicket.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + m_jScrollTableTicket.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + m_jScrollTableTicket.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + + m_jTicketTable.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jTicketTable.setFocusable(false); + m_jTicketTable.setIntercellSpacing(new java.awt.Dimension(0, 1)); + m_jTicketTable.setRequestFocusEnabled(false); + m_jTicketTable.setShowVerticalLines(false); + m_jScrollTableTicket.setViewportView(m_jTicketTable); + + add(m_jScrollTableTicket, java.awt.BorderLayout.CENTER); + }// </editor-fold>//GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JScrollPane m_jScrollTableTicket; + private javax.swing.JTable m_jTicketTable; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/JTicketsBag.java b/src/main/java/com/unicenta/pos/sales/JTicketsBag.java new file mode 100644 index 0000000..205b463 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JTicketsBag.java @@ -0,0 +1,86 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.sales.restaurant.JTicketsBagRestaurantMap; +import com.unicenta.pos.sales.restaurant.JTicketsBagRestaurant; +import com.unicenta.pos.sales.shared.JTicketsBagShared; +import com.unicenta.pos.sales.simple.JTicketsBagSimple; +import javax.swing.JComponent; +import javax.swing.JPanel; + +/** + * + * @author JG uniCenta + */ +public abstract class JTicketsBag extends JPanel { + + /** + * + */ + protected AppView m_App; + + /** + * + */ + protected DataLogicSales m_dlSales; + + /** + * + */ + protected TicketsEditor m_panelticket; + + /** Creates new form JTicketsBag + * @param oApp + * @param panelticket */ + public JTicketsBag(AppView oApp, TicketsEditor panelticket) { + m_App = oApp; + m_panelticket = panelticket; + m_dlSales = (DataLogicSales) m_App.getBean("com.unicenta.pos.forms.DataLogicSales"); + } + + public abstract void activate(); + public abstract boolean deactivate(); + public abstract void deleteTicket(); + protected abstract JComponent getBagComponent(); + protected abstract JComponent getNullComponent(); + + /** + * + * @param sName + * @param app + * @param panelticket + * @return + */ + public static JTicketsBag createTicketsBag(String sName, AppView app, TicketsEditor panelticket) { + switch (sName) { + case "standard": + // return new JTicketsBagMulti(oApp, user, panelticket); + return new JTicketsBagShared(app, panelticket); + case "restaurant": + return new JTicketsBagRestaurantMap(app, panelticket); + default: + // "simple" + return new JTicketsBagSimple(app, panelticket); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/sales/JTicketsBagTicket.form b/src/main/java/com/unicenta/pos/sales/JTicketsBagTicket.form new file mode 100644 index 0000000..3cb7c25 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JTicketsBagTicket.form @@ -0,0 +1,397 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <NonVisualComponents> + <Component class="javax.swing.ButtonGroup" name="buttonGroup1"> + </Component> + </NonVisualComponents> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-63,0,0,2,68"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="m_jOptions"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="m_jButtons"> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jTicketId" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="32767" attributes="0"/> + <Component id="jButton2" min="-2" max="-2" attributes="0"/> + <EmptySpace min="5" pref="5" max="-2" attributes="0"/> + <Component id="m_jEdit" min="-2" max="-2" attributes="0"/> + <EmptySpace min="5" pref="5" max="-2" attributes="0"/> + <Component id="m_jRefund" min="-2" max="-2" attributes="0"/> + <EmptySpace min="5" pref="5" max="-2" attributes="0"/> + <Component id="m_jPrint" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jTicketId" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <EmptySpace min="5" pref="5" max="-2" attributes="0"/> + <Component id="jButton2" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <EmptySpace min="5" pref="5" max="-2" attributes="0"/> + <Component id="m_jEdit" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <EmptySpace min="5" pref="5" max="-2" attributes="0"/> + <Component id="m_jRefund" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <EmptySpace min="5" pref="5" max="-2" attributes="0"/> + <Component id="m_jPrint" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="m_jTicketId"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" id="white" palette="0" red="ff" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jButton2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="11" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/search24.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.ticketsearch" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 4, 0, 4]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton2ActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jEdit"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="11" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/sale_editline.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.ticketedit" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 4, 0, 4]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jEditActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jRefund"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="11" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/inbox.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.ticketrefund" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 4, 0, 4]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jRefundActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jPrint"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="11" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/printer24.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.ticketreprint" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 4, 0, 4]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jPrintActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel2"> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="0"/> + </Layout> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="m_jPanelTicket"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + </Container> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> + <Property name="axis" type="int" value="1"/> + </Layout> + <SubComponents> + <Component class="com.unicenta.editor.JEditorKeys" name="m_jKeys"> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jKeysActionPerformed"/> + </Events> + </Component> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> + <SubComponents> + <Component class="javax.swing.JButton" name="jButton1"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.edit.findticket" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton1ActionPerformed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="com.unicenta.editor.JEditorIntegerPositive" name="m_jTicketEditor"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[130, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JRadioButton" name="jrbSales"> + <Properties> + <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor"> + <ComponentRef name="buttonGroup1"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="1"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.sales" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.edit.salesopt" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JRadioButton" name="jrbRefunds"> + <Properties> + <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor"> + <ComponentRef name="buttonGroup1"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="1"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="0" green="0" red="ff" type="rgb"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.refunds" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.edit.refundopt" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/JTicketsBagTicket.java b/src/main/java/com/unicenta/pos/sales/JTicketsBagTicket.java new file mode 100644 index 0000000..01ff78b --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JTicketsBagTicket.java @@ -0,0 +1,613 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.pos.customers.DataLogicCustomers; +import com.unicenta.pos.panels.JTicketsFinder; +import com.unicenta.pos.ticket.FindTicketsInfo; +import com.unicenta.pos.ticket.TicketTaxInfo; +import java.awt.*; +import java.util.ArrayList; +import javax.swing.*; +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.JMessageDialog; +import com.unicenta.data.gui.ListKeyed; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppProperties; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.forms.DataLogicSystem; +import com.unicenta.pos.printer.DeviceTicket; +import com.unicenta.pos.printer.TicketParser; +import com.unicenta.pos.printer.TicketPrinterException; +import com.unicenta.pos.scripting.ScriptEngine; +import com.unicenta.pos.scripting.ScriptException; +import com.unicenta.pos.scripting.ScriptFactory; +import com.unicenta.pos.ticket.TicketInfo; +import com.unicenta.pos.ticket.TicketLineInfo; + +/** + * + * @author JG uniCenta + */ +public class JTicketsBagTicket extends JTicketsBag { + + private DataLogicSystem m_dlSystem = null; + protected DataLogicCustomers dlCustomers = null; + private final DataLogicSales m_dlSales; + + private TaxesLogic taxeslogic; + private ListKeyed taxcollection; + + private final DeviceTicket m_TP; + private final TicketParser m_TTP; + private final TicketParser m_TTP2; + + private TicketInfo m_ticket; + private TicketInfo m_ticketCopy; + + private final JTicketsBagTicketBag m_TicketsBagTicketBag; + private final JPanelTicketEdits m_panelticketedit; + + private final AppView m_App; + + /** Creates new form JTicketsBagTicket + * @param app + * @param panelticket */ + public JTicketsBagTicket(AppView app, JPanelTicketEdits panelticket) { + + super(app, panelticket); + m_App = app; + + m_panelticketedit = panelticket; + m_dlSystem = (DataLogicSystem) m_App.getBean("com.unicenta.pos.forms.DataLogicSystem"); + m_dlSales = (DataLogicSales) m_App.getBean("com.unicenta.pos.forms.DataLogicSales"); + dlCustomers = (DataLogicCustomers) m_App.getBean("com.unicenta.pos.customers.DataLogicCustomers"); + AppProperties props = null; + + m_TP = new DeviceTicket(); + + m_TTP = new TicketParser(m_TP, m_dlSystem); // display ticket + m_TTP2 = new TicketParser(m_App.getDeviceTicket(), m_dlSystem); // print ticket + + initComponents(); + + m_TicketsBagTicketBag = new JTicketsBagTicketBag(this); + + m_jTicketEditor.addEditorKeys(m_jKeys); + + m_jPanelTicket.add(m_TP.getDevicePrinter("1").getPrinterComponent(), BorderLayout.CENTER); + + try { + taxeslogic = new TaxesLogic(m_dlSales.getTaxList().list()); + } catch (BasicException ex) { + } + } + + /** + * + */ + @Override + public void activate() { + + m_ticket = null; + m_ticketCopy = null; + + printTicket(); + + m_jTicketEditor.reset(); + m_jTicketEditor.activate(); + + m_panelticketedit.setActiveTicket(null, null); + + jrbSales.setSelected(true); + + m_jEdit.setVisible(m_App.getAppUserView().getUser().hasPermission("sales.EditTicket")); + m_jRefund.setVisible(m_App.getAppUserView().getUser().hasPermission("sales.RefundTicket")); + m_jPrint.setVisible(m_App.getAppUserView().getUser().hasPermission("sales.PrintTicket")); + + } + + /** + * + * @return + */ + @Override + public boolean deactivate() { + + m_ticket = null; + m_ticketCopy = null; + return true; + + } + + /** + * + */ + @Override + public void deleteTicket() { + + if (m_ticketCopy != null) { + try { + m_dlSales.deleteTicket(m_ticketCopy, m_App.getInventoryLocation()); + } catch (BasicException eData) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, + AppLocal.getIntString("message.nosaveticket"), + eData); + msg.show(this); + } + } + + m_ticket = null; + m_ticketCopy = null; + resetToTicket(); + } + + /** + * + */ + public void canceleditionTicket() { + + m_ticketCopy = null; + resetToTicket(); + } + + private void resetToTicket() { + printTicket(); + m_jTicketEditor.reset(); + m_jTicketEditor.activate(); + m_panelticketedit.setActiveTicket(null, null); + } + + /** + * + * @return + */ + @Override + protected JComponent getBagComponent() { + return m_TicketsBagTicketBag; + } + + /** + * + * @return + */ + @Override + protected JComponent getNullComponent() { + return this; + } + + private void readTicket(int iTicketid, int iTickettype) { + Integer findTicket=0; + try { + findTicket = m_jTicketEditor.getValueInteger(); + }catch (Exception e){ + } + + try { + + TicketInfo ticket = (iTicketid==-1) + ? m_dlSales.loadTicket(iTickettype, findTicket) + : m_dlSales.loadTicket(iTickettype, iTicketid) ; + + if (ticket == null) { + JFrame frame = new JFrame(); + JOptionPane.showMessageDialog(frame, + AppLocal.getIntString("message.notexiststicket"), + AppLocal.getIntString("message.notexiststickettitle"), + JOptionPane.WARNING_MESSAGE); + + } else { + m_ticket = ticket; + m_ticketCopy = null; + if(m_ticket.getTicketStatus()> 0) { + JFrame frame = new JFrame(); + JOptionPane.showMessageDialog(frame, + AppLocal.getIntString("message.ticketrefunded"), + AppLocal.getIntString("message.ticketrefundedtitle"), + JOptionPane.WARNING_MESSAGE); + m_jEdit.setEnabled(false); + m_jRefund.setEnabled(false); + }else{ + if (m_ticket.getTicketStatus() > 0) { + m_jEdit.setEnabled(false); + m_jRefund.setEnabled(false); + } else { + m_jEdit.setEnabled(true); + m_jRefund.setEnabled(true); + } + } + try { + taxeslogic.calculateTaxes(m_ticket); + TicketTaxInfo[] taxlist = m_ticket.getTaxLines(); + } catch (TaxesException ex) {} + + printTicket(); + } + + } catch (BasicException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.cannotloadticket"), e); + msg.show(this); + } + + m_jTicketEditor.reset(); + m_jTicketEditor.activate(); + } + + private void printTicket() { + + try { + m_jEdit.setEnabled( + m_ticket != null + && (m_ticket.getTicketType() == TicketInfo.RECEIPT_NORMAL + && m_ticket.getTicketStatus() == 0) + && m_dlSales.isCashActive(m_ticket.getActiveCash())); + } catch (BasicException e) { + m_jEdit.setEnabled(false); + m_jRefund.setEnabled(false); + } + + if (m_ticket != null + && (m_ticket.getTicketType() == TicketInfo.RECEIPT_NORMAL + && m_ticket.getTicketStatus() == 0)) { + m_jRefund.setEnabled(true); + } + + m_jPrint.setEnabled(m_ticket != null); + + m_TP.getDevicePrinter("1").reset(); + + if (m_ticket == null) { + m_jTicketId.setText(null); + } else { + m_jTicketId.setText(m_ticket.getName()); + + try { + ScriptEngine script = ScriptFactory.getScriptEngine(ScriptFactory.VELOCITY); + script.put("ticket", m_ticket); + script.put("taxes", m_ticket.getTaxLines()); + m_TTP.printTicket(script.eval(m_dlSystem.getResourceAsXML("Printer.TicketPreview")).toString()); + } catch ( ScriptException | TicketPrinterException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.cannotprintticket"), e); + msg.show(this); + } + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + buttonGroup1 = new javax.swing.ButtonGroup(); + m_jOptions = new javax.swing.JPanel(); + m_jButtons = new javax.swing.JPanel(); + m_jTicketId = new javax.swing.JLabel(); + jButton2 = new javax.swing.JButton(); + m_jEdit = new javax.swing.JButton(); + m_jRefund = new javax.swing.JButton(); + m_jPrint = new javax.swing.JButton(); + jPanel2 = new javax.swing.JPanel(); + m_jPanelTicket = new javax.swing.JPanel(); + jPanel3 = new javax.swing.JPanel(); + jPanel4 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel5 = new javax.swing.JPanel(); + jButton1 = new javax.swing.JButton(); + m_jTicketEditor = new com.unicenta.editor.JEditorIntegerPositive(); + jPanel1 = new javax.swing.JPanel(); + jrbSales = new javax.swing.JRadioButton(); + jrbRefunds = new javax.swing.JRadioButton(); + + setLayout(new java.awt.BorderLayout()); + + m_jTicketId.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jTicketId.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + m_jTicketId.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jTicketId.setOpaque(true); + m_jTicketId.setPreferredSize(new java.awt.Dimension(200, 30)); + m_jTicketId.setRequestFocusEnabled(false); + + jButton2.setFont(new java.awt.Font("Arial", 0, 11)); // NOI18N + jButton2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/search24.png"))); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jButton2.setToolTipText(bundle.getString("tooltip.ticketsearch")); // NOI18N + jButton2.setFocusPainted(false); + jButton2.setFocusable(false); + jButton2.setMargin(new java.awt.Insets(0, 4, 0, 4)); + jButton2.setMaximumSize(new java.awt.Dimension(50, 40)); + jButton2.setMinimumSize(new java.awt.Dimension(50, 40)); + jButton2.setPreferredSize(new java.awt.Dimension(80, 45)); + jButton2.setRequestFocusEnabled(false); + jButton2.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton2ActionPerformed(evt); + } + }); + + m_jEdit.setFont(new java.awt.Font("Arial", 0, 11)); // NOI18N + m_jEdit.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/sale_editline.png"))); // NOI18N + m_jEdit.setToolTipText(bundle.getString("tooltip.ticketedit")); // NOI18N + m_jEdit.setFocusPainted(false); + m_jEdit.setFocusable(false); + m_jEdit.setMargin(new java.awt.Insets(0, 4, 0, 4)); + m_jEdit.setMaximumSize(new java.awt.Dimension(50, 40)); + m_jEdit.setMinimumSize(new java.awt.Dimension(50, 40)); + m_jEdit.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jEdit.setRequestFocusEnabled(false); + m_jEdit.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jEditActionPerformed(evt); + } + }); + + m_jRefund.setFont(new java.awt.Font("Arial", 0, 11)); // NOI18N + m_jRefund.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/inbox.png"))); // NOI18N + m_jRefund.setToolTipText(bundle.getString("tooltip.ticketrefund")); // NOI18N + m_jRefund.setFocusPainted(false); + m_jRefund.setFocusable(false); + m_jRefund.setMargin(new java.awt.Insets(0, 4, 0, 4)); + m_jRefund.setMaximumSize(new java.awt.Dimension(50, 40)); + m_jRefund.setMinimumSize(new java.awt.Dimension(50, 40)); + m_jRefund.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jRefund.setRequestFocusEnabled(false); + m_jRefund.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jRefundActionPerformed(evt); + } + }); + + m_jPrint.setFont(new java.awt.Font("Arial", 0, 11)); // NOI18N + m_jPrint.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/printer24.png"))); // NOI18N + m_jPrint.setToolTipText(bundle.getString("tooltip.ticketreprint")); // NOI18N + m_jPrint.setFocusPainted(false); + m_jPrint.setFocusable(false); + m_jPrint.setMargin(new java.awt.Insets(0, 4, 0, 4)); + m_jPrint.setMaximumSize(new java.awt.Dimension(50, 40)); + m_jPrint.setMinimumSize(new java.awt.Dimension(50, 40)); + m_jPrint.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jPrint.setRequestFocusEnabled(false); + m_jPrint.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jPrintActionPerformed(evt); + } + }); + + org.jdesktop.layout.GroupLayout m_jButtonsLayout = new org.jdesktop.layout.GroupLayout(m_jButtons); + m_jButtons.setLayout(m_jButtonsLayout); + m_jButtonsLayout.setHorizontalGroup( + m_jButtonsLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(m_jButtonsLayout.createSequentialGroup() + .addContainerGap() + .add(m_jTicketId, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .add(jButton2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(5, 5, 5) + .add(m_jEdit, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(5, 5, 5) + .add(m_jRefund, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .add(5, 5, 5) + .add(m_jPrint, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + ); + m_jButtonsLayout.setVerticalGroup( + m_jButtonsLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(m_jButtonsLayout.createSequentialGroup() + .addContainerGap() + .add(m_jTicketId, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(m_jButtonsLayout.createSequentialGroup() + .add(5, 5, 5) + .add(jButton2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(m_jButtonsLayout.createSequentialGroup() + .add(5, 5, 5) + .add(m_jEdit, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(m_jButtonsLayout.createSequentialGroup() + .add(5, 5, 5) + .add(m_jRefund, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .add(m_jButtonsLayout.createSequentialGroup() + .add(5, 5, 5) + .add(m_jPrint, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + ); + + m_jOptions.add(m_jButtons); + + jPanel2.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT)); + m_jOptions.add(jPanel2); + + add(m_jOptions, java.awt.BorderLayout.NORTH); + + m_jPanelTicket.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + m_jPanelTicket.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N + m_jPanelTicket.setLayout(new java.awt.BorderLayout()); + add(m_jPanelTicket, java.awt.BorderLayout.CENTER); + + jPanel3.setLayout(new java.awt.BorderLayout()); + + jPanel4.setLayout(new javax.swing.BoxLayout(jPanel4, javax.swing.BoxLayout.Y_AXIS)); + + m_jKeys.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jKeysActionPerformed(evt); + } + }); + jPanel4.add(m_jKeys); + + jPanel5.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel5.setLayout(new java.awt.GridBagLayout()); + + jButton1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jButton1.setToolTipText(bundle.getString("tooltip.edit.findticket")); // NOI18N + jButton1.setFocusPainted(false); + jButton1.setFocusable(false); + jButton1.setMargin(new java.awt.Insets(8, 14, 8, 14)); + jButton1.setPreferredSize(new java.awt.Dimension(80, 45)); + jButton1.setRequestFocusEnabled(false); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + jPanel5.add(jButton1, gridBagConstraints); + + m_jTicketEditor.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jTicketEditor.setPreferredSize(new java.awt.Dimension(130, 30)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + jPanel5.add(m_jTicketEditor, gridBagConstraints); + + jPanel4.add(jPanel5); + + jPanel3.add(jPanel4, java.awt.BorderLayout.NORTH); + + buttonGroup1.add(jrbSales); + jrbSales.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + jrbSales.setText(AppLocal.getIntString("label.sales")); // NOI18N + jrbSales.setToolTipText(bundle.getString("tooltip.edit.salesopt")); // NOI18N + jrbSales.setFocusPainted(false); + jrbSales.setFocusable(false); + jrbSales.setRequestFocusEnabled(false); + jPanel1.add(jrbSales); + + buttonGroup1.add(jrbRefunds); + jrbRefunds.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + jrbRefunds.setForeground(new java.awt.Color(255, 0, 0)); + jrbRefunds.setText(AppLocal.getIntString("label.refunds")); // NOI18N + jrbRefunds.setToolTipText(bundle.getString("tooltip.edit.refundopt")); // NOI18N + jrbRefunds.setFocusPainted(false); + jrbRefunds.setFocusable(false); + jrbRefunds.setRequestFocusEnabled(false); + jPanel1.add(jrbRefunds); + + jPanel3.add(jPanel1, java.awt.BorderLayout.CENTER); + + add(jPanel3, java.awt.BorderLayout.EAST); + }// </editor-fold>//GEN-END:initComponents + + private void m_jEditActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jEditActionPerformed + + m_ticketCopy = m_ticket; + m_TicketsBagTicketBag.showEdit(); + m_panelticketedit.showCatalog(); + m_ticketCopy.setOldTicket(true); + m_panelticketedit.setActiveTicket(m_ticket.copyTicket(), null); + + }//GEN-LAST:event_m_jEditActionPerformed + + private void m_jPrintActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jPrintActionPerformed + + if (m_ticket != null) { + try { + ScriptEngine script = ScriptFactory.getScriptEngine(ScriptFactory.VELOCITY); + script.put("ticket", m_ticket); + script.put("taxes", m_ticket.getTaxLines()); + m_TTP2.printTicket(script.eval(m_dlSystem.getResourceAsXML("Printer.TicketPreview")).toString()); + } catch (ScriptException | TicketPrinterException e) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_NOTICE, + AppLocal.getIntString("message.cannotprint"), e)); + } + } + + }//GEN-LAST:event_m_jPrintActionPerformed + + private void m_jRefundActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jRefundActionPerformed + + java.util.List aRefundLines = new ArrayList(); + + for(int i = 0; i < m_ticket.getLinesCount(); i++) { + TicketLineInfo newline = new TicketLineInfo(m_ticket.getLine(i)); + aRefundLines.add(newline); + } + + m_ticketCopy = null; + m_TicketsBagTicketBag.showRefund(); + m_panelticketedit.showRefundLines(aRefundLines); + + TicketInfo refundticket = new TicketInfo(); + refundticket.setTicketType(TicketInfo.RECEIPT_REFUND); + refundticket.setTicketStatus(m_ticket.getTicketId()); + refundticket.setCustomer(m_ticket.getCustomer()); + refundticket.setPayments(m_ticket.getPayments()); + refundticket.setOldTicket(true); + m_panelticketedit.setActiveTicket(refundticket, null); + }//GEN-LAST:event_m_jRefundActionPerformed + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + + readTicket(-1, jrbSales.isSelected() ? 0 : 1); + + }//GEN-LAST:event_jButton1ActionPerformed + + private void m_jKeysActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jKeysActionPerformed + + readTicket(-1, jrbSales.isSelected() ? 0 : 1); + + }//GEN-LAST:event_m_jKeysActionPerformed + +private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed + JTicketsFinder finder = JTicketsFinder.getReceiptFinder(this, m_dlSales, dlCustomers); + finder.setVisible(true); + FindTicketsInfo selectedTicket = finder.getSelectedCustomer(); + + if (selectedTicket == null) { + m_jTicketEditor.reset(); + m_jTicketEditor.activate(); + } else { + readTicket(selectedTicket.getTicketId(), selectedTicket.getTicketType()); + } +}//GEN-LAST:event_jButton2ActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.ButtonGroup buttonGroup1; + private javax.swing.JButton jButton1; + private javax.swing.JButton jButton2; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JRadioButton jrbRefunds; + private javax.swing.JRadioButton jrbSales; + private javax.swing.JPanel m_jButtons; + private javax.swing.JButton m_jEdit; + private com.unicenta.editor.JEditorKeys m_jKeys; + private javax.swing.JPanel m_jOptions; + private javax.swing.JPanel m_jPanelTicket; + private javax.swing.JButton m_jPrint; + private javax.swing.JButton m_jRefund; + private com.unicenta.editor.JEditorIntegerPositive m_jTicketEditor; + private javax.swing.JLabel m_jTicketId; + // End of variables declaration//GEN-END:variables + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/sales/JTicketsBagTicketBag.form b/src/main/java/com/unicenta/pos/sales/JTicketsBagTicketBag.form new file mode 100644 index 0000000..b112f2f --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JTicketsBagTicketBag.form @@ -0,0 +1,128 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,52,0,0,1,-112"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignCardLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanEdit"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription"> + <CardConstraints cardName="edit"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="0"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="m_jBtnDelete"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/sale_delete.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.deleteticket" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Delete current Ticket"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 4, 0, 4]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jBtnDeleteActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jBtnCancel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.cancel" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Cancel Action"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 4, 0, 4]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jBtnCancelActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanRefund"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription"> + <CardConstraints cardName="refund"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="0"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="m_jBtnCancel1"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/fileclose.png"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jBtnCancel1ActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/JTicketsBagTicketBag.java b/src/main/java/com/unicenta/pos/sales/JTicketsBagTicketBag.java new file mode 100644 index 0000000..1fcea34 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/JTicketsBagTicketBag.java @@ -0,0 +1,170 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.pos.forms.AppLocal; +import java.awt.CardLayout; +import javax.swing.JOptionPane; + +/** + * + * @author JG uniCenta + */ +public class JTicketsBagTicketBag extends javax.swing.JPanel { + + private final JTicketsBagTicket m_ticketsbagticket; + + /** Creates new form JTicketsBagTicketBag + * @param ticketsbagticket */ + public JTicketsBagTicketBag(JTicketsBagTicket ticketsbagticket) { + m_ticketsbagticket = ticketsbagticket; + initComponents(); + } + + /** + * + */ + public void showEdit() { + showView("edit"); + } + + /** + * + */ + public void showRefund() { + showView("refund"); + } + + private void showView(String view) { + CardLayout cl = (CardLayout)(getLayout()); + cl.show(this, view); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanEdit = new javax.swing.JPanel(); + m_jBtnDelete = new javax.swing.JButton(); + m_jBtnCancel = new javax.swing.JButton(); + jPanRefund = new javax.swing.JPanel(); + m_jBtnCancel1 = new javax.swing.JButton(); + + setLayout(new java.awt.CardLayout()); + + jPanEdit.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT)); + + m_jBtnDelete.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jBtnDelete.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/sale_delete.png"))); // NOI18N + m_jBtnDelete.setText(AppLocal.getIntString("button.deleteticket")); // NOI18N + m_jBtnDelete.setToolTipText("Delete current Ticket"); + m_jBtnDelete.setFocusPainted(false); + m_jBtnDelete.setFocusable(false); + m_jBtnDelete.setMargin(new java.awt.Insets(0, 4, 0, 4)); + m_jBtnDelete.setMaximumSize(new java.awt.Dimension(50, 40)); + m_jBtnDelete.setMinimumSize(new java.awt.Dimension(50, 40)); + m_jBtnDelete.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jBtnDelete.setRequestFocusEnabled(false); + m_jBtnDelete.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jBtnDeleteActionPerformed(evt); + } + }); + jPanEdit.add(m_jBtnDelete); + + m_jBtnCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jBtnCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + m_jBtnCancel.setText(AppLocal.getIntString("button.cancel")); // NOI18N + m_jBtnCancel.setToolTipText("Cancel Action"); + m_jBtnCancel.setFocusPainted(false); + m_jBtnCancel.setFocusable(false); + m_jBtnCancel.setMargin(new java.awt.Insets(0, 4, 0, 4)); + m_jBtnCancel.setMaximumSize(new java.awt.Dimension(50, 40)); + m_jBtnCancel.setMinimumSize(new java.awt.Dimension(50, 40)); + m_jBtnCancel.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jBtnCancel.setRequestFocusEnabled(false); + m_jBtnCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jBtnCancelActionPerformed(evt); + } + }); + jPanEdit.add(m_jBtnCancel); + + add(jPanEdit, "edit"); + + jPanRefund.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT)); + + m_jBtnCancel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/fileclose.png"))); // NOI18N + m_jBtnCancel1.setFocusPainted(false); + m_jBtnCancel1.setFocusable(false); + m_jBtnCancel1.setMargin(new java.awt.Insets(8, 14, 8, 14)); + m_jBtnCancel1.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jBtnCancel1.setRequestFocusEnabled(false); + m_jBtnCancel1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jBtnCancel1ActionPerformed(evt); + } + }); + jPanRefund.add(m_jBtnCancel1); + + add(jPanRefund, "refund"); + }// </editor-fold>//GEN-END:initComponents + + private void m_jBtnCancel1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jBtnCancel1ActionPerformed + + m_ticketsbagticket.canceleditionTicket(); + + }//GEN-LAST:event_m_jBtnCancel1ActionPerformed + + private void m_jBtnDeleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jBtnDeleteActionPerformed + + int res = JOptionPane.showConfirmDialog(this, + AppLocal.getIntString("message.wannadelete"), + AppLocal.getIntString("title.editor"), + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE); + + if (res == JOptionPane.YES_OPTION) { + m_ticketsbagticket.deleteTicket(); + + } + + }//GEN-LAST:event_m_jBtnDeleteActionPerformed + + private void m_jBtnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jBtnCancelActionPerformed + + m_ticketsbagticket.canceleditionTicket(); + + }//GEN-LAST:event_m_jBtnCancelActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanEdit; + private javax.swing.JPanel jPanRefund; + private javax.swing.JButton m_jBtnCancel; + private javax.swing.JButton m_jBtnCancel1; + private javax.swing.JButton m_jBtnDelete; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/KitchenDisplay.java b/src/main/java/com/unicenta/pos/sales/KitchenDisplay.java new file mode 100644 index 0000000..e32e3aa --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/KitchenDisplay.java @@ -0,0 +1,86 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.unicenta.pos.sales; + +import com.unicenta.data.loader.Session; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSystem; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.Statement; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * + * @author Administrator + */ +public class KitchenDisplay { + private Session s; + private Connection con; + private Statement stmt; + private PreparedStatement pstmt; + private String SQL; + private ResultSet rs; + private AppView m_App; + + /** + * + */ + protected DataLogicSystem dlSystem; + + /** + * + * @param oApp + */ + public KitchenDisplay(AppView oApp) { + m_App=oApp; + +//get database connection details + try{ + s=m_App.getSession(); + con=s.getConnection(); + } +// catch (Exception e){System.out.print("No session or connection"); + catch (Exception e){ } + } + + /** + * + * @param ID + * @param table + * @param pickupID + * @param product + * @param multiply + * @param attributes + */ + public void addRecord(String ID, String table, String pickupID, String product, String multiply, String attributes){ + DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); + Date date = new Date(); + + try{ + SQL = "INSERT INTO KITCHENDISPLAY (ID, ORDERTIME, PLACE, PICKUPID, PRODUCT, MULTIPLY, ATTRIBUTES) VALUES (?, ?, ?, ?, ?, ?, ?) "; + pstmt=con.prepareStatement(SQL); + pstmt.setString(1,ID); + pstmt.setString(2,dateFormat.format(date).toString()); + pstmt.setString(3,table); + pstmt.setString(4,pickupID); + pstmt.setString(5,product); + pstmt.setString(6,multiply); + pstmt.setString(7,attributes); + pstmt.executeUpdate(); + }catch(Exception e){ + } + + } + + +// stmt = (Statement) con.createStatement(); +// rs = stmt.executeQuery(SQL); + + +} diff --git a/src/main/java/com/unicenta/pos/sales/MenuActionListener.java b/src/main/java/com/unicenta/pos/sales/MenuActionListener.java new file mode 100644 index 0000000..dd891bf --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/MenuActionListener.java @@ -0,0 +1,14 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.unicenta.pos.sales; + +/** + * + * @author jack + */ +public class MenuActionListener { + +} diff --git a/src/main/java/com/unicenta/pos/sales/ReceiptSplit.form b/src/main/java/com/unicenta/pos/sales/ReceiptSplit.form new file mode 100644 index 0000000..2aa28a8 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/ReceiptSplit.form @@ -0,0 +1,235 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="caption.split" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="resizable" type="boolean" value="false"/> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-42,0,0,2,-38"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="2"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="m_jButtonCancel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.cancel" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jButtonCancelActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jButtonOK"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.OK" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jButtonOKActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + </Container> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> + <SubComponents> + <Component class="javax.swing.JButton" name="jBtnToRightAll"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/2rightarrow.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Split All Line Items"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnToRightAllActionPerformed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="-1" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JButton" name="jBtnToRightOne"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/1rightarrow.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Split only one of the Line Items"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnToRightOneActionPerformed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="-1" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JButton" name="jBtnToLeftOne"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/1leftarrow.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Un-Split only one of the Line Items"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnToLeftOneActionPerformed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="-1" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JButton" name="jBtnToLeftAll"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/2leftarrow.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Un-Split All Line Items"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnToLeftAllActionPerformed"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="-1" gridY="3" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/ReceiptSplit.java b/src/main/java/com/unicenta/pos/sales/ReceiptSplit.java new file mode 100644 index 0000000..33652f2 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/ReceiptSplit.java @@ -0,0 +1,339 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.pos.customers.DataLogicCustomers; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.ticket.TicketInfo; +import com.unicenta.pos.ticket.TicketLineInfo; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.Window; +import javax.swing.JFrame; + +/** + * + * @author adrianromero + */ +public class ReceiptSplit extends javax.swing.JDialog { + + private boolean accepted; + + SimpleReceipt receiptone; + SimpleReceipt receipttwo; + + /** Creates new form ReceiptSplit + * @param parent */ + protected ReceiptSplit(java.awt.Frame parent) { + super(parent, true); + } + /** Creates new form ReceiptSplit + * @param parent */ + protected ReceiptSplit(java.awt.Dialog parent) { + super(parent, true); + } + + private void init(String ticketline, DataLogicSales dlSales, DataLogicCustomers dlCustomers, TaxesLogic taxeslogic) { + + initComponents(); + getRootPane().setDefaultButton(m_jButtonOK); + + receiptone = new SimpleReceipt(ticketline, dlSales, dlCustomers, taxeslogic); + receiptone.setCustomerEnabled(false); + jPanel5.add(receiptone, BorderLayout.CENTER); + + receipttwo = new SimpleReceipt(ticketline, dlSales, dlCustomers, taxeslogic); + jPanel3.add(receipttwo, BorderLayout.CENTER); + } + + /** + * + * @param parent + * @param ticketline + * @param dlSales + * @param dlCustomers + * @param taxeslogic + * @return + */ + public static ReceiptSplit getDialog(Component parent, String ticketline, DataLogicSales dlSales, DataLogicCustomers dlCustomers, TaxesLogic taxeslogic) { + + Window window = getWindow(parent); + + ReceiptSplit myreceiptsplit; + + if (window instanceof Frame) { + myreceiptsplit = new ReceiptSplit((Frame) window); + } else { + myreceiptsplit = new ReceiptSplit((Dialog) window); + } + + myreceiptsplit.init(ticketline, dlSales, dlCustomers, taxeslogic); + + return myreceiptsplit; + } + + /** + * + * @param parent + * @return + */ + protected static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window)parent; + } else { + return getWindow(parent.getParent()); + } + } + + /** + * + * @param ticket + * @param ticket2 + * @param ticketext + * @return + */ + public boolean showDialog(TicketInfo ticket, TicketInfo ticket2, Object ticketext) { + + receiptone.setTicket(ticket, ticketext); + receipttwo.setTicket(ticket2, ticketext); + + setVisible(true); + return accepted; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + jPanel2 = new javax.swing.JPanel(); + m_jButtonCancel = new javax.swing.JButton(); + m_jButtonOK = new javax.swing.JButton(); + jPanel1 = new javax.swing.JPanel(); + jPanel5 = new javax.swing.JPanel(); + jPanel4 = new javax.swing.JPanel(); + jBtnToRightAll = new javax.swing.JButton(); + jBtnToRightOne = new javax.swing.JButton(); + jBtnToLeftOne = new javax.swing.JButton(); + jBtnToLeftAll = new javax.swing.JButton(); + jPanel3 = new javax.swing.JPanel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(AppLocal.getIntString("caption.split")); // NOI18N + setResizable(false); + + jPanel2.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT)); + + m_jButtonCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jButtonCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + m_jButtonCancel.setText(AppLocal.getIntString("button.cancel")); // NOI18N + m_jButtonCancel.setFocusPainted(false); + m_jButtonCancel.setFocusable(false); + m_jButtonCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jButtonCancel.setPreferredSize(new java.awt.Dimension(110, 45)); + m_jButtonCancel.setRequestFocusEnabled(false); + m_jButtonCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jButtonCancelActionPerformed(evt); + } + }); + jPanel2.add(m_jButtonCancel); + + m_jButtonOK.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jButtonOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + m_jButtonOK.setText(AppLocal.getIntString("button.OK")); // NOI18N + m_jButtonOK.setFocusPainted(false); + m_jButtonOK.setFocusable(false); + m_jButtonOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jButtonOK.setPreferredSize(new java.awt.Dimension(110, 45)); + m_jButtonOK.setRequestFocusEnabled(false); + m_jButtonOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jButtonOKActionPerformed(evt); + } + }); + jPanel2.add(m_jButtonOK); + + getContentPane().add(jPanel2, java.awt.BorderLayout.SOUTH); + + jPanel1.setLayout(new javax.swing.BoxLayout(jPanel1, javax.swing.BoxLayout.LINE_AXIS)); + + jPanel5.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel5.setLayout(new java.awt.BorderLayout()); + jPanel1.add(jPanel5); + + jPanel4.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel4.setLayout(new java.awt.GridBagLayout()); + + jBtnToRightAll.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/2rightarrow.png"))); // NOI18N + jBtnToRightAll.setToolTipText("Split All Line Items"); + jBtnToRightAll.setFocusPainted(false); + jBtnToRightAll.setFocusable(false); + jBtnToRightAll.setMargin(new java.awt.Insets(8, 14, 8, 14)); + jBtnToRightAll.setPreferredSize(new java.awt.Dimension(80, 45)); + jBtnToRightAll.setRequestFocusEnabled(false); + jBtnToRightAll.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnToRightAllActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridy = 0; + jPanel4.add(jBtnToRightAll, gridBagConstraints); + + jBtnToRightOne.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/1rightarrow.png"))); // NOI18N + jBtnToRightOne.setToolTipText("Split only one of the Line Items"); + jBtnToRightOne.setFocusPainted(false); + jBtnToRightOne.setFocusable(false); + jBtnToRightOne.setMargin(new java.awt.Insets(8, 14, 8, 14)); + jBtnToRightOne.setPreferredSize(new java.awt.Dimension(80, 45)); + jBtnToRightOne.setRequestFocusEnabled(false); + jBtnToRightOne.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnToRightOneActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridy = 1; + gridBagConstraints.insets = new java.awt.Insets(5, 0, 0, 0); + jPanel4.add(jBtnToRightOne, gridBagConstraints); + + jBtnToLeftOne.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/1leftarrow.png"))); // NOI18N + jBtnToLeftOne.setToolTipText("Un-Split only one of the Line Items"); + jBtnToLeftOne.setFocusPainted(false); + jBtnToLeftOne.setFocusable(false); + jBtnToLeftOne.setMargin(new java.awt.Insets(8, 14, 8, 14)); + jBtnToLeftOne.setPreferredSize(new java.awt.Dimension(80, 45)); + jBtnToLeftOne.setRequestFocusEnabled(false); + jBtnToLeftOne.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnToLeftOneActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridy = 2; + gridBagConstraints.insets = new java.awt.Insets(5, 0, 0, 0); + jPanel4.add(jBtnToLeftOne, gridBagConstraints); + + jBtnToLeftAll.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/2leftarrow.png"))); // NOI18N + jBtnToLeftAll.setToolTipText("Un-Split All Line Items"); + jBtnToLeftAll.setFocusPainted(false); + jBtnToLeftAll.setFocusable(false); + jBtnToLeftAll.setMargin(new java.awt.Insets(8, 14, 8, 14)); + jBtnToLeftAll.setPreferredSize(new java.awt.Dimension(80, 45)); + jBtnToLeftAll.setRequestFocusEnabled(false); + jBtnToLeftAll.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnToLeftAllActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridy = 3; + gridBagConstraints.insets = new java.awt.Insets(5, 0, 0, 0); + jPanel4.add(jBtnToLeftAll, gridBagConstraints); + + jPanel1.add(jPanel4); + + jPanel3.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel3.setLayout(new java.awt.BorderLayout()); + jPanel1.add(jPanel3); + + getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER); + + setSize(new java.awt.Dimension(730, 470)); + setLocationRelativeTo(null); + }// </editor-fold>//GEN-END:initComponents + + private void m_jButtonOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jButtonOKActionPerformed + + if (receipttwo.getTicket().getLinesCount() > 0) { + accepted = true; + dispose(); + } + + }//GEN-LAST:event_m_jButtonOKActionPerformed + + private void m_jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jButtonCancelActionPerformed + + dispose(); + + }//GEN-LAST:event_m_jButtonCancelActionPerformed + + private void jBtnToRightAllActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnToRightAllActionPerformed + + TicketLineInfo[] lines = receiptone.getSelectedLines(); + if (lines != null) { + receipttwo.addSelectedLines(lines); + } + +}//GEN-LAST:event_jBtnToRightAllActionPerformed + + private void jBtnToRightOneActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnToRightOneActionPerformed + + TicketLineInfo[] lines = receiptone.getSelectedLinesUnit(); + if (lines != null) { + receipttwo.addSelectedLines(lines); + } + +}//GEN-LAST:event_jBtnToRightOneActionPerformed + + private void jBtnToLeftOneActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnToLeftOneActionPerformed + + TicketLineInfo[] lines = receipttwo.getSelectedLinesUnit(); + if (lines != null) { + receiptone.addSelectedLines(lines); + } + +}//GEN-LAST:event_jBtnToLeftOneActionPerformed + + private void jBtnToLeftAllActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnToLeftAllActionPerformed + + TicketLineInfo[] lines = receipttwo.getSelectedLines(); + if (lines != null) { + receiptone.addSelectedLines(lines); + } + +}//GEN-LAST:event_jBtnToLeftAllActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jBtnToLeftAll; + private javax.swing.JButton jBtnToLeftOne; + private javax.swing.JButton jBtnToRightAll; + private javax.swing.JButton jBtnToRightOne; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JButton m_jButtonCancel; + private javax.swing.JButton m_jButtonOK; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/ReprintTicketInfo.java b/src/main/java/com/unicenta/pos/sales/ReprintTicketInfo.java new file mode 100644 index 0000000..77a68f0 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/ReprintTicketInfo.java @@ -0,0 +1,93 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.DataWrite; +import com.unicenta.data.loader.SerializableRead; +import com.unicenta.data.loader.SerializableWrite; + +/** + * @author JG uniCenta + * Sept 2018 + * Recall + Reprint of last ticket + * Allows for reprint ticket from any terminal rather than only local +*/ +public class ReprintTicketInfo implements SerializableRead, SerializableWrite { + + private static final long serialVersionUID = 7640633837719L; + private String id; + private String total; + private String ticketDate; + private String UserName; + + + /** Creates a new instance of ReprintTicketInfo */ + public ReprintTicketInfo() { + } + + /** + * + * @param dr + * @throws BasicException + */ + @Override + public void readValues(DataRead dr) throws BasicException { + id = dr.getString(1); + total = dr.getString(2); + ticketDate = dr.getString(3); + UserName = dr.getString(4); + + } + + /** + * + * @param dp + * @throws BasicException + */ + @Override + public void writeValues(DataWrite dp) throws BasicException { + dp.setString(1, id); + dp.setString(2, total); + dp.setString(3, ticketDate); + dp.setString(4, UserName); + } + + /** + * + * @return + */ + public String getId() { + return id; + } + + public String getTotal() { + return total; + } + + public String getTicketDate() { + return ticketDate; + } + + public String getUserName() { + return UserName; + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/sales/SharedTicketInfo.java b/src/main/java/com/unicenta/pos/sales/SharedTicketInfo.java new file mode 100644 index 0000000..f25b28f --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/SharedTicketInfo.java @@ -0,0 +1,113 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.DataWrite; +import com.unicenta.data.loader.SerializableRead; +import com.unicenta.data.loader.SerializableWrite; + +public class SharedTicketInfo implements SerializableRead, SerializableWrite { + + private static final long serialVersionUID = 7640633837719L; + private String id; + private String name; + private String UserName; + private String status; +/* + * For : RickyO - display Customer Name | Phone | PickupId + * Change : JG uniCenta + * Date : May 2017 +*/ + private String phone; + private String pickupid; + + /** Creates a new instance of SharedTicketInfo */ + public SharedTicketInfo() { + } + + /** + * + * @param dr + * @throws BasicException + */ + @Override + public void readValues(DataRead dr) throws BasicException { + id = dr.getString(1); + name = dr.getString(2); + UserName = dr.getString(3); + status = dr.getString(4); +/* + * For : RickyO - display Customer Name | Phone | PickupId + * Change : JG uniCenta + * Date : May 2017 +*/ + pickupid = dr.getString(5); + phone = dr.getString(6); + + } + + /** + * + * @param dp + * @throws BasicException + */ + @Override + public void writeValues(DataWrite dp) throws BasicException { + dp.setString(1, id); + dp.setString(2, name); + dp.setString(3, UserName); + dp.setString(4, status); + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public String getAppUser() { + return UserName; + } + + public String getStatus() { + return status; + } + +/* + * For : RickyO - display Customer Name | Phone | PickupId + * Change : JG uniCenta + * Date : May 2017 +*/ + public String getPhone() { + return phone; + } +/* + * For : RickyO - display Customer Name | Phone | PickupId + * Change : JG uniCenta + * Date : May 2017 +*/ + public String getPickupId() { + return pickupid; + } +} diff --git a/src/main/java/com/unicenta/pos/sales/SimpleReceipt.form b/src/main/java/com/unicenta/pos/sales/SimpleReceipt.form new file mode 100644 index 0000000..9389200 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/SimpleReceipt.form @@ -0,0 +1,296 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,84,0,0,1,98"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="m_jPanTotals"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> + <SubComponents> + <Component class="javax.swing.JLabel" name="m_jTotalEuros"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" id="white" palette="0" red="ff" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="1" gridY="2" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="0" insetsRight="0" anchor="23" weightX="1.0" weightY="1.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="m_jLblTotalEuros1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.totalcash" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="23" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="m_jSubtotalEuros"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" id="white" palette="0" red="ff" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="0" insetsRight="0" anchor="23" weightX="1.0" weightY="1.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="m_jTaxesEuros"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" id="white" palette="0" red="ff" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="0" insetsRight="0" anchor="23" weightX="1.0" weightY="1.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="m_jLblTotalEuros2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.taxcash" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="23" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="m_jLblTotalEuros3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.subtotalcash" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="23" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="m_jButtons"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="0"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="m_jTicketId"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" id="white" palette="0" red="ff" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.CompoundBorderInfo"> + <CompoundBorder> + <Border PropertyName="outside" info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="64" green="6f" id="Button.darkShadow" palette="3" red="71" type="palette"/> + </LineBorder> + </Border> + <Border PropertyName="inside" info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="1" left="4" right="4" top="1"/> + </Border> + </CompoundBorder> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 25]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="btnCustomer"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/customer_sml.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Show Customers"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnCustomerActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/SimpleReceipt.java b/src/main/java/com/unicenta/pos/sales/SimpleReceipt.java new file mode 100644 index 0000000..df7d335 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/SimpleReceipt.java @@ -0,0 +1,450 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.pos.customers.DataLogicCustomers; +import com.unicenta.pos.customers.JCustomerFinder; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.ticket.TicketInfo; +import com.unicenta.pos.ticket.TicketLineInfo; +import java.awt.BorderLayout; +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author adrian + */ +public class SimpleReceipt extends javax.swing.JPanel { + + /** + * + */ + protected DataLogicCustomers dlCustomers; + + /** + * + */ + protected DataLogicSales dlSales; + + /** + * + */ + protected TaxesLogic taxeslogic; + + private JTicketLines ticketlines; + private TicketInfo ticket; + private Object ticketext; + + /** Creates new form SimpleReceipt + * @param ticketline + * @param dlSales + * @param taxeslogic + * @param dlCustomers */ + public SimpleReceipt(String ticketline, DataLogicSales dlSales, DataLogicCustomers dlCustomers, TaxesLogic taxeslogic) { + + initComponents(); + + // dlSystem.getResourceAsXML("Ticket.Line") + ticketlines = new JTicketLines(ticketline); + this.dlCustomers = dlCustomers; + this.dlSales = dlSales; + this.taxeslogic = taxeslogic; + + jPanel2.add(ticketlines, BorderLayout.CENTER); + } + + /** + * + * @param value + */ + public void setCustomerEnabled(boolean value) { + btnCustomer.setEnabled(value); + } + + /** + * + * @param ticket + * @param ticketext + */ + public void setTicket(TicketInfo ticket, Object ticketext) { + + this.ticket = ticket; + this.ticketext = ticketext; + + // The ticket name + m_jTicketId.setText(ticket.getName(ticketext)); + + ticketlines.clearTicketLines(); + for (int i = 0; i < ticket.getLinesCount(); i++) { + ticketlines.addTicketLine(ticket.getLine(i)); + } + + if (ticket.getLinesCount() > 0) { + ticketlines.setSelectedIndex(0); + } + + printTotals(); + + } + + private void refreshTicketTaxes() { + + for (TicketLineInfo line : ticket.getLines()) { + line.setTaxInfo(taxeslogic.getTaxInfo(line.getProductTaxCategoryID(), ticket.getCustomer())); + } + } + + private void printTotals() { + + if (ticket.getLinesCount() == 0) { + m_jSubtotalEuros.setText(null); + m_jTaxesEuros.setText(null); + m_jTotalEuros.setText(null); + } else { + m_jSubtotalEuros.setText(ticket.printSubTotal()); + m_jTaxesEuros.setText(ticket.printTax()); + m_jTotalEuros.setText(ticket.printTotal()); + } + } + + /** + * + * @return + */ + public TicketInfo getTicket() { + return ticket; + } + + private int findFirstNonAuxiliarLine() { + + int i = ticketlines.getSelectedIndex(); + while (i >= 0 && ticket.getLine(i).isProductCom()) { + i--; + } + return i; + } + + /** + * + * @return + */ + public TicketLineInfo[] getSelectedLines() { + + // never returns an empty array, or null, or an array with at least one element. + + int i = findFirstNonAuxiliarLine(); + + if (i >= 0) { + + List<TicketLineInfo> l = new ArrayList<>(); + + TicketLineInfo line = ticket.getLine(i); + l.add(line); + ticket.removeLine(i); + ticketlines.removeTicketLine(i); + + // add also auxiliars + while (i < ticket.getLinesCount() && ticket.getLine(i).isProductCom()) { + l.add(ticket.getLine(i)); + ticket.removeLine(i); + ticketlines.removeTicketLine(i); + } + printTotals(); + return l.toArray(new TicketLineInfo[l.size()]); + } else { + return null; + } + } + + /** + * + * @return + */ + public TicketLineInfo[] getSelectedLinesUnit() { + + // never returns an empty array, or null, or an array with at least one element. + + int i = findFirstNonAuxiliarLine(); + + if (i >= 0) { + + TicketLineInfo line = ticket.getLine(i); + + if (line.getMultiply() >= 1.0) { + + List<TicketLineInfo> l = new ArrayList<>(); + + if (line.getMultiply() > 1.0) { + line.setMultiply(line.getMultiply() -1.0); + ticketlines.setTicketLine(i, line); + line = line.copyTicketLine(); + line.setMultiply(1.0); + l.add(line); + i++; + } else { // == 1.0 + l.add(line); + ticket.removeLine(i); + ticketlines.removeTicketLine(i); + } + + // add also auxiliars + while (i < ticket.getLinesCount() && ticket.getLine(i).isProductCom()) { + l.add(ticket.getLine(i)); + ticket.removeLine(i); + ticketlines.removeTicketLine(i); + } + printTotals(); + return l.toArray(new TicketLineInfo[l.size()]); + } else { // < 1.0 + return null; + } + } else { + return null; + } + } + + /** + * + * @param lines + */ + public void addSelectedLines(TicketLineInfo[] lines) { + + int i = findFirstNonAuxiliarLine(); + + TicketLineInfo firstline = lines[0]; + + if (i >= 0 + && ticket.getLine(i).getProductID() != null && firstline.getProductID() != null && ticket.getLine(i).getProductID().equals(firstline.getProductID()) + && ticket.getLine(i).getTaxInfo().getId().equals(firstline.getTaxInfo().getId()) + && ticket.getLine(i).getPrice() == firstline.getPrice()) { + + // add the auxiliars. + for (int j = 1; j < lines.length; j++) { + ticket.insertLine(i + 1, lines[j]); + ticketlines.insertTicketLine(i + 1, lines[j]); + } + + // inc the line + ticket.getLine(i).setMultiply(ticket.getLine(i).getMultiply() + firstline.getMultiply()); + ticketlines.setTicketLine(i, ticket.getLine(i)); + ticketlines.setSelectedIndex(i); + + } else { + // add all at the end in inverse order. + int insertpoint = ticket.getLinesCount(); + for (int j = lines.length - 1; j >= 0; j--) { + ticket.insertLine(insertpoint, lines[j]); + ticketlines.insertTicketLine(insertpoint, lines[j]); + } + } + + printTotals(); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + jPanel1 = new javax.swing.JPanel(); + m_jPanTotals = new javax.swing.JPanel(); + m_jTotalEuros = new javax.swing.JLabel(); + m_jLblTotalEuros1 = new javax.swing.JLabel(); + m_jSubtotalEuros = new javax.swing.JLabel(); + m_jTaxesEuros = new javax.swing.JLabel(); + m_jLblTotalEuros2 = new javax.swing.JLabel(); + m_jLblTotalEuros3 = new javax.swing.JLabel(); + m_jButtons = new javax.swing.JPanel(); + m_jTicketId = new javax.swing.JLabel(); + btnCustomer = new javax.swing.JButton(); + jPanel2 = new javax.swing.JPanel(); + + setLayout(new java.awt.BorderLayout()); + + jPanel1.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel1.setLayout(new java.awt.BorderLayout()); + + m_jPanTotals.setLayout(new java.awt.GridBagLayout()); + + m_jTotalEuros.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jTotalEuros.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jTotalEuros.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jTotalEuros.setOpaque(true); + m_jTotalEuros.setPreferredSize(new java.awt.Dimension(150, 30)); + m_jTotalEuros.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(5, 5, 0, 0); + m_jPanTotals.add(m_jTotalEuros, gridBagConstraints); + + m_jLblTotalEuros1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jLblTotalEuros1.setText(AppLocal.getIntString("label.totalcash")); // NOI18N + m_jLblTotalEuros1.setPreferredSize(new java.awt.Dimension(110, 30)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 2; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.insets = new java.awt.Insets(5, 0, 0, 0); + m_jPanTotals.add(m_jLblTotalEuros1, gridBagConstraints); + + m_jSubtotalEuros.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSubtotalEuros.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jSubtotalEuros.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jSubtotalEuros.setOpaque(true); + m_jSubtotalEuros.setPreferredSize(new java.awt.Dimension(150, 30)); + m_jSubtotalEuros.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + m_jPanTotals.add(m_jSubtotalEuros, gridBagConstraints); + + m_jTaxesEuros.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jTaxesEuros.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + m_jTaxesEuros.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jTaxesEuros.setOpaque(true); + m_jTaxesEuros.setPreferredSize(new java.awt.Dimension(150, 30)); + m_jTaxesEuros.setRequestFocusEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(5, 5, 0, 0); + m_jPanTotals.add(m_jTaxesEuros, gridBagConstraints); + + m_jLblTotalEuros2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jLblTotalEuros2.setText(AppLocal.getIntString("label.taxcash")); // NOI18N + m_jLblTotalEuros2.setPreferredSize(new java.awt.Dimension(110, 30)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.insets = new java.awt.Insets(5, 0, 0, 0); + m_jPanTotals.add(m_jLblTotalEuros2, gridBagConstraints); + + m_jLblTotalEuros3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jLblTotalEuros3.setText(AppLocal.getIntString("label.subtotalcash")); // NOI18N + m_jLblTotalEuros3.setPreferredSize(new java.awt.Dimension(110, 30)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + m_jPanTotals.add(m_jLblTotalEuros3, gridBagConstraints); + + jPanel1.add(m_jPanTotals, java.awt.BorderLayout.EAST); + + add(jPanel1, java.awt.BorderLayout.SOUTH); + + m_jButtons.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT)); + + m_jTicketId.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jTicketId.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + m_jTicketId.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createLineBorder(javax.swing.UIManager.getDefaults().getColor("Button.darkShadow")), javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4))); + m_jTicketId.setOpaque(true); + m_jTicketId.setPreferredSize(new java.awt.Dimension(160, 25)); + m_jTicketId.setRequestFocusEnabled(false); + m_jButtons.add(m_jTicketId); + + btnCustomer.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/customer_sml.png"))); // NOI18N + btnCustomer.setToolTipText("Show Customers"); + btnCustomer.setFocusPainted(false); + btnCustomer.setFocusable(false); + btnCustomer.setMargin(new java.awt.Insets(8, 14, 8, 14)); + btnCustomer.setMaximumSize(new java.awt.Dimension(50, 40)); + btnCustomer.setMinimumSize(new java.awt.Dimension(50, 40)); + btnCustomer.setPreferredSize(new java.awt.Dimension(80, 45)); + btnCustomer.setRequestFocusEnabled(false); + btnCustomer.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnCustomerActionPerformed(evt); + } + }); + m_jButtons.add(btnCustomer); + + add(m_jButtons, java.awt.BorderLayout.NORTH); + + jPanel2.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel2.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N + jPanel2.setLayout(new java.awt.BorderLayout()); + add(jPanel2, java.awt.BorderLayout.CENTER); + }// </editor-fold>//GEN-END:initComponents + + private void btnCustomerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCustomerActionPerformed + + JCustomerFinder finder = JCustomerFinder.getCustomerFinder(this, dlCustomers); + finder.search(ticket.getCustomer()); + finder.setVisible(true); + + try { + ticket.setCustomer(finder.getSelectedCustomer() == null + ? null + : dlSales.loadCustomerExt(finder.getSelectedCustomer().getId())); + } catch (BasicException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotfindcustomer"), e); + msg.show(this); + } + + // The ticket name + m_jTicketId.setText(ticket.getName(ticketext)); + + refreshTicketTaxes(); + + // refresh the receipt.... + setTicket(ticket, ticketext); + + }//GEN-LAST:event_btnCustomerActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btnCustomer; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel m_jButtons; + private javax.swing.JLabel m_jLblTotalEuros1; + private javax.swing.JLabel m_jLblTotalEuros2; + private javax.swing.JLabel m_jLblTotalEuros3; + private javax.swing.JPanel m_jPanTotals; + private javax.swing.JLabel m_jSubtotalEuros; + private javax.swing.JLabel m_jTaxesEuros; + private javax.swing.JLabel m_jTicketId; + private javax.swing.JLabel m_jTotalEuros; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/TaxesException.java b/src/main/java/com/unicenta/pos/sales/TaxesException.java new file mode 100644 index 0000000..c845260 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/TaxesException.java @@ -0,0 +1,51 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +/** + * + * @author adrianromero + */ +public class TaxesException extends Exception { + + /** + * Creates a new instance of <code>TaxesException</code> without detail message. + * @param t + */ + public TaxesException(Throwable t) { + super(t); + } + + /** + * + * @param msg + * @param t + */ + public TaxesException(String msg, Throwable t) { + super(msg, t); + } + /** + * Constructs an instance of <code>TaxesException</code> with the specified detail message. + * @param msg the detail message. + */ + public TaxesException(String msg) { + super(msg); + } +} diff --git a/src/main/java/com/unicenta/pos/sales/TaxesLogic.java b/src/main/java/com/unicenta/pos/sales/TaxesLogic.java new file mode 100644 index 0000000..80552c6 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/TaxesLogic.java @@ -0,0 +1,314 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.pos.customers.CustomerInfoExt; +import com.unicenta.pos.inventory.TaxCategoryInfo; +import com.unicenta.pos.ticket.TaxInfo; +import com.unicenta.pos.ticket.TicketInfo; +import com.unicenta.pos.ticket.TicketLineInfo; +import com.unicenta.pos.ticket.TicketTaxInfo; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * + * @author adrianromero + */ +public class TaxesLogic { + + private List<TaxInfo> taxlist; + + private Map<String, TaxesLogicElement> taxtrees; + + /** + * + * @param taxlist + */ + public TaxesLogic(List<TaxInfo> taxlist) { + this.taxlist = taxlist; + +// JG June 2013 use diamond inference + taxtrees = new HashMap<>(); + + // Order the taxlist by Application Order... + // JG June 2013 use diamond inference + List<TaxInfo> taxlistordered = new ArrayList<>(); + taxlistordered.addAll(taxlist); + Collections.sort(taxlistordered, new Comparator<TaxInfo>() { + @Override + public int compare(TaxInfo o1, TaxInfo o2) { + if (o1.getApplicationOrder() < o2.getApplicationOrder()) { + return -1; + } else if (o1.getApplicationOrder() == o2.getApplicationOrder()) { + return 0; + } else { + return 1; + } + } + }); + + // Generate the taxtrees + // JG June 2013 use diamond inference + HashMap<String, TaxesLogicElement> taxorphans = new HashMap<>(); + + for (TaxInfo t : taxlistordered) { + + TaxesLogicElement te = new TaxesLogicElement(t); + + // get the parent + TaxesLogicElement teparent = taxtrees.get(t.getParentID()); + if (teparent == null) { + // orphan node + teparent = taxorphans.get(t.getParentID()); + if (teparent == null) { + teparent = new TaxesLogicElement(null); + taxorphans.put(t.getParentID(), teparent); + } + } + + teparent.getSons().add(te); + + // Does it have orphans ? + teparent = taxorphans.get(t.getId()); + if (teparent != null) { + // get all the sons + te.getSons().addAll(teparent.getSons()); + // remove the orphans + taxorphans.remove(t.getId()); + } + + // Add it to the tree... + taxtrees.put(t.getId(), te); + } + } + + /** + * + * @param ticket + * @throws TaxesException + */ + public void calculateTaxes(TicketInfo ticket) throws TaxesException { + + // JG June 2013 use diamond inference + List<TicketTaxInfo> tickettaxes = new ArrayList<>(); + + for (TicketLineInfo line: ticket.getLines()) { + tickettaxes = sumLineTaxes(tickettaxes, calculateTaxes(line)); + } + + ticket.setTaxes(tickettaxes); + } + + /** + * + * @param line + * @return + * @throws TaxesException + */ + public List<TicketTaxInfo> calculateTaxes(TicketLineInfo line) throws TaxesException { + + TaxesLogicElement taxesapplied = getTaxesApplied(line.getTaxInfo()); + return calculateLineTaxes(line.getSubValue(), taxesapplied); + } + + private List<TicketTaxInfo> calculateLineTaxes(double base, TaxesLogicElement taxesapplied) { + + // JG June 2013 use diamond inference + List<TicketTaxInfo> linetaxes = new ArrayList<>(); + + if (taxesapplied.getSons().isEmpty()) { + TicketTaxInfo tickettax = new TicketTaxInfo(taxesapplied.getTax()); + tickettax.add(base); + linetaxes.add(tickettax); + } else { + double acum = base; + + for (TaxesLogicElement te : taxesapplied.getSons()) { + + List<TicketTaxInfo> sublinetaxes = calculateLineTaxes( + te.getTax().isCascade() ? acum : base, + te); + linetaxes.addAll(sublinetaxes); + acum += sumTaxes(sublinetaxes); + } + } + + return linetaxes; + } + + private TaxesLogicElement getTaxesApplied(TaxInfo t) throws TaxesException { + + if (t == null) { + throw new TaxesException(new java.lang.NullPointerException()); + } + + return taxtrees.get(t.getId()); + } + + private double sumTaxes(List<TicketTaxInfo> linetaxes) { + + double taxtotal = 0.0; + + taxtotal = linetaxes.stream().map((tickettax) -> + tickettax.getTax()).reduce(taxtotal, (accumulator, _item) -> accumulator + _item); + return taxtotal; + } + + private List<TicketTaxInfo> sumLineTaxes(List<TicketTaxInfo> list1, List<TicketTaxInfo> list2) { + + list2.forEach((tickettax) -> { + TicketTaxInfo i = searchTicketTax(list1, tickettax.getTaxInfo().getId()); + if (i == null) { + list1.add(tickettax); + } else { + i.add(tickettax.getSubTotal()); + } + }); + return list1; + } + + private TicketTaxInfo searchTicketTax(List<TicketTaxInfo> l, String id) { + + for (TicketTaxInfo tickettax : l) { + if (id.equals(tickettax.getTaxInfo().getId())) { + return tickettax; + } + } + return null; + } + + /** + * + * @param tcid + * @return + */ + public double getTaxRate(String tcid) { + return getTaxRate(tcid, null); + } + + /** + * + * @param tc + * @return + */ + public double getTaxRate(TaxCategoryInfo tc) { + return getTaxRate(tc, null); + } + + /** + * + * @param tc + * @param customer + * @return + */ + public double getTaxRate(TaxCategoryInfo tc, CustomerInfoExt customer) { + + if (tc == null) { + return 0.0; + } else { + return getTaxRate(tc.getID(), customer); + } + } + + /** + * + * @param tcid + * @param customer + * @return + */ + public double getTaxRate(String tcid, CustomerInfoExt customer) { + + if (tcid == null) { + return 0.0; + } else { + TaxInfo tax = getTaxInfo(tcid, customer); + if (tax == null) { + return 0.0; + } else { + return tax.getRate(); + } + } + } + + /** + * + * @param tcid + * @return + */ + public TaxInfo getTaxInfo(String tcid) { + return getTaxInfo(tcid, null); + } + + /** + * + * @param tc + * @return + */ + public TaxInfo getTaxInfo(TaxCategoryInfo tc) { + return getTaxInfo(tc.getID(), null); + } + + /** + * + * @param tc + * @param customer + * @return + */ + public TaxInfo getTaxInfo(TaxCategoryInfo tc, CustomerInfoExt customer) { + return getTaxInfo(tc.getID(), customer); + } + + /** + * + * @param tcid + * @param customer + * @return + */ + public TaxInfo getTaxInfo(String tcid, CustomerInfoExt customer) { + + TaxInfo defaulttax = null; + + for (TaxInfo tax : taxlist) { + if (tax.getParentID() == null && tax.getTaxCategoryID().equals(tcid)) { + if ((customer == null + || customer.getTaxCustCategoryID() == null) + && tax.getTaxCustCategoryID() == null) { + return tax; + } else if (customer != null + && customer.getTaxCustCategoryID() != null + && customer.getTaxCustCategoryID().equals(tax.getTaxCustCategoryID())) { + return tax; + } + + if (tax.getTaxCustCategoryID() == null) { + defaulttax = tax; + } + } + } + + // No tax found + return defaulttax; + } +} diff --git a/src/main/java/com/unicenta/pos/sales/TaxesLogicElement.java b/src/main/java/com/unicenta/pos/sales/TaxesLogicElement.java new file mode 100644 index 0000000..c302def --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/TaxesLogicElement.java @@ -0,0 +1,61 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-20167 +// 2008-2013 Openbravo, S.L. +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.pos.ticket.TaxInfo; +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author adrianromero + */ +public class TaxesLogicElement { + + private TaxInfo tax; + private List<TaxesLogicElement> taxsons; + + /** + * + * @param tax + */ + public TaxesLogicElement(TaxInfo tax) { + this.tax = tax; + // JG June 2013 use diamond inference + this.taxsons = new ArrayList<>(); + } + + /** + * + * @return + */ + public TaxInfo getTax() { + return tax; + } + + /** + * + * @return + */ + public List<TaxesLogicElement> getSons() { + return taxsons; + } +} diff --git a/src/main/java/com/unicenta/pos/sales/TicketsBagRestaurantMap.java b/src/main/java/com/unicenta/pos/sales/TicketsBagRestaurantMap.java new file mode 100644 index 0000000..da15edb --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/TicketsBagRestaurantMap.java @@ -0,0 +1,13 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.unicenta.pos.sales; + +/** + * + * @author Administrator + */ +class TicketsBagRestaurantMap { + +} diff --git a/src/main/java/com/unicenta/pos/sales/TicketsEditor.java b/src/main/java/com/unicenta/pos/sales/TicketsEditor.java new file mode 100644 index 0000000..b96b7dd --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/TicketsEditor.java @@ -0,0 +1,42 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales; + +import com.unicenta.pos.ticket.TicketInfo; + +/** + * + * @author JG uniCenta + */ +public interface TicketsEditor { + + /** + * + * @param oTicket + * @param oTicketExt + */ + public void setActiveTicket(TicketInfo oTicket, Object oTicketExt); // el ticket mas informacion extra... + + /** + * + * @return + */ + public TicketInfo getActiveTicket(); +} diff --git a/src/main/java/com/unicenta/pos/sales/dlSales.java b/src/main/java/com/unicenta/pos/sales/dlSales.java new file mode 100644 index 0000000..1f6e8b4 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/dlSales.java @@ -0,0 +1,13 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.unicenta.pos.sales; + +/** + * + * @author JG uniCenta + */ +class dlSales { + +} diff --git a/src/main/java/com/unicenta/pos/sales/restaurant/Floor.java b/src/main/java/com/unicenta/pos/sales/restaurant/Floor.java new file mode 100644 index 0000000..3a215ad --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/restaurant/Floor.java @@ -0,0 +1,138 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales.restaurant; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.ImageUtils; +import com.unicenta.data.loader.SerializableRead; +import com.unicenta.pos.util.ThumbNailBuilder; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.image.BufferedImage; +import javax.imageio.ImageIO; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JPanel; + +/** + * + * @author JG uniCenta + */ +public class Floor implements SerializableRead { + + private static final long serialVersionUID = 8694154682897L; + private String m_sID; + private String m_sName; + private Container m_container; + private Icon m_icon; + + private static Image defimg = null; + + /** Creates a new instance of Floor */ + public Floor() { + try { + defimg = ImageIO.read(getClass().getClassLoader().getResourceAsStream("com/unicenta/images/floors.png")); + } catch (Exception fnfe) { + } + } + + /** + * + * @param dr + * @throws BasicException + */ + @Override + public void readValues(DataRead dr) throws BasicException { + m_sID = dr.getString(1); + m_sName = dr.getString(2); + BufferedImage img = ImageUtils.readImage(dr.getBytes(3)); + ThumbNailBuilder tnbcat = new ThumbNailBuilder(32, 32, defimg); + m_container = new JPanelDrawing(img); + m_icon = new ImageIcon(tnbcat.getThumbNail(img)); + } + + /** + * + * @return + */ + public String getID() { + return m_sID; + } + + /** + * + * @return + */ + public String getName() { + return m_sName; + } + + /** + * + * @return + */ + public Icon getIcon() { + return m_icon; + } + + /** + * + * @return + */ + public Container getContainer() { + return m_container; + } + + private static class JPanelDrawing extends JPanel { + private Image img; + + public JPanelDrawing(Image img) { + this.img = img; + setLayout(null); + } + + @Override + protected void paintComponent (Graphics g) { + super.paintComponent(g); + if (img != null) { + g.drawImage(img, 0, 0, this); + } + } + + @Override + public Dimension getPreferredSize() { + return (img == null) +// ? new Dimension(640, 480) + ? new Dimension(950, 560) + : new Dimension(img.getWidth(this), img.getHeight(this)); + } + @Override + public Dimension getMinimumSize() { + return getPreferredSize(); + } + @Override + public Dimension getMaximumSize() { + return getPreferredSize(); + } + } +} diff --git a/src/main/java/com/unicenta/pos/sales/restaurant/JCalendarItemRenderer.form b/src/main/java/com/unicenta/pos/sales/restaurant/JCalendarItemRenderer.form new file mode 100644 index 0000000..6cbf3c9 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/restaurant/JCalendarItemRenderer.form @@ -0,0 +1,96 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="0"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,68,0,0,1,-113"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Component class="javax.swing.JLabel" name="m_jDescription"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="<html>This is a test comment that shows how a long line is printed with this renderer."/> + <Property name="verticalAlignment" type="int" value="1"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="20" right="20" top="5"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + </Component> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="opaque" type="boolean" value="false"/> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Component class="javax.swing.JLabel" name="m_jTime"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="0" red="0" type="rgb"/> + </Property> + <Property name="text" type="java.lang.String" value="10:20"/> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="West"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="m_jTitle"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value=" This is a test"/> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="0" left="5" right="0" top="0"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JLabel" name="m_jChairs"> + <Properties> + <Property name="text" type="java.lang.String" value="5"/> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/restaurant/JCalendarItemRenderer.java b/src/main/java/com/unicenta/pos/sales/restaurant/JCalendarItemRenderer.java new file mode 100644 index 0000000..b401eff --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/restaurant/JCalendarItemRenderer.java @@ -0,0 +1,186 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales.restaurant; + +import javax.swing.*; +import javax.swing.border.*; + +import java.awt.Component; +import java.awt.Font; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Insets; + +import java.io.Serializable; +import com.unicenta.format.Formats; + +/** + * + * @author JG uniCenta + */ +public class JCalendarItemRenderer extends javax.swing.JPanel implements ListCellRenderer, Serializable { + + /** + * + */ + protected static Border noFocusBorder; + + private boolean m_bDone = false; + + /** Creates new form JCalendarItemRenderer */ + public JCalendarItemRenderer() { + + super(); + if (noFocusBorder == null) { + noFocusBorder = new EmptyBorder(1, 1, 1, 1); + } + + initComponents(); + + m_jTime.setFont(new Font("SansSerif", Font.BOLD, 14)); // HORA + m_jTitle.setFont(new Font("SansSerif", Font.BOLD, 14)); // TITULO + m_jDescription.setFont(new Font("SansSerif", Font.ITALIC, 14)); // TEXTO EXPLICATIVO + + setOpaque(true); + setBorder(noFocusBorder); + } + + @Override + public Component getListCellRendererComponent(JList list, Object value, + int index, boolean isSelected, boolean cellHasFocus) { + + applyComponentOrientation(list.getComponentOrientation()); + + if (isSelected) { + setBackground(list.getSelectionBackground()); + m_jTime.setForeground(list.getSelectionForeground()); + m_jTitle.setForeground(list.getSelectionForeground()); + m_jDescription.setForeground(list.getSelectionForeground()); + } else { + setBackground(list.getBackground()); + m_jTime.setForeground(Color.BLUE); + m_jTitle.setForeground(list.getForeground()); + m_jDescription.setForeground(list.getForeground()); + } + + if (value == null) { + m_jTime.setText(""); + m_jTitle.setText(""); + m_jChairs.setText(""); + m_bDone = false; + m_jDescription.setText(""); + } else { + Object[] avalue = (Object []) value; + m_jTime.setText(Formats.TIME.formatValue(avalue[2])); + m_jTitle.setText(Formats.STRING.formatValue(avalue[6])); + m_jChairs.setText(Formats.INT.formatValue(avalue[7])); + m_bDone = ((Boolean) avalue[8]).booleanValue(); + m_jDescription.setText(Formats.STRING.formatValue(avalue[9])); + } + + setEnabled(list.isEnabled()); + setFont(list.getFont()); + setBorder((cellHasFocus) ? UIManager.getBorder("List.focusCellHighlightBorder") : noFocusBorder); + + return this; + } + + public void paintComponent(Graphics g) { + super.paintComponent(g); + + if (m_bDone) { + Insets in = getInsets(); + g.drawLine(in.left, 10, getWidth() - in.right, 10); + } + } + + + /** + * Overridden for performance reasons. + */ + @Override + protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {} + @Override + public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {} + @Override + public void firePropertyChange(String propertyName, char oldValue, char newValue) {} + @Override + public void firePropertyChange(String propertyName, short oldValue, short newValue) {} + @Override + public void firePropertyChange(String propertyName, int oldValue, int newValue) {} + @Override + public void firePropertyChange(String propertyName, long oldValue, long newValue) {} + @Override + public void firePropertyChange(String propertyName, float oldValue, float newValue) {} + @Override + public void firePropertyChange(String propertyName, double oldValue, double newValue) {} + @Override + public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {} + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jDescription = new javax.swing.JLabel(); + jPanel1 = new javax.swing.JPanel(); + m_jTime = new javax.swing.JLabel(); + m_jTitle = new javax.swing.JLabel(); + m_jChairs = new javax.swing.JLabel(); + + setLayout(new java.awt.BorderLayout()); + + m_jDescription.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jDescription.setText("<html>This is a test comment that shows how a long line is printed with this renderer."); + m_jDescription.setVerticalAlignment(javax.swing.SwingConstants.TOP); + m_jDescription.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 20, 5, 20)); + add(m_jDescription, java.awt.BorderLayout.CENTER); + + jPanel1.setOpaque(false); + jPanel1.setLayout(new java.awt.BorderLayout()); + + m_jTime.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jTime.setForeground(new java.awt.Color(0, 0, 255)); + m_jTime.setText("10:20"); + jPanel1.add(m_jTime, java.awt.BorderLayout.WEST); + + m_jTitle.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jTitle.setText(" This is a test"); + m_jTitle.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 5, 0, 0)); + jPanel1.add(m_jTitle, java.awt.BorderLayout.CENTER); + + m_jChairs.setText("5"); + jPanel1.add(m_jChairs, java.awt.BorderLayout.EAST); + + add(jPanel1, java.awt.BorderLayout.NORTH); + }// </editor-fold>//GEN-END:initComponents + + // Variables declaration - do not modify//GEN-BEGIN:variables + javax.swing.JPanel jPanel1; + javax.swing.JLabel m_jChairs; + javax.swing.JLabel m_jDescription; + javax.swing.JLabel m_jTime; + javax.swing.JLabel m_jTitle; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurant.form b/src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurant.form new file mode 100644 index 0000000..8e534d4 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurant.form @@ -0,0 +1,174 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 50]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[430, 50]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,54,0,0,1,-72"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="0"/> + <Property name="horizontalGap" type="int" value="4"/> + <Property name="verticalGap" type="int" value="3"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="j_btnGuests"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="1"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="99" green="0" red="ff" type="rgb"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/customer_add_sml.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.guests" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="horizontalTextPosition" type="int" value="4"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 4, 0, 4]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="j_btnGuestsActionPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="JTicketsBagRestaurant_j_btnGuests"/> + </AuxValues> + </Component> + <Component class="javax.swing.JButton" name="m_TablePlan"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/tables.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Go to Table Plan"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 4, 0, 4]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_TablePlanActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_MoveTable"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/movetable.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Move Table"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 4, 0, 4]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_MoveTableActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_DelTicket"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/sale_delete.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Delete Current Order"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 4, 0, 4]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_DelTicketActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="j_btnKitchen"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/printer24.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Send to Kichen Printer"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 4, 0, 4]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" value="Send to Remote Printer"/> + </AccessibilityProperties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="j_btnKitchenActionPerformed"/> + </Events> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurant.java b/src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurant.java new file mode 100644 index 0000000..e0b6baf --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurant.java @@ -0,0 +1,440 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// + +package com.unicenta.pos.sales.restaurant; + +import bsh.EvalError; +import bsh.Interpreter; +import com.alee.extended.time.ClockType; +import com.alee.extended.time.WebClock; +import com.alee.managers.notification.NotificationIcon; +import com.alee.managers.notification.NotificationManager; +import com.alee.managers.notification.WebNotification; +import com.unicenta.basic.BasicException; +import com.unicenta.beans.JGuestsPop; +import com.unicenta.beans.JNumberPop; +import com.unicenta.data.gui.JMessageDialog; +import com.unicenta.data.gui.ListKeyed; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.pos.forms.*; +import com.unicenta.pos.printer.DeviceTicket; +import com.unicenta.pos.printer.TicketParser; +import com.unicenta.pos.printer.TicketPrinterException; +import com.unicenta.pos.sales.DataLogicReceipts; +import com.unicenta.pos.sales.TaxesLogic; +import com.unicenta.pos.scripting.ScriptEngine; +import com.unicenta.pos.scripting.ScriptException; +import com.unicenta.pos.scripting.ScriptFactory; +import com.unicenta.pos.ticket.TicketInfo; +import com.unicenta.pos.ticket.TicketLineInfo; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.*; +import java.util.List; + +/** + * + * @author JG uniCenta + */ +@Slf4j +public class JTicketsBagRestaurant extends javax.swing.JPanel { + + private final AppView m_App; + private final JTicketsBagRestaurantMap m_restaurant; + private List<TicketLineInfo> m_aLines; + private TicketLineInfo line; + private TicketInfo ticket; + private final Object ticketExt; + private DataLogicSystem m_dlSystem = null; + private final DeviceTicket m_TP; + private final TicketParser m_TTP2; + private final RestaurantDBUtils restDB; + + private final DataLogicSystem dlSystem = null; + private final DataLogicReceipts dlReceipts = null; + private DataLogicSales dlSales = null; + + private TicketParser m_TTP; + + private SentenceList senttax; + private ListKeyed taxcollection; + private TaxesLogic taxeslogic; + + private Interpreter i; + + + /** Creates new form JTicketsBagRestaurantMap + * @param app + * @param restaurant */ + public JTicketsBagRestaurant(AppView app, JTicketsBagRestaurantMap restaurant) { + super(); + m_App = app; + m_restaurant = restaurant; + + initComponents(); + + ticketExt = null; + + restDB = new RestaurantDBUtils(m_App); + + m_dlSystem = (DataLogicSystem) m_App.getBean("com.unicenta.pos.forms.DataLogicSystem"); + dlSales = (DataLogicSales) m_App.getBean("com.unicenta.pos.forms.DataLogicSales"); + DataLogicReceipts m_dlReceipts = (DataLogicReceipts) m_App.getBean("com.unicenta.pos.sales.DataLogicReceipts"); + + m_TP = new DeviceTicket(); + m_TTP2 = new TicketParser(m_App.getDeviceTicket(), m_dlSystem); + + j_btnKitchen.setVisible(false); + + m_TablePlan.setVisible(m_App.getAppUserView().getUser(). + hasPermission("sales.TablePlan")); + +// j_btnGuests.setText(null); + + } + + /** + * + */ + public void activate() { + + m_DelTicket.setEnabled(m_App.getAppUserView().getUser() + .hasPermission("com.unicenta.pos.sales.JPanelTicketEdits")); + + m_TablePlan.setEnabled(m_App.getAppUserView().getUser() + .hasPermission("com.unicenta.pos.sales.JPanelTicketEdits")); + + m_TablePlan.setVisible(true); + + } + + /** + * + * @param pTicket + * @return + */ + public String getPickupString(TicketInfo pTicket){ + if (pTicket == null){ + return("0"); + } + String tmpPickupId=Integer.toString(pTicket.getPickupId()); + String pickupSize =(m_App.getProperties().getProperty("till.pickupsize")); + + if (pickupSize!=null && (Integer.parseInt(pickupSize) >= tmpPickupId.length())){ + while (tmpPickupId.length()< (Integer.parseInt(pickupSize))){ + tmpPickupId="0"+tmpPickupId; + } + } + return (tmpPickupId); + } + + /** + * + * @param resource + */ + public void printTicket(String resource) { + printTicket(resource, ticket, m_restaurant.getTable()); + printNotify(); +// j_btnKitchen.setEnabled(false); + } + + private void printTicket(String sresourcename, TicketInfo ticket, String table) { + if (ticket != null) { + + if (ticket.getPickupId()== 0){ + try{ + ticket.setPickupId(dlSales.getNextPickupIndex()); + }catch (BasicException e){ + ticket.setPickupId(0); + } + } + + try { + ScriptEngine script = ScriptFactory.getScriptEngine(ScriptFactory.VELOCITY); + + script.put("ticket", ticket); + script.put("place",m_restaurant.getTableName()); + script.put("pickupid",getPickupString(ticket)); + + m_TTP2.printTicket(script.eval(m_dlSystem.getResourceAsXML(sresourcename)).toString()); + + } catch ( ScriptException | TicketPrinterException e) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_NOTICE, + AppLocal.getIntString("message.cannotprint"), e)); + } + } + } + + public void printNotify(){ + final WebNotification notificationPopup = new WebNotification (); + notificationPopup.setIcon ( NotificationIcon.information ); + notificationPopup.setDisplayTime ( 4000 ); + + final WebClock clock = new WebClock (); + clock.setClockType ( ClockType.timer ); + clock.setTimeLeft ( 5000 ); + clock.setTimePattern ( "'Printed successfully'" ); + notificationPopup.setContent ( clock ); + + NotificationManager.showNotification ( notificationPopup ); + clock.start (); + } + + public void updateGuestCount() { + Integer count = restDB.getGuestsInTable(m_restaurant.getTable()); + + if (count > 0) { + j_btnGuests.setText(Integer.toString(count)); + + } else { + j_btnGuests.setText(""); + } + System.out.println("Table : " + m_restaurant.getTable() + " GuestsCount :" + count); + + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + j_btnGuests = new javax.swing.JButton(); + m_TablePlan = new javax.swing.JButton(); + m_MoveTable = new javax.swing.JButton(); + m_DelTicket = new javax.swing.JButton(); + j_btnKitchen = new javax.swing.JButton(); + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setMinimumSize(new java.awt.Dimension(250, 50)); + setPreferredSize(new java.awt.Dimension(430, 50)); + setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 4, 3)); + + j_btnGuests.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + j_btnGuests.setForeground(new java.awt.Color(255, 0, 153)); + j_btnGuests.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/customer_add_sml.png"))); // NOI18N + j_btnGuests.setToolTipText(AppLocal.getIntString("tooltip.guests")); // NOI18N + j_btnGuests.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + j_btnGuests.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT); + j_btnGuests.setMargin(new java.awt.Insets(0, 4, 0, 4)); + j_btnGuests.setMaximumSize(new java.awt.Dimension(50, 40)); + j_btnGuests.setMinimumSize(new java.awt.Dimension(50, 40)); + j_btnGuests.setPreferredSize(new java.awt.Dimension(80, 45)); + j_btnGuests.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + j_btnGuestsActionPerformed(evt); + } + }); + add(j_btnGuests); + + m_TablePlan.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/tables.png"))); // NOI18N + m_TablePlan.setToolTipText("Go to Table Plan"); + m_TablePlan.setFocusPainted(false); + m_TablePlan.setFocusable(false); + m_TablePlan.setMargin(new java.awt.Insets(0, 4, 0, 4)); + m_TablePlan.setMaximumSize(new java.awt.Dimension(50, 40)); + m_TablePlan.setMinimumSize(new java.awt.Dimension(50, 40)); + m_TablePlan.setPreferredSize(new java.awt.Dimension(80, 45)); + m_TablePlan.setRequestFocusEnabled(false); + m_TablePlan.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_TablePlanActionPerformed(evt); + } + }); + add(m_TablePlan); + + m_MoveTable.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/movetable.png"))); // NOI18N + m_MoveTable.setToolTipText("Move Table"); + m_MoveTable.setFocusPainted(false); + m_MoveTable.setFocusable(false); + m_MoveTable.setMargin(new java.awt.Insets(0, 4, 0, 4)); + m_MoveTable.setMaximumSize(new java.awt.Dimension(50, 40)); + m_MoveTable.setMinimumSize(new java.awt.Dimension(50, 40)); + m_MoveTable.setPreferredSize(new java.awt.Dimension(80, 45)); + m_MoveTable.setRequestFocusEnabled(false); + m_MoveTable.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_MoveTableActionPerformed(evt); + } + }); + add(m_MoveTable); + + m_DelTicket.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/sale_delete.png"))); // NOI18N + m_DelTicket.setToolTipText("Delete Current Order"); + m_DelTicket.setFocusPainted(false); + m_DelTicket.setFocusable(false); + m_DelTicket.setMargin(new java.awt.Insets(0, 4, 0, 4)); + m_DelTicket.setMaximumSize(new java.awt.Dimension(50, 40)); + m_DelTicket.setMinimumSize(new java.awt.Dimension(50, 40)); + m_DelTicket.setPreferredSize(new java.awt.Dimension(80, 45)); + m_DelTicket.setRequestFocusEnabled(false); + m_DelTicket.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_DelTicketActionPerformed(evt); + } + }); + add(m_DelTicket); + + j_btnKitchen.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/printer24.png"))); // NOI18N + j_btnKitchen.setToolTipText("Send to Kichen Printer"); + j_btnKitchen.setMargin(new java.awt.Insets(0, 4, 0, 4)); + j_btnKitchen.setMaximumSize(new java.awt.Dimension(50, 40)); + j_btnKitchen.setMinimumSize(new java.awt.Dimension(50, 40)); + j_btnKitchen.setPreferredSize(new java.awt.Dimension(80, 45)); + j_btnKitchen.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + j_btnKitchenActionPerformed(evt); + } + }); + add(j_btnKitchen); + j_btnKitchen.getAccessibleContext().setAccessibleDescription("Send to Remote Printer"); + }// </editor-fold>//GEN-END:initComponents + + private void m_MoveTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_MoveTableActionPerformed + +// JG 6 Nov 13 - clear Customer from orignal table - Thanks David Kurniawan + restDB.clearCustomerNameInTableById(m_restaurant.getTable()); + restDB.clearWaiterNameInTableById(m_restaurant.getTable()); + restDB.clearTicketIdInTableById(m_restaurant.getTable()); + restDB.clearGuestsInTable(m_restaurant.getTable()); + restDB.clearOccupied(m_restaurant.getTable()); + restDB.setTableMovedFlag(m_restaurant.getTable()); + + m_restaurant.moveTicket(); + + }//GEN-LAST:event_m_MoveTableActionPerformed + + @SuppressWarnings("empty-statement") + private void m_DelTicketActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_DelTicketActionPerformed + boolean pinOK = false; + + if (m_App.getProperties().getProperty("override.check").equals("true")) { + Integer secret = Integer.parseInt(m_App.getProperties().getProperty("override.pin")); + Integer iValue = JNumberPop.showEditNumber(this, AppLocal.getIntString("title.override.enterpin")); + + if (iValue == null ? secret == null : iValue.equals(secret)) { + pinOK = true; + int res = JOptionPane.showConfirmDialog(this + , AppLocal.getIntString("message.wannadelete") + , AppLocal.getIntString("title.editor") + , JOptionPane.YES_NO_OPTION + , JOptionPane.QUESTION_MESSAGE); + if (res == JOptionPane.YES_OPTION) { + restDB.clearCustomerNameInTableById(m_restaurant.getTable()); + restDB.clearWaiterNameInTableById(m_restaurant.getTable()); + restDB.clearTicketIdInTableById(m_restaurant.getTable()); + restDB.clearGuestsInTable(m_restaurant.getTable()); + restDB.clearOccupied(m_restaurant.getTable()); + + m_restaurant.deleteTicket(); + } + } else { + pinOK = false; + JOptionPane.showMessageDialog(this, + AppLocal.getIntString("message.override.badpin")); + } + } else { + int res = JOptionPane.showConfirmDialog(this + , AppLocal.getIntString("message.wannadelete") + , AppLocal.getIntString("title.editor") + , JOptionPane.YES_NO_OPTION + , JOptionPane.QUESTION_MESSAGE); + if (res == JOptionPane.YES_OPTION) { + restDB.clearCustomerNameInTableById(m_restaurant.getTable()); + restDB.clearWaiterNameInTableById(m_restaurant.getTable()); + restDB.clearTicketIdInTableById(m_restaurant.getTable()); + restDB.clearGuestsInTable(m_restaurant.getTable()); + restDB.clearOccupied(m_restaurant.getTable()); + + m_restaurant.deleteTicket(); + } + } + }//GEN-LAST:event_m_DelTicketActionPerformed + + private void m_TablePlanActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_TablePlanActionPerformed + // outta here back to TableMap + m_restaurant.newTicket(); + + }//GEN-LAST:event_m_TablePlanActionPerformed + + private void j_btnGuestsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_j_btnGuestsActionPerformed + + Integer iValue = JGuestsPop.showEditNumber(this, + AppLocal.getIntString("title.guestspop.enterguests")); + restDB.setGuestsInTable(iValue, m_restaurant.getTable()); + j_btnGuests.setText(iValue.toString()); + + }//GEN-LAST:event_j_btnGuestsActionPerformed + + @SuppressWarnings("empty-statement") + private void j_btnKitchenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_j_btnKitchenActionPerformed + /* + * This is legacy and deprecated and should use RemotePrinter which covers + * all sales screens for i.e.: Kitchen Print + Click & Collect & etc + * It may be removed from future version + */ + ticket = m_restaurant.getActiveTicket(); + String rScript = (m_dlSystem.getResourceAsText("script.SendOrder")); + + Interpreter i = new Interpreter(); + try { + i.set("ticket", ticket); + i.set("place",m_restaurant.getTableName()); + i.set("user", m_App.getAppUserView().getUser()); + i.set("sales", this); + i.set("pickupid", ticket.getPickupId()); + Object result = i.eval(rScript); + } catch (EvalError ex) { + log.error(ex.getMessage()); + } + // Autologoff after sales + String autoLogoff = (m_App.getProperties().getProperty("till.autoLogoff")); + String autoLogoffRestaurant =(m_App.getProperties().getProperty("till.autoLogoffrestaurant")); + if (autoLogoff != null){ + if (autoLogoff.equals("true")){ + if (autoLogoffRestaurant == null){ + ((JRootApp)m_App).closeAppView(); + }else if (autoLogoffRestaurant.equals("true")){ + m_restaurant.newTicket(); + }else{ + ((JRootApp)m_App).closeAppView(); + } + } + } + }//GEN-LAST:event_j_btnKitchenActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton j_btnGuests; + private javax.swing.JButton j_btnKitchen; + private javax.swing.JButton m_DelTicket; + private javax.swing.JButton m_MoveTable; + private javax.swing.JButton m_TablePlan; + // End of variables declaration//GEN-END:variables + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurantMap.form b/src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurantMap.form new file mode 100644 index 0000000..98aa321 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurantMap.form @@ -0,0 +1,225 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-83,0,0,3,27"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignCardLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="m_jPanelMap"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription"> + <CardConstraints cardName="map"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Before"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="0"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="m_jbtnReservations"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/date.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.reservations" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Open Reservations screen"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[133, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[133, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[133, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jbtnReservationsActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jbtnRefresh"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/reload.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.reloadticket" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Reload table information"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jbtnRefreshActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jbtnLayout"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/movetable.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.layout" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value=""/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jbtnLayoutActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jbtnSave"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/filesave.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.save" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value=""/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jbtnSaveActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="m_jText"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" red="ff" type="rgb"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="99" red="0" type="rgb"/> + </Property> + <Property name="opaque" type="boolean" value="true"/> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="com.alee.laf.label.WebLabel" name="webLblautoRefresh"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="33" green="33" red="ff" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.autoRefreshTableMapTimerON" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurantMap.java b/src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurantMap.java new file mode 100644 index 0000000..67d3a66 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurantMap.java @@ -0,0 +1,1085 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales.restaurant; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.gui.NullIcon; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.loader.SerializerReadClass; +import com.unicenta.data.loader.StaticSentence; +import com.unicenta.pos.customers.CustomerInfo; +import com.unicenta.pos.forms.*; +import com.unicenta.pos.sales.DataLogicReceipts; +import com.unicenta.pos.sales.JTicketsBag; +import com.unicenta.pos.sales.SharedTicketInfo; +import com.unicenta.pos.sales.TicketsEditor; +import com.unicenta.pos.ticket.TicketInfo; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +/** + * + * @author JG uniCenta + */ +@Slf4j +public class JTicketsBagRestaurantMap extends JTicketsBag { + + private static class ServerCurrent { + + public ServerCurrent() { + } + } + + private java.util.List<Place> m_aplaces; + private java.util.List<Floor> m_afloors; + + private JTicketsBagRestaurant m_restaurantmap; + + private final JTicketsBagRestaurantRes m_jreservations; + private Place m_PlaceCurrent; + private ServerCurrent m_ServerCurrent; + private Place m_PlaceClipboard; + private CustomerInfo customer; + + private DataLogicReceipts dlReceipts = null; + private DataLogicSales dlSales = null; + private DataLogicSystem dlSystem = null; + private final RestaurantDBUtils restDB; + private static final Icon ICO_OCU_SM = new ImageIcon(Place.class.getResource("/com/unicenta/images/edit_group_sm.png")); + private static final Icon ICO_WAITER = new NullIcon(1, 1); + private static final Icon ICO_FRE = new NullIcon(22, 22); + private String waiterDetails; + private String customerDetails; + private String tableName; + private Boolean transBtns; + private Boolean actionEnabled = true; + private int newX; + private int newY; + private AppView m_app; + private Boolean showLayout = false; + + + /** Creates new form JTicketsBagRestaurant + * @param app + * @param panelticket */ + + public JTicketsBagRestaurantMap(AppView app, TicketsEditor panelticket) { + + super(app, panelticket); + + restDB = new RestaurantDBUtils(app); + transBtns = AppConfig.getInstance().getBoolean("table.transbtn"); + + dlReceipts = (DataLogicReceipts) app.getBean("com.unicenta.pos.sales.DataLogicReceipts"); + dlSales = (DataLogicSales) m_App.getBean("com.unicenta.pos.forms.DataLogicSales"); + dlSystem = (DataLogicSystem) m_App.getBean("com.unicenta.pos.forms.DataLogicSystem"); + + m_restaurantmap = new JTicketsBagRestaurant(app, this); + m_PlaceCurrent = null; + m_PlaceClipboard = null; + customer = null; + + try { + SentenceList sent = new StaticSentence( + app.getSession(), + "SELECT ID, NAME, IMAGE FROM floors ORDER BY NAME", + null, + new SerializerReadClass(Floor.class)); + m_afloors = sent.list(); + + } catch (BasicException eD) { + m_afloors = new ArrayList<>(); + } + try { + SentenceList sent = new StaticSentence( + app.getSession(), + "SELECT ID, NAME, SEATS, X, Y, FLOOR, CUSTOMER, WAITER, " + + "TICKETID, TABLEMOVED, WIDTH, HEIGHT, GUESTS, OCCUPIED " + + "FROM places " + + "ORDER BY FLOOR ", + null, + new SerializerReadClass(Place.class)); + m_aplaces = sent.list(); + } catch (BasicException eD) { + m_aplaces = new ArrayList<>(); + } + + initComponents(); + + m_jbtnSave.setVisible(false); + + if (m_afloors.size() > 1) { + JTabbedPane jTabFloors = new JTabbedPane(); + jTabFloors.applyComponentOrientation(getComponentOrientation()); + jTabFloors.setBorder(new javax.swing.border.EmptyBorder(new Insets(5, 5, 5, 5))); + jTabFloors.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); + jTabFloors.setFocusable(false); + jTabFloors.setRequestFocusEnabled(false); + m_jPanelMap.add(jTabFloors, BorderLayout.CENTER); + + m_afloors.stream().map((f) -> { + f.getContainer().applyComponentOrientation(getComponentOrientation()); + return f; + }).forEach((f) -> { + JScrollPane jScrCont = new JScrollPane(); + jScrCont.applyComponentOrientation(getComponentOrientation()); + JPanel jPanCont = new JPanel(); + jPanCont.applyComponentOrientation(getComponentOrientation()); + + jTabFloors.addTab(f.getName(), f.getIcon(), jScrCont); + jScrCont.setViewportView(jPanCont); + jPanCont.add(f.getContainer()); + }); + } else if (m_afloors.size() == 1) { + Floor f = m_afloors.get(0); + f.getContainer().applyComponentOrientation(getComponentOrientation()); + + JPanel jPlaces = new JPanel(); + jPlaces.applyComponentOrientation(getComponentOrientation()); + jPlaces.setLayout(new BorderLayout()); + jPlaces.setBorder(new javax.swing.border.CompoundBorder( + new javax.swing.border.EmptyBorder(new Insets(5, 5, 5, 5)), + new javax.swing.border.TitledBorder(f.getName()))); + + JScrollPane jScrCont = new JScrollPane(); + jScrCont.applyComponentOrientation(getComponentOrientation()); + JPanel jPanCont = new JPanel(); + jPanCont.applyComponentOrientation(getComponentOrientation()); + + m_jPanelMap.add(jPlaces, BorderLayout.CENTER); + jPlaces.add(jScrCont, BorderLayout.CENTER); + jScrCont.setViewportView(jPanCont); + jPanCont.add(f.getContainer()); + } + + Floor currfloor = null; + + for (Place pl : m_aplaces) { + int iFloor = 0; + + if (currfloor == null || !currfloor.getID().equals(pl.getFloor())) { + do { + currfloor = m_afloors.get(iFloor++); + } while (!currfloor.getID().equals(pl.getFloor())); + } + + currfloor.getContainer().add(pl.getButton()); + pl.setButtonBounds(); + + if (transBtns) { + pl.getButton().setOpaque(false); + pl.getButton().setContentAreaFilled(false); + pl.getButton().setBorderPainted(false); + } + + pl.getButton().addMouseMotionListener(new MouseAdapter() { + @Override + public void mouseDragged(MouseEvent E) { + if (!actionEnabled) { + if (pl.getDiffX() == 0) { + pl.setDiffX(pl.getButton().getX() - pl.getX()); + pl.setDiffY(pl.getButton().getY() - pl.getY()); + } + newX = E.getX() + pl.getButton().getX(); + newY = E.getY() + pl.getButton().getY(); + pl.getButton().setBounds(newX + pl.getDiffX(), newY + pl.getDiffY(), + pl.getButton().getWidth(), pl.getButton().getHeight()); + pl.setX(newX); + pl.setY(newY); + } + } + } + ); + + pl.getButton().addActionListener(new MyActionListener(pl)); + } + + m_jreservations = new JTicketsBagRestaurantRes(app, this); + add(m_jreservations, "res"); + + showLayout = m_App.getAppUserView().getUser().hasPermission("sales.Layout"); + if (showLayout) { + m_jbtnLayout.setVisible(true); + m_jbtnSave.setVisible(false); + } else { + m_jbtnLayout.setVisible(false); + m_jbtnSave.setVisible(false); + } + + if (m_App.getProperties().getProperty("till.autoRefreshTableMap").equals("true")) { + webLblautoRefresh.setText(java.util.ResourceBundle.getBundle("pos_messages") + .getString("label.autoRefreshTableMapTimerON")); + + Timer autoRefreshTimer = new Timer(Integer.parseInt(m_App.getProperties() + .getProperty("till.autoRefreshTimer"))*1000, new tableMapRefresh()); + + autoRefreshTimer.start(); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + autoRefreshTimer.stop(); + } + } else { + webLblautoRefresh.setText(java.util.ResourceBundle.getBundle("pos_messages") + .getString("label.autoRefreshTableMapTimerOFF")); + } + +} + + class tableMapRefresh implements ActionListener { + + @Override + public void actionPerformed(ActionEvent e) { + loadTickets(); + printState(); + } + } + + /** + * + */ + @Override + public void activate() { + + showLayout = m_App.getAppUserView().getUser().hasPermission("sales.Layout"); + if (showLayout) { + m_jbtnLayout.setVisible(true); + m_jbtnSave.setVisible(false); + } else { + m_jbtnLayout.setVisible(false); + m_jbtnSave.setVisible(false); + } + + m_PlaceClipboard = null; + customer = null; + loadTickets(); + printState(); + + m_panelticket.setActiveTicket(null, null); + m_restaurantmap.activate(); + + showView("map"); + } + + /** + * + * @return + */ + @Override + public boolean deactivate() { + + if (viewTables()) { + m_PlaceClipboard = null; + customer = null; + + if (m_PlaceCurrent != null) { + + try { + dlReceipts.updateSharedTicket(m_PlaceCurrent.getId(), + m_panelticket.getActiveTicket(), + m_panelticket.getActiveTicket().getPickupId()); + dlReceipts.unlockSharedTicket(m_PlaceCurrent.getId(),null); + } catch (BasicException e) { + new MessageInf(e).show(this); + } + + m_PlaceCurrent = null; + + } + printState(); + m_panelticket.setActiveTicket(null, null); + + return true; + } else { + return false; + } + } + + /** + * + * @return + */ + @Override + protected JComponent getBagComponent() { + return m_restaurantmap; + } + + /** + * + * @return + */ + @Override + protected JComponent getNullComponent() { + return this; + } + + /** + * + * @return + */ + public TicketInfo getActiveTicket() { + return m_panelticket.getActiveTicket(); + } + + /** + * + */ + public void moveTicket() { + if (m_PlaceCurrent != null) { + try { + dlReceipts.updateRSharedTicket(m_PlaceCurrent.getId(), + m_panelticket.getActiveTicket(),m_panelticket.getActiveTicket().getPickupId()); + } catch (BasicException e) { + new MessageInf(e).show(this); + } + + m_PlaceClipboard = m_PlaceCurrent; // put FROM table to TO table + + customer = null; +// m_PlaceCurrent = null; // Hang on we'll clear later after we're done + } + + printState(); + m_panelticket.setActiveTicket(null, null); + } + + /** + * + * @param c + * @return + */ + public boolean viewTables(CustomerInfo c) { + if (m_jreservations.deactivate()) { + showView("map"); + m_PlaceClipboard = null; + customer = c; + printState(); + return true; + } else { + return false; + } + } + + /** + * + * @return + */ + public boolean viewTables() { + return viewTables(null); + } + + /** + * + */ + public void newTicket() { + + if (m_PlaceCurrent != null) { + + try { + String m_lockState = null; + m_lockState = dlReceipts.getLockState(m_PlaceCurrent.getId(), m_lockState); + dlReceipts.getSharedTicket(m_PlaceCurrent.getId()); + + if ("override".equals(m_lockState) + || "locked".equals(m_lockState)) { + dlReceipts.updateSharedTicket(m_PlaceCurrent.getId(), + m_panelticket.getActiveTicket(), + m_panelticket.getActiveTicket().getPickupId()); + dlReceipts.unlockSharedTicket(m_PlaceCurrent.getId(), null); + m_PlaceCurrent = null; + + } else { + JOptionPane.showMessageDialog(null + , AppLocal.getIntString("message.sharedticketlockoverriden") + , AppLocal.getIntString("title.editor") + , JOptionPane.INFORMATION_MESSAGE); + } + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + } + + printState(); + m_panelticket.setActiveTicket(null, null); + } + + /** + * + * @return + */ + public String getTable() { + String id = null; + if (m_PlaceCurrent != null) { + id = m_PlaceCurrent.getId(); + } + return(id); + } + + /** + * + * @return + */ + public String getTableName() { + String stableName = null; + if (m_PlaceCurrent != null) { + stableName = m_PlaceCurrent.getName(); + } + return(stableName); + } + + /** + * + */ + @Override + public void deleteTicket() { + + if (m_PlaceCurrent != null) { + String id = m_PlaceCurrent.getId(); + try { + dlReceipts.deleteSharedTicket(id); + dlSystem.execTicketRemoved( + new Object[] { + m_App.getAppUserView().getUser().getName(), + "Void", + "Ticket Deleted", + 0.0 + }); + + } catch (BasicException e) { + new MessageInf(e).show(this); + } + + m_PlaceCurrent.setPeople(false); + m_PlaceCurrent = null; + } + + printState(); + m_panelticket.setActiveTicket(null, null); + } + + /** + * + */ + public void changeServer() { + + if (m_ServerCurrent != null) { + } + } + + /** + * + */ + public void loadTickets() { + + Set<String> atickets = new HashSet<>(); + + try { + java.util.List<SharedTicketInfo> l = dlReceipts.getSharedTicketList(); + l.stream().forEach((ticket) -> { + atickets.add(ticket.getId()); + }); + } catch (BasicException e) { + new MessageInf(e).show(this); + } + + m_aplaces.stream().forEach((table) -> { + table.setPeople(atickets.contains(table.getId())); + }); + } + +/* + * Populate the floor plans and tables +*/ + private void printState() { + String sDB; + sDB = m_App.getProperties().getProperty("db.engine"); + + if (m_PlaceClipboard == null) { + if (customer == null) { + m_jText.setText(null); + + m_aplaces.stream() + .map((place) -> { + place.getButton().setEnabled(true); + Integer guests = restDB.getGuestsInTable(place.getId()); + place.setGuests(guests); + Date occupied = restDB.getOccupied(place.getId()); + place.setOccupied(occupied); + return place; + }) + + .map((place) -> { + if (m_App.getProperties().getProperty("table.tablecolour")== null){ + tableName="<style=font-size:9px;font-weight:bold;><font color = black>" + + place.getName()+"</font></style>"; + }else{ + if (place.getOccupied() != null) { + Date date = new java.util.Date(); + Timestamp t1 = new Timestamp(date.getTime()); + Timestamp t2 = new Timestamp(place.getOccupied().getTime()); + + long milliseconds = t1.getTime() - t2.getTime(); + int seconds = (int) milliseconds / 1000; + int hours = seconds / 3600; + int minutes = (seconds % 3600) / 60; + +Integer count = restDB.getGuestsInTable(place.getId()); + + tableName="<style=font-size:9px;font-weight:bold;><font color =" + + m_App.getProperties().getProperty("table.tablecolour")+ ">" + + place.getName() + " / " + place.getSeats() + "<br>" +// + AppLocal.getIntString("button.guest") + place.getGuests() + "<br>" + + AppLocal.getIntString("button.guest") + count + "<br>" + + AppLocal.getIntString("button.occupied") + + hours + "h" + ":" + minutes + "m" + + "<br>" + + "</font></style>"; + } else { + tableName="<style=font-size:9px;font-weight:bold;><font color =" + + m_App.getProperties().getProperty("table.tablecolour")+ ">" + + place.getName() + " / " + place.getSeats() + "<br>" + + "</font></style>"; + } + } + return place; + }) + + .map((place) -> { + if (Boolean.parseBoolean(m_App.getProperties().getProperty("table.showwaiterdetails"))){ + if (m_App.getProperties().getProperty("table.waitercolour")== null){ + waiterDetails = (restDB.getWaiterNameInTable(place.getName()) ==null)? "" + :"<style=font-size:9px;font-weight:bold;><font color = red>" + + restDB.getWaiterNameInTableById(place.getId())+"</font></style><br>"; + }else{ + waiterDetails = (restDB.getWaiterNameInTable(place.getName()) ==null)? "" + :"<style=font-size:9px;font-weight:bold;><font color =" + + m_App.getProperties().getProperty("table.waitercolour")+ ">" + + restDB.getWaiterNameInTableById(place.getId())+"</font></style><br>"; + } + place.getButton().setIcon(ICO_OCU_SM); + } else { + waiterDetails = ""; + } + return place; + }) + + .map((place) -> { + if (Boolean.parseBoolean( + m_App.getProperties().getProperty("table.showcustomerdetails"))){ + place.getButton().setIcon((Boolean.parseBoolean( + m_App.getProperties().getProperty("table.showwaiterdetails")) + && (restDB.getCustomerNameInTable(place.getName()) !=null)) + ? ICO_WAITER:ICO_OCU_SM); + if (m_App.getProperties().getProperty("table.customercolour")== null){ + customerDetails = (restDB.getCustomerNameInTable(place.getName()) ==null)? "" + :"<style=font-size:9px;font-weight:bold;><font color = blue>" + + restDB.getCustomerNameInTableById(place.getId())+"</font></style><br>"; + }else{ + customerDetails = (restDB.getCustomerNameInTable(place.getName()) ==null)? "" + :"<style=font-size:9px;font-weight:bold;><font color =" + + m_App.getProperties().getProperty("table.customercolour")+ ">" + + restDB.getCustomerNameInTableById(place.getId())+"</font></style><br>"; + } + } else { + customerDetails = ""; + } + return place; + }) + + .map((place) -> { + if ((Boolean.parseBoolean( + m_App.getProperties().getProperty("table.showwaiterdetails"))) + || (Boolean.parseBoolean( + m_App.getProperties().getProperty("table.showcustomerdetails")))) { + place.getButton().setText("<html><center>" + + customerDetails + waiterDetails +tableName+"</html>" ); + }else{ + if (m_App.getProperties().getProperty("table.tablecolour")== null){ + tableName="<style=font-size:10px;font-weight:bold;><font color = black>" + + place.getName()+"</font></style>"; + }else{ + tableName="<style=font-size:10px;font-weight:bold;><font color =" + + m_App.getProperties().getProperty("table.tablecolour")+ ">" + + place.getName()+"</font></style>"; + } + place.getButton().setText("<html><center>"+tableName+"</html>"); + } + return place; + }) + + .filter((place) -> (!place.hasPeople())) + + .forEach((place) -> { + place.getButton().setIcon(ICO_FRE); + }); + + m_jbtnReservations.setEnabled(true); +// places here + + } else { + m_jText.setText(AppLocal.getIntString("label.restaurantcustomer" + , new Object[] { + customer.getName() + } + ) + ); + + m_aplaces.stream() + .forEach((place) -> { + place.getButton().setEnabled(!place.hasPeople()); + }); + m_jbtnReservations.setEnabled(false); + } + } else { + m_jText.setText(AppLocal.getIntString("label.restaurantmove" + , new Object[] { + m_PlaceClipboard.getName() + } + )); + + m_aplaces.stream() + .forEach((place) -> { + Integer guests = restDB.getGuestsInTable(place.getId()); + place.setGuests(guests); + Date occupied = restDB.getOccupied(place.getId()); + place.setOccupied(occupied); + place.getButton().setEnabled(true); + }); + + m_jbtnReservations.setEnabled(false); + } + } + + private TicketInfo getTicketInfo(Place place) { + + try { + return dlReceipts.getSharedTicket(place.getId()); + } catch (BasicException e) { + new MessageInf(e).show(JTicketsBagRestaurantMap.this); + return null; + } + } + + private void setActivePlace(Place place, TicketInfo ticket) { + m_PlaceCurrent = place; + m_panelticket.setActiveTicket(ticket, m_PlaceCurrent.getName()); + m_restaurantmap.updateGuestCount(); + + try { + dlReceipts.lockSharedTicket(m_PlaceCurrent.getId(),"locked"); + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + } + + private void showView(String view) { + CardLayout cl = (CardLayout)(getLayout()); + cl.show(this, view); + } + + private class MyActionListener implements ActionListener { + + private final Place m_place; + public MyActionListener(Place place) { + m_place = place; + } + @Override + public void actionPerformed(ActionEvent evt) { + m_App.getAppUserView().getUser(); + + if (!actionEnabled) { + m_place.setDiffX(0); + } else { + if (m_PlaceClipboard == null) { + TicketInfo ticket = getTicketInfo(m_place); + if (ticket == null) { // It's an empty table + ticket = new TicketInfo(); + ticket.setUser(m_App.getAppUserView().getUser().getUserInfo()); + try { + dlReceipts.insertSharedTicket(m_place.getId(), ticket, ticket.getPickupId()); + } catch (BasicException e) { + new MessageInf(e).show(JTicketsBagRestaurantMap.this); + } + m_place.setPeople(true); + m_place.setGuests(restDB.updateGuestsInTable(m_place.getId())); + setActivePlace(m_place, ticket); + } else { // Table not empty + String m_lockState = null; + try { + m_lockState = dlReceipts.getLockState(m_place.getId(), m_lockState); //check lockstate + + if ("locked".equals(m_lockState)) { // It's locked + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.sharedticketlock")); + + if (m_App.getAppUserView().getUser().hasPermission("sales.Override")) { // Override it + int res = JOptionPane.showConfirmDialog(null + , AppLocal.getIntString("message.sharedticketlockoverride") + , AppLocal.getIntString("title.editor") + , JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); + + if (res == JOptionPane.YES_OPTION) { + m_place.setPeople(true); + m_PlaceClipboard = null; + setActivePlace(m_place, ticket); + dlReceipts.lockSharedTicket(m_PlaceCurrent.getId(),"locked"); + } + } + } else { // It's not locked + String m_user = m_App.getAppUserView().getUser().getId(); + String ticketuser = dlReceipts.getServer(m_place.getId(),m_user); + + if (m_App.getAppUserView().getUser().hasPermission("sales.Override") //Check User permission + || m_user.equals(ticketuser)) { + m_place.setPeople(true); + + m_PlaceClipboard = null; + m_lockState = "locked"; + setActivePlace(m_place, ticket); + } else { + JOptionPane.showMessageDialog(null + , AppLocal.getIntString("message.sharedticket") + , AppLocal.getIntString("title.editor") + , JOptionPane.OK_OPTION); + } + } + } catch (BasicException ex) { + log.error(ex.getMessage()); + } +// printState(); // show table map. Why here? + } + } +// This block handles Merge +// at this stage m_PlaceClipboard is FROM table +// at this point m_place is TO table + + if (m_PlaceClipboard != null) { // Anything in the Clipboard? + TicketInfo ticketclip = getTicketInfo(m_PlaceClipboard); // add ticket object from clipboard + + if (ticketclip != null) { + + if (m_PlaceClipboard == m_place) { // check if FROM same as TO + Place placeclip = m_PlaceClipboard; + m_PlaceClipboard = null; + customer = null; + printState(); + setActivePlace(placeclip, ticketclip); + } + + if (m_place.hasPeople()) { // check if TO table already occupied + TicketInfo ticket = getTicketInfo(m_place); // add TO ticket object + + if (ticket != null) { // It does, so... + + if (JOptionPane.showConfirmDialog(JTicketsBagRestaurantMap.this, + AppLocal.getIntString("message.mergetablequestion"), + AppLocal.getIntString("message.mergetable"), + JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { + try { + m_PlaceClipboard.setPeople(false); + + if (ticket.getCustomer() == null) { + ticket.setCustomer(ticketclip.getCustomer()); + } + ticketclip.getLines().stream().forEach((line) -> { + ticket.addLine(line); + }); + dlReceipts.updateRSharedTicket(m_place.getId(), + ticket, ticket.getPickupId()); + dlReceipts.deleteSharedTicket(m_PlaceClipboard.getId()); + m_place.setGuests(m_PlaceClipboard.getGuests()); // Add Guests from Clipboard + + } catch (BasicException e) { + new MessageInf(e).show(JTicketsBagRestaurantMap.this); + } + m_PlaceClipboard = null; + customer = null; + + restDB.clearCustomerNameInTable(restDB.getTableDetails(ticketclip.getId())); + restDB.clearWaiterNameInTable(restDB.getTableDetails(ticketclip.getId())); + restDB.clearTableMovedFlag(restDB.getTableDetails(ticketclip.getId())); + restDB.clearTicketIdInTable(restDB.getTableDetails(ticketclip.getId())); + restDB.clearOccupiedTable(restDB.getTableDetails(ticketclip.getId())); + + printState(); + setActivePlace(m_place, ticket); + } else { + Place placeclip = m_PlaceClipboard; // don't want to merge so clear clipboard + m_PlaceClipboard = null; + customer = null; + printState(); + setActivePlace(placeclip, ticketclip); + } + } else { + new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.tableempty")) + .show(JTicketsBagRestaurantMap.this); + m_place.setPeople(false); + } + } else { // The TO table is empty + TicketInfo ticket = getTicketInfo(m_place); // fill ticket object with TO table + + if (ticket == null) { + try { + dlReceipts.insertRSharedTicket(m_place.getId(), ticketclip, ticketclip.getPickupId()); + m_place.setPeople(true); + m_place.setGuests(m_PlaceClipboard.getGuests()); // Add Guests from Clipboard + dlReceipts.deleteSharedTicket(m_PlaceClipboard.getId()); + m_PlaceClipboard.setPeople(false); + } catch (BasicException e) { + new MessageInf(e).show(JTicketsBagRestaurantMap.this); + } + printState(); + setActivePlace(m_place, ticketclip); + m_PlaceClipboard = null; + customer = null; + } else { + new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.tablefull")) + .show(JTicketsBagRestaurantMap.this); + m_PlaceClipboard.setPeople(true); + printState(); + } + } + } else { // table empty! Do we need it here? + new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.tableempty")).show(JTicketsBagRestaurantMap.this); + m_PlaceClipboard.setPeople(false); + m_PlaceClipboard = null; + customer = null; + printState(); + } + } // end of Merge + } // end of !actionEnabled + } // end of actionPerformed + } // end of Action Listener + + /** + * + * @param btnText + */ + public void setButtonTextBags(String btnText){ + m_PlaceClipboard.setButtonText(btnText); + } + + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jPanelMap = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + m_jbtnReservations = new javax.swing.JButton(); + m_jbtnRefresh = new javax.swing.JButton(); + m_jbtnLayout = new javax.swing.JButton(); + m_jbtnSave = new javax.swing.JButton(); + m_jText = new javax.swing.JLabel(); + webLblautoRefresh = new com.alee.laf.label.WebLabel(); + + setLayout(new java.awt.CardLayout()); + + m_jPanelMap.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jPanelMap.setLayout(new java.awt.BorderLayout()); + + jPanel1.setLayout(new java.awt.BorderLayout()); + + jPanel2.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel2.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT)); + + m_jbtnReservations.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jbtnReservations.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/date.png"))); // NOI18N + m_jbtnReservations.setText(AppLocal.getIntString("button.reservations")); // NOI18N + m_jbtnReservations.setToolTipText("Open Reservations screen"); + m_jbtnReservations.setFocusPainted(false); + m_jbtnReservations.setFocusable(false); + m_jbtnReservations.setMargin(new java.awt.Insets(8, 14, 8, 14)); + m_jbtnReservations.setMaximumSize(new java.awt.Dimension(133, 40)); + m_jbtnReservations.setMinimumSize(new java.awt.Dimension(133, 40)); + m_jbtnReservations.setPreferredSize(new java.awt.Dimension(133, 45)); + m_jbtnReservations.setRequestFocusEnabled(false); + m_jbtnReservations.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtnReservationsActionPerformed(evt); + } + }); + jPanel2.add(m_jbtnReservations); + + m_jbtnRefresh.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jbtnRefresh.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reload.png"))); // NOI18N + m_jbtnRefresh.setText(AppLocal.getIntString("button.reloadticket")); // NOI18N + m_jbtnRefresh.setToolTipText("Reload table information"); + m_jbtnRefresh.setFocusPainted(false); + m_jbtnRefresh.setFocusable(false); + m_jbtnRefresh.setMargin(new java.awt.Insets(8, 14, 8, 14)); + m_jbtnRefresh.setMaximumSize(new java.awt.Dimension(100, 40)); + m_jbtnRefresh.setMinimumSize(new java.awt.Dimension(100, 40)); + m_jbtnRefresh.setPreferredSize(new java.awt.Dimension(100, 45)); + m_jbtnRefresh.setRequestFocusEnabled(false); + m_jbtnRefresh.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtnRefreshActionPerformed(evt); + } + }); + jPanel2.add(m_jbtnRefresh); + + m_jbtnLayout.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jbtnLayout.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/movetable.png"))); // NOI18N + m_jbtnLayout.setText(AppLocal.getIntString("button.layout")); // NOI18N + m_jbtnLayout.setToolTipText(""); + m_jbtnLayout.setFocusPainted(false); + m_jbtnLayout.setFocusable(false); + m_jbtnLayout.setMargin(new java.awt.Insets(8, 14, 8, 14)); + m_jbtnLayout.setMaximumSize(new java.awt.Dimension(100, 40)); + m_jbtnLayout.setMinimumSize(new java.awt.Dimension(100, 40)); + m_jbtnLayout.setPreferredSize(new java.awt.Dimension(100, 45)); + m_jbtnLayout.setRequestFocusEnabled(false); + m_jbtnLayout.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtnLayoutActionPerformed(evt); + } + }); + jPanel2.add(m_jbtnLayout); + + m_jbtnSave.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jbtnSave.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/filesave.png"))); // NOI18N + m_jbtnSave.setText(AppLocal.getIntString("button.save")); // NOI18N + m_jbtnSave.setToolTipText(""); + m_jbtnSave.setFocusPainted(false); + m_jbtnSave.setFocusable(false); + m_jbtnSave.setMargin(new java.awt.Insets(8, 14, 8, 14)); + m_jbtnSave.setMaximumSize(new java.awt.Dimension(100, 40)); + m_jbtnSave.setMinimumSize(new java.awt.Dimension(100, 40)); + m_jbtnSave.setPreferredSize(new java.awt.Dimension(100, 45)); + m_jbtnSave.setRequestFocusEnabled(false); + m_jbtnSave.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtnSaveActionPerformed(evt); + } + }); + jPanel2.add(m_jbtnSave); + + m_jText.setBackground(new java.awt.Color(255, 255, 255)); + m_jText.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jText.setForeground(new java.awt.Color(0, 153, 255)); + m_jText.setOpaque(true); + jPanel2.add(m_jText); + + jPanel1.add(jPanel2, java.awt.BorderLayout.LINE_START); + + webLblautoRefresh.setBackground(new java.awt.Color(255, 51, 51)); + webLblautoRefresh.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + webLblautoRefresh.setText(bundle.getString("label.autoRefreshTableMapTimerON")); // NOI18N + webLblautoRefresh.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanel1.add(webLblautoRefresh, java.awt.BorderLayout.CENTER); + + m_jPanelMap.add(jPanel1, java.awt.BorderLayout.NORTH); + + add(m_jPanelMap, "map"); + }// </editor-fold>//GEN-END:initComponents + + private void m_jbtnRefreshActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtnRefreshActionPerformed + + loadTickets(); + printState(); + }//GEN-LAST:event_m_jbtnRefreshActionPerformed + + private void m_jbtnReservationsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtnReservationsActionPerformed + showView("res"); + m_jreservations.activate(); + }//GEN-LAST:event_m_jbtnReservationsActionPerformed + + private void m_jbtnLayoutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtnLayoutActionPerformed + if (java.util.ResourceBundle.getBundle("pos_messages") + .getString("button.layout").equals(m_jbtnLayout.getText())) { + actionEnabled = false; + m_jbtnSave.setVisible(true); + m_jbtnLayout.setText(java.util.ResourceBundle + .getBundle("pos_messages").getString("button.disablelayout")); + + m_aplaces.stream().filter((pl) -> (transBtns)).map((pl) -> { + pl.getButton().setOpaque(true); + return pl; + }).map((pl) -> { + pl.getButton().setContentAreaFilled(true); + return pl; + }).forEachOrdered((pl) -> { + pl.getButton().setBorderPainted(true); + }); + } else { + actionEnabled = true; + m_jbtnSave.setVisible(false); + m_jbtnLayout.setText(java.util.ResourceBundle + .getBundle("pos_messages").getString("button.layout")); + + m_aplaces.stream().filter((pl) -> (transBtns)).map((pl) -> { + pl.getButton().setOpaque(false); + return pl; + }).map((pl) -> { + pl.getButton().setContentAreaFilled(false); + return pl; + }).forEachOrdered((pl) -> { + pl.getButton().setBorderPainted(false); + }); + } + }//GEN-LAST:event_m_jbtnLayoutActionPerformed + + private void m_jbtnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtnSaveActionPerformed + m_aplaces.forEach((pl) -> { + try { + dlSystem.updatePlaces(pl.getX(), pl.getY(), pl.getId()); + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + }); + }//GEN-LAST:event_m_jbtnSaveActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel m_jPanelMap; + private javax.swing.JLabel m_jText; + private javax.swing.JButton m_jbtnLayout; + private javax.swing.JButton m_jbtnRefresh; + private javax.swing.JButton m_jbtnReservations; + private javax.swing.JButton m_jbtnSave; + private com.alee.laf.label.WebLabel webLblautoRefresh; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurantRes.form b/src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurantRes.form new file mode 100644 index 0000000..378721d --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurantRes.form @@ -0,0 +1,480 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[1000, 750]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,-18,0,0,3,-12"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanNorth"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[1000, 350]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="10" pref="10" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel5" min="-2" max="-2" attributes="0"/> + <EmptySpace min="10" pref="10" max="-2" attributes="0"/> + <Component id="jButton1" min="-2" pref="70" max="-2" attributes="0"/> + <EmptySpace min="6" pref="6" max="-2" attributes="0"/> + <Component id="txtCustomer" min="-2" max="-2" attributes="0"/> + <EmptySpace min="4" pref="4" max="-2" attributes="0"/> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + <EmptySpace min="4" pref="4" max="-2" attributes="0"/> + <Component id="m_jtxtChairs" min="-2" pref="90" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="m_jPanelTime" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jbtnShowCalendar" min="-2" pref="200" max="-2" attributes="0"/> + <Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel4" min="-2" max="-2" attributes="0"/> + <EmptySpace min="4" pref="4" max="-2" attributes="0"/> + <Component id="m_jtxtDescription" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="22" max="-2" attributes="0"/> + <Component id="m_jPanelList" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="m_jToolbar" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jKeys" min="-2" pref="1" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + <Component id="m_jbtnReceive" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jbtnTables" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="42" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jToolbar" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="24" max="-2" attributes="0"/> + <Component id="m_jKeys" min="-2" pref="32" max="-2" attributes="0"/> + </Group> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jbtnTables" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jbtnReceive" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="5" pref="5" max="-2" attributes="0"/> + <Component id="jLabel5" min="-2" pref="40" max="-2" attributes="0"/> + </Group> + <Component id="jButton1" min="-2" max="-2" attributes="0"/> + <Group type="102" attributes="0"> + <EmptySpace min="7" pref="7" max="-2" attributes="0"/> + <Component id="txtCustomer" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <EmptySpace min="7" pref="7" max="-2" attributes="0"/> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <EmptySpace min="7" pref="7" max="-2" attributes="0"/> + <Component id="m_jtxtChairs" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <EmptySpace min="7" pref="7" max="-2" attributes="0"/> + <Component id="jLabel4" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <EmptySpace min="7" pref="7" max="-2" attributes="0"/> + <Component id="m_jtxtDescription" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="2" attributes="0"> + <EmptySpace min="-2" pref="31" max="-2" attributes="0"/> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="42" max="-2" attributes="0"/> + <Component id="jbtnShowCalendar" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="2" attributes="0"> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jPanelTime" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jPanelList" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Container class="javax.swing.JPanel" name="m_jToolbar"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[500, 55]"/> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + </Container> + <Component class="javax.swing.JButton" name="m_jbtnReceive"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/receive.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.receive" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Receive pre-Booked Customer"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[130, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jbtnReceiveActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jbtnTables"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/tables.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.tables" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Go to Table Plan"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[130, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jbtnTablesActionPerformed"/> + </Events> + </Component> + <Container class="javax.swing.JPanel" name="m_jPanelList"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 200]"/> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + </Container> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="rest.label.selectcustomer" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 45]"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleName" type="java.lang.String" value="Select Person"/> + </AccessibilityProperties> + </Component> + <Component class="javax.swing.JButton" name="jButton1"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/customer_add_sml.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Show Customers"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 33]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 33]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton1ActionPerformed"/> + </Events> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="txtCustomer"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="rest.label.chairs" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorIntegerPositive" name="m_jtxtChairs"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 25]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="rest.label.notes" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jtxtDescription"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[180, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="rest.label.date" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="verticalAlignment" type="int" value="1"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Container class="javax.swing.JPanel" name="m_jPanelTime"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 200]"/> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + </Container> + <Component class="javax.swing.JButton" name="jbtnShowCalendar"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/date.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="rest.label.showcalendar" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="rest.label.showcalendar" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[129, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnShowCalendarActionPerformed"/> + </Events> + </Component> + <Component class="com.unicenta.editor.JEditorKeys" name="m_jKeys"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[5, 5]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanSouth"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[1000, 350]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <EmptySpace min="0" pref="1012" max="32767" attributes="0"/> + <Group type="103" rootIndex="1" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + <Component id="jCalendar" min="-2" max="-2" attributes="0"/> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + </Group> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <EmptySpace min="0" pref="350" max="32767" attributes="0"/> + <Group type="103" rootIndex="1" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + <Component id="jCalendar" min="-2" max="-2" attributes="0"/> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + </Group> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Container class="javax.swing.JPanel" name="jCalendar"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[1000, 350]"/> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout"> + <Property name="useNullLayout" type="boolean" value="false"/> + </Layout> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanelTime"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 250]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="0" y="50" width="-1" height="-1"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + </Container> + <Container class="javax.swing.JPanel" name="jPanelDate"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[700, 345]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription"> + <AbsoluteConstraints x="270" y="5" width="-1" height="-1"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurantRes.java b/src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurantRes.java new file mode 100644 index 0000000..f6abccc --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/restaurant/JTicketsBagRestaurantRes.java @@ -0,0 +1,710 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales.restaurant; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.beans.*; +import java.util.*; + +import com.unicenta.beans.*; +import com.unicenta.data.gui.*; +import com.unicenta.data.loader.*; +import com.unicenta.data.user.*; + +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.format.Formats; +import com.unicenta.basic.BasicException; +import com.unicenta.pos.customers.DataLogicCustomers; +import com.unicenta.pos.customers.JCustomerFinder; +import com.unicenta.pos.customers.CustomerInfo; + +/** + * + * @author JG uniCenta + */ +public class JTicketsBagRestaurantRes extends javax.swing.JPanel implements EditorRecord { + + private final JTicketsBagRestaurantMap m_restaurantmap; + + private DataLogicCustomers dlCustomers = null; + + private final DirtyManager m_Dirty; + private Object m_sID; + private CustomerInfo customer; + private Date m_dCreated; + private final JTimePanel m_timereservation; + private boolean m_bReceived; + private final BrowsableEditableData m_bd; + + private Date m_dcurrentday; + + private final JCalendarPanel m_datepanel; + private final JTimePanel m_timepanel; + private boolean m_bpaintlock = false; + + + /** Creates new form JPanelReservations + * @param oApp + * @param restaurantmap */ + public JTicketsBagRestaurantRes(AppView oApp, JTicketsBagRestaurantMap restaurantmap) { + + m_restaurantmap = restaurantmap; + + dlCustomers = (DataLogicCustomers) oApp.getBean("com.unicenta.pos.customers.DataLogicCustomers"); + + m_dcurrentday = null; + + initComponents(); + jCalendar.setVisible(false); + + m_datepanel = new JCalendarPanel(); + jPanelDate.add(m_datepanel, BorderLayout.CENTER); + m_datepanel.addPropertyChangeListener("Date", new DateChangeCalendarListener()); + + m_timepanel = new JTimePanel(null, JTimePanel.BUTTONS_HOUR); + m_timepanel.setPeriod(3600000L); + jPanelTime.add(m_timepanel, BorderLayout.CENTER); + m_timepanel.addPropertyChangeListener("Date", new DateChangeTimeListener()); + + m_timereservation = new JTimePanel(null, JTimePanel.BUTTONS_MINUTE); + m_jPanelTime.add(m_timereservation, BorderLayout.CENTER); + + txtCustomer.addEditorKeys(m_jKeys); + m_jtxtChairs.addEditorKeys(m_jKeys); + m_jtxtDescription.addEditorKeys(m_jKeys); + + m_Dirty = new DirtyManager(); + m_timereservation.addPropertyChangeListener("Date", m_Dirty); + txtCustomer.addPropertyChangeListener("Text", m_Dirty); + txtCustomer.addPropertyChangeListener("Text", new PropertyChangeListener(){ + @Override + public void propertyChange(PropertyChangeEvent evt) { + customer = new CustomerInfo(null); + customer.setTaxid(null); + customer.setSearchkey(null); + customer.setName(txtCustomer.getText()); + } + }); + m_jtxtChairs.addPropertyChangeListener("Text", m_Dirty); + m_jtxtDescription.addPropertyChangeListener("Text", m_Dirty); + + writeValueEOF(); + + ListProvider lpr = new ListProviderCreator(dlCustomers.getReservationsList(), new MyDateFilter()); + SaveProvider spr = new SaveProvider(dlCustomers.getReservationsUpdate(), + dlCustomers.getReservationsInsert(), dlCustomers.getReservationsDelete()); + + m_bd = new BrowsableEditableData(lpr, spr, new CompareReservations(), this, m_Dirty); + + JListNavigator nl = new JListNavigator(m_bd, true); + nl.setCellRenderer(new JCalendarItemRenderer()); + m_jPanelList.add(nl, BorderLayout.CENTER); + + m_jToolbar.add(new JLabelDirty(m_Dirty)); + m_jToolbar.add(new JCounter(m_bd)); + m_jToolbar.add(new JNavigator(m_bd)); + m_jToolbar.add(new JSaver(m_bd)); + } + + private class MyDateFilter implements EditorCreator { + @Override + public Object createValue() throws BasicException { + return new Object[] {m_dcurrentday, new Date(m_dcurrentday.getTime() + 3600000L)}; + } + } + + /** + * + */ + public void activate() { + reload(DateUtils.getTodayHours(new Date())); + } + + /** + * + */ + @Override + public void refresh() { + } + + /** + * + * @return + */ + public boolean deactivate() { + try { + return m_bd.actionClosingForm(this); + } catch (BasicException eD) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, + AppLocal.getIntString("message.CannotMove"), eD); + msg.show(this); + return false; + } + } + + /** + * + */ + @Override + public void writeValueEOF() { + m_sID = null; + m_dCreated = null; + m_timereservation.setDate(null); + assignCustomer(new CustomerInfo(null)); + m_jtxtChairs.reset(); + m_bReceived = false; + m_jtxtDescription.reset(); + m_timereservation.setEnabled(false); + txtCustomer.setEnabled(false); + m_jtxtChairs.setEnabled(false); + m_jtxtDescription.setEnabled(false); + m_jKeys.setEnabled(false); + + m_jbtnReceive.setEnabled(false); + } + + /** + * + */ + @Override + public void writeValueInsert() { + m_sID = null; + m_dCreated = null; + m_timereservation.setCheckDates(m_dcurrentday, new Date(m_dcurrentday.getTime() + 3600000L)); + m_timereservation.setDate(m_dcurrentday); + assignCustomer(new CustomerInfo(null)); + m_jtxtChairs.setValueInteger(2); + m_bReceived = false; + m_jtxtDescription.reset(); + m_timereservation.setEnabled(true); + txtCustomer.setEnabled(true); + m_jtxtChairs.setEnabled(true); + m_jtxtDescription.setEnabled(true); + m_jKeys.setEnabled(true); + + m_jbtnReceive.setEnabled(true); + + txtCustomer.activate(); + } + + /** + * + * @param value + */ + @Override + public void writeValueDelete(Object value) { + Object[] res = (Object[]) value; + m_sID = res[0]; + m_dCreated = (Date) res[1]; + m_timereservation.setCheckDates(m_dcurrentday, new Date(m_dcurrentday.getTime() + 3600000L)); + m_timereservation.setDate((Date) res[2]); + CustomerInfo c = new CustomerInfo((String) res[3]); + c.setTaxid((String) res[4]); + c.setSearchkey((String) res[5]); + c.setName((String) res[6]); + assignCustomer(c); + m_jtxtChairs.setValueInteger(((Integer)res[7]).intValue()); + m_bReceived = ((Boolean)res[8]).booleanValue(); + m_jtxtDescription.setText(Formats.STRING.formatValue(res[9])); + m_timereservation.setEnabled(false); + txtCustomer.setEnabled(false); + m_jtxtChairs.setEnabled(false); + m_jtxtDescription.setEnabled(false); + m_jKeys.setEnabled(false); + + m_jbtnReceive.setEnabled(false); + } + + /** + * + * @param value + */ + @Override + public void writeValueEdit(Object value) { + Object[] res = (Object[]) value; + m_sID = res[0]; + m_dCreated = (Date) res[1]; + m_timereservation.setCheckDates(m_dcurrentday, new Date(m_dcurrentday.getTime() + 3600000L)); + m_timereservation.setDate((Date) res[2]); + CustomerInfo c = new CustomerInfo((String) res[3]); + c.setTaxid((String) res[4]); + c.setSearchkey((String) res[5]); + c.setName((String) res[6]); + assignCustomer(c); + m_jtxtChairs.setValueInteger(((Integer)res[7]).intValue()); + m_bReceived = ((Boolean)res[8]).booleanValue(); + m_jtxtDescription.setText(Formats.STRING.formatValue(res[9])); + m_timereservation.setEnabled(true); + txtCustomer.setEnabled(true); + m_jtxtChairs.setEnabled(true); + m_jtxtDescription.setEnabled(true); + m_jKeys.setEnabled(true); + + m_jbtnReceive.setEnabled(!m_bReceived); // se habilita si no se ha recibido al cliente + + txtCustomer.activate(); + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + Object[] res = new Object[10]; + + res[0] = m_sID == null ? UUID.randomUUID().toString() : m_sID; + res[1] = m_dCreated == null ? new Date() : m_dCreated; + res[2] = m_timereservation.getDate(); + res[3] = customer.getId(); + res[4] = customer.getTaxid(); + res[5] = customer.getSearchkey(); + res[6] = customer.getName(); + res[7] = m_jtxtChairs.getValueInteger(); + res[8] = m_bReceived; + res[9] = m_jtxtDescription.getText(); + + return res; + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + private static class CompareReservations implements Comparator { + @Override + public int compare(Object o1, Object o2) { + Object[] a1 = (Object[]) o1; + Object[] a2 = (Object[]) o2; + Date d1 = (Date) a1[2]; + Date d2 = (Date) a2[2]; + int c = d1.compareTo(d2); + if (c == 0) { + d1 = (Date) a1[1]; + d2 = (Date) a2[1]; + return d1.compareTo(d2); + } else { + return c; + } + } + } + + private void reload(Date dDate) { + + if (!dDate.equals(m_dcurrentday)) { + + Date doldcurrentday = m_dcurrentday; + m_dcurrentday = dDate; + try { + m_bd.actionLoad(); + } catch (BasicException eD) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, + LocalRes.getIntString("message.noreload"), eD); + msg.show(this); + m_dcurrentday = doldcurrentday; // nos retractamos... + } + } + + paintDate(); + } + + private void paintDate() { + + m_bpaintlock = true; + m_datepanel.setDate(m_dcurrentday); + m_timepanel.setDate(m_dcurrentday); + m_bpaintlock = false; + } + + private void assignCustomer(CustomerInfo c) { + + txtCustomer.setText(c.getName()); + customer = c; + } + + private class DateChangeCalendarListener implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (!m_bpaintlock) { + reload(DateUtils.getTodayHours(DateUtils.getDate(m_datepanel.getDate(), + m_timepanel.getDate()))); + } + } + } + + private class DateChangeTimeListener implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (!m_bpaintlock) { + reload(DateUtils.getTodayHours(DateUtils.getDate(m_datepanel.getDate(), + m_timepanel.getDate()))); + } + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanNorth = new javax.swing.JPanel(); + m_jToolbar = new javax.swing.JPanel(); + m_jbtnReceive = new javax.swing.JButton(); + m_jbtnTables = new javax.swing.JButton(); + m_jPanelList = new javax.swing.JPanel(); + jLabel5 = new javax.swing.JLabel(); + jButton1 = new javax.swing.JButton(); + txtCustomer = new com.unicenta.editor.JEditorString(); + jLabel3 = new javax.swing.JLabel(); + m_jtxtChairs = new com.unicenta.editor.JEditorIntegerPositive(); + jLabel4 = new javax.swing.JLabel(); + m_jtxtDescription = new com.unicenta.editor.JEditorString(); + jLabel1 = new javax.swing.JLabel(); + m_jPanelTime = new javax.swing.JPanel(); + jbtnShowCalendar = new javax.swing.JButton(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanSouth = new javax.swing.JPanel(); + jCalendar = new javax.swing.JPanel(); + jPanelTime = new javax.swing.JPanel(); + jPanelDate = new javax.swing.JPanel(); + + setPreferredSize(new java.awt.Dimension(1000, 750)); + setLayout(new java.awt.BorderLayout()); + + jPanNorth.setPreferredSize(new java.awt.Dimension(1000, 350)); + + m_jToolbar.setPreferredSize(new java.awt.Dimension(500, 55)); + m_jToolbar.setLayout(new java.awt.BorderLayout()); + + m_jbtnReceive.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jbtnReceive.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/receive.png"))); // NOI18N + m_jbtnReceive.setText(AppLocal.getIntString("button.receive")); // NOI18N + m_jbtnReceive.setToolTipText("Receive pre-Booked Customer"); + m_jbtnReceive.setFocusPainted(false); + m_jbtnReceive.setFocusable(false); + m_jbtnReceive.setPreferredSize(new java.awt.Dimension(130, 45)); + m_jbtnReceive.setRequestFocusEnabled(false); + m_jbtnReceive.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtnReceiveActionPerformed(evt); + } + }); + + m_jbtnTables.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jbtnTables.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/tables.png"))); // NOI18N + m_jbtnTables.setText(AppLocal.getIntString("button.tables")); // NOI18N + m_jbtnTables.setToolTipText("Go to Table Plan"); + m_jbtnTables.setFocusPainted(false); + m_jbtnTables.setFocusable(false); + m_jbtnTables.setPreferredSize(new java.awt.Dimension(130, 45)); + m_jbtnTables.setRequestFocusEnabled(false); + m_jbtnTables.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jbtnTablesActionPerformed(evt); + } + }); + + m_jPanelList.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + m_jPanelList.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPanelList.setPreferredSize(new java.awt.Dimension(300, 200)); + m_jPanelList.setLayout(new java.awt.BorderLayout()); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("rest.label.selectcustomer")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(100, 45)); + + jButton1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/customer_add_sml.png"))); // NOI18N + jButton1.setToolTipText("Show Customers"); + jButton1.setFocusPainted(false); + jButton1.setFocusable(false); + jButton1.setMaximumSize(new java.awt.Dimension(40, 33)); + jButton1.setMinimumSize(new java.awt.Dimension(40, 33)); + jButton1.setPreferredSize(new java.awt.Dimension(80, 45)); + jButton1.setRequestFocusEnabled(false); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + + txtCustomer.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtCustomer.setMaximumSize(new java.awt.Dimension(250, 30)); + txtCustomer.setMinimumSize(new java.awt.Dimension(200, 25)); + txtCustomer.setPreferredSize(new java.awt.Dimension(250, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("rest.label.chairs")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jtxtChairs.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jtxtChairs.setMaximumSize(new java.awt.Dimension(50, 25)); + m_jtxtChairs.setMinimumSize(new java.awt.Dimension(50, 25)); + m_jtxtChairs.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("rest.label.notes")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jtxtDescription.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jtxtDescription.setMaximumSize(new java.awt.Dimension(180, 25)); + m_jtxtDescription.setPreferredSize(new java.awt.Dimension(250, 30)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("rest.label.date")); // NOI18N + jLabel1.setVerticalAlignment(javax.swing.SwingConstants.TOP); + jLabel1.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jPanelTime.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPanelTime.setPreferredSize(new java.awt.Dimension(200, 200)); + m_jPanelTime.setLayout(new java.awt.BorderLayout()); + + jbtnShowCalendar.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jbtnShowCalendar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/date.png"))); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jbtnShowCalendar.setText(bundle.getString("rest.label.showcalendar")); // NOI18N + jbtnShowCalendar.setToolTipText(bundle.getString("rest.label.showcalendar")); // NOI18N + jbtnShowCalendar.setPreferredSize(new java.awt.Dimension(129, 45)); + jbtnShowCalendar.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnShowCalendarActionPerformed(evt); + } + }); + + m_jKeys.setPreferredSize(new java.awt.Dimension(5, 5)); + + javax.swing.GroupLayout jPanNorthLayout = new javax.swing.GroupLayout(jPanNorth); + jPanNorth.setLayout(jPanNorthLayout); + jPanNorthLayout.setHorizontalGroup( + jPanNorthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanNorthLayout.createSequentialGroup() + .addGap(10, 10, 10) + .addGroup(jPanNorthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(jPanNorthLayout.createSequentialGroup() + .addGroup(jPanNorthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanNorthLayout.createSequentialGroup() + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(6, 6, 6) + .addComponent(txtCustomer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(4, 4, 4) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(4, 4, 4) + .addComponent(m_jtxtChairs, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanNorthLayout.createSequentialGroup() + .addComponent(m_jPanelTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanNorthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jbtnShowCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanNorthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanNorthLayout.createSequentialGroup() + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(4, 4, 4) + .addComponent(m_jtxtDescription, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanNorthLayout.createSequentialGroup() + .addGap(22, 22, 22) + .addComponent(m_jPanelList, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) + .addGroup(jPanNorthLayout.createSequentialGroup() + .addComponent(m_jToolbar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jKeys, javax.swing.GroupLayout.PREFERRED_SIZE, 1, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(m_jbtnReceive, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jbtnTables, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(42, 42, 42)))) + ); + jPanNorthLayout.setVerticalGroup( + jPanNorthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanNorthLayout.createSequentialGroup() + .addGroup(jPanNorthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jToolbar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanNorthLayout.createSequentialGroup() + .addGap(24, 24, 24) + .addComponent(m_jKeys, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanNorthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jbtnTables, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jbtnReceive, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanNorthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanNorthLayout.createSequentialGroup() + .addGap(5, 5, 5) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanNorthLayout.createSequentialGroup() + .addGap(7, 7, 7) + .addComponent(txtCustomer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanNorthLayout.createSequentialGroup() + .addGap(7, 7, 7) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanNorthLayout.createSequentialGroup() + .addGap(7, 7, 7) + .addComponent(m_jtxtChairs, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanNorthLayout.createSequentialGroup() + .addGap(7, 7, 7) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanNorthLayout.createSequentialGroup() + .addGap(7, 7, 7) + .addComponent(m_jtxtDescription, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanNorthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanNorthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.CENTER, jPanNorthLayout.createSequentialGroup() + .addGap(31, 31, 31) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(42, 42, 42) + .addComponent(jbtnShowCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(javax.swing.GroupLayout.Alignment.CENTER, jPanNorthLayout.createSequentialGroup() + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jPanelTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanNorthLayout.createSequentialGroup() + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jPanelList, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) + ); + + jLabel5.getAccessibleContext().setAccessibleName("Select Person"); + + add(jPanNorth, java.awt.BorderLayout.CENTER); + + jPanSouth.setPreferredSize(new java.awt.Dimension(1000, 350)); + + jCalendar.setPreferredSize(new java.awt.Dimension(1000, 350)); + jCalendar.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout()); + + jPanelTime.setPreferredSize(new java.awt.Dimension(250, 250)); + jPanelTime.setLayout(new java.awt.BorderLayout()); + jCalendar.add(jPanelTime, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 50, -1, -1)); + + jPanelDate.setPreferredSize(new java.awt.Dimension(700, 345)); + jPanelDate.setLayout(new java.awt.BorderLayout()); + jCalendar.add(jPanelDate, new org.netbeans.lib.awtextra.AbsoluteConstraints(270, 5, -1, -1)); + + javax.swing.GroupLayout jPanSouthLayout = new javax.swing.GroupLayout(jPanSouth); + jPanSouth.setLayout(jPanSouthLayout); + jPanSouthLayout.setHorizontalGroup( + jPanSouthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 1012, Short.MAX_VALUE) + .addGroup(jPanSouthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanSouthLayout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(jCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE))) + ); + jPanSouthLayout.setVerticalGroup( + jPanSouthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 350, Short.MAX_VALUE) + .addGroup(jPanSouthLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanSouthLayout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(jCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE))) + ); + + add(jPanSouth, java.awt.BorderLayout.SOUTH); + }// </editor-fold>//GEN-END:initComponents + + private void m_jbtnReceiveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtnReceiveActionPerformed + + m_bReceived = true; + m_Dirty.setDirty(true); + + try { + m_bd.saveData(); + m_restaurantmap.viewTables(customer); + } catch (BasicException eD) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, + LocalRes.getIntString("message.nosaveticket"), eD); + msg.show(this); + } + + }//GEN-LAST:event_m_jbtnReceiveActionPerformed + + private void m_jbtnTablesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jbtnTablesActionPerformed + + m_restaurantmap.viewTables(); + + }//GEN-LAST:event_m_jbtnTablesActionPerformed + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + + JCustomerFinder finder = JCustomerFinder.getCustomerFinder(this, dlCustomers); + finder.search(customer); + finder.setVisible(true); + + CustomerInfo c = finder.getSelectedCustomer(); + + if (c == null) { + assignCustomer(new CustomerInfo(null)); + } else { + assignCustomer(c); + } + + }//GEN-LAST:event_jButton1ActionPerformed + + private void jbtnShowCalendarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnShowCalendarActionPerformed + if (jCalendar.isShowing()) { + jCalendar.setVisible(false); + jbtnShowCalendar.setText("Show Calendar"); + }else{ + jbtnShowCalendar.setText("Hide Calendar"); + jCalendar.setVisible(true); + } + }//GEN-LAST:event_jbtnShowCalendarActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + private javax.swing.JPanel jCalendar; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JPanel jPanNorth; + private javax.swing.JPanel jPanSouth; + private javax.swing.JPanel jPanelDate; + private javax.swing.JPanel jPanelTime; + private javax.swing.JButton jbtnShowCalendar; + private com.unicenta.editor.JEditorKeys m_jKeys; + private javax.swing.JPanel m_jPanelList; + private javax.swing.JPanel m_jPanelTime; + private javax.swing.JPanel m_jToolbar; + private javax.swing.JButton m_jbtnReceive; + private javax.swing.JButton m_jbtnTables; + private com.unicenta.editor.JEditorIntegerPositive m_jtxtChairs; + private com.unicenta.editor.JEditorString m_jtxtDescription; + private com.unicenta.editor.JEditorString txtCustomer; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/restaurant/Place.java b/src/main/java/com/unicenta/pos/sales/restaurant/Place.java new file mode 100644 index 0000000..d7a6422 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/restaurant/Place.java @@ -0,0 +1,233 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales.restaurant; + +import java.awt.Dimension; +import java.awt.Insets; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.SwingConstants; +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.NullIcon; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.SerializableRead; +import java.util.Date; + +/** + * + * @author JG uniCenta + */ +public class Place implements SerializableRead, java.io.Serializable { + + private static final long serialVersionUID = 8652254694281L; + private static final Icon ICO_OCU = new ImageIcon(Place.class.getResource("/com/unicenta/images/edit_group.png")); + private static final Icon ICO_FRE = new NullIcon(22, 22); + + private String m_sId; + private String m_sName; + private String m_sSeats; + private int m_ix; + private int m_iy; + private int m_diffx; + private int m_diffy; + private String m_sfloor; + private String m_customer; + private String m_waiter; + private String m_ticketId; + private Boolean m_tableMoved; + private Boolean m_changed = false; + + private boolean m_bPeople; + private JButton m_btn; + + private int m_theight; + private int m_twidth; + private int m_guests; + private Date m_occupied; + + + /** + * Creates a new instance of TablePlace + */ + public Place() { + } + + /** + * + * @param dr + * @throws BasicException + */ + @Override + public void readValues(DataRead dr) throws BasicException { + m_sId = dr.getString(1); + m_sName = dr.getString(2); + m_sSeats = dr.getString(3); + m_ix = dr.getInt(4); + m_iy = dr.getInt(5); + m_sfloor = dr.getString(6); + m_customer = dr.getString(7); + m_waiter = dr.getString(8); + m_ticketId = dr.getString(9); + m_tableMoved = dr.getBoolean(10); + m_twidth = dr.getInt(11); + m_theight = dr.getInt(12); + m_guests = dr.getInt(13); + m_occupied = dr.getTimestamp(14); + + m_bPeople = false; + m_btn = new JButton(); + m_btn.setFocusPainted(false); + m_btn.setFocusable(false); + m_btn.setRequestFocusEnabled(false); + m_btn.setHorizontalTextPosition(SwingConstants.CENTER); + m_btn.setVerticalTextPosition(SwingConstants.BOTTOM); + m_btn.setIcon(ICO_FRE); + m_btn.setText(m_sName); + m_btn.setMargin(new Insets(2,5,2,5)); + m_diffx=0; + m_diffy=0; + + } + + public String getId() { + return m_sId; + } + + public String getTicketID(){ + return m_ticketId; + } + public String getName() { + return m_sName; + } + + public String getSeats() { + return m_sSeats; + } + + public int getX() { + return m_ix; + } + + public int getY() { + return m_iy; + } + + public void setX(int x) { + this.m_ix = x; + } + + public void setY(int y) { + this.m_iy = y; + } + + public int gettWidth() { + return m_twidth; + } + + public int gettHeight() { + return m_theight; + } + + public void settWidth(int twidth) { + this.m_twidth = twidth; + } + + public void settHeight(int theight) { + this.m_theight = theight; + } + + public int getDiffX() { + return m_diffx; + } + + public int getDiffY() { + return m_diffy; + } + + public void setDiffX(int x) { + this.m_diffx = x; + } + + public void setDiffY(int y) { + this.m_diffy = y; + } + + public Boolean getChanged() { + return m_changed; + } + + public void setChanged(Boolean changed) { + this.m_changed = changed; + } + + + public String getFloor() { + return m_sfloor; + } + + public JButton getButton() { + return m_btn; + } + + public String getCustomer() { + return m_customer; + } + + public String getWaiter() { + return m_waiter; + } + + public boolean hasPeople() { + return m_bPeople; + } + + public void setPeople(boolean bValue) { + m_bPeople = bValue; + m_btn.setIcon(bValue ? ICO_OCU : ICO_FRE); + } + + public int getGuests() { + return m_guests; + } + + public void setGuests(int guests) { + this.m_guests = guests; + } + + public Date getOccupied() { + return m_occupied; + } + + public void setOccupied(Date occupied) { + this.m_occupied = occupied; + } + + public void setButtonBounds() { + Dimension d = m_btn.getPreferredSize(); + m_btn.setPreferredSize(new Dimension(d.width + m_twidth, d.height + m_theight)); + d = m_btn.getPreferredSize(); + m_btn.setBounds(m_ix - d.width / 2, m_iy - d.height / 2, d.width, d.height); + } + + public void setButtonText(String btnText) { + m_btn.setText(btnText); + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/sales/restaurant/RestaurantDBUtils.java b/src/main/java/com/unicenta/pos/sales/restaurant/RestaurantDBUtils.java new file mode 100644 index 0000000..feba2ac --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/restaurant/RestaurantDBUtils.java @@ -0,0 +1,624 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.unicenta.pos.sales.restaurant; + +import com.unicenta.data.loader.Session; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSystem; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Timestamp; + +/** + * + * @author JDL + */ + +public class RestaurantDBUtils { + private Session s; + private Connection con; + private Statement stmt; + private PreparedStatement pstmt; + private String SQL; + private ResultSet rs; + private AppView m_App; + + protected DataLogicSystem dlSystem; + + /** + * + * @param oApp + */ + public RestaurantDBUtils(AppView oApp) { + m_App=oApp; + + try{ + s=m_App.getSession(); + con=s.getConnection(); + } catch (SQLException e){ + } + } + + /** + * + * @param newTable + * @param ticketID + */ + public void moveCustomer(String newTable, String ticketID){ + String oldTable=getTableDetails(ticketID); + + if (countTicketIdInTable(ticketID)>1){ + setCustomerNameInTable(getCustomerNameInTable(oldTable),newTable); + setWaiterNameInTable(getWaiterNameInTable(oldTable),newTable); + setTicketIdInTable(ticketID,newTable); + setGuestsInTable(getGuestsInTable(oldTable),newTable); + + + + oldTable = getTableMovedName(ticketID); + if ((oldTable != null) && (oldTable != newTable)){ + clearCustomerNameInTable(oldTable); + clearWaiterNameInTable(oldTable); + clearTicketIdInTable(oldTable); + clearTableMovedFlag(oldTable); + } else { + oldTable = getTableMovedName(ticketID); + clearTableMovedFlag(oldTable); + } + } + } + + /** + * + * @param custName + * @param tableName + */ + public void setCustomerNameInTable(String custName, String tableName){ + try{ + SQL = "UPDATE places SET CUSTOMER=? WHERE NAME=?"; + pstmt=con.prepareStatement(SQL); + pstmt.setString(1,custName); + pstmt.setString(2,tableName); + pstmt.executeUpdate(); + }catch(SQLException e){ + } + } + + /** + * + * @param custName + * @param tableID + */ + public void setCustomerNameInTableById(String custName, String tableID){ + try{ + SQL = "UPDATE places SET CUSTOMER=? WHERE ID=?"; + pstmt=con.prepareStatement(SQL); + pstmt.setString(1,custName); + pstmt.setString(2,tableID); + pstmt.executeUpdate(); + }catch(SQLException e){ + } + } + + /** + * + * @param custName + * @param ticketID + */ + public void setCustomerNameInTableByTicketId(String custName, String ticketID){ + try{ + SQL = "UPDATE places SET CUSTOMER=? WHERE TICKETID=?"; + pstmt=con.prepareStatement(SQL); + pstmt.setString(1,custName); + pstmt.setString(2,ticketID); + pstmt.executeUpdate(); + }catch(SQLException e){ + } +} + + /** + * + * @param tableName + * @return + */ + public String getCustomerNameInTable(String tableName){ + try{ + SQL = "SELECT customer FROM places WHERE NAME='"+ tableName + "'"; + stmt = (Statement) con.createStatement(); + rs = stmt.executeQuery(SQL); + + if (rs.next()){ + String customer =rs.getString("CUSTOMER"); + return(customer); + } + }catch(SQLException e){ + } + + return ""; + } + + /** + * + * @param tableId + * @return + */ + public String getCustomerNameInTableById(String tableId){ + try{ + SQL = "SELECT customer FROM places WHERE ID='"+ tableId + "'"; + stmt = (Statement) con.createStatement(); + rs = stmt.executeQuery(SQL); + if (rs.next()){ + String customer =rs.getString("CUSTOMER"); + return(customer); } + }catch(SQLException e){ + } + + return ""; + } + + /** + * + * @param tableName + */ + public void clearCustomerNameInTable(String tableName){ + try{ + SQL = "UPDATE places SET CUSTOMER=null WHERE NAME=?"; + pstmt=con.prepareStatement(SQL); + pstmt.setString(1,tableName); + pstmt.executeUpdate(); + }catch(SQLException e){ + } + } + + /** + * + * @param tableID + */ + public void clearCustomerNameInTableById(String tableID){ + try{ + SQL = "UPDATE places SET CUSTOMER=null WHERE ID=?"; + pstmt=con.prepareStatement(SQL); + pstmt.setString(1,tableID); + pstmt.executeUpdate(); + }catch(SQLException e){ + } + } + + /** + * + * @param waiterName + * @param tableName + */ + public void setWaiterNameInTable(String waiterName, String tableName){ + try{ + SQL = "UPDATE places SET WAITER=? WHERE NAME=?"; + pstmt=con.prepareStatement(SQL); + pstmt.setString(1,waiterName); + pstmt.setString(2,tableName); + pstmt.executeUpdate(); + }catch(SQLException e){ + } + } + + /** + * + * @param waiterName + * @param tableID + */ + public void setWaiterNameInTableById(String waiterName, String tableID){ + try{ + SQL = "UPDATE places SET WAITER=? WHERE ID=?"; + pstmt=con.prepareStatement(SQL); + pstmt.setString(1,waiterName); + pstmt.setString(2,tableID); + pstmt.executeUpdate(); + }catch(SQLException e){ + } + } + + /** + * + * @param tableName + * @return + */ + public String getWaiterNameInTable(String tableName){ + try{ + SQL = "SELECT waiter FROM places WHERE NAME='"+ tableName + "'"; + stmt = (Statement) con.createStatement(); + rs = stmt.executeQuery(SQL); + + if (rs.next()){ + String waiter =rs.getString("WAITER"); + return(waiter); + } + }catch(SQLException e){ + } + + return ""; + } + + /** + * + * @param tableID + * @return + */ + public String getWaiterNameInTableById(String tableID){ + try{ + SQL = "SELECT waiter FROM places WHERE ID='"+ tableID + "'"; + stmt = (Statement) con.createStatement(); + rs = stmt.executeQuery(SQL); + + if (rs.next()){ + String waiter =rs.getString("WAITER"); + return(waiter); + } + }catch(SQLException e){ + } + + return ""; + } + + /** + * + * @param tableName + */ + public void clearWaiterNameInTable(String tableName){ + try{ + SQL = "UPDATE places SET WAITER=null WHERE NAME=?"; + pstmt=con.prepareStatement(SQL); + pstmt.setString(1,tableName); + pstmt.executeUpdate(); + }catch(SQLException e){ + } + } + + /** + * + * @param tableID + */ + public void clearWaiterNameInTableById(String tableID){ + try{ + SQL = "UPDATE places SET WAITER=null WHERE ID=?"; + pstmt=con.prepareStatement(SQL); + pstmt.setString(1,tableID); + pstmt.executeUpdate(); + + }catch(SQLException e){ + } + } + + /** + * + * @param ID + * @return + */ + public String getTicketIdInTable(String ID){ + try{ + SQL = "SELECT TICKETID FROM places WHERE ID='"+ ID + "'"; + stmt = (Statement) con.createStatement(); + rs = stmt.executeQuery(SQL); + + if (rs.next()){ + String customer =rs.getString("TICKETID"); + return(customer); + } + }catch(SQLException e){ + } + + return ""; + } + + /** + * + * @param TicketID + * @param tableName + */ + public void setTicketIdInTable(String TicketID, String tableName){ + try{ +// SQL = "UPDATE places SET TICKETID=?, GUESTS=SEATS WHERE NAME=?"; + SQL = "UPDATE places SET TICKETID=? WHERE NAME=?"; + pstmt=con.prepareStatement(SQL); + pstmt.setString(1,TicketID); + pstmt.setString(2,tableName); + pstmt.executeUpdate(); + + }catch(SQLException e){ + } + } + + /** + * + * @param tableName + */ + public void clearTicketIdInTable(String tableName){ + try{ +// SQL = "UPDATE places SET TICKETID=null WHERE NAME=?"; + SQL = "UPDATE places SET TICKETID=null, OCCUPIED=null WHERE NAME=?"; + pstmt=con.prepareStatement(SQL); + pstmt.setString(1,tableName); + pstmt.executeUpdate(); + }catch(SQLException e){ + } + + clearGuestsInTable(tableName); + + } + + /** + * + * @param tableID + */ + public void clearTicketIdInTableById(String tableID){ + try{ + SQL = "UPDATE places SET TICKETID=null WHERE ID=?"; + pstmt=con.prepareStatement(SQL); + pstmt.setString(1,tableID); + pstmt.executeUpdate(); + + }catch(SQLException e){ + } + } + + /** + * + * @param tableID + * @return + */ + public Integer getGuestsInTable(String tableID){ + try{ + SQL = "SELECT guests FROM places WHERE ID='"+ tableID + "'"; + stmt = (Statement) con.createStatement(); + rs = stmt.executeQuery(SQL); + + if (rs.next()){ + Integer guests =rs.getInt("GUESTS"); + return(guests); + } + }catch(SQLException e){ + } + + return 0; + } + + /** + * + * @param guests + * @param tableID + */ + public void setGuestsInTable(Integer guests, String tableID){ + try{ + SQL = "UPDATE places SET GUESTS=? WHERE ID=?"; + pstmt=con.prepareStatement(SQL); + pstmt.setInt(1,guests); + pstmt.setString(2,tableID); + pstmt.executeUpdate(); + }catch(SQLException e){ + } + } + + /** + * + * @param tableID + * @return + */ + public Integer updateGuestsInTable(String tableID){ + try{ + SQL = "SELECT guests FROM places WHERE ID='"+ tableID + "'"; + stmt = (Statement) con.createStatement(); + rs = stmt.executeQuery(SQL); + + if (rs.next()){ + Integer guests =rs.getInt("GUESTS"); + return(guests); + } + }catch(SQLException e){ + } + + return 0; + } + + /** + * + * @param tableID + */ + public void clearGuestsInTable(String tableID){ + try{ + SQL = "UPDATE places SET guests=0 WHERE ID=?"; + pstmt=con.prepareStatement(SQL); + pstmt.setString(1,tableID); + pstmt.executeUpdate(); + }catch(SQLException e){ + } + } + /** + * + * @param table + */ + public void clearGuestsTable(String table){ + try{ + SQL = "UPDATE places SET guests=0 WHERE NAME=?"; + pstmt=con.prepareStatement(SQL); + pstmt.setString(1,table); + pstmt.executeUpdate(); + }catch(SQLException e){ + } + } + + /** + * + * @param tableID + */ + public void clearOccupied(String tableID){ + try{ + SQL = "UPDATE places SET occupied=null WHERE ID=?"; + pstmt=con.prepareStatement(SQL); + pstmt.setString(1,tableID); + pstmt.executeUpdate(); + }catch(SQLException e){ + + } + } + /** + * + * @param table + */ + public void clearOccupiedTable(String table){ + try{ + SQL = "UPDATE places SET occupied=null WHERE NAME=?"; + pstmt=con.prepareStatement(SQL); + pstmt.setString(1,table); + pstmt.executeUpdate(); + }catch(SQLException e){ + } + } + /** + * + * @param tableID + * @return + */ + public Timestamp getOccupied(String tableID){ + try{ + SQL = "SELECT occupied FROM places WHERE ID='"+ tableID + "'"; + stmt = (Statement) con.createStatement(); + rs = stmt.executeQuery(SQL); + + if (rs.next()){ + Timestamp occupied =rs.getTimestamp("OCCUPIED"); + return(occupied); + } + }catch(SQLException e){ + } + + return null; + } + + /** + * + * @param ticketID + */ + public void setOccupied(String ticketID){ + try{ + SQL = "UPDATE places SET occupied=NOW() WHERE TICKETID=?"; + pstmt=con.prepareStatement(SQL); + pstmt.setString(1,ticketID); + pstmt.executeUpdate(); + }catch(SQLException e){ + } + } + + /** + * + * @param ticketID + * @return + */ + public Integer countTicketIdInTable(String ticketID){ + try{ + SQL = "SELECT COUNT(*) AS RECORDCOUNT FROM places WHERE TICKETID='"+ ticketID + "'"; + stmt = (Statement) con.createStatement(); + rs = stmt.executeQuery(SQL); + + if (rs.next()){ + Integer count =rs.getInt("RECORDCOUNT"); + return(count); + } + }catch(SQLException e){ + } + + return 0; + } + + /** + * + * @param ticketID + * @return + */ + public String getTableDetails (String ticketID){ + try{ + SQL = "SELECT NAME FROM places WHERE TICKETID='"+ ticketID + "'"; + stmt = (Statement) con.createStatement(); + rs = stmt.executeQuery(SQL); + + if (rs.next()){ + String name =rs.getString("NAME"); + return(name); + } + }catch(SQLException e){ + } + + return ""; + } + + /** + * + * @param tableID + */ + public void setTableMovedFlag (String tableID){ + try{ + SQL = "UPDATE places SET TABLEMOVED='true' WHERE ID=?"; + pstmt=con.prepareStatement(SQL); + pstmt.setString(1,tableID); + pstmt.executeUpdate(); + }catch(SQLException e){ + } + } + + /** + * + * @param ticketID + * @return + */ + public String getTableMovedName (String ticketID){ + try{ + SQL = "SELECT NAME FROM places WHERE TICKETID='"+ ticketID + "' AND TABLEMOVED ='true'"; + stmt = (Statement) con.createStatement(); + rs = stmt.executeQuery(SQL); + + if (rs.next()){ + String name =rs.getString("NAME"); + return(name); + } + }catch(SQLException e){ + } + + return null; + } + + /** + * + * @param ticketID + * @return + */ + public Boolean getTableMovedFlag (String ticketID){ + try{ + SQL = "SELECT TABLEMOVED FROM places WHERE TICKETID='"+ ticketID + "'"; + stmt = (Statement) con.createStatement(); + rs = stmt.executeQuery(SQL); + + if (rs.next()){ + return(rs.getBoolean("TABLEMOVED")); + } + }catch(SQLException e){ + } + + return (false); + } + + /** + * + * @param tableID + */ + public void clearTableMovedFlag (String tableID){ + try{ + SQL = "UPDATE places SET TABLEMOVED='false' WHERE NAME=?"; + pstmt=con.prepareStatement(SQL); + pstmt.setString(1,tableID); + pstmt.executeUpdate(); + }catch(SQLException e){ + } + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/sales/shared/JTicketsBagShared.form b/src/main/java/com/unicenta/pos/sales/shared/JTicketsBagShared.form new file mode 100644 index 0000000..9bef47e --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/shared/JTicketsBagShared.form @@ -0,0 +1,202 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,51,0,0,1,-53"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="West"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JButton" name="m_jNewTicket"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="11" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/sale_new.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.addnewticket" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 4, 0, 4]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jNewTicketActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jListTickets"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="1"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="99" green="0" red="ff" type="rgb"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/sale_pending.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.layaway" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="horizontalTextPosition" type="int" value="4"/> + <Property name="iconTextGap" type="int" value="1"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 2, 0, 2]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + <Property name="verticalTextPosition" type="int" value="1"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jListTicketsActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jDelTicket"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="11" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/sale_delete.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.delete" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 4, 0, 4]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jDelTicketActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jReprintTickets"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="1"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="99" green="0" red="ff" type="rgb"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/reprint24.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.reprint" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="iconTextGap" type="int" value="1"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 2, 0, 2]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + <Property name="verticalTextPosition" type="int" value="1"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jReprintTicketsActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jHold"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="11" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/logout.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.quicklogoff" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 4, 0, 4]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jHoldActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/shared/JTicketsBagShared.java b/src/main/java/com/unicenta/pos/sales/shared/JTicketsBagShared.java new file mode 100644 index 0000000..21be4aa --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/shared/JTicketsBagShared.java @@ -0,0 +1,504 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales.shared; + +import com.unicenta.basic.BasicException; +import com.unicenta.beans.JNumberPop; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.JRootApp; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.forms.DataLogicSystem; +import com.unicenta.pos.sales.DataLogicReceipts; +import com.unicenta.pos.sales.JTicketsBag; +import com.unicenta.pos.sales.ReprintTicketInfo; +import com.unicenta.pos.sales.SharedTicketInfo; +import com.unicenta.pos.sales.TicketsEditor; +import com.unicenta.pos.ticket.TicketInfo; +import java.util.List; +import java.util.UUID; +import javax.swing.JComponent; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +/** + * + * @author JG uniCenta + */ +public class JTicketsBagShared extends JTicketsBag { + + private String m_sCurrentTicket = null; + private DataLogicReceipts dlReceipts = null; + private DataLogicSales dlSales = null; + private final DataLogicSystem dlSystem; + private Boolean showList; + + + /** Creates new form JTicketsBagShared + * @param app + * @param panelticket */ + public JTicketsBagShared(AppView app, TicketsEditor panelticket) { + + super(app, panelticket); + + dlReceipts = (DataLogicReceipts) app.getBean("com.unicenta.pos.sales.DataLogicReceipts"); + dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + dlSystem = (DataLogicSystem) m_App.getBean("com.unicenta.pos.forms.DataLogicSystem"); + + initComponents(); + + m_jReprintTickets.setVisible(false); + + } + + /** + * + */ + @Override + public void activate() { + + m_sCurrentTicket = null; + selectValidTicket(); + + m_jDelTicket.setEnabled(m_App.getAppUserView().getUser().hasPermission( + "com.unicenta.pos.sales.JPanelTicketEdits")); + m_jDelTicket.setEnabled(m_App.getAppUserView().getUser().hasPermission("sales.DeleteTicket")); + } + + /** + * + * @return + */ + @Override + public boolean deactivate() { + + saveCurrentTicket(); + + m_sCurrentTicket = null; + m_panelticket.setActiveTicket(null, null); + + return true; + } + + /** + * + */ + @Override + public void deleteTicket() { + + dlSystem.execTicketRemoved( + new Object[] { + m_App.getAppUserView().getUser().getName(), + "Void", + "Ticket Deleted", + 0.0 + }); + + m_sCurrentTicket = null; + selectValidTicket(); + } + + public void updateCount() { + try { + List<SharedTicketInfo> l = dlReceipts.getSharedTicketList(); + int count = l.size(); + + if (count > 0) { + m_jListTickets.setText(Integer.toString(count)); + } else { + m_jListTickets.setText(""); + } + } catch (BasicException ex) { + new MessageInf(ex).show(this); + m_jListTickets.setText(""); + } + } + + + /** + * + * @return + */ + @Override + protected JComponent getBagComponent() { + return this; + } + + /** + * + * @return + */ + @Override + protected JComponent getNullComponent() { + return new JPanel(); + } + + private void saveCurrentTicket() { + + if (m_sCurrentTicket != null) { + try { + dlReceipts.insertSharedTicket(m_sCurrentTicket, + m_panelticket.getActiveTicket(), + m_panelticket.getActiveTicket().getPickupId()); + m_jListTickets.setText("*"); + TicketInfo l = dlReceipts.getSharedTicket(m_sCurrentTicket); + if(l.getLinesCount() == 0) { + dlReceipts.deleteSharedTicket(m_sCurrentTicket); + } + } catch (BasicException e) { + new MessageInf(e).show(this); + } + } + + updateCount(); + } + + private void setActiveTicket(String id) throws BasicException{ + + TicketInfo ticket = dlReceipts.getSharedTicket(id); + if (ticket == null) { + m_jListTickets.setText(""); + throw new BasicException(AppLocal.getIntString("message.noticket")); + } else { + dlReceipts.getPickupId(id); + Integer pickUp = dlReceipts.getPickupId(id); + dlReceipts.deleteSharedTicket(id); + m_sCurrentTicket = id; + m_panelticket.setActiveTicket(ticket, null); + ticket.setPickupId(pickUp); + } + + updateCount(); + } + + private void setActiveReprintTicket(String id) throws BasicException{ + + + TicketInfo ticket = dlSales.getReprintTicket(id); + m_sCurrentTicket = id; + } + + private void selectValidTicket() { + + newTicket(); + updateCount(); + + try { + List<SharedTicketInfo> l = dlReceipts.getSharedTicketList(); + if (l.isEmpty()) { + m_jListTickets.setText(""); + newTicket(); + } else { + showList = m_App.getAppUserView().getUser().hasPermission("sales.ShowList"); + if (showList) { + m_jListTickets.doClick(); + } + } + } catch (BasicException e) { + new MessageInf(e).show(this); + newTicket(); + } + } + + private void newTicket() { + + saveCurrentTicket(); + + TicketInfo ticket = new TicketInfo(); + m_sCurrentTicket = UUID.randomUUID().toString(); + m_panelticket.setActiveTicket(ticket, null); + + updateCount(); + + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + m_jNewTicket = new javax.swing.JButton(); + m_jListTickets = new javax.swing.JButton(); + m_jDelTicket = new javax.swing.JButton(); + m_jReprintTickets = new javax.swing.JButton(); + m_jHold = new javax.swing.JButton(); + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setLayout(new java.awt.BorderLayout()); + + m_jNewTicket.setFont(new java.awt.Font("Arial", 0, 11)); // NOI18N + m_jNewTicket.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/sale_new.png"))); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + m_jNewTicket.setToolTipText(bundle.getString("tooltip.addnewticket")); // NOI18N + m_jNewTicket.setFocusPainted(false); + m_jNewTicket.setFocusable(false); + m_jNewTicket.setMargin(new java.awt.Insets(0, 4, 0, 4)); + m_jNewTicket.setMaximumSize(new java.awt.Dimension(50, 40)); + m_jNewTicket.setMinimumSize(new java.awt.Dimension(50, 40)); + m_jNewTicket.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jNewTicket.setRequestFocusEnabled(false); + m_jNewTicket.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jNewTicketActionPerformed(evt); + } + }); + jPanel1.add(m_jNewTicket); + + m_jListTickets.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + m_jListTickets.setForeground(new java.awt.Color(255, 0, 153)); + m_jListTickets.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/sale_pending.png"))); // NOI18N + m_jListTickets.setToolTipText(bundle.getString("tooltip.layaway")); // NOI18N + m_jListTickets.setFocusPainted(false); + m_jListTickets.setFocusable(false); + m_jListTickets.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + m_jListTickets.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT); + m_jListTickets.setIconTextGap(1); + m_jListTickets.setMargin(new java.awt.Insets(0, 2, 0, 2)); + m_jListTickets.setMaximumSize(new java.awt.Dimension(50, 40)); + m_jListTickets.setMinimumSize(new java.awt.Dimension(50, 40)); + m_jListTickets.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jListTickets.setRequestFocusEnabled(false); + m_jListTickets.setVerticalTextPosition(javax.swing.SwingConstants.TOP); + m_jListTickets.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jListTicketsActionPerformed(evt); + } + }); + jPanel1.add(m_jListTickets); + + m_jDelTicket.setFont(new java.awt.Font("Arial", 0, 11)); // NOI18N + m_jDelTicket.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/sale_delete.png"))); // NOI18N + m_jDelTicket.setToolTipText(bundle.getString("tooltip.delete")); // NOI18N + m_jDelTicket.setFocusPainted(false); + m_jDelTicket.setFocusable(false); + m_jDelTicket.setMargin(new java.awt.Insets(0, 4, 0, 4)); + m_jDelTicket.setMaximumSize(new java.awt.Dimension(50, 40)); + m_jDelTicket.setMinimumSize(new java.awt.Dimension(50, 40)); + m_jDelTicket.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jDelTicket.setRequestFocusEnabled(false); + m_jDelTicket.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jDelTicketActionPerformed(evt); + } + }); + jPanel1.add(m_jDelTicket); + + m_jReprintTickets.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N + m_jReprintTickets.setForeground(new java.awt.Color(255, 0, 153)); + m_jReprintTickets.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reprint24.png"))); // NOI18N + m_jReprintTickets.setToolTipText(bundle.getString("tooltip.reprint")); // NOI18N + m_jReprintTickets.setFocusPainted(false); + m_jReprintTickets.setFocusable(false); + m_jReprintTickets.setIconTextGap(1); + m_jReprintTickets.setMargin(new java.awt.Insets(0, 2, 0, 2)); + m_jReprintTickets.setMaximumSize(new java.awt.Dimension(50, 40)); + m_jReprintTickets.setMinimumSize(new java.awt.Dimension(50, 40)); + m_jReprintTickets.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jReprintTickets.setRequestFocusEnabled(false); + m_jReprintTickets.setVerticalTextPosition(javax.swing.SwingConstants.TOP); + m_jReprintTickets.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jReprintTicketsActionPerformed(evt); + } + }); + jPanel1.add(m_jReprintTickets); + + m_jHold.setFont(new java.awt.Font("Arial", 0, 11)); // NOI18N + m_jHold.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/logout.png"))); // NOI18N + m_jHold.setToolTipText(bundle.getString("tooltip.quicklogoff")); // NOI18N + m_jHold.setFocusPainted(false); + m_jHold.setFocusable(false); + m_jHold.setMargin(new java.awt.Insets(0, 4, 0, 4)); + m_jHold.setMaximumSize(new java.awt.Dimension(50, 40)); + m_jHold.setMinimumSize(new java.awt.Dimension(50, 40)); + m_jHold.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jHold.setRequestFocusEnabled(false); + m_jHold.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jHoldActionPerformed(evt); + } + }); + jPanel1.add(m_jHold); + + add(jPanel1, java.awt.BorderLayout.WEST); + }// </editor-fold>//GEN-END:initComponents + + private void m_jListTicketsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jListTicketsActionPerformed + + SwingUtilities.invokeLater(() -> { + try { + if (!m_App.getAppUserView().getUser().hasPermission("sales.ViewSharedTicket")){ + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.sharedticket"), + AppLocal.getIntString("message.sharedtickettitle"), + JOptionPane.INFORMATION_MESSAGE); + }else{ + + if("0".equals(m_App.getAppUserView().getUser().getRole()) + || "1".equals(m_App.getAppUserView().getUser().getRole()) + || m_App.getAppUserView().getUser().hasPermission("sales.ViewSharedTicket") + || m_App.getAppUserView().getUser().hasPermission("sales.Override")) + { + List<SharedTicketInfo> l = dlReceipts.getSharedTicketList(); + JTicketsBagSharedList listDialog = JTicketsBagSharedList.newJDialog(JTicketsBagShared.this); + String id = listDialog.showTicketsList(l, dlReceipts); + + if (id != null) { + saveCurrentTicket(); + setActiveTicket(id); + } + }else{ + + String appuser = m_App.getAppUserView().getUser().getId(); + List<SharedTicketInfo> l = dlReceipts.getUserSharedTicketList( + appuser); + + JTicketsBagSharedList listDialog = JTicketsBagSharedList.newJDialog(JTicketsBagShared.this); + + String id = listDialog.showTicketsList(l, dlReceipts); + + if (id != null) { + saveCurrentTicket(); + setActiveTicket(id); + } + } + } + }catch (BasicException e) { + new MessageInf(e).show(JTicketsBagShared.this); + newTicket(); + } + }); + + }//GEN-LAST:event_m_jListTicketsActionPerformed + + private void m_jNewTicketActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jNewTicketActionPerformed + + newTicket(); + + }//GEN-LAST:event_m_jNewTicketActionPerformed + + private void m_jHoldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jHoldActionPerformed + deactivate(); + ((JRootApp)m_App).closeAppView(); + }//GEN-LAST:event_m_jHoldActionPerformed + + private void m_jReprintTicketsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jReprintTicketsActionPerformed + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + + try { + if (!m_App.getAppUserView().getUser().hasPermission("sales.ReprintTicket")){ + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.reprintticket"), + AppLocal.getIntString("message.reprinttickettitle"), + JOptionPane.INFORMATION_MESSAGE); + }else{ + + if("0".equals(m_App.getAppUserView().getUser().getRole()) + || "1".equals(m_App.getAppUserView().getUser().getRole()) + || m_App.getAppUserView().getUser().hasPermission("sales.ViewSharedTicket") + || m_App.getAppUserView().getUser().hasPermission("sales.Override")) + { + List<ReprintTicketInfo> l = dlSales.getReprintTicketList(); + JTicketsReprintList listDialog = JTicketsReprintList.newJDialog(JTicketsBagShared.this); + String id = listDialog.showTicketsList(l, dlSales); + + }else{ + + String appuser = m_App.getAppUserView().getUser().getId(); + List<ReprintTicketInfo> l = dlSales.getReprintTicketList(); + + JTicketsReprintList listDialog = JTicketsReprintList.newJDialog(JTicketsBagShared.this); + + String id = listDialog.showTicketsList(l, dlSales); + + if (id != null) { + saveCurrentTicket(); + setActiveReprintTicket(id); + } + } + } + }catch (BasicException e) { + new MessageInf(e).show(JTicketsBagShared.this); + newTicket(); + } + } + }); + }//GEN-LAST:event_m_jReprintTicketsActionPerformed + + private void m_jDelTicketActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jDelTicketActionPerformed +// Only called in simple & standard NOT RESTAURANT +// For Restaurant-mode see JTicketsBagRestaurant + + boolean pinOK = false; + + if (m_sCurrentTicket != null) { + + if (m_App.getProperties().getProperty("override.check").equals("true")) { + Integer secret = Integer.parseInt(m_App.getProperties().getProperty("override.pin")); + Integer iValue = JNumberPop.showEditNumber(this, AppLocal.getIntString("title.override.enterpin")); + + if (iValue == null ? secret == null : iValue.equals(secret)) { + pinOK = true; + int res = JOptionPane.showConfirmDialog(this + , AppLocal.getIntString("message.wannadelete") + , AppLocal.getIntString("title.editor") + , JOptionPane.YES_NO_OPTION + , JOptionPane.QUESTION_MESSAGE); + + if (res == JOptionPane.YES_OPTION) { + deleteTicket(); + } + } else { + pinOK = false; + JOptionPane.showMessageDialog(this, AppLocal.getIntString("message.override.badpin")); + } + } else { + int res = JOptionPane.showConfirmDialog(this + , AppLocal.getIntString("message.wannadelete") + , AppLocal.getIntString("title.editor") + , JOptionPane.YES_NO_OPTION + , JOptionPane.QUESTION_MESSAGE); + + if (res == JOptionPane.YES_OPTION) { + deleteTicket(); + } + } + } + }//GEN-LAST:event_m_jDelTicketActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JButton m_jDelTicket; + private javax.swing.JButton m_jHold; + private javax.swing.JButton m_jListTickets; + private javax.swing.JButton m_jNewTicket; + private javax.swing.JButton m_jReprintTickets; + // End of variables declaration//GEN-END:variables + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/sales/shared/JTicketsBagSharedList.form b/src/main/java/com/unicenta/pos/sales/shared/JTicketsBagSharedList.form new file mode 100644 index 0000000..c9dec8a --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/shared/JTicketsBagSharedList.form @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="caption.tickets" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="resizable" type="boolean" value="false"/> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,21,0,0,2,6"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JScrollPane" name="jScrollPane1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="m_jtickets"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> + <Property name="columns" type="int" value="1"/> + <Property name="horizontalGap" type="int" value="5"/> + <Property name="rows" type="int" value="0"/> + <Property name="verticalGap" type="int" value="5"/> + </Layout> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="2"/> + </Layout> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel4"> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + </Container> + <Component class="javax.swing.JButton" name="m_jButtonCancel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.close" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jButtonCancelActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/shared/JTicketsBagSharedList.java b/src/main/java/com/unicenta/pos/sales/shared/JTicketsBagSharedList.java new file mode 100644 index 0000000..3692d67 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/shared/JTicketsBagSharedList.java @@ -0,0 +1,236 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales.shared; + + +import com.unicenta.pos.sales.SharedTicketInfo; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.JButton; +import javax.swing.JFrame; +import com.unicenta.basic.BasicException; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.ticket.TicketInfo; +import com.unicenta.pos.sales.DataLogicReceipts; +import javax.swing.JOptionPane; + + +/** + * + * @author JG uniCenta + */ +public class JTicketsBagSharedList extends javax.swing.JDialog { + + private String m_sDialogTicket; + + /** Creates new form JTicketsBagSharedList */ + private JTicketsBagSharedList(java.awt.Frame parent, boolean modal) { + super(parent, modal); + } + /** Creates new form JTicketsBagSharedList */ + private JTicketsBagSharedList(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + } + + /** + * + * @param atickets + * @param dlReceipts + * @return + */ + public String showTicketsList(java.util.List<SharedTicketInfo> atickets, DataLogicReceipts dlReceipts) { +// JG Dec 2014 + SharedTicketInfo m_Ticket = null; + + for (SharedTicketInfo aticket : atickets) { + m_jtickets.add(new JButtonTicket(aticket, dlReceipts)); + } + + m_sDialogTicket = null; + + int lsize = atickets.size(); + if (lsize > 0) { + setVisible(true); + }else{ + JOptionPane.showMessageDialog(this, + AppLocal.getIntString("message.nosharedtickets"), + AppLocal.getIntString("message.sharedtickettitle"), + JOptionPane.OK_OPTION); + } + + return m_sDialogTicket; + } + + /** + * + * @param ticketsbagshared + * @return + */ + public static JTicketsBagSharedList newJDialog(JTicketsBagShared ticketsbagshared) { + + Window window = getWindow(ticketsbagshared); + JTicketsBagSharedList mydialog; + if (window instanceof Frame) { + mydialog = new JTicketsBagSharedList((Frame) window, true); + } else { + mydialog = new JTicketsBagSharedList((Dialog) window, true); + } + + mydialog.initComponents(); + + mydialog.jScrollPane1.getVerticalScrollBar().setPreferredSize(new Dimension(35, 35)); + mydialog.jScrollPane1.getHorizontalScrollBar().setPreferredSize(new Dimension(25, 25)); + + return mydialog; + } + + private static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window) parent; + } else { + return getWindow(parent.getParent()); + } + } + + private class JButtonTicket extends JButton { + + private final SharedTicketInfo m_Ticket; + + public JButtonTicket(SharedTicketInfo ticket, DataLogicReceipts dlReceipts){ + + super(); + + m_Ticket = ticket; + setFocusPainted(false); + setFocusable(false); + setRequestFocusEnabled(false); + setMargin(new Insets(8, 14, 8, 14)); + setFont(new java.awt.Font ("Dialog", 0, 14)); + setBackground(new java.awt.Color (220, 220, 220)); + addActionListener(new ActionListenerImpl()); + +// JG Nov 2014 + String total; + try { + TicketInfo ticket2 = dlReceipts.getSharedTicket(ticket.getId()); + total = " - " + ticket2.printTotal(); + } catch (BasicException ex) { + total = ""; + } + + setText(ticket.getPickupId() + " - " + + ticket.getName() + + total); + } + + private class ActionListenerImpl implements ActionListener { + + public ActionListenerImpl() { + } + + @Override + public void actionPerformed(ActionEvent evt) { + + m_sDialogTicket = m_Ticket.getId(); + JTicketsBagSharedList.this.setVisible(false); + + } + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jScrollPane1 = new javax.swing.JScrollPane(); + jPanel2 = new javax.swing.JPanel(); + m_jtickets = new javax.swing.JPanel(); + jPanel3 = new javax.swing.JPanel(); + jPanel4 = new javax.swing.JPanel(); + m_jButtonCancel = new javax.swing.JButton(); + + setTitle(AppLocal.getIntString("caption.tickets")); // NOI18N + setResizable(false); + + jPanel1.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel1.setLayout(new java.awt.BorderLayout()); + + jPanel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanel2.setLayout(new java.awt.BorderLayout()); + + m_jtickets.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + m_jtickets.setLayout(new java.awt.GridLayout(0, 1, 5, 5)); + jPanel2.add(m_jtickets, java.awt.BorderLayout.NORTH); + + jScrollPane1.setViewportView(jPanel2); + + jPanel1.add(jScrollPane1, java.awt.BorderLayout.CENTER); + + getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER); + + jPanel3.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT)); + jPanel3.add(jPanel4); + + m_jButtonCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jButtonCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + m_jButtonCancel.setText(AppLocal.getIntString("button.close")); // NOI18N + m_jButtonCancel.setFocusPainted(false); + m_jButtonCancel.setFocusable(false); + m_jButtonCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jButtonCancel.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jButtonCancel.setRequestFocusEnabled(false); + m_jButtonCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jButtonCancelActionPerformed(evt); + } + }); + jPanel3.add(m_jButtonCancel); + + getContentPane().add(jPanel3, java.awt.BorderLayout.SOUTH); + + setSize(new java.awt.Dimension(518, 533)); + setLocationRelativeTo(null); + }// </editor-fold>//GEN-END:initComponents + + private void m_jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jButtonCancelActionPerformed + + dispose(); + + }//GEN-LAST:event_m_jButtonCancelActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JButton m_jButtonCancel; + private javax.swing.JPanel m_jtickets; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/shared/JTicketsReprintList.form b/src/main/java/com/unicenta/pos/sales/shared/JTicketsReprintList.form new file mode 100644 index 0000000..590d08d --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/shared/JTicketsReprintList.form @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="caption.tickets" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="resizable" type="boolean" value="false"/> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-113,0,0,2,7"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JScrollPane" name="jScrollPane1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="m_jtickets"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> + <Property name="columns" type="int" value="1"/> + <Property name="horizontalGap" type="int" value="5"/> + <Property name="rows" type="int" value="0"/> + <Property name="verticalGap" type="int" value="5"/> + </Layout> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="2"/> + </Layout> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel4"> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + </Container> + <Component class="javax.swing.JButton" name="m_jButtonCancel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.close" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jButtonCancelActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/shared/JTicketsReprintList.java b/src/main/java/com/unicenta/pos/sales/shared/JTicketsReprintList.java new file mode 100644 index 0000000..f9defc1 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/shared/JTicketsReprintList.java @@ -0,0 +1,415 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales.shared; + + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ListKeyed; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.pos.forms.*; +import com.unicenta.pos.printer.DeviceTicket; +import com.unicenta.pos.printer.TicketParser; +import com.unicenta.pos.printer.TicketPrinterException; +import com.unicenta.pos.sales.ReprintTicketInfo; +import com.unicenta.pos.sales.TaxesException; +import com.unicenta.pos.sales.TaxesLogic; +import com.unicenta.pos.scripting.ScriptEngine; +import com.unicenta.pos.scripting.ScriptException; +import com.unicenta.pos.scripting.ScriptFactory; +import com.unicenta.pos.ticket.TicketInfo; +import com.unicenta.pos.ticket.TicketTaxInfo; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + + +/** + * + * @author JG uniCenta + */ +@Slf4j +public class JTicketsReprintList extends javax.swing.JDialog { + + private String m_sDialogTicket; + private final DeviceTicket m_TP; + private final TicketParser m_TTP; +// private final TicketParser m_TTP2; + private TaxesLogic taxeslogic; + private ListKeyed taxcollection; + + private TicketInfo m_ticket; + private TicketInfo m_ticketCopy; + private AppView m_App; + + private DataLogicSystem dlSystem = null; + private DataLogicSales dlSales = null; + + /** Creates new form JTicketsReprintList */ + private JTicketsReprintList(java.awt.Frame parent, boolean modal) { + super(parent, modal); + AppView app = null; + m_App = app; + AppProperties props = null; + + m_TP = new DeviceTicket(); + + m_TTP = new TicketParser(m_TP, dlSystem); +// m_TTP2 = new TicketParser(m_App.getDeviceTicket(), dlSystem); + } + /** Creates new form JTicketsReprintList */ + private JTicketsReprintList(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + AppProperties props = null; + + m_TP = new DeviceTicket(); + m_TTP = new TicketParser(m_TP, dlSystem); + } + + /** + * + * @param atickets + * @param dlSales + * @return + */ + public String showTicketsList(java.util.List<ReprintTicketInfo> atickets, DataLogicSales dlSales) { + + m_ticket = null; + m_ticketCopy = null; + +ReprintTicketInfo m_Ticket = null; + + for (ReprintTicketInfo aticket : atickets) { + m_jtickets.add(new JButtonTicket(aticket, dlSales)); + } + + m_sDialogTicket = null; + + int lsize = atickets.size(); + if (lsize > 0) { + setVisible(true); + }else{ + JOptionPane.showMessageDialog(this, + AppLocal.getIntString("message.nosharedtickets"), + AppLocal.getIntString("message.sharedtickettitle"), + JOptionPane.OK_OPTION); + } + + return m_sDialogTicket; + } + + /** + * + * @param ticketsbagshared + * @return + */ + public static JTicketsReprintList newJDialog(JTicketsBagShared ticketsbagshared) { + + Window window = getWindow(ticketsbagshared); + JTicketsReprintList mydialog; + if (window instanceof Frame) { + mydialog = new JTicketsReprintList((Frame) window, true); + } else { + mydialog = new JTicketsReprintList((Dialog) window, true); + } + + mydialog.initComponents(); + + mydialog.jScrollPane1.getVerticalScrollBar().setPreferredSize(new Dimension(35, 35)); + mydialog.jScrollPane1.getHorizontalScrollBar().setPreferredSize(new Dimension(25, 25)); + + return mydialog; + } + + private static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window) parent; + } else { + return getWindow(parent.getParent()); + } + } + + private class JButtonTicket extends JButton { + + private final ReprintTicketInfo m_Ticket; + + public JButtonTicket(ReprintTicketInfo ticket, DataLogicSales dlSales){ + + super(); + + m_Ticket = ticket; + setFocusPainted(false); + setFocusable(false); + setRequestFocusEnabled(false); + setMargin(new Insets(8, 14, 8, 14)); + setFont(new java.awt.Font ("Dialog", 0, 14)); + setBackground(new java.awt.Color (220, 220, 220)); + addActionListener(new ActionListenerImpl()); + + setText(ticket.getId() + " - " + + ticket.getTicketDate() + " - " + + ticket.getUserName()); + } + + private class ActionListenerImpl implements ActionListener { + + public ActionListenerImpl() { + } + + @Override + public void actionPerformed(ActionEvent evt) { + + try { + m_sDialogTicket = m_Ticket.getId(); + + JTicketsReprintList.this.setVisible(false); + int iTkt=Integer.valueOf(m_sDialogTicket); + int iTt = 0; +// readTicket(iTkt, iTt); +// readTicket(m_sDialogTicket); + + TicketInfo ticket = dlSales.loadTicket(iTt, iTkt); + + if (ticket == null) { + JFrame frame = new JFrame(); + JOptionPane.showMessageDialog(frame, AppLocal.getIntString("message.notexiststicket"), AppLocal.getIntString("message.notexiststickettitle"), JOptionPane.WARNING_MESSAGE); + } else { + m_ticket = ticket; + m_ticketCopy = null; + try { + taxeslogic.calculateTaxes(m_ticket); + TicketTaxInfo[] taxlist = m_ticket.getTaxLines(); + } catch (TaxesException ex) { + } + printTicket("Printer.ReprintLastTicket", m_ticket, null); + } +// } catch (BasicException e) { +// MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotloadticket"), e); +// msg.show(this); +// } +// } + } catch (BasicException ex) { + log.error(ex.getMessage()); + + } + + + } + } + } + +// private void readTicket(int iTicketid, int iTickettype) { + private void readTicket(String Id) { +// Integer findTicket=Integer.valueOf(m_sDialogTicket); + + try { + //TicketInfo ticket = new TicketInfo(); + +// TicketInfo ticket = dlSales.loadTicket(iTickettype, iTicketid); + +TicketInfo ticket = dlSales.getReprintTicket(Id); + if (ticket == null) { + JFrame frame = new JFrame(); + JOptionPane.showMessageDialog(frame, + AppLocal.getIntString("message.notexiststicket"), + AppLocal.getIntString("message.notexiststickettitle"), + JOptionPane.WARNING_MESSAGE); + + } else { + m_ticket = ticket; + m_ticketCopy = null; + + if(m_ticket.getTicketType()== 1 + || m_ticket.getTicketStatus()> 0) { + JFrame frame = new JFrame(); + JOptionPane.showMessageDialog(frame, + AppLocal.getIntString("message.ticketrefunded"), + AppLocal.getIntString("message.ticketrefundedtitle"), + JOptionPane.WARNING_MESSAGE); +// m_jEdit.setEnabled(false); +// m_jRefund.setEnabled(false); + }else{ +// m_jEdit.setEnabled(true); +// m_jRefund.setEnabled(true); + } + try { + taxeslogic.calculateTaxes(m_ticket); + TicketTaxInfo[] taxlist = m_ticket.getTaxLines(); + } catch (TaxesException ex) {} + +// printTicket(); + } + + } catch (BasicException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotloadticket"), e); + msg.show(this); + } + + } + +/* private void printTicket() { + + if (m_ticket != null + && (m_ticket.getTicketType() == TicketInfo.RECEIPT_NORMAL + && m_ticket.getTicketStatus() == 0)) { + } + + m_TP.getDevicePrinter("1").reset(); + + if (m_ticket == null) { +// m_jTicketId.setText(m_ticket.getName()); + + try { + ScriptEngine script = ScriptFactory.getScriptEngine(ScriptFactory.VELOCITY); + script.put("ticket", m_ticket); + script.put("taxes", m_ticket.getTaxLines()); + m_TTP.printTicket(script.eval(dlSystem.getResourceAsXML("Printer.TicketPreview")).toString()); + } catch ( ScriptException | TicketPrinterException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotprintticket"), e); + msg.show(this); + } + } + } +*/ + + private void printTicket(String sresourcename, TicketInfo ticket, Object ticketext) { + + String sresource = dlSystem.getResourceAsXML(sresourcename); + if (sresource == null) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotprintticket")); +// msg.show(JPanelTicket.this); + } else { + +// if this is ticket does not have a pickup code assign on now + if (ticket.getPickupId() == 0) { + try { + ticket.setPickupId(dlSales.getNextPickupIndex()); + } catch (BasicException e) { + ticket.setPickupId(0); + } + } + try { + ScriptEngine script = ScriptFactory.getScriptEngine(ScriptFactory.VELOCITY); +// JG 19 Feb 14 unnecessary boolean parse - if (Boolean.valueOf(m_App.getProperties().getProperty("receipt.newlayout")).booleanValue()){ + if (Boolean.parseBoolean(m_App.getProperties().getProperty("receipt.newlayout"))) { + script.put("taxes", ticket.getTaxLines()); + } else { + script.put("taxes", taxcollection); + } + script.put("taxeslogic", taxeslogic); + script.put("ticket", ticket); + script.put("place", ticketext); + Object warrantyPrint; +// script.put("warranty", warrantyPrint); +// script.put("pickupid", getPickupString(ticket)); + +// JG Aug 2014 +// refreshTicket(); + + m_TTP.printTicket(script.eval(sresource).toString(), ticket); + +// JG May 2013 replaced with Multicatch + } catch (ScriptException | TicketPrinterException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotprintticket"), e); +// msg.show(JPanelTicket.this); + } + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jScrollPane1 = new javax.swing.JScrollPane(); + jPanel2 = new javax.swing.JPanel(); + m_jtickets = new javax.swing.JPanel(); + jPanel3 = new javax.swing.JPanel(); + jPanel4 = new javax.swing.JPanel(); + m_jButtonCancel = new javax.swing.JButton(); + + setTitle(AppLocal.getIntString("caption.tickets")); // NOI18N + setResizable(false); + + jPanel1.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel1.setLayout(new java.awt.BorderLayout()); + + jPanel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanel2.setLayout(new java.awt.BorderLayout()); + + m_jtickets.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + m_jtickets.setLayout(new java.awt.GridLayout(0, 1, 5, 5)); + jPanel2.add(m_jtickets, java.awt.BorderLayout.NORTH); + + jScrollPane1.setViewportView(jPanel2); + + jPanel1.add(jScrollPane1, java.awt.BorderLayout.CENTER); + + getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER); + + jPanel3.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT)); + jPanel3.add(jPanel4); + + m_jButtonCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + m_jButtonCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + m_jButtonCancel.setText(AppLocal.getIntString("button.close")); // NOI18N + m_jButtonCancel.setFocusPainted(false); + m_jButtonCancel.setFocusable(false); + m_jButtonCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jButtonCancel.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jButtonCancel.setRequestFocusEnabled(false); + m_jButtonCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jButtonCancelActionPerformed(evt); + } + }); + jPanel3.add(m_jButtonCancel); + + getContentPane().add(jPanel3, java.awt.BorderLayout.SOUTH); + + setSize(new java.awt.Dimension(519, 399)); + setLocationRelativeTo(null); + }// </editor-fold>//GEN-END:initComponents + + private void m_jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jButtonCancelActionPerformed + + dispose(); + + }//GEN-LAST:event_m_jButtonCancelActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JButton m_jButtonCancel; + private javax.swing.JPanel m_jtickets; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/sales/simple/JTicketsBagSimple.form b/src/main/java/com/unicenta/pos/sales/simple/JTicketsBagSimple.form new file mode 100644 index 0000000..ed1408b --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/simple/JTicketsBagSimple.form @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,49,0,0,0,-47"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="0"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="m_jDelTicket"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/sale_delete.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.delete" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 4, 0, 4]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 40]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jDelTicketActionPerformed"/> + </Events> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/sales/simple/JTicketsBagSimple.java b/src/main/java/com/unicenta/pos/sales/simple/JTicketsBagSimple.java new file mode 100644 index 0000000..8d4c6a2 --- /dev/null +++ b/src/main/java/com/unicenta/pos/sales/simple/JTicketsBagSimple.java @@ -0,0 +1,142 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.sales.simple; + +import com.unicenta.pos.forms.*; +import javax.swing.*; +import com.unicenta.pos.sales.*; +import com.unicenta.pos.ticket.TicketInfo; + +/** + * + * @author JG uniCenta + */ +public class JTicketsBagSimple extends JTicketsBag { + + /** Creates new form JTicketsBagSimple + * @param app + * @param panelticket */ + public JTicketsBagSimple(AppView app, TicketsEditor panelticket) { + + super(app, panelticket); + + initComponents(); + } + + /** + * + */ + @Override + public void activate() { + + m_panelticket.setActiveTicket(new TicketInfo(), null); + + // Authorization + m_jDelTicket.setEnabled(m_App.getAppUserView().getUser().hasPermission("com.unicenta.pos.sales.JPanelTicketEdits")); + + } + + /** + * + * @return + */ + @Override + public boolean deactivate() { + m_panelticket.setActiveTicket(null, null); + return true; + } + + /** + * + */ + @Override + public void deleteTicket() { + m_panelticket.setActiveTicket(new TicketInfo(), null); + } + + /** + * + * @return + */ + @Override + protected JComponent getBagComponent() { + return this; + } + + /** + * + * @return + */ + @Override + protected JComponent getNullComponent() { + return new JPanel(); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jDelTicket = new javax.swing.JButton(); + + setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT)); + + m_jDelTicket.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/sale_delete.png"))); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + m_jDelTicket.setToolTipText(bundle.getString("tooltip.delete")); // NOI18N + m_jDelTicket.setFocusPainted(false); + m_jDelTicket.setFocusable(false); + m_jDelTicket.setMargin(new java.awt.Insets(0, 4, 0, 4)); + m_jDelTicket.setMaximumSize(new java.awt.Dimension(50, 40)); + m_jDelTicket.setMinimumSize(new java.awt.Dimension(50, 40)); + m_jDelTicket.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jDelTicket.setRequestFocusEnabled(false); + m_jDelTicket.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jDelTicketActionPerformed(evt); + } + }); + add(m_jDelTicket); + }// </editor-fold>//GEN-END:initComponents + + private void m_jDelTicketActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jDelTicketActionPerformed + + int res = JOptionPane.showConfirmDialog(this, + AppLocal.getIntString("message.wannadelete"), + AppLocal.getIntString("title.editor"), + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE); + + if (res == JOptionPane.YES_OPTION) { + deleteTicket(); + } + + }//GEN-LAST:event_m_jDelTicketActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton m_jDelTicket; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/scale/DeviceScale.java b/src/main/java/com/unicenta/pos/scale/DeviceScale.java new file mode 100644 index 0000000..6ff516f --- /dev/null +++ b/src/main/java/com/unicenta/pos/scale/DeviceScale.java @@ -0,0 +1,106 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.scale; + +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppProperties; +import com.unicenta.pos.util.StringParser; +import java.awt.Component; + +/** + * + * @author JG uniCenta + */ +public class DeviceScale { + + private Scale m_scale; + + /** Creates a new instance of DeviceScale + * @param parent + * @param props */ + public DeviceScale(Component parent, AppProperties props) { + StringParser sd = new StringParser(props.getProperty("machine.scale")); + String sScaleType = sd.nextToken(':'); + String sScaleParam1 = sd.nextToken(','); + // String sScaleParam2 = sd.nextToken(','); + switch (sScaleType) { + case "acompc100": + m_scale = new ScaleAcomPC100(sScaleParam1); + break; + case "averyberkel6720": + m_scale = new ScaleAvery(sScaleParam1); + break; + case "casiopd1": + m_scale = new ScaleCasioPD1(sScaleParam1); + break; + case "dialog1": + m_scale = new ScaleComm(sScaleParam1); + break; + case "samsungesp": + m_scale = new ScaleSamsungEsp(sScaleParam1); + break; + case "caspdii": + m_scale = new ScaleCASPDII(sScaleParam1); + break; + case "fake": + // a fake scale for debugging purposes + m_scale = new ScaleFake(); + break; + case "screen": + // on screen scale + m_scale = new ScaleDialog(parent); + break; + default: + m_scale = null; + break; + } + } + + /** + * + * @return + */ + public boolean existsScale() { + return m_scale != null; + } + + /** + * + * @return + * @throws ScaleException + */ + public Double readWeight() throws ScaleException { + + if (m_scale == null) { + throw new ScaleException(AppLocal.getIntString("scale.notdefined")); + } else { + Double result = m_scale.readWeight(); + if (result == null) { + return null; // Canceled by the user / scale + } else if (result < 0.002) { + // invalid result. nothing on the scale + throw new ScaleException(AppLocal.getIntString("scale.invalidvalue")); + } else { + // valid result + return result; + } + } + } +} diff --git a/src/main/java/com/unicenta/pos/scale/Scale.java b/src/main/java/com/unicenta/pos/scale/Scale.java new file mode 100644 index 0000000..1702665 --- /dev/null +++ b/src/main/java/com/unicenta/pos/scale/Scale.java @@ -0,0 +1,34 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.scale; + +/** + * + * @author JG uniCenta + */ +public interface Scale { + + /** + * + * @return + * @throws ScaleException + */ + public Double readWeight() throws ScaleException; +} diff --git a/src/main/java/com/unicenta/pos/scale/ScaleAcomPC100.java b/src/main/java/com/unicenta/pos/scale/ScaleAcomPC100.java new file mode 100644 index 0000000..c4d5f8f --- /dev/null +++ b/src/main/java/com/unicenta/pos/scale/ScaleAcomPC100.java @@ -0,0 +1,181 @@ +//    uniCenta oPOS  - Touch Friendly Point Of Sale +//    Copyright (c) 2018 uniCenta & previous Openbravo POS works +// Contribution by Hajinder Singh +//    https://unicenta.com +// +//    This file is part of uniCenta oPOS +// +//    uniCenta oPOS is free software: you can redistribute it and/or modify +//    it under the terms of the GNU General Public License as published by +//    the Free Software Foundation, either version 3 of the License, or +//    (at your option) any later version. +// +//   uniCenta oPOS is distributed in the hope that it will be useful, +//    but WITHOUT ANY WARRANTY; without even the implied warranty of +//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +//    GNU General Public License for more details. +// +//    You should have received a copy of the GNU General Public License +//    along with uniCenta oPOS.  If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.scale; + +import gnu.io.*; +import java.io.*; +import java.util.TooManyListenersException; + +/** +* +* @author uniCenta + H Singh +*/ +public class ScaleAcomPC100 implements Scale, SerialPortEventListener { + +private CommPortIdentifier m_PortIdPrinter; +private SerialPort m_CommPortPrinter; + +private final String m_sPortScale; +private OutputStream m_out; +private InputStream m_in; + +private static final int SCALE_READY = 0; +private static final int SCALE_READING = 1; +private static final int SCALE_READINGDECIMALS = 2; + +private double m_dWeightBuffer; +private double m_dWeightDecimals; +private int m_iStatusScale; +private String m_sScaleReading; + +/** Creates a new instance of ScaleComm +* @param sPortPrinter */ + public ScaleAcomPC100(String sPortPrinter) { + m_sPortScale = sPortPrinter; + m_out = null; + m_in = null; + m_iStatusScale = SCALE_READY; + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + } + +/** +* +* @return +*/ +@Override +public Double readWeight() { + + synchronized(this) { + + if (m_iStatusScale != SCALE_READY) { + try { + wait(200); + } catch (InterruptedException e) { + } + if (m_iStatusScale != SCALE_READY) { + m_iStatusScale = SCALE_READY; + } + } + + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + write(new byte[] {0x57,0X0D}); // $ + flush(); + + try { + wait(200); + } catch (InterruptedException e) { + } + + if (m_iStatusScale == SCALE_READY) { + double dWeight = m_dWeightBuffer / m_dWeightDecimals; + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + return dWeight; + } else { + m_iStatusScale = SCALE_READY; + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + return 0.0; + } + } +} + +private void flush() { + try { + m_out.flush(); + } catch (IOException e) { + } +} + +private void write(byte[] data) { + try { + if (m_out == null) { + m_PortIdPrinter = CommPortIdentifier.getPortIdentifier(m_sPortScale); + m_CommPortPrinter = (SerialPort) m_PortIdPrinter.open("PORTID", 2000); + + m_out = m_CommPortPrinter.getOutputStream(); + m_in = m_CommPortPrinter.getInputStream(); + + m_CommPortPrinter.addEventListener(this); + m_CommPortPrinter.notifyOnDataAvailable(true); + + m_CommPortPrinter.setSerialPortParams(9600, + SerialPort.DATABITS_7, + SerialPort.STOPBITS_1, + SerialPort.PARITY_EVEN); + } + m_out.write(data); + } catch (NoSuchPortException | PortInUseException | UnsupportedCommOperationException + | TooManyListenersException | IOException e) { + } +} + +/** +* +* @param e +*/ +@Override +public void serialEvent(SerialPortEvent e) { + + switch (e.getEventType()) { + case SerialPortEvent.BI: + case SerialPortEvent.OE: + case SerialPortEvent.FE: + case SerialPortEvent.PE: + case SerialPortEvent.CD: + case SerialPortEvent.CTS: + case SerialPortEvent.DSR: + case SerialPortEvent.RI: + case SerialPortEvent.OUTPUT_BUFFER_EMPTY: + break; + case SerialPortEvent.DATA_AVAILABLE: + try { + int i; + i = m_in.available(); + byte[] readBuffer = new byte[i]; + if (i > 0) { + m_in.read(readBuffer); + } + + m_sScaleReading = m_sScaleReading + new String(readBuffer); + + try { + int start = m_sScaleReading.indexOf((char) 10); + int end = m_sScaleReading.indexOf((char) 3); + + if (start >= 0 && end >= 0) { + + start = m_sScaleReading.indexOf((char) 10); + end = m_sScaleReading.indexOf((char) 75); + m_dWeightBuffer = Double.parseDouble(m_sScaleReading.substring(start+1, end)); + m_sScaleReading = ""; + } + } catch (IndexOutOfBoundsException ex) { + System.out.println("IndexOutOfBoundsException, message not complete yet. Waiting for more data."); + } + + } catch (IOException eIO) {} + break; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/scale/ScaleAvery.java b/src/main/java/com/unicenta/pos/scale/ScaleAvery.java new file mode 100644 index 0000000..e533cb9 --- /dev/null +++ b/src/main/java/com/unicenta/pos/scale/ScaleAvery.java @@ -0,0 +1,195 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +/* + * uniCenta Feb 2017 + * Original code supplied Ryan Airey Feb 2017 +*/ + +package com.unicenta.pos.scale; + +import gnu.io.*; +import java.io.*; +import java.util.TooManyListenersException; + +public class ScaleAvery implements Scale, SerialPortEventListener { + + private CommPortIdentifier m_PortIdPrinter; + private SerialPort m_CommPortPrinter; + + private String m_sPortScale; + private OutputStream m_out; + private InputStream m_in; + + private static final int SCALE_READY = 0; + private static final int SCALE_READING = 1; + private static final int SCALE_READINGDECIMALS = 2; + private static int SCALE_NOMORE = 1; + + private double m_dWeightBuffer; + private double m_dWeightDecimals; + private int m_iStatusScale; + + public ScaleAvery(String sPortPrinter) { + m_sPortScale = sPortPrinter; + m_out = null; + m_in = null; + + m_iStatusScale = SCALE_READY; + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + + } + + @Override + public Double readWeight() { + synchronized(this) { + if (m_iStatusScale != SCALE_READY) { + try { + wait(1000); + } catch (InterruptedException e) { + } + if (m_iStatusScale != SCALE_READY) { + + m_iStatusScale = SCALE_READY; + } + } + + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + + // Send command to get data from scale + write(new byte[] {0x0057}); + flush(); + write(new byte[] {0x000D}); + try { + wait(1000); + } catch (InterruptedException e) { + } + + if (m_iStatusScale == SCALE_READY) { + double dWeight = m_dWeightBuffer / m_dWeightDecimals; +// System.out.println(" ----- ScaleAvery : readWeight --- if ------ "+dWeight); + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + return dWeight; + } else { + m_iStatusScale = SCALE_READY; + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + return 0.0; + } + } + } + + private void flush() { + try { + m_out.flush(); + } catch (IOException e) { + } + } + + private void write(byte[] data) { + try { + + + if (m_out == null) { + + m_PortIdPrinter = CommPortIdentifier.getPortIdentifier(m_sPortScale); + m_CommPortPrinter = (SerialPort) m_PortIdPrinter.open("PORTID", 2000); + m_out = m_CommPortPrinter.getOutputStream(); + m_in = m_CommPortPrinter.getInputStream(); + + m_CommPortPrinter.addEventListener(this); + m_CommPortPrinter.notifyOnDataAvailable(true); + + m_CommPortPrinter.setSerialPortParams(9600, + SerialPort.DATABITS_7, + SerialPort.STOPBITS_1, + SerialPort.PARITY_EVEN); + } + m_out.write(data); + + } catch (NoSuchPortException | PortInUseException + | UnsupportedCommOperationException | TooManyListenersException + | IOException e) { +// System.out.println(" Exception While Writing the Data, Might be Serial Dll Missing or COM Port not Supported, Or COM Port already in use"); + } + } + + @Override + public void serialEvent(SerialPortEvent e) { + + switch (e.getEventType()) { + case SerialPortEvent.BI: + case SerialPortEvent.OE: + case SerialPortEvent.FE: + case SerialPortEvent.PE: + case SerialPortEvent.CD: + case SerialPortEvent.CTS: + case SerialPortEvent.DSR: + case SerialPortEvent.RI: + case SerialPortEvent.OUTPUT_BUFFER_EMPTY: + break; + case SerialPortEvent.DATA_AVAILABLE: + try { + while (m_in.available() > 0) { + int b = m_in.read(); + if (b==0x0003 || b==3) { + synchronized (this) { + SCALE_NOMORE = 1; + m_iStatusScale = SCALE_READY; + notifyAll(); } + } else if (b == 0x004C || b==76) { + synchronized (this) { + SCALE_NOMORE = 0; } + } else if (SCALE_NOMORE==0){ + m_iStatusScale = SCALE_READY; + } else if (b > 0x002F + && b < 0x003A + && SCALE_NOMORE==1 + || b == 0x002E) { + synchronized(this) { + if (m_iStatusScale == SCALE_READY) { + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + m_iStatusScale = SCALE_READING; + } + if (b == 0x002E) { + m_iStatusScale = SCALE_READINGDECIMALS; + } else { + m_dWeightBuffer = m_dWeightBuffer * 10.0 + b - 0x0030; + if (m_iStatusScale == SCALE_READINGDECIMALS) { + m_dWeightDecimals *= 10.0; + } + } + } + } else { + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + m_iStatusScale = SCALE_READY; + } + } + } catch (IOException eIO) { +// System.out.println(" Error At serialEvent due to unknowen response data from scale "); + } + break; + } + } + } \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/scale/ScaleCASPDII.java b/src/main/java/com/unicenta/pos/scale/ScaleCASPDII.java new file mode 100644 index 0000000..2b95747 --- /dev/null +++ b/src/main/java/com/unicenta/pos/scale/ScaleCASPDII.java @@ -0,0 +1,178 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com/ +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.scale; + +import gnu.io.*; +import java.io.*; +import java.util.TooManyListenersException; + +public class ScaleCASPDII implements Scale, SerialPortEventListener { + + private CommPortIdentifier m_PortIdPrinter; + private SerialPort m_CommPortPrinter; + + private final String m_sPortScale; + private OutputStream m_out; + private InputStream m_in; + + private static final int SCALE_READY = 0; + private static final int SCALE_READING = 1; + private static final int SCALE_READINGDECIMALS = 2; + + private double m_dWeightBuffer; + private double m_dWeightDecimals; + private int m_iStatusScale; + + /** Creates a new instance of ScaleComm + * @param sPortPrinter */ + public ScaleCASPDII(String sPortPrinter) { + m_sPortScale = sPortPrinter; + m_out = null; + m_in = null; + + m_iStatusScale = SCALE_READY; + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + } + + @Override + public Double readWeight() { + + synchronized(this) { + + if (m_iStatusScale != SCALE_READY) { + try { + wait(1000); + } catch (InterruptedException e) { + } + if (m_iStatusScale != SCALE_READY) { + m_iStatusScale = SCALE_READY; + } + } + + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + write(new byte[] {0x57}); + flush(); + + try { + wait(1000); + } catch (InterruptedException e) { + } + + if (m_iStatusScale == SCALE_READY) { + double dWeight = m_dWeightBuffer / m_dWeightDecimals; + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1000.0; + return dWeight; + } else { + m_iStatusScale = SCALE_READY; + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1000.0; + return 0.0; + } + } + } + + private void flush() { + try { + m_out.flush(); + } catch (IOException e) { + } + } + + private void write(byte[] data) { + try { + if (m_out == null) { + m_PortIdPrinter = CommPortIdentifier.getPortIdentifier(m_sPortScale); + m_CommPortPrinter = (SerialPort) m_PortIdPrinter.open("PORTID", 1000); + + m_out = m_CommPortPrinter.getOutputStream(); + m_in = m_CommPortPrinter.getInputStream(); + + m_CommPortPrinter.addEventListener(this); + m_CommPortPrinter.notifyOnDataAvailable(true); + + m_CommPortPrinter.setSerialPortParams(9600, + SerialPort.DATABITS_7, + SerialPort.STOPBITS_1, + SerialPort.PARITY_EVEN); + } + m_out.write(data); + } catch (NoSuchPortException | + PortInUseException | + UnsupportedCommOperationException | + TooManyListenersException | + IOException e) { + } + } + + @Override + public void serialEvent(SerialPortEvent e) { + + switch (e.getEventType()) { + case SerialPortEvent.BI: + case SerialPortEvent.OE: + case SerialPortEvent.FE: + case SerialPortEvent.PE: + case SerialPortEvent.CD: + case SerialPortEvent.CTS: + case SerialPortEvent.DSR: + case SerialPortEvent.RI: + case SerialPortEvent.OUTPUT_BUFFER_EMPTY: + break; + case SerialPortEvent.DATA_AVAILABLE: + try { + while (m_in.available() > 0) { + int b = m_in.read(); + + if (b == 0x000D) { + synchronized (this) { + m_iStatusScale = SCALE_READY; + notifyAll(); + } + } else if ((b > 0x002F && b < 0x003A) || b == 0x002E){ + synchronized(this) { + if (m_iStatusScale == SCALE_READY) { + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1000.0; + m_iStatusScale = SCALE_READING; + } + if (b == 0x002E) { + m_iStatusScale = SCALE_READINGDECIMALS; + } else { + m_dWeightBuffer = m_dWeightBuffer * 10.0 + b - 0x0030; + if (m_iStatusScale == SCALE_READINGDECIMALS) { + m_dWeightDecimals *= 10.0; + } + } + } + } else { + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1000.0; + m_iStatusScale = SCALE_READY; + } + } + + } catch (IOException eIO) {} + break; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/scale/ScaleCasioPD1.java b/src/main/java/com/unicenta/pos/scale/ScaleCasioPD1.java new file mode 100644 index 0000000..2b8b2d1 --- /dev/null +++ b/src/main/java/com/unicenta/pos/scale/ScaleCasioPD1.java @@ -0,0 +1,202 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.scale; + +import gnu.io.*; +import java.io.*; +import java.util.TooManyListenersException; + +/** + * + * @author JG uniCenta + */ +public class ScaleCasioPD1 implements Scale, SerialPortEventListener { + + private CommPortIdentifier m_PortIdPrinter; + private SerialPort m_CommPortPrinter; + + private String m_sPortScale; + private OutputStream m_out; + private InputStream m_in; + + private static final int SCALE_READY = 0; + private static final int SCALE_READING = 1; + private static final int SCALE_READINGDECIMALS = 2; + private static int SCALE_NOMORE = 1; + + private double m_dWeightBuffer; + private double m_dWeightDecimals; + private int m_iStatusScale; + + /** Creates a new instance of ScaleComm + * @param sPortPrinter */ + public ScaleCasioPD1(String sPortPrinter) { + m_sPortScale = sPortPrinter; + m_out = null; + m_in = null; + + m_iStatusScale = SCALE_READY; + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + } + + /** + * + * @return + */ + @Override + public Double readWeight() { + + synchronized(this) { + + if (m_iStatusScale != SCALE_READY) { + try { + wait(1000); + } catch (InterruptedException e) { + } + if (m_iStatusScale != SCALE_READY) { + // bascula tonta. + m_iStatusScale = SCALE_READY; + } + } + + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + write(new byte[] {0x0057}); + flush(); + write(new byte[] {0x000D}); + + // Esperamos un ratito + try { + wait(1000); + } catch (InterruptedException e) { + } + + if (m_iStatusScale == SCALE_READY) { + double dWeight = m_dWeightBuffer / m_dWeightDecimals; + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + return dWeight; + } else { + m_iStatusScale = SCALE_READY; + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + return 0.0; + } + } + } + + private void flush() { + try { + m_out.flush(); + } catch (IOException e) { + } + } + + private void write(byte[] data) { + try { + if (m_out == null) { + m_PortIdPrinter = CommPortIdentifier.getPortIdentifier(m_sPortScale); + m_CommPortPrinter = (SerialPort) m_PortIdPrinter.open("PORTID", 2000); + + m_out = m_CommPortPrinter.getOutputStream(); + m_in = m_CommPortPrinter.getInputStream(); + + m_CommPortPrinter.addEventListener(this); + m_CommPortPrinter.notifyOnDataAvailable(true); + + m_CommPortPrinter.setSerialPortParams(9600, + SerialPort.DATABITS_7, + SerialPort.STOPBITS_1, + SerialPort.PARITY_EVEN); + } + m_out.write(data); + } catch (NoSuchPortException | PortInUseException | UnsupportedCommOperationException | TooManyListenersException | IOException e) { + } + } + + /** + * + * @param e + */ + @Override + public void serialEvent(SerialPortEvent e) { + + // Determine type of event. + switch (e.getEventType()) { + case SerialPortEvent.BI: + case SerialPortEvent.OE: + case SerialPortEvent.FE: + case SerialPortEvent.PE: + case SerialPortEvent.CD: + case SerialPortEvent.CTS: + case SerialPortEvent.DSR: + case SerialPortEvent.RI: + case SerialPortEvent.OUTPUT_BUFFER_EMPTY: + break; + case SerialPortEvent.DATA_AVAILABLE: + try { + while (m_in.available() > 0) { + int b = m_in.read(); + + if (b==0x0003 || b==3) { + synchronized (this) { + SCALE_NOMORE = 1; + m_iStatusScale = SCALE_READY; + notifyAll(); + } + + }else if (b == 0x004C || b==76) { + synchronized (this) { + SCALE_NOMORE = 0; + } + + }else if (SCALE_NOMORE==0){ + m_iStatusScale = SCALE_READY; + + }else if (b > 0x002F && b < 0x003A && SCALE_NOMORE==1 || b == 0x002E){ + synchronized(this) { + + if (m_iStatusScale == SCALE_READY) { + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + m_iStatusScale = SCALE_READING; + } + if (b == 0x002E) { + m_iStatusScale = SCALE_READINGDECIMALS; + } else { + m_dWeightBuffer = m_dWeightBuffer * 10.0 + b - 0x0030; + + if (m_iStatusScale == SCALE_READINGDECIMALS) { + m_dWeightDecimals *= 10.0; + } + } + } + } else { + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + m_iStatusScale = SCALE_READY; + } + } + } catch (IOException eIO) {} + break; + } + } + } \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/scale/ScaleComm.java b/src/main/java/com/unicenta/pos/scale/ScaleComm.java new file mode 100644 index 0000000..0336aab --- /dev/null +++ b/src/main/java/com/unicenta/pos/scale/ScaleComm.java @@ -0,0 +1,178 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.scale; + +import gnu.io.*; +import java.io.*; +import java.util.TooManyListenersException; + +/** + * + * @author JG uniCenta + */ +public class ScaleComm implements Scale, SerialPortEventListener { + + private String m_sPortScale; + private CommPortIdentifier m_PortIdPrinter; + private SerialPort m_CommPortPrinter; + private OutputStream m_out; + private InputStream m_in; + + private static final int SCALE_READY = 0; + private static final int SCALE_READING = 1; + + private double m_dWeightBuffer; + private int m_iStatusScale; + + /** Creates a new instance of ScaleComm + * @param sPortPrinter */ + public ScaleComm(String sPortPrinter) { + m_sPortScale = sPortPrinter; + m_out = null; + m_in = null; + + m_iStatusScale = SCALE_READY; + m_dWeightBuffer = 0.0; + } + + /** + * + * @return + */ + @Override + public Double readWeight() { + + synchronized(this) { + + if (m_iStatusScale != SCALE_READY) { + try { + wait(1000); + } catch (InterruptedException e) { + } + if (m_iStatusScale != SCALE_READY) { + // bascula tonta. + m_iStatusScale = SCALE_READY; + } + } + + // Ya estamos en SCALE_READY + m_dWeightBuffer = 0.0; + write(new byte[] {0x05}); + flush(); + + // Esperamos un ratito + try { + wait(1000); + } catch (InterruptedException e) { + } + + if (m_iStatusScale == SCALE_READY) { + // a value as been readed. + double dWeight = m_dWeightBuffer / 1000.0; + m_dWeightBuffer = 0.0; + return new Double(dWeight); + } else { + m_iStatusScale = SCALE_READY; + m_dWeightBuffer = 0.0; + return new Double(0.0); + } + } + } + + private void flush() { + try { + m_out.flush(); + } catch (IOException e) { + } + } + + private void write(byte[] data) { + try { + if (m_out == null) { + m_PortIdPrinter = CommPortIdentifier.getPortIdentifier(m_sPortScale); // Tomamos el puerto + m_CommPortPrinter = (SerialPort) m_PortIdPrinter.open("PORTID", 2000); // Abrimos el puerto + + m_out = m_CommPortPrinter.getOutputStream(); // Tomamos el chorro de escritura + m_in = m_CommPortPrinter.getInputStream(); + + m_CommPortPrinter.addEventListener(this); + m_CommPortPrinter.notifyOnDataAvailable(true); + + m_CommPortPrinter.setSerialPortParams(4800, + SerialPort.DATABITS_8, + SerialPort.STOPBITS_1, + SerialPort.PARITY_ODD); // Configuramos el puerto + } + m_out.write(data); + } catch (NoSuchPortException | PortInUseException | UnsupportedCommOperationException | TooManyListenersException | IOException e) { + } + } + + /** + * + * @param e + */ + @Override + public void serialEvent(SerialPortEvent e) { + + // Determine type of event. + switch (e.getEventType()) { + case SerialPortEvent.BI: + case SerialPortEvent.OE: + case SerialPortEvent.FE: + case SerialPortEvent.PE: + case SerialPortEvent.CD: + case SerialPortEvent.CTS: + case SerialPortEvent.DSR: + case SerialPortEvent.RI: + case SerialPortEvent.OUTPUT_BUFFER_EMPTY: + break; + case SerialPortEvent.DATA_AVAILABLE: + try { + while (m_in.available() > 0) { + int b = m_in.read(); + + if (b == 0x001E) { // RS ASCII + // Fin de lectura + synchronized (this) { + m_iStatusScale = SCALE_READY; + notifyAll(); + } + } else if (b > 0x002F && b < 0x003A){ + synchronized(this) { + if (m_iStatusScale == SCALE_READY) { + m_dWeightBuffer = 0.0; // se supone que esto debe estar ya garantizado + m_iStatusScale = SCALE_READING; + } + m_dWeightBuffer = m_dWeightBuffer * 10.0 + b - 0x0030; + } + } else { + // caracteres invalidos, reseteamos. + m_dWeightBuffer = 0.0; // se supone que esto debe estar ya garantizado + m_iStatusScale = SCALE_READY; + } + } + + } catch (IOException eIO) {} + break; + } + + } +} diff --git a/src/main/java/com/unicenta/pos/scale/ScaleDialog.java b/src/main/java/com/unicenta/pos/scale/ScaleDialog.java new file mode 100644 index 0000000..1bd4015 --- /dev/null +++ b/src/main/java/com/unicenta/pos/scale/ScaleDialog.java @@ -0,0 +1,57 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.scale; + +import com.unicenta.beans.JNumberDialog; +import com.unicenta.pos.forms.AppLocal; +import java.awt.Component; +import javax.swing.ImageIcon; + +/** + * + * @author adrian + */ +public class ScaleDialog implements Scale { + + private Component parent; + + /** + * + * @param parent + */ + public ScaleDialog(Component parent) { + this.parent = parent; + } + + /** + * + * @return + * @throws ScaleException + */ + @Override + public Double readWeight() throws ScaleException { + + // Set title for grams Kilos, ounzes, pounds, ... + return JNumberDialog.showEditNumber(parent, + AppLocal.getIntString("label.scale"), + AppLocal.getIntString("label.scaleinput"), + new ImageIcon(ScaleDialog.class.getResource("/com/unicenta/images/ark2.png"))); + } +} diff --git a/src/main/java/com/unicenta/pos/scale/ScaleException.java b/src/main/java/com/unicenta/pos/scale/ScaleException.java new file mode 100644 index 0000000..6b56da4 --- /dev/null +++ b/src/main/java/com/unicenta/pos/scale/ScaleException.java @@ -0,0 +1,41 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.scale; + +/** + * + * @author JG uniCenta + */ +public class ScaleException extends java.lang.Exception { + + /** + * Creates a new instance of <code>ScaleException</code> without detail message. + */ + public ScaleException() { + } + + /** + * Constructs an instance of <code>ScaleException</code> with the specified detail message. + * @param msg the detail message. + */ + public ScaleException(String msg) { + super(msg); + } +} diff --git a/src/main/java/com/unicenta/pos/scale/ScaleFake.java b/src/main/java/com/unicenta/pos/scale/ScaleFake.java new file mode 100644 index 0000000..22a50fc --- /dev/null +++ b/src/main/java/com/unicenta/pos/scale/ScaleFake.java @@ -0,0 +1,38 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009 Openbravo, S.L. +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.scale; + +public class ScaleFake implements Scale { + + /** Creates a new instance of ScaleFake */ + public ScaleFake() { + } + + /** + * + * @return + * @throws ScaleException + */ + @Override + public Double readWeight() throws ScaleException { + return new Double(Math.random() * 2.0); + } + +} diff --git a/src/main/java/com/unicenta/pos/scale/ScaleMTIND221.java b/src/main/java/com/unicenta/pos/scale/ScaleMTIND221.java new file mode 100644 index 0000000..798dd51 --- /dev/null +++ b/src/main/java/com/unicenta/pos/scale/ScaleMTIND221.java @@ -0,0 +1,198 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.scale; + +import gnu.io.*; +import lombok.extern.slf4j.Slf4j; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream;import java.util.TooManyListenersException; + +/** + * + * @author Nicholas Fritz - changes by JG + */ +@Slf4j +public class ScaleMTIND221 implements Scale, SerialPortEventListener { + + private CommPortIdentifier m_PortIdPrinter; + private SerialPort m_CommPortPrinter; + + private final String m_sPortScale; + private OutputStream m_out; + private InputStream m_in; + + private static final int SCALE_READY = 0; + private static final int SCALE_READING = 1; + private static final int SCALE_READINGDECIMALS = 2; + + private double m_dWeightBuffer; + private double m_dWeightDecimals; + private int m_iStatusScale; + + /** Creates a new instance of ScaleComm + * @param sPortPrinter */ + public ScaleMTIND221(String sPortPrinter) { + m_sPortScale = sPortPrinter; + m_out = null; + m_in = null; + + m_iStatusScale = SCALE_READY; + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + } + + /** + * + * @return + */ + @Override + public Double readWeight() { + + synchronized(this) { + + if (m_iStatusScale != SCALE_READY) { + try { + wait(1000); + } catch (InterruptedException ex) { + log.error(ex.getMessage()); + } + if (m_iStatusScale != SCALE_READY) { + // bascula tonta. + m_iStatusScale = SCALE_READY; + } + } + + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + try { + write(new byte[] {0x50}); // P + } catch (TooManyListenersException ex) { + log.error(ex.getMessage()); + } + flush(); + + try { + wait(1000); + } catch (InterruptedException ex) { + log.error(ex.getMessage()); + } + + if (m_iStatusScale == SCALE_READY) { + // hemos recibido cositas o si no hemos recibido nada estamos a 0.0 + double dWeight = m_dWeightBuffer / (m_dWeightDecimals*100.0); + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + return dWeight; + } else { + m_iStatusScale = SCALE_READY; + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + return 0.0; + } + } + } + + private void flush() { + try { + m_out.flush(); + } catch (IOException e) { + } + } + + private void write(byte[] data) throws TooManyListenersException { + try { + if (m_out == null) { + m_PortIdPrinter = CommPortIdentifier.getPortIdentifier(m_sPortScale); // Tomamos el puerto + m_CommPortPrinter = (SerialPort) m_PortIdPrinter.open("PORTID", 2000); // Abrimos el puerto + + m_out = m_CommPortPrinter.getOutputStream(); // Tomamos el chorro de escritura + m_in = m_CommPortPrinter.getInputStream(); + + m_CommPortPrinter.addEventListener(this); + m_CommPortPrinter.notifyOnDataAvailable(true); + + m_CommPortPrinter.setSerialPortParams(9600, 8, 1, 0); // Configuramos el puerto + } + m_out.write(data); + } catch (NoSuchPortException | PortInUseException | UnsupportedCommOperationException | IOException e) { + } + } + + /** + * + * @param e + */ + @Override + public void serialEvent(SerialPortEvent e) { + + // Determine type of event. + switch (e.getEventType()) { + case SerialPortEvent.BI: + case SerialPortEvent.OE: + case SerialPortEvent.FE: + case SerialPortEvent.PE: + case SerialPortEvent.CD: + case SerialPortEvent.CTS: + case SerialPortEvent.DSR: + case SerialPortEvent.RI: + case SerialPortEvent.OUTPUT_BUFFER_EMPTY: + break; + case SerialPortEvent.DATA_AVAILABLE: + try { + while (m_in.available() > 0) { + int b = m_in.read(); + + if (b == 0x000D) { // CR ASCII + // Fin de lectura + synchronized (this) { + m_iStatusScale = SCALE_READY; + notifyAll(); + } + } else if (((b > 0x002F) && (b < 0x003A)) || (b == 0x002E)){ + synchronized(this) { + if (m_iStatusScale == SCALE_READY) { + m_dWeightBuffer = 0.0; // se supone que esto debe estar ya garantizado + m_dWeightDecimals = 1.0; + m_iStatusScale = SCALE_READING; + } + if (b == 0x002E) { + m_iStatusScale = SCALE_READINGDECIMALS; + } else { + m_dWeightBuffer = m_dWeightBuffer * 10.0 + b - 0x0030; + if (m_iStatusScale == SCALE_READINGDECIMALS) { + m_dWeightDecimals *= 10.0; + } + } + } + } else { + // caracteres invalidos, reseteamos. + //m_dWeightBuffer = 0.0; // se supone que esto debe estar ya garantizado + m_dWeightDecimals = 1.0; + m_iStatusScale = SCALE_READY; + } + } + + } catch (IOException eIO) {} + break; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/scale/ScaleSamsungEsp.java b/src/main/java/com/unicenta/pos/scale/ScaleSamsungEsp.java new file mode 100644 index 0000000..5ae8499 --- /dev/null +++ b/src/main/java/com/unicenta/pos/scale/ScaleSamsungEsp.java @@ -0,0 +1,193 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.scale; + +import gnu.io.*; +import java.io.*; +import java.util.TooManyListenersException; + +/** + * + * @author JG uniCenta + */ +public class ScaleSamsungEsp implements Scale, SerialPortEventListener { + + private CommPortIdentifier m_PortIdPrinter; + private SerialPort m_CommPortPrinter; + + private String m_sPortScale; + private OutputStream m_out; + private InputStream m_in; + + private static final int SCALE_READY = 0; + private static final int SCALE_READING = 1; + private static final int SCALE_READINGDECIMALS = 2; + + private double m_dWeightBuffer; + private double m_dWeightDecimals; + private int m_iStatusScale; + + /** Creates a new instance of ScaleComm + * @param sPortPrinter */ + public ScaleSamsungEsp(String sPortPrinter) { + m_sPortScale = sPortPrinter; + m_out = null; + m_in = null; + + m_iStatusScale = SCALE_READY; + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + } + + /** + * + * @return + */ + @Override + public Double readWeight() { + + synchronized(this) { + + if (m_iStatusScale != SCALE_READY) { + try { + wait(1000); + } catch (InterruptedException e) { + } + if (m_iStatusScale != SCALE_READY) { + // bascula tonta. + m_iStatusScale = SCALE_READY; + } + } + + // Ya estamos en SCALE_READY + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + write(new byte[] {0x24}); // $ + flush(); + + // Esperamos un ratito + try { + wait(1000); + } catch (InterruptedException e) { + } + + if (m_iStatusScale == SCALE_READY) { + // hemos recibido cositas o si no hemos recibido nada estamos a 0.0 + double dWeight = m_dWeightBuffer / m_dWeightDecimals; + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + return new Double(dWeight); + } else { + m_iStatusScale = SCALE_READY; + m_dWeightBuffer = 0.0; + m_dWeightDecimals = 1.0; + return new Double(0.0); + } + } + } + + private void flush() { + try { + m_out.flush(); + } catch (IOException e) { + } + } + + private void write(byte[] data) { + try { + if (m_out == null) { + m_PortIdPrinter = CommPortIdentifier.getPortIdentifier(m_sPortScale); // Tomamos el puerto + m_CommPortPrinter = (SerialPort) m_PortIdPrinter.open("PORTID", 2000); // Abrimos el puerto + + m_out = m_CommPortPrinter.getOutputStream(); // Tomamos el chorro de escritura + m_in = m_CommPortPrinter.getInputStream(); + + m_CommPortPrinter.addEventListener(this); + m_CommPortPrinter.notifyOnDataAvailable(true); + + m_CommPortPrinter.setSerialPortParams(4800, + SerialPort.DATABITS_8, + SerialPort.STOPBITS_1, + SerialPort.PARITY_ODD); // Configuramos el puerto + } + m_out.write(data); + } catch (NoSuchPortException | PortInUseException | UnsupportedCommOperationException | TooManyListenersException | IOException e) { + } + } + + /** + * + * @param e + */ + @Override + public void serialEvent(SerialPortEvent e) { + + // Determine type of event. + switch (e.getEventType()) { + case SerialPortEvent.BI: + case SerialPortEvent.OE: + case SerialPortEvent.FE: + case SerialPortEvent.PE: + case SerialPortEvent.CD: + case SerialPortEvent.CTS: + case SerialPortEvent.DSR: + case SerialPortEvent.RI: + case SerialPortEvent.OUTPUT_BUFFER_EMPTY: + break; + case SerialPortEvent.DATA_AVAILABLE: + try { + while (m_in.available() > 0) { + int b = m_in.read(); + + if (b == 0x000D) { // CR ASCII + // Fin de lectura + synchronized (this) { + m_iStatusScale = SCALE_READY; + notifyAll(); + } + } else if ((b > 0x002F && b < 0x003A) || b == 0x002E){ + synchronized(this) { + if (m_iStatusScale == SCALE_READY) { + m_dWeightBuffer = 0.0; // se supone que esto debe estar ya garantizado + m_dWeightDecimals = 1.0; + m_iStatusScale = SCALE_READING; + } + if (b == 0x002E) { + m_iStatusScale = SCALE_READINGDECIMALS; + } else { + m_dWeightBuffer = m_dWeightBuffer * 10.0 + b - 0x0030; + if (m_iStatusScale == SCALE_READINGDECIMALS) { + m_dWeightDecimals *= 10.0; + } + } + } + } else { + // caracteres invalidos, reseteamos. + m_dWeightBuffer = 0.0; // se supone que esto debe estar ya garantizado + m_dWeightDecimals = 1.0; + m_iStatusScale = SCALE_READY; + } + } + + } catch (IOException eIO) {} + break; + } + } +} diff --git a/src/main/java/com/unicenta/pos/scanpal2/DeviceScanner.java b/src/main/java/com/unicenta/pos/scanpal2/DeviceScanner.java new file mode 100644 index 0000000..d5cdc26 --- /dev/null +++ b/src/main/java/com/unicenta/pos/scanpal2/DeviceScanner.java @@ -0,0 +1,72 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.scanpal2; + +/** + * + * @author JG uniCenta + */ +public interface DeviceScanner { + + /** + * + * @throws DeviceScannerException + */ + public void connectDevice() throws DeviceScannerException; + + /** + * + */ + public void disconnectDevice(); + + /** + * + * @throws DeviceScannerException + */ + public void startDownloadProduct() throws DeviceScannerException; + + /** + * + * @return + * @throws DeviceScannerException + */ + public ProductDownloaded recieveProduct() throws DeviceScannerException; + + /** + * + * @throws DeviceScannerException + */ + public void startUploadProduct() throws DeviceScannerException; + + /** + * + * @param sName + * @param sCode + * @param dPrice + * @throws DeviceScannerException + */ + public void sendProduct(String sName, String sCode, Double dPrice) throws DeviceScannerException; + + /** + * + * @throws DeviceScannerException + */ + public void stopUploadProduct() throws DeviceScannerException; +} diff --git a/src/main/java/com/unicenta/pos/scanpal2/DeviceScannerComm.java b/src/main/java/com/unicenta/pos/scanpal2/DeviceScannerComm.java new file mode 100644 index 0000000..97d3f7e --- /dev/null +++ b/src/main/java/com/unicenta/pos/scanpal2/DeviceScannerComm.java @@ -0,0 +1,368 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.scanpal2; + +import gnu.io.*; +import java.io.*; +import java.util.LinkedList; +import java.util.Queue; +import java.util.StringTokenizer; + +/** + * + * @author JG uniCenta + */ +public class DeviceScannerComm implements DeviceScanner, SerialPortEventListener { + + private CommPortIdentifier m_PortIdPrinter; + private SerialPort m_CommPortPrinter; + + private String m_sPort; + private OutputStream m_out; + private InputStream m_in; + + private static final byte[] COMMAND_READ = new byte[] {0x52, 0x45, 0x41, 0x44}; + private static final byte[] COMMAND_CIPHER = new byte[] {0x43, 0x49, 0x50, 0x48, 0x45, 0x52}; + private static final byte[] COMMAND_OVER = new byte[] {0x4F, 0x56, 0x45, 0x52}; + private static final byte[] COMMAND_ACK = new byte[] {0x41, 0x43, 0x4B}; + + private Queue<byte[]> m_aLines; + private ByteArrayOutputStream m_abuffer; + private int m_iStatus; +// private static final int STATUS_WAITING = 0; +// private static final int STATUS_LINEREADY = 1; +// private static final int STATUS_READING = 2; + + private int m_iProductOrder; + + /** Creates a new instance of ScanDeviceComm */ + DeviceScannerComm(String sPort) { + m_sPort = sPort; + + m_PortIdPrinter = null; + m_CommPortPrinter = null; + m_out = null; + m_in = null; + } + + /** + * + * @throws DeviceScannerException + */ + public void connectDevice() throws DeviceScannerException { + + try { + // Conecto con el puerto + m_PortIdPrinter = CommPortIdentifier.getPortIdentifier(m_sPort); // Tomamos el puerto + m_CommPortPrinter = (SerialPort) m_PortIdPrinter.open("PORTID", 2000); // Abrimos el puerto + + m_out = m_CommPortPrinter.getOutputStream(); // Tomamos el chorro de escritura + m_in = m_CommPortPrinter.getInputStream(); + + m_CommPortPrinter.addEventListener(this); + m_CommPortPrinter.notifyOnDataAvailable(true); + + m_CommPortPrinter.setSerialPortParams(115200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); // Configuramos el puerto +// } catch (NoSuchPortException e) { +// e.printStackTrace(); +// } catch (PortInUseException e) { +// e.printStackTrace(); +// } catch (UnsupportedCommOperationException e) { +// e.printStackTrace(); +// } catch (TooManyListenersException e) { +// e.printStackTrace(); +// } catch (IOException e) { +// e.printStackTrace(); + } catch (Exception e) { + m_PortIdPrinter = null; + m_CommPortPrinter = null; + m_out = null; + m_in = null; + throw new DeviceScannerException(e); + } + + synchronized(this) { + // m_iStatus = STATUS_WAITING; + m_aLines = new LinkedList<byte[]>(); + m_abuffer = new ByteArrayOutputStream(); + } + } + + /** + * + */ + public void disconnectDevice() { + + try { + m_out.close(); + m_in.close(); + m_CommPortPrinter.close(); + } catch (IOException e) { + } + + synchronized(this) { + // m_iStatus = STATUS_WAITING; + m_aLines = null; + m_abuffer = null; + } + + m_PortIdPrinter = null; + m_CommPortPrinter = null; + m_out = null; + m_in = null; + } + + /** + * + * @throws DeviceScannerException + */ + public void startDownloadProduct() throws DeviceScannerException { + writeLine(COMMAND_READ); // writeLine(COMMAND_READ); + readCommand(COMMAND_ACK); + } + + /** + * + * @return + * @throws DeviceScannerException + */ + public ProductDownloaded recieveProduct() throws DeviceScannerException { + byte[] line = readLine(); + if (checkCommand(COMMAND_OVER, line)) { + // La Scanpal a terminado. + return null; + } else { + // procesamos la linea + ProductDownloaded p = new ProductDownloaded(); + try { + String sLine = new String(line, 1, line.length - 3, "ISO-8859-1"); + StringTokenizer T = new StringTokenizer(sLine, "|"); + while (T.hasMoreTokens()) { + String sToken = T.nextToken(); + if (sToken.startsWith("IEAN")) { + p.setCode(sToken.substring(4).trim()); + } else if (sToken.startsWith("ICANT")) { + try { + p.setQuantity(Double.parseDouble(sToken.substring(5).trim())); + } catch (NumberFormatException e) { + } + } + } + } catch (UnsupportedEncodingException e) { + } + writeLine(COMMAND_ACK); + return p; + } + } + + /** + * + * @throws DeviceScannerException + */ + public void startUploadProduct() throws DeviceScannerException { + // Inicializamos la conversacion + writeLine(COMMAND_CIPHER); + readCommand(COMMAND_ACK); + m_iProductOrder = 0; + } + + /** + * + * @param sName + * @param sCode + * @param dPrice + * @throws DeviceScannerException + */ + public void sendProduct(String sName, String sCode, Double dPrice) throws DeviceScannerException { + + m_iProductOrder++; + + ByteArrayOutputStream lineout = new ByteArrayOutputStream(); + try { + lineout.write(convert(Integer.toString(m_iProductOrder))); + lineout.write(0x7c); // El Pipe "|" + lineout.write(convert(sName)); + lineout.write(0x7c); // El Pipe "|" + lineout.write(convert(sCode)); + lineout.write(0x7c); // El Pipe "|" + lineout.write(0x7c); // El Pipe "|" + lineout.write(0x7c); // El Pipe "|" + lineout.write(0x7c); // El Pipe "|" + lineout.write(convert(dPrice.toString())); + lineout.write(0x7c); // El Pipe "|" + // Mandamos el checksum + lineout.write(calcCheckSum1(lineout.toByteArray())); + } catch (UnsupportedEncodingException e) { + } catch (IOException e) { + } + + writeLine(lineout.toByteArray()); + readCommand(COMMAND_ACK); + } + + /** + * + * @throws DeviceScannerException + */ + public void stopUploadProduct() throws DeviceScannerException { + // Cerramos la conversacion + writeLine(COMMAND_OVER); + readCommand(COMMAND_ACK); + } + + private void readCommand(byte[] cmd) throws DeviceScannerException { + byte[] b = readLine(); + if (!checkCommand(cmd, b)) { + // excepcion que te crio. + throw new DeviceScannerException("Command not expected"); + } + } + + private void writeLine(byte[] aline) throws DeviceScannerException { + + if (m_CommPortPrinter == null) { + throw new DeviceScannerException("No Serial port opened"); + } else { + + synchronized(this) { + try { + m_out.write(aline); + m_out.write(0x0D); + m_out.flush(); + } catch (IOException e) { + throw new DeviceScannerException(e); + } + } + } + } + + private byte[] readLine() throws DeviceScannerException { + + synchronized (this) { + + if (!m_aLines.isEmpty()) { + return m_aLines.poll(); + } + + // esperamos un ratito + try { + wait(1000); + } catch (InterruptedException e) { + } + + if (m_aLines.isEmpty()) { + throw new DeviceScannerException("Timeout"); + } else { + return m_aLines.poll(); + } + } + } + + private byte[] convert(String sdata) { + + // return sdata.getBytes("ISO-8859-1"); + if (sdata == null) { + return new byte[0]; + } else { + byte[] result = new byte[sdata.length()]; + + for (int i = 0; i < sdata.length(); i++) { + char c = sdata.charAt(i); + if (c == 0x7c) { // El pipe | + result[i] = '.'; + } else if ((c >= 0x0020) && (c < 0x0080)) { + result[i] = (byte) c; + } else { + result[i] = ' '; + } + } + return result; + } + } + + private byte[] calcCheckSum1(byte[] adata) { + + int isum = 0; + for (int i = 0; i < adata.length; i++) { + isum += adata[i]; + } + + byte high = (byte) ((isum & 0xFF00) >> 8); + if (high == 0x0D) high = 0x0E; + byte low = (byte) (isum & 0x00FF); + if (low == 0x0D) low = 0x0E; + + byte[] result = new byte[2]; + result[0] = high; + result[1] = low; + return result; + } + + private boolean checkCommand(byte[] bcommand, byte[] brecieved) { + + if (bcommand.length == brecieved.length) { + for (int i = 0; i < bcommand.length; i++) { + if (bcommand[i] != brecieved[i]) { + return false; + } + } + return true; + } else { + return false; + } + } + + /** + * + * @param e + */ + public void serialEvent(SerialPortEvent e) { + + // Determine type of event. + switch (e.getEventType()) { + case SerialPortEvent.BI: + case SerialPortEvent.OE: + case SerialPortEvent.FE: + case SerialPortEvent.PE: + case SerialPortEvent.CD: + case SerialPortEvent.CTS: + case SerialPortEvent.DSR: + case SerialPortEvent.RI: + case SerialPortEvent.OUTPUT_BUFFER_EMPTY: + break; + case SerialPortEvent.DATA_AVAILABLE: + try { + while (m_in.available() > 0) { + int b = m_in.read(); + synchronized(this) { + if (b == 0x0D) { + m_aLines.add(m_abuffer.toByteArray()); + m_abuffer.reset(); + notifyAll(); + } else { + m_abuffer.write(b); + } + } + } + } catch (IOException eIO) {} + break; + } + } +} diff --git a/src/main/java/com/unicenta/pos/scanpal2/DeviceScannerException.java b/src/main/java/com/unicenta/pos/scanpal2/DeviceScannerException.java new file mode 100644 index 0000000..445a783 --- /dev/null +++ b/src/main/java/com/unicenta/pos/scanpal2/DeviceScannerException.java @@ -0,0 +1,60 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + + +package com.unicenta.pos.scanpal2; + +/** + * + * @author adrianromero + */ +public class DeviceScannerException extends java.lang.Exception { + + /** + * Creates a new instance of <code>DeviceScannerException</code> without detail message. + */ + public DeviceScannerException() { + } + + + /** + * Constructs an instance of <code>DeviceScannerException</code> with the specified detail message. + * @param msg the detail message. + */ + public DeviceScannerException(String msg) { + super(msg); + } + + /** + * + * @param msg + * @param cause + */ + public DeviceScannerException(String msg, Throwable cause) { + super(msg, cause); + } + + /** + * + * @param cause + */ + public DeviceScannerException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/unicenta/pos/scanpal2/DeviceScannerFactory.java b/src/main/java/com/unicenta/pos/scanpal2/DeviceScannerFactory.java new file mode 100644 index 0000000..c546aa0 --- /dev/null +++ b/src/main/java/com/unicenta/pos/scanpal2/DeviceScannerFactory.java @@ -0,0 +1,53 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.scanpal2; + +import com.unicenta.pos.forms.AppProperties; +import com.unicenta.pos.util.StringParser; + +/** + * + * @author JG uniCenta + */ +public class DeviceScannerFactory { + + /** Creates a new instance of DeviceScannerFactory */ + private DeviceScannerFactory() { + } + + /** + * + * @param props + * @return + */ + public static DeviceScanner createInstance(AppProperties props) { + + StringParser sd = new StringParser(props.getProperty("machine.scanner")); + String sScannerType = sd.nextToken(':'); + String sScannerParam1 = sd.nextToken(','); + // String sScannerParam2 = sd.nextToken(','); + + if ("scanpal2".equals(sScannerType)) { + return new DeviceScannerComm(sScannerParam1); + } else { + return null; + } + } +} diff --git a/src/main/java/com/unicenta/pos/scanpal2/ProductDownloaded.java b/src/main/java/com/unicenta/pos/scanpal2/ProductDownloaded.java new file mode 100644 index 0000000..8e27ef2 --- /dev/null +++ b/src/main/java/com/unicenta/pos/scanpal2/ProductDownloaded.java @@ -0,0 +1,68 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.scanpal2; + +/** + * + * @author JG uniCenta + */ +public class ProductDownloaded { + + private String m_sCode; + private double m_dQuantity; + + /** + * + */ + public ProductDownloaded() { + } + + /** + * + * @param value + */ + public void setCode(String value) { + m_sCode = value; + } + + /** + * + * @return + */ + public String getCode() { + return m_sCode; + } + + /** + * + * @param value + */ + public void setQuantity(double value) { + m_dQuantity = value; + } + + /** + * + * @return + */ + public double getQuantity() { + return m_dQuantity; + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/scripting/ScriptEngine.java b/src/main/java/com/unicenta/pos/scripting/ScriptEngine.java new file mode 100644 index 0000000..0d8623b --- /dev/null +++ b/src/main/java/com/unicenta/pos/scripting/ScriptEngine.java @@ -0,0 +1,52 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.scripting; + +/** + * + * @author adrianromero + * Created on 5 de marzo de 2007, 19:56 + * + */ +public interface ScriptEngine { + + /** + * + * @param key + * @param value + */ + public void put(String key, Object value); + + /** + * + * @param key + * @return + */ + public Object get(String key); + + /** + * + * @param src + * @return + * @throws ScriptException + */ + public Object eval(String src) throws ScriptException; + +} diff --git a/src/main/java/com/unicenta/pos/scripting/ScriptEngineBeanshell.java b/src/main/java/com/unicenta/pos/scripting/ScriptEngineBeanshell.java new file mode 100644 index 0000000..4fd3f7e --- /dev/null +++ b/src/main/java/com/unicenta/pos/scripting/ScriptEngineBeanshell.java @@ -0,0 +1,68 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.scripting; + +import bsh.EvalError; +import bsh.Interpreter; + +/** + * + * @author adrianromero + * Created on 5 de marzo de 2007, 19:57 + * + */ +class ScriptEngineBeanshell implements ScriptEngine { + + private Interpreter i; + + /** Creates a new instance of ScriptEngineBeanshell */ + public ScriptEngineBeanshell() { + i = new Interpreter(); + } + + @Override + public void put(String key, Object value) { + + try { + i.set(key, value); + } catch (EvalError e) { + } + } + + @Override + public Object get(String key) { + + try { + return i.get(key); + } catch (EvalError e) { + return null; + } + } + + @Override + public Object eval(String src) throws ScriptException { + + try { + return i.eval(src); + } catch (EvalError e) { + throw new ScriptException(e.getMessage(), e); + } + } +} diff --git a/src/main/java/com/unicenta/pos/scripting/ScriptEngineVelocity.java b/src/main/java/com/unicenta/pos/scripting/ScriptEngineVelocity.java new file mode 100644 index 0000000..1e0650f --- /dev/null +++ b/src/main/java/com/unicenta/pos/scripting/ScriptEngineVelocity.java @@ -0,0 +1,107 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.scripting; + +import com.unicenta.pos.forms.AppView; +// import com.unicenta.pos.util.ScriptletUtil; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; +import org.apache.velocity.exception.MethodInvocationException; +import org.apache.velocity.exception.ParseErrorException; + +/** + * + * @author adrianromero + * Created on 5 de marzo de 2007, 19:57 + * + */ +class ScriptEngineVelocity implements ScriptEngine { + + private static VelocityEngine m_ve = null; + + private VelocityContext c = null; + private AppView m_App; + + + /** Creates a new instance of ScriptEngineVelocity */ + public ScriptEngineVelocity() throws ScriptException { + + if (m_ve == null) { + // Inicializo Velocity + m_ve = new VelocityEngine(); + // ve.setProperty(VelocityEngine.RUNTIME_LOG_LOGSYSTEM, this); + + // m_ve.setProperty(VelocityEngine.RESOURCE_LOADER, "class"); + // // m_ve.setProperty("class.resource.loader.description", "Velocity Classpath Resource Loader"); + // // m_ve.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); + // m_ve.setProperty("class.resource.loader.class", "com.unicenta.pos.forms.SystemResourceLoader"); + // m_ve.setProperty("class.resource.loader.description", "Velocity Resource Loader"); + // m_ve.setProperty("class.resource.loader.appresources", this); + + m_ve.setProperty(VelocityEngine.RUNTIME_LOG_LOGSYSTEM_CLASS, "org.apache.velocity.runtime.log.NullLogSystem"); + m_ve.setProperty(VelocityEngine.ENCODING_DEFAULT, "UTF-8"); + m_ve.setProperty(VelocityEngine.INPUT_ENCODING, "UTF-8"); + try { + m_ve.init(); + } catch (Exception e) { + throw new ScriptException("Cannot initialize Velocity Engine", e); + } + } + c = new VelocityContext(); + +// Add JG uniCenta - see com.unicenta.pos.ScriptletUtil +// this.put("scriptletutil", new ScriptletUtil()); + + } + + @Override + public void put(String key, Object value) { + c.put(key, value); + } + @Override + public Object get(String key) { + return c.get(key); + } + + @Override + public Object eval(String src) throws ScriptException { + if (m_ve == null) { + throw new ScriptException("Velocity engine not initialized."); + } else { + Writer w = new StringWriter(); + try { + if (m_ve.evaluate(c, w, "log", new StringReader(src))) { + return w.toString(); + } else { + throw new ScriptException("Velocity engine unexpected error."); + } + } catch (ParseErrorException e) { + throw new ScriptException(e.getMessage(), e); + } catch (MethodInvocationException e) { + throw new ScriptException(e.getMessage(), e); + } catch (Exception e) { + throw new ScriptException(e.getMessage(), e); + } + } + } +} diff --git a/src/main/java/com/unicenta/pos/scripting/ScriptException.java b/src/main/java/com/unicenta/pos/scripting/ScriptException.java new file mode 100644 index 0000000..2fecb37 --- /dev/null +++ b/src/main/java/com/unicenta/pos/scripting/ScriptException.java @@ -0,0 +1,52 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.scripting; + +/** + * + * @author adrianromero + */ +public class ScriptException extends java.lang.Exception { + + /** + * Creates a new instance of <code>ScriptException</code> without detail message. + */ + public ScriptException() { + } + + + /** + * Constructs an instance of <code>ScriptException</code> with the specified detail message. + * @param msg the detail message. + */ + public ScriptException(String msg) { + super(msg); + } + + /** + * + * @param msg + * @param cause + */ + public ScriptException(String msg, Throwable cause) { + super(msg, cause); + } + +} diff --git a/src/main/java/com/unicenta/pos/scripting/ScriptFactory.java b/src/main/java/com/unicenta/pos/scripting/ScriptFactory.java new file mode 100644 index 0000000..84ee619 --- /dev/null +++ b/src/main/java/com/unicenta/pos/scripting/ScriptFactory.java @@ -0,0 +1,70 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.scripting; + +/** + * + * @author adrianromero + * Created on 5 de marzo de 2007, 19:56 + * + */ +public class ScriptFactory { + + /** + * + */ + public static final String VELOCITY = "velocity"; + + /** + * + */ + public static final String BEANSHELL = "beanshell"; + + /** + * + */ + public static final String RHINO = "rhino"; + + /** Creates a new instance of ScriptFactory */ + private ScriptFactory() { + } + + /** + * + * @param name + * @return + * @throws ScriptException + */ + public static ScriptEngine getScriptEngine(String name) throws ScriptException { +// JG 16 May use switch + switch (name) { + case VELOCITY: + return new ScriptEngineVelocity(); + case BEANSHELL: + return new ScriptEngineBeanshell(); + // } else if (RHINO.equals(name)) { + // return new ScriptEngineRhino(); + // } else if (name.startsWith("generic:")) { + // return new ScriptEngineGeneric(name.substring(8)); + default: + throw new ScriptException("Script engine not found: " + name); + } + } +} diff --git a/src/main/java/com/unicenta/pos/suppliers/DataLogicSuppliers.java b/src/main/java/com/unicenta/pos/suppliers/DataLogicSuppliers.java new file mode 100644 index 0000000..89ec360 --- /dev/null +++ b/src/main/java/com/unicenta/pos/suppliers/DataLogicSuppliers.java @@ -0,0 +1,242 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.suppliers; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.*; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.BeanFactoryDataSingle; +import java.util.List; + +/** + * @author JG uniCenta + */ +public class DataLogicSuppliers extends BeanFactoryDataSingle { + + /** + * Main Method for supplier object + */ + protected Session s; + private TableDefinition tsuppliers; + private static final Datas[] supplierdatas = new Datas[] { + Datas.STRING, + Datas.STRING, + Datas.STRING, + Datas.STRING, + Datas.STRING, + Datas.STRING, + Datas.STRING}; + + /** + * + * @param s + */ + @Override + public void init(Session s){ + this.s = s; + tsuppliers = new TableDefinition(s + , "suppliers" + , new String[] { + "ID", + "SEARCHKEY", + "TAXID", + "NAME", + "MAXDEBT", + "ADDRESS", + "ADDRESS2", + "POSTAL", + "CITY", + "REGION", + "COUNTRY", + "FIRSTNAME", + "LASTNAME", + "EMAIL", + "PHONE", + "PHONE2", + "FAX", + "NOTES", + "VISIBLE", + "CURDATE", + "CURDEBT", + "VATID" } + , new String[] { + "ID", + AppLocal.getIntString("label.searchkey"), + AppLocal.getIntString("label.suppliertaxid"), + AppLocal.getIntString("label.name"), + + AppLocal.getIntString("label.maxdebt"), + AppLocal.getIntString("label.address"), + AppLocal.getIntString("label.address2"), + AppLocal.getIntString("label.postal"), + + AppLocal.getIntString("label.city"), + AppLocal.getIntString("label.region"), + AppLocal.getIntString("label.country"), + AppLocal.getIntString("label.firstname"), + + AppLocal.getIntString("label.lastname"), + AppLocal.getIntString("label.email"), + AppLocal.getIntString("label.phone"), + AppLocal.getIntString("label.phone2"), + + AppLocal.getIntString("label.fax"), + AppLocal.getIntString("label.notes"), + "VISIBLE", + AppLocal.getIntString("label.curdate"), + + AppLocal.getIntString("label.curdebt"), + AppLocal.getIntString("label.suppliervatid") } + , new Datas[] { + Datas.STRING, Datas.STRING, Datas.STRING, Datas.STRING, + Datas.DOUBLE, Datas.STRING, Datas.STRING, Datas.STRING, + Datas.STRING, Datas.STRING, Datas.STRING, Datas.STRING, + Datas.STRING, Datas.STRING, Datas.STRING, Datas.STRING, + Datas.STRING, Datas.STRING, Datas.BOOLEAN, Datas.TIMESTAMP, + Datas.DOUBLE, Datas.STRING } + , new Formats[] { + Formats.STRING, Formats.STRING, Formats.STRING, Formats.STRING, + Formats.CURRENCY, Formats.STRING, Formats.STRING, Formats.STRING, + Formats.STRING, Formats.STRING, Formats.STRING, Formats.STRING, + Formats.STRING, Formats.STRING, Formats.STRING, Formats.STRING, + Formats.STRING, Formats.STRING, Formats.BOOLEAN, Formats.TIMESTAMP, + Formats.CURRENCY, Formats.STRING } + , new int[] {0} + ); + } + + /** + * + * @return supplier data + */ + public SentenceList getSupplierList() { + return new StaticSentence(s + , new QBFBuilder("SELECT " + + "ID, SEARCHKEY, TAXID, NAME, " + + "POSTAL, PHONE, EMAIL " + + "FROM suppliers " + + "WHERE VISIBLE = " + s.DB.TRUE() + " AND ?(QBF_FILTER) ORDER BY NAME" + , new String[] {"SEARCHKEY", "TAXID", "NAME", "POSTAL", "PHONE", "EMAIL"}) + , new SerializerWriteBasic(new Datas[] { + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING}) + , (DataRead dr) -> { + SupplierInfo s1 = new SupplierInfo(dr.getString(1)); + s1.setSearchkey(dr.getString(2)); + s1.setTaxid(dr.getString(3)); + s1.setName(dr.getString(4)); + s1.setPostal(dr.getString(5)); + s1.setPhone(dr.getString(6)); + s1.setEmail(dr.getString(7)); + return s1; + }); + } + + /** + * + * @return supplier data + */ + public SentenceList getSuppList() { + return new StaticSentence(s + , new QBFBuilder("SELECT " + + "ID, SEARCHKEY, TAXID, NAME, " + + "POSTAL, PHONE, EMAIL " + + "FROM suppliers " + + "WHERE VISIBLE = " + s.DB.TRUE() + " ORDER BY NAME" + , new String[] {"SEARCHKEY", "TAXID", "NAME", "POSTAL", "PHONE", "EMAIL"}) + , new SerializerWriteBasic(new Datas[] { + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING}) + , (DataRead dr) -> { + SupplierInfo s1 = new SupplierInfo(dr.getString(1)); + s1.setSearchkey(dr.getString(2)); + s1.setTaxid(dr.getString(3)); + s1.setName(dr.getString(4)); + s1.setPostal(dr.getString(5)); + s1.setPhone(dr.getString(6)); + s1.setEmail(dr.getString(7)); + return s1; + }); + } + + /** + * + * @param supplier + * @return + * @throws BasicException + */ + public int updateSupplierExt(final SupplierInfoExt supplier) throws BasicException { + + return new PreparedSentence(s + , "UPDATE suppliers SET NOTES = ? WHERE ID = ?" + , SerializerWriteParams.INSTANCE ) + .exec(new DataParams() { + @Override + public void writeValues() throws BasicException { + setString(1, supplier.getNotes()); + setString(2, supplier.getID()); + } + }); + } + public final TableDefinition getTableSuppliers() { + return tsuppliers; + } + + /** + * JG Aug 2017 - Return Supplier Id - sId param + * @param sId + * @return + * @throws BasicException + */ + @SuppressWarnings("unchecked") + public final List<SupplierTransaction> getSuppliersTransactionList(String sId) throws BasicException { + + return new PreparedSentence(s, + "SELECT " + + "stockdiary.datenew, " + + "products.NAME, " + + "stockdiary.units, " + + "stockdiary.price, " + + "stockdiary.reason, " + + "suppliers.id " + + "FROM (stockdiary stockdiary " + + "INNER JOIN suppliers suppliers " + + "ON (stockdiary.supplier = suppliers.id)) " + + "INNER JOIN products products " + + "ON (stockdiary.product = products.ID) " + + "WHERE suppliers.id = ? " + + "GROUP BY " + + "stockdiary.datenew, " + + "products.NAME, " + + "stockdiary.reason " + + "ORDER BY stockdiary.datenew DESC", + SerializerWriteString.INSTANCE, + SupplierTransaction.getSerializerRead()).list(sId); + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/suppliers/JDialogNewSupplier.form b/src/main/java/com/unicenta/pos/suppliers/JDialogNewSupplier.form new file mode 100644 index 0000000..27543e4 --- /dev/null +++ b/src/main/java/com/unicenta/pos/suppliers/JDialogNewSupplier.form @@ -0,0 +1,424 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.supplier" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="resizable" type="boolean" value="false"/> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-57,0,0,2,116"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleName" type="java.lang.String" value=""/> + </AccessibilityProperties> + <AuxValues> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,26,0,0,4,11"/> + </AuxValues> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLblEmail" alignment="0" max="-2" attributes="1"/> + <Component id="jLblTelephone1" alignment="0" max="-2" attributes="1"/> + <Component id="jLblTelephone2" alignment="1" max="-2" attributes="1"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="txtPhone" max="-2" attributes="2"/> + <Component id="txtEmail" max="-2" attributes="2"/> + <Component id="txtPhone2" max="-2" attributes="1"/> + </Group> + </Group> + <Group type="103" alignment="0" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLblFirstName" max="-2" attributes="1"/> + <Component id="jLblLastName" alignment="1" max="-2" attributes="1"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="txtLastName" max="-2" attributes="2"/> + <Component id="txtFirstName" max="-2" attributes="1"/> + </Group> + </Group> + <Group type="103" alignment="0" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLblTaxID" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jTaxID" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="24" max="-2" attributes="0"/> + <Component id="jLblSearchkey" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jSearchkey" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLblName" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jName" max="32767" attributes="0"/> + </Group> + </Group> + </Group> + </Group> + <EmptySpace pref="34" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace max="32767" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" alignment="0" groupAlignment="3" attributes="0"> + <Component id="jLblSearchkey" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jSearchkey" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="103" alignment="0" groupAlignment="3" attributes="0"> + <Component id="m_jTaxID" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLblTaxID" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLblName" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="txtFirstName" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLblFirstName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLblLastName" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtLastName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLblEmail" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtEmail" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLblTelephone1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtPhone" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLblTelephone2" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtPhone2" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLblTaxID"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.taxid" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jTaxID"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="CustomersView_m_jTaxID"/> + </AuxValues> + </Component> + <Component class="javax.swing.JLabel" name="jLblSearchkey"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.searchkeym" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[82, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jSearchkey"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor"> + <Color id="Text Cursor"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.supplier" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 25]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[400, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblFirstName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.firstname" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="alignmentX" type="float" value="0.5"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtFirstName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblLastName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.lastname" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtLastName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblEmail"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.email" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtEmail"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblTelephone1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.phone" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtPhone"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblTelephone2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.phone2" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtPhone2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="2"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="m_jBtnOK"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="Button.OK" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jBtnOKActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="m_jBtnCancel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="Button.Cancel" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jBtnCancelActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/suppliers/JDialogNewSupplier.java b/src/main/java/com/unicenta/pos/suppliers/JDialogNewSupplier.java new file mode 100644 index 0000000..fb7eef8 --- /dev/null +++ b/src/main/java/com/unicenta/pos/suppliers/JDialogNewSupplier.java @@ -0,0 +1,399 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +package com.unicenta.pos.suppliers; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.loader.LocalRes; +import com.unicenta.data.loader.TableDefinition; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.Window; +import java.util.UUID; +import javax.swing.JFrame; + +public class JDialogNewSupplier extends javax.swing.JDialog { + + private DataLogicSuppliers dlSupplier; + private DataLogicSales dlSales; + private TableDefinition tsuppliers; + private SupplierInfoExt selectedSupplier; + private Object m_oId; + + /** Creates new form quick New Supplier + * @param parent */ + protected JDialogNewSupplier(java.awt.Frame parent) { + super(parent, true); + } + + /** Creates new form quick New Supplier + * @param parent */ + protected JDialogNewSupplier(java.awt.Dialog parent) { + super(parent, true); + } + + private void init(AppView app) { + + dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + dlSupplier = (DataLogicSuppliers) app.getBean("com.unicenta.pos.suppliers.DataLogicSuppliers"); + tsuppliers = dlSupplier.getTableSuppliers(); + + initComponents(); + + getRootPane().setDefaultButton(m_jBtnOK); + + } + + public Object createValue() throws BasicException { + Object[] supplier = new Object[22]; + supplier[0] = m_oId; + supplier[1] = m_jSearchkey.getText(); + supplier[2] = m_jTaxID.getText(); + supplier[3] = m_jName.getText(); + supplier[4] = 0.0; + supplier[5] = null; + supplier[6] = null; + supplier[7] = null; + supplier[8] = null; + supplier[9] = null; + supplier[10] = null; + supplier[11] = Formats.STRING.parseValue(txtFirstName.getText()); + supplier[12] = Formats.STRING.parseValue(txtLastName.getText()); + supplier[13] = Formats.STRING.parseValue(txtEmail.getText()); + supplier[14] = Formats.STRING.parseValue(txtPhone.getText()); + supplier[15] = Formats.STRING.parseValue(txtPhone2.getText()); + supplier[16] = null; + supplier[17] = null; + supplier[18] = true; + supplier[19] = null; + supplier[20] = 0.0; + supplier[21] = null; + + return supplier; + } + + + public static JDialogNewSupplier getDialog(Component parent,AppView app) { + + Window window = getWindow(parent); + + JDialogNewSupplier quicknewsupplier; + + if (window instanceof Frame) { + quicknewsupplier = new JDialogNewSupplier((Frame) window); + } else { + quicknewsupplier = new JDialogNewSupplier((Dialog) window); + } + + quicknewsupplier.init(app); + + return quicknewsupplier; + } + + protected static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window)parent; + } else { + return getWindow(parent.getParent()); + } + } + + public SupplierInfoExt getSelectedSupplier() { + return selectedSupplier; + } + + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel3 = new javax.swing.JPanel(); + jLblTaxID = new javax.swing.JLabel(); + m_jTaxID = new javax.swing.JTextField(); + jLblSearchkey = new javax.swing.JLabel(); + m_jSearchkey = new javax.swing.JTextField(); + jLblName = new javax.swing.JLabel(); + m_jName = new javax.swing.JTextField(); + jLblFirstName = new javax.swing.JLabel(); + txtFirstName = new javax.swing.JTextField(); + jLblLastName = new javax.swing.JLabel(); + txtLastName = new javax.swing.JTextField(); + jLblEmail = new javax.swing.JLabel(); + txtEmail = new javax.swing.JTextField(); + jLblTelephone1 = new javax.swing.JLabel(); + txtPhone = new javax.swing.JTextField(); + jLblTelephone2 = new javax.swing.JLabel(); + txtPhone2 = new javax.swing.JTextField(); + jPanel2 = new javax.swing.JPanel(); + m_jBtnOK = new javax.swing.JButton(); + m_jBtnCancel = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(AppLocal.getIntString("label.supplier")); // NOI18N + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + setResizable(false); + + jPanel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + + jLblTaxID.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblTaxID.setText(AppLocal.getIntString("label.taxid")); // NOI18N + jLblTaxID.setMaximumSize(new java.awt.Dimension(150, 30)); + jLblTaxID.setMinimumSize(new java.awt.Dimension(140, 25)); + jLblTaxID.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jTaxID.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jTaxID.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLblSearchkey.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblSearchkey.setText(AppLocal.getIntString("label.searchkeym")); // NOI18N + jLblSearchkey.setPreferredSize(new java.awt.Dimension(82, 30)); + + m_jSearchkey.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSearchkey.setHorizontalAlignment(javax.swing.JTextField.LEFT); + m_jSearchkey.setCursor(new java.awt.Cursor(java.awt.Cursor.TEXT_CURSOR)); + m_jSearchkey.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLblName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblName.setText(AppLocal.getIntString("label.supplier")); // NOI18N + jLblName.setMaximumSize(new java.awt.Dimension(140, 25)); + jLblName.setMinimumSize(new java.awt.Dimension(140, 25)); + jLblName.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(400, 30)); + + jLblFirstName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblFirstName.setText(AppLocal.getIntString("label.firstname")); // NOI18N + jLblFirstName.setAlignmentX(0.5F); + jLblFirstName.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtFirstName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtFirstName.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLblLastName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblLastName.setText(AppLocal.getIntString("label.lastname")); // NOI18N + jLblLastName.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtLastName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtLastName.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLblEmail.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblEmail.setText(AppLocal.getIntString("label.email")); // NOI18N + jLblEmail.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtEmail.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtEmail.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLblTelephone1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblTelephone1.setText(AppLocal.getIntString("label.phone")); // NOI18N + jLblTelephone1.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtPhone.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtPhone.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLblTelephone2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblTelephone2.setText(AppLocal.getIntString("label.phone2")); // NOI18N + jLblTelephone2.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtPhone2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtPhone2.setPreferredSize(new java.awt.Dimension(200, 30)); + + javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); + jPanel3.setLayout(jPanel3Layout); + jPanel3Layout.setHorizontalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(jPanel3Layout.createSequentialGroup() + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLblEmail, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblTelephone1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblTelephone2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(txtPhone, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtEmail, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtPhone2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLblFirstName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblLastName, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(txtLastName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtFirstName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addComponent(jLblTaxID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jTaxID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(24, 24, 24) + .addComponent(jLblSearchkey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jSearchkey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel3Layout.createSequentialGroup() + .addComponent(jLblName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))) + .addContainerGap(34, Short.MAX_VALUE)) + ); + jPanel3Layout.setVerticalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLblSearchkey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jSearchkey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jTaxID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblTaxID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLblName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(txtFirstName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblFirstName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLblLastName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtLastName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLblEmail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtEmail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLblTelephone1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtPhone, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLblTelephone2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtPhone2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + ); + + getContentPane().add(jPanel3, java.awt.BorderLayout.NORTH); + jPanel3.getAccessibleContext().setAccessibleName(""); + + jPanel2.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT)); + + m_jBtnOK.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jBtnOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + m_jBtnOK.setText(AppLocal.getIntString("Button.OK")); // NOI18N + m_jBtnOK.setFocusPainted(false); + m_jBtnOK.setFocusable(false); + m_jBtnOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jBtnOK.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jBtnOK.setRequestFocusEnabled(false); + m_jBtnOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jBtnOKActionPerformed(evt); + } + }); + jPanel2.add(m_jBtnOK); + + m_jBtnCancel.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jBtnCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + m_jBtnCancel.setText(AppLocal.getIntString("Button.Cancel")); // NOI18N + m_jBtnCancel.setFocusPainted(false); + m_jBtnCancel.setFocusable(false); + m_jBtnCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + m_jBtnCancel.setPreferredSize(new java.awt.Dimension(80, 45)); + m_jBtnCancel.setRequestFocusEnabled(false); + m_jBtnCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jBtnCancelActionPerformed(evt); + } + }); + jPanel2.add(m_jBtnCancel); + + getContentPane().add(jPanel2, java.awt.BorderLayout.SOUTH); + + setSize(new java.awt.Dimension(628, 455)); + setLocationRelativeTo(null); + }// </editor-fold>//GEN-END:initComponents + + private void m_jBtnOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jBtnOKActionPerformed + try { + m_oId = UUID.randomUUID().toString(); + Object supplier = createValue() ; + int status = tsuppliers.getInsertSentence().exec(supplier); + if (status>0){ + selectedSupplier = dlSales.loadSupplierExt(m_oId.toString()); + dispose(); + }else{ + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, + LocalRes.getIntString("message.nosave"), "Error save"); + msg.show(this); + } + } catch (BasicException ex) { + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE, + LocalRes.getIntString("message.nosave"), ex); + msg.show(this); + } + + }//GEN-LAST:event_m_jBtnOKActionPerformed + + private void m_jBtnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jBtnCancelActionPerformed + + dispose(); + + }//GEN-LAST:event_m_jBtnCancelActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLblEmail; + private javax.swing.JLabel jLblFirstName; + private javax.swing.JLabel jLblLastName; + private javax.swing.JLabel jLblName; + private javax.swing.JLabel jLblSearchkey; + private javax.swing.JLabel jLblTaxID; + private javax.swing.JLabel jLblTelephone1; + private javax.swing.JLabel jLblTelephone2; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JButton m_jBtnCancel; + private javax.swing.JButton m_jBtnOK; + private javax.swing.JTextField m_jName; + private javax.swing.JTextField m_jSearchkey; + private javax.swing.JTextField m_jTaxID; + private javax.swing.JTextField txtEmail; + private javax.swing.JTextField txtFirstName; + private javax.swing.JTextField txtLastName; + private javax.swing.JTextField txtPhone; + private javax.swing.JTextField txtPhone2; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/suppliers/JSupplierFinder.form b/src/main/java/com/unicenta/pos/suppliers/JSupplierFinder.form new file mode 100644 index 0000000..bbbf0ce --- /dev/null +++ b/src/main/java/com/unicenta/pos/suppliers/JSupplierFinder.form @@ -0,0 +1,545 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.5" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="form.customertitle" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor"> + <Color id="Default Cursor"/> + </Property> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,122,0,0,2,-10"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Properties> + <Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor"> + <Color id="Default Cursor"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="After"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Component class="com.unicenta.editor.JEditorKeys" name="m_jKeys"> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="JCustomerFinder_m_jKeys"/> + </AuxValues> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + </Component> + <Container class="javax.swing.JPanel" name="jPanel8"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Last"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="After"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JButton" name="jcmdCancel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.Cancel" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jcmdCancelActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jcmdOK"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.OK" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[103, 44]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[103, 44]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jcmdOKActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Component class="com.unicenta.data.gui.JImageViewerCustomer" name="jImageViewerSupplier"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[450, 0]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="First"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel7"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLblName" min="-2" max="-2" attributes="0"/> + <Component id="jLblSearchKey" min="-2" max="-2" attributes="0"/> + <Component id="jLblPostal" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jtxtSearchKey" min="-2" max="-2" attributes="0"/> + <Component id="m_jtxtPostal" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="m_jtxtName" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLblTaxID" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jtxtTaxID" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="1" max="-2" attributes="0"> + <Component id="jLblEmail" max="-2" attributes="0"/> + <Component id="jLblPhone" alignment="0" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jtxtPhone" min="-2" max="-2" attributes="0"/> + <Component id="m_jtxtName2" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jtxtTaxID" min="-2" max="-2" attributes="0"/> + <Component id="jLblTaxID" alignment="1" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jtxtSearchKey" min="-2" max="-2" attributes="0"/> + <Component id="jLblSearchKey" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLblPostal" min="-2" max="-2" attributes="0"/> + <Component id="m_jtxtPostal" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jtxtName" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="jLblName" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jtxtPhone" min="-2" max="-2" attributes="0"/> + <Component id="jLblPhone" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLblEmail" min="-2" max="-2" attributes="0"/> + <Component id="m_jtxtName2" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLblTaxID"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.taxid" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 15]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 15]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jtxtTaxID"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblSearchKey"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.searchkey" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 15]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 15]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jtxtSearchKey"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblPostal"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" value="Postal"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 15]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 15]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="JCustomerFinder_jLblPostal"/> + </AuxValues> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jtxtPostal"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="JCustomerFinder_m_jtxtPostal"/> + </AuxValues> + </Component> + <Component class="javax.swing.JLabel" name="jLblName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodname" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 15]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 15]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jtxtName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleName" type="java.lang.String" value=""/> + </AccessibilityProperties> + </Component> + <Component class="javax.swing.JLabel" name="jLblPhone"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.companytelephone" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLblEmail"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.companyemail" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jtxtPhone"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jtxtName2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[450, 140]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JScrollPane" name="jScrollPane1"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[400, 147]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JList" name="jListSuppliers"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="focusable" type="boolean" value="false"/> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="jListSuppliersMouseClicked"/> + <EventHandler event="valueChanged" listener="javax.swing.event.ListSelectionListener" parameters="javax.swing.event.ListSelectionEvent" handler="jListSuppliersValueChanged"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel6"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="First"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JButton" name="jbtnReset"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/reload.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.reset" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Clear Filter"/> + <Property name="actionCommand" type="java.lang.String" value="Reset "/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" value=""/> + </AccessibilityProperties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnResetActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jbtnExecute"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.executefilter" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Execute Filter"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 45]"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" value=""/> + </AccessibilityProperties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnExecuteActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/suppliers/JSupplierFinder.java b/src/main/java/com/unicenta/pos/suppliers/JSupplierFinder.java new file mode 100644 index 0000000..2a2cffc --- /dev/null +++ b/src/main/java/com/unicenta/pos/suppliers/JSupplierFinder.java @@ -0,0 +1,692 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.suppliers; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.QBFCompareEnum; +import com.unicenta.data.user.EditorCreator; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import java.awt.*; +import java.util.ArrayList; +import javax.swing.JFrame; +import javax.swing.*; + +import java.awt.event.KeyEvent; + +/** + * + * @author adrianromero + */ +public class JSupplierFinder extends javax.swing.JDialog implements EditorCreator { + + private SupplierInfo m_ReturnSupplier; + private ListProvider lpr; + private AppView appView; + + public class Global { + + } + + public void searchKey() { + jbtnExecute.setMnemonic(KeyEvent.VK_E); + executeSearch(); + + + } + + public void resetKey() { + jbtnReset.setMnemonic(KeyEvent.VK_R); + m_jtxtTaxID.reset(); + m_jtxtSearchKey.reset(); + m_jtxtName.reset(); + m_jtxtPostal.reset(); + m_jtxtPhone.reset(); + m_jtxtName2.reset(); + + m_jtxtTaxID.activate(); + + cleanSearch(); + + } + + public void setAppView(AppView appView) { + this.appView = appView; + } + + /** Creates new form JSupplierFinder */ + private JSupplierFinder(java.awt.Frame parent, boolean modal) { + super(parent, modal); + } + + /** + * Creates new form JSupplierFinder + */ + private JSupplierFinder(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + } + + /** + * + * @param parent + * @param dlSuppliers + * @return + */ + public static JSupplierFinder getSupplierFinder(Component parent, DataLogicSuppliers dlSuppliers) { + Window window = getWindow(parent); + + JSupplierFinder myMsg; + if (window instanceof Frame) { + myMsg = new JSupplierFinder((Frame) window, true); + } else { + myMsg = new JSupplierFinder((Dialog) window, true); + } + myMsg.init(dlSuppliers); + myMsg.applyComponentOrientation(parent.getComponentOrientation()); + + return myMsg; + } + + /** + * + * @return + */ + public SupplierInfo getSelectedSupplier() { + return m_ReturnSupplier; + } + + private void init(DataLogicSuppliers dlSuppliers) { + + initComponents(); + + jImageViewerSupplier.setVisible(false); + + jScrollPane1.getVerticalScrollBar().setPreferredSize(new Dimension(35, 35)); + + m_jtxtTaxID.addEditorKeys(m_jKeys); + m_jtxtSearchKey.addEditorKeys(m_jKeys); + m_jtxtName.addEditorKeys(m_jKeys); + m_jtxtPostal.addEditorKeys(m_jKeys); + m_jtxtPhone.addEditorKeys(m_jKeys); + m_jtxtName2.addEditorKeys(m_jKeys); + + m_jtxtTaxID.reset(); + m_jtxtSearchKey.reset(); + m_jtxtName.reset(); + m_jtxtPostal.reset(); + m_jtxtPhone.reset(); + m_jtxtName2.reset(); + + m_jtxtTaxID.activate(); + + lpr = new ListProviderCreator(dlSuppliers.getSupplierList(), this); + + jListSuppliers.setCellRenderer(new SupplierRenderer()); + + getRootPane().setDefaultButton(jcmdOK); + + m_ReturnSupplier = null; +// m_jKeys.setSupplierFinder(this); + + } + + /** + * + * @param supplier + */ + public void search(SupplierInfo supplier) { + + if (supplier == null || supplier.getName() == null || supplier.getName().equals("")) { + + m_jtxtTaxID.reset(); + m_jtxtSearchKey.reset(); + m_jtxtName.reset(); + m_jtxtPostal.reset(); + m_jtxtPhone.reset(); + m_jtxtName2.reset(); + + m_jtxtTaxID.activate(); + + cleanSearch(); + } else { + + m_jtxtTaxID.setText(supplier.getTaxid()); + m_jtxtSearchKey.setText(supplier.getSearchkey()); + m_jtxtName.setText(supplier.getName()); + m_jtxtPostal.setText(supplier.getPostal()); + m_jtxtPhone.setText(supplier.getPhone()); + m_jtxtName2.setText(supplier.getEmail()); + + m_jtxtTaxID.activate(); + + executeSearch(); + } + } + + private void cleanSearch() { + m_jtxtTaxID.setText(""); + m_jtxtSearchKey.setText(""); + m_jtxtName.setText(""); + m_jtxtPostal.setText(""); + m_jtxtPhone.setText(""); + m_jtxtName2.setText(""); + + jListSuppliers.setModel(new MyListData(new ArrayList())); + } + + /** + * This method actions the Supplier data search + */ + public void executeSearch() { + + try { + jListSuppliers.setModel(new MyListData(lpr.loadData())); + if (jListSuppliers.getModel().getSize() > 0) { + jListSuppliers.setSelectedIndex(0); + } else { + if(!m_jtxtName.getText().equals("")) { + + int n = JOptionPane.showConfirmDialog( + null, + AppLocal.getIntString("message.suppliernotfound"), + AppLocal.getIntString("title.editor"), + JOptionPane.YES_NO_OPTION); + + if (n != 1) { + SupplierInfoGlobal supplierInfoGlobal = SupplierInfoGlobal.getInstance(); + SupplierInfoExt supplierInfoExt = supplierInfoGlobal.getSupplierInfoExt(); + this.setVisible(false); + appView.getAppUserView().showTask("com.unicenta.pos.suppliers.SuppliersPanel"); + JOptionPane.showMessageDialog(null, + "You must complete Account and Search Key Then Save to add to Ticket", + "Create Supplier",JOptionPane.OK_OPTION); + } + } + } + } catch (BasicException e) { + } + } + + /** + * + * @return creates object for search method + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + Object[] afilter = new Object[12]; + + // TaxID + if (m_jtxtTaxID.getText() == null || m_jtxtTaxID.getText().equals("")) { + afilter[0] = QBFCompareEnum.COMP_NONE; + afilter[1] = null; + } else { + afilter[0] = QBFCompareEnum.COMP_RE; + afilter[1] = "%" + m_jtxtTaxID.getText() + "%"; + } + + // SearchKey + if (m_jtxtSearchKey.getText() == null || m_jtxtSearchKey.getText().equals("")) { + afilter[2] = QBFCompareEnum.COMP_NONE; + afilter[3] = null; + } else { + afilter[2] = QBFCompareEnum.COMP_RE; + afilter[3] = "%" + m_jtxtSearchKey.getText() + "%"; + } + + // Name + if (m_jtxtName.getText() == null || m_jtxtName.getText().equals("")) { + afilter[4] = QBFCompareEnum.COMP_NONE; + afilter[5] = null; + } else { + afilter[4] = QBFCompareEnum.COMP_RE; + afilter[5] = "%" + m_jtxtName.getText() + "%"; + } + + // Postal + if (m_jtxtPostal.getText() == null || m_jtxtPostal.getText().equals("")) { + afilter[6] = QBFCompareEnum.COMP_NONE; + afilter[7] = null; + } else { + afilter[6] = QBFCompareEnum.COMP_RE; + afilter[7] = "%" + m_jtxtPostal.getText() + "%"; + } + + // Phone + if (m_jtxtPhone.getText() == null || m_jtxtPhone.getText().equals("")) { + afilter[8] = QBFCompareEnum.COMP_NONE; + afilter[9] = null; + } else { + afilter[8] = QBFCompareEnum.COMP_RE; + afilter[9] = "%" + m_jtxtPhone.getText() + "%"; + } + + // Email + if (m_jtxtName2.getText() == null || m_jtxtName2.getText().equals("")) { + afilter[10] = QBFCompareEnum.COMP_NONE; + afilter[11] = null; + } else { + afilter[10] = QBFCompareEnum.COMP_RE; + afilter[11] = "%" + m_jtxtName2.getText() + "%"; + } + + return afilter; + } + + private static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window) parent; + } else { + return getWindow(parent.getParent()); + } + } + + private static class MyListData extends javax.swing.AbstractListModel { + + private final java.util.List m_data; + + public MyListData(java.util.List data) { + m_data = data; + } + + @Override + public Object getElementAt(int index) { + return m_data.get(index); + } + + @Override + public int getSize() { + return m_data.size(); + } + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel2 = new javax.swing.JPanel(); + m_jKeys = new com.unicenta.editor.JEditorKeys(); + jPanel8 = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + jcmdCancel = new javax.swing.JButton(); + jcmdOK = new javax.swing.JButton(); + jImageViewerSupplier = new com.unicenta.data.gui.JImageViewerCustomer(); + jPanel3 = new javax.swing.JPanel(); + jPanel5 = new javax.swing.JPanel(); + jPanel7 = new javax.swing.JPanel(); + jLblTaxID = new javax.swing.JLabel(); + m_jtxtTaxID = new com.unicenta.editor.JEditorString(); + jLblSearchKey = new javax.swing.JLabel(); + m_jtxtSearchKey = new com.unicenta.editor.JEditorString(); + jLblPostal = new javax.swing.JLabel(); + m_jtxtPostal = new com.unicenta.editor.JEditorString(); + jLblName = new javax.swing.JLabel(); + m_jtxtName = new com.unicenta.editor.JEditorString(); + jLblPhone = new javax.swing.JLabel(); + jLblEmail = new javax.swing.JLabel(); + m_jtxtPhone = new com.unicenta.editor.JEditorString(); + m_jtxtName2 = new com.unicenta.editor.JEditorString(); + jPanel4 = new javax.swing.JPanel(); + jScrollPane1 = new javax.swing.JScrollPane(); + jListSuppliers = new javax.swing.JList(); + jPanel6 = new javax.swing.JPanel(); + jbtnReset = new javax.swing.JButton(); + jbtnExecute = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(AppLocal.getIntString("form.customertitle")); // NOI18N + setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + + jPanel2.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + jPanel2.setLayout(new java.awt.BorderLayout()); + jPanel2.add(m_jKeys, java.awt.BorderLayout.NORTH); + + jPanel8.setLayout(new java.awt.BorderLayout()); + + jcmdCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + jcmdCancel.setText(AppLocal.getIntString("button.Cancel")); // NOI18N + jcmdCancel.setFocusPainted(false); + jcmdCancel.setFocusable(false); + jcmdCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdCancel.setPreferredSize(new java.awt.Dimension(110, 45)); + jcmdCancel.setRequestFocusEnabled(false); + jcmdCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdCancelActionPerformed(evt); + } + }); + jPanel1.add(jcmdCancel); + + jcmdOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jcmdOK.setText(AppLocal.getIntString("button.OK")); // NOI18N + jcmdOK.setEnabled(false); + jcmdOK.setFocusPainted(false); + jcmdOK.setFocusable(false); + jcmdOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdOK.setMaximumSize(new java.awt.Dimension(103, 44)); + jcmdOK.setMinimumSize(new java.awt.Dimension(103, 44)); + jcmdOK.setPreferredSize(new java.awt.Dimension(110, 45)); + jcmdOK.setRequestFocusEnabled(false); + jcmdOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdOKActionPerformed(evt); + } + }); + jPanel1.add(jcmdOK); + + jPanel8.add(jPanel1, java.awt.BorderLayout.LINE_END); + + jPanel2.add(jPanel8, java.awt.BorderLayout.PAGE_END); + jPanel2.add(jImageViewerSupplier, java.awt.BorderLayout.CENTER); + + getContentPane().add(jPanel2, java.awt.BorderLayout.LINE_END); + + jPanel3.setPreferredSize(new java.awt.Dimension(450, 0)); + jPanel3.setLayout(new java.awt.BorderLayout()); + + jPanel5.setLayout(new java.awt.BorderLayout()); + + jLblTaxID.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblTaxID.setText(AppLocal.getIntString("label.taxid")); // NOI18N + jLblTaxID.setMaximumSize(new java.awt.Dimension(60, 15)); + jLblTaxID.setMinimumSize(new java.awt.Dimension(60, 15)); + jLblTaxID.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jtxtTaxID.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jtxtTaxID.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLblSearchKey.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblSearchKey.setText(AppLocal.getIntString("label.searchkey")); // NOI18N + jLblSearchKey.setMaximumSize(new java.awt.Dimension(60, 15)); + jLblSearchKey.setMinimumSize(new java.awt.Dimension(60, 15)); + jLblSearchKey.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jtxtSearchKey.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jtxtSearchKey.setPreferredSize(new java.awt.Dimension(250, 30)); + + jLblPostal.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblPostal.setText("Postal"); + jLblPostal.setMaximumSize(new java.awt.Dimension(60, 15)); + jLblPostal.setMinimumSize(new java.awt.Dimension(60, 15)); + jLblPostal.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jtxtPostal.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jtxtPostal.setPreferredSize(new java.awt.Dimension(250, 30)); + + jLblName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblName.setText(AppLocal.getIntString("label.prodname")); // NOI18N + jLblName.setMaximumSize(new java.awt.Dimension(60, 15)); + jLblName.setMinimumSize(new java.awt.Dimension(60, 15)); + jLblName.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jtxtName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jtxtName.setPreferredSize(new java.awt.Dimension(250, 30)); + + jLblPhone.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jLblPhone.setText(bundle.getString("label.companytelephone")); // NOI18N + jLblPhone.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLblEmail.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblEmail.setText(bundle.getString("label.companyemail")); // NOI18N + jLblEmail.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jtxtPhone.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jtxtPhone.setMinimumSize(new java.awt.Dimension(150, 30)); + m_jtxtPhone.setPreferredSize(new java.awt.Dimension(250, 30)); + + m_jtxtName2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jtxtName2.setMinimumSize(new java.awt.Dimension(150, 30)); + m_jtxtName2.setPreferredSize(new java.awt.Dimension(250, 30)); + + javax.swing.GroupLayout jPanel7Layout = new javax.swing.GroupLayout(jPanel7); + jPanel7.setLayout(jPanel7Layout); + jPanel7Layout.setHorizontalGroup( + jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel7Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel7Layout.createSequentialGroup() + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLblName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblSearchKey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblPostal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jtxtSearchKey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jtxtPostal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jtxtName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanel7Layout.createSequentialGroup() + .addComponent(jLblTaxID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jtxtTaxID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel7Layout.createSequentialGroup() + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(jLblEmail, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblPhone, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jtxtPhone, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jtxtName2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addContainerGap()) + ); + jPanel7Layout.setVerticalGroup( + jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel7Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jtxtTaxID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblTaxID, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jtxtSearchKey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblSearchKey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(jPanel7Layout.createSequentialGroup() + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLblPostal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jtxtPostal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jtxtName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jLblName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jtxtPhone, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblPhone, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLblEmail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jtxtName2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + + m_jtxtName.getAccessibleContext().setAccessibleName(""); + + jPanel5.add(jPanel7, java.awt.BorderLayout.CENTER); + + jPanel3.add(jPanel5, java.awt.BorderLayout.PAGE_START); + + jPanel4.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel4.setPreferredSize(new java.awt.Dimension(450, 140)); + jPanel4.setLayout(new java.awt.BorderLayout()); + + jScrollPane1.setPreferredSize(new java.awt.Dimension(400, 147)); + + jListSuppliers.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jListSuppliers.setFocusable(false); + jListSuppliers.setRequestFocusEnabled(false); + jListSuppliers.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + jListSuppliersMouseClicked(evt); + } + }); + jListSuppliers.addListSelectionListener(new javax.swing.event.ListSelectionListener() { + public void valueChanged(javax.swing.event.ListSelectionEvent evt) { + jListSuppliersValueChanged(evt); + } + }); + jScrollPane1.setViewportView(jListSuppliers); + + jPanel4.add(jScrollPane1, java.awt.BorderLayout.CENTER); + + jbtnReset.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnReset.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reload.png"))); // NOI18N + jbtnReset.setText(bundle.getString("button.reset")); // NOI18N + jbtnReset.setToolTipText("Clear Filter"); + jbtnReset.setActionCommand("Reset "); + jbtnReset.setFocusable(false); + jbtnReset.setPreferredSize(new java.awt.Dimension(110, 45)); + jbtnReset.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnResetActionPerformed(evt); + } + }); + jPanel6.add(jbtnReset); + jbtnReset.getAccessibleContext().setAccessibleDescription(""); + + jbtnExecute.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnExecute.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jbtnExecute.setText(AppLocal.getIntString("button.executefilter")); // NOI18N + jbtnExecute.setToolTipText("Execute Filter"); + jbtnExecute.setFocusPainted(false); + jbtnExecute.setPreferredSize(new java.awt.Dimension(110, 45)); + jbtnExecute.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnExecuteActionPerformed(evt); + } + }); + jPanel6.add(jbtnExecute); + jbtnExecute.getAccessibleContext().setAccessibleDescription(""); + + jPanel4.add(jPanel6, java.awt.BorderLayout.PAGE_START); + + jPanel3.add(jPanel4, java.awt.BorderLayout.CENTER); + + getContentPane().add(jPanel3, java.awt.BorderLayout.CENTER); + + setSize(new java.awt.Dimension(758, 634)); + setLocationRelativeTo(null); + }// </editor-fold>//GEN-END:initComponents + private void jcmdOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdOKActionPerformed + + m_ReturnSupplier = (SupplierInfo) jListSuppliers.getSelectedValue(); + dispose(); + + }//GEN-LAST:event_jcmdOKActionPerformed + + private void jcmdCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdCancelActionPerformed + + dispose(); + + }//GEN-LAST:event_jcmdCancelActionPerformed + + private void jbtnExecuteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnExecuteActionPerformed + + m_ReturnSupplier=null; + executeSearch(); + + }//GEN-LAST:event_jbtnExecuteActionPerformed + + private void jListSuppliersValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_jListSuppliersValueChanged + + m_ReturnSupplier = (SupplierInfo) jListSuppliers.getSelectedValue(); + + if (m_ReturnSupplier != null) { + m_ReturnSupplier = (SupplierInfo) jListSuppliers.getSelectedValue(); + +// if (m_ReturnSupplier != null) { +// jImageViewerSupplier.setImage(m_ReturnSupplier.getImage()); +// } + } + + jcmdOK.setEnabled(jListSuppliers.getSelectedValue() != null); + + }//GEN-LAST:event_jListSuppliersValueChanged + + private void jListSuppliersMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jListSuppliersMouseClicked + + m_ReturnSupplier = (SupplierInfo) jListSuppliers.getSelectedValue(); + + if (m_ReturnSupplier != null) { + m_ReturnSupplier = (SupplierInfo) jListSuppliers.getSelectedValue(); + +// if (m_ReturnSupplier != null) { +// jImageViewerSupplier.setImage(m_ReturnSupplier.getImage()); +// } + } + + }//GEN-LAST:event_jListSuppliersMouseClicked + +private void jbtnResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnResetActionPerformed + + m_jtxtTaxID.reset(); + m_jtxtSearchKey.reset(); + m_jtxtName.reset(); + m_jtxtPostal.reset(); + m_jtxtPhone.reset(); + m_jtxtName2.reset(); + + m_jtxtTaxID.activate(); + + cleanSearch(); +}//GEN-LAST:event_jbtnResetActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private com.unicenta.data.gui.JImageViewerCustomer jImageViewerSupplier; + private javax.swing.JLabel jLblEmail; + private javax.swing.JLabel jLblName; + private javax.swing.JLabel jLblPhone; + private javax.swing.JLabel jLblPostal; + private javax.swing.JLabel jLblSearchKey; + private javax.swing.JLabel jLblTaxID; + private javax.swing.JList jListSuppliers; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JPanel jPanel6; + private javax.swing.JPanel jPanel7; + private javax.swing.JPanel jPanel8; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JButton jbtnExecute; + private javax.swing.JButton jbtnReset; + private javax.swing.JButton jcmdCancel; + private javax.swing.JButton jcmdOK; + private com.unicenta.editor.JEditorKeys m_jKeys; + private com.unicenta.editor.JEditorString m_jtxtName; + private com.unicenta.editor.JEditorString m_jtxtName2; + private com.unicenta.editor.JEditorString m_jtxtPhone; + private com.unicenta.editor.JEditorString m_jtxtPostal; + private com.unicenta.editor.JEditorString m_jtxtSearchKey; + private com.unicenta.editor.JEditorString m_jtxtTaxID; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/suppliers/OrderSupplierList.form b/src/main/java/com/unicenta/pos/suppliers/OrderSupplierList.form new file mode 100644 index 0000000..391ee3b --- /dev/null +++ b/src/main/java/com/unicenta/pos/suppliers/OrderSupplierList.form @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[256, 560]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[256, 560]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,88,0,0,1,44"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanelSuppliers"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignCardLayout"/> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/suppliers/OrderSupplierList.java b/src/main/java/com/unicenta/pos/suppliers/OrderSupplierList.java new file mode 100644 index 0000000..e57d235 --- /dev/null +++ b/src/main/java/com/unicenta/pos/suppliers/OrderSupplierList.java @@ -0,0 +1,334 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.suppliers; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.pos.catalog.JCatalogTab; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.sales.DataLogicReceipts; +import com.unicenta.pos.sales.SharedTicketInfo; +import com.unicenta.pos.sales.TicketsEditor; +import com.unicenta.pos.ticket.TicketInfo; +import com.unicenta.pos.util.ThumbNailBuilder; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import javax.swing.*; +import javax.swing.event.EventListenerList; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.*; + +/** + * + * @author JG uniCenta - outline/prep for uniCenta mobile + eCommerce connector + */ +@Slf4j +public class OrderSupplierList extends JPanel implements SupplierTicketSelector { + + /** + * Source origin and Ticket + */ + protected AppView application; + private String currentTicket; + + /** + * This instance interface + */ + protected TicketsEditor panelticket; + + /** + * Set listeners for new/change Supplier/Receipt events + */ + protected EventListenerList listeners = new EventListenerList(); + private final DataLogicSuppliers dataLogicSuppliers; + private final DataLogicReceipts dataLogicReceipts; + private final ThumbNailBuilder tnbbutton; + + /** + * Creates new form SuppliersList + * @param dlSuppliers + * @param app + * @param panelticket + */ + public OrderSupplierList(DataLogicSuppliers dlSuppliers, AppView app, TicketsEditor panelticket) { + this.application = app; + this.panelticket = panelticket; + this.dataLogicSuppliers = dlSuppliers; + this.dataLogicReceipts = (DataLogicReceipts) application.getBean("com.unicenta.pos.sales.DataLogicReceipts"); + tnbbutton = new ThumbNailBuilder(90, 98); + + initComponents(); + } + + /** + * + * @return + */ + public Component getComponent() { + return this; + } + + /** + * + * @throws BasicException + */ + public void reloadSuppliers() throws BasicException { +// synchroniseData(); + loadSuppliers(); + } + + /** + * + * @throws BasicException + */ + + public void loadSuppliers() throws BasicException { + + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + + long time = System.currentTimeMillis(); + jPanelSuppliers.removeAll(); + + JCatalogTab flowTab = new JCatalogTab(); + jPanelSuppliers.add(flowTab); + + List<SupplierInfoExt> suppliers = null; + List<SharedTicketInfo> ticketList = null; + try { + log.info("Time of getSuppliersWithOutImage {}", (System.currentTimeMillis() - time)); + + time = System.currentTimeMillis(); + + ticketList = dataLogicReceipts.getSharedTicketList(); + log.info("Time of getSharedTicketList {}", (System.currentTimeMillis() - time)); + time = System.currentTimeMillis(); + + + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + HashMap<SharedTicketInfo, SupplierInfoExt> orderMap = new HashMap<>(); + + for (SharedTicketInfo sharedTicketInfo : ticketList) { + + String ticketName = sharedTicketInfo.getName().trim(); + + if (ticketName.contains("[") && ticketName.contains("]")) { + + // found order + if (ticketName.startsWith("[")) { + orderMap.put(sharedTicketInfo, null); + } else if (!suppliers.isEmpty()) { + for (SupplierInfoExt supplier : suppliers) { + if (supplier != null) { + String name = supplier.getName().trim(); + if (ticketName.startsWith(name)) { + orderMap.put(sharedTicketInfo, supplier); + break; + } + } + } + } + } + } + // sort + SupplierComparator bvc = new SupplierComparator(orderMap); + TreeMap<SharedTicketInfo, SupplierInfoExt> sortedMap = new TreeMap<>(bvc); + sortedMap.putAll(orderMap); + log.info("Time of orderMap {}", (System.currentTimeMillis() - time)); + time = System.currentTimeMillis(); + + // set button list + for (Map.Entry<SharedTicketInfo, SupplierInfoExt> entry : sortedMap.entrySet()) { + SharedTicketInfo ticket = entry.getKey(); + SupplierInfoExt supplier = entry.getValue(); + + String name = ticket.getName(); + BufferedImage image = null; + + if (image == null) { + try { + InputStream is = getClass().getResourceAsStream("/com/unicenta/images/no_image.png"); + if (is != null) { + image = ImageIO.read(is); + } + } catch (IOException ex) { + log.error(ex.getMessage()); + } + } + String username; + if (name.indexOf("[") != 0) { + username = name.substring(0, name.indexOf("[") - 1); + username = username.replace("-", ""); + } else { + username = "unknown"; + } + String orderId = name.substring(name.indexOf("["), name.indexOf("]") + 1); + String text = "<html><center>" + username.trim() + "<br/>" + orderId.trim() + "</center></html>"; + + ImageIcon icon = new ImageIcon(tnbbutton.getThumbNailText(image, text)); +// flowTab.addButton(icon, new SelectedSupplierAction(ticket.getId())); + } + log.info("Time of finished loadSupplierOrders {}", (System.currentTimeMillis() - time)); + } + }); + } + + /** + * + * @param value + */ + + public void setComponentEnabled(boolean value) { + jPanelSuppliers.setEnabled(value); + + synchronized (jPanelSuppliers.getTreeLock()) { + int compCount = jPanelSuppliers.getComponentCount(); + for (int i = 0; i < compCount; i++) { + jPanelSuppliers.getComponent(i).setEnabled(value); + } + } + this.setEnabled(value); + } + + /** + * + * @param l + */ + + public void addActionListener(ActionListener l) { + listeners.add(ActionListener.class, l); + } + + /** + * + * @param l + */ + + public void removeActionListener(ActionListener l) { + listeners.remove(ActionListener.class, l); + } + + private void setActiveTicket(String id) throws BasicException { + + currentTicket = panelticket.getActiveTicket().getId(); + + TicketInfo ticket = dataLogicReceipts.getSharedTicket(id); + if (ticket == null) { + throw new BasicException(AppLocal.getIntString("message.noticket")); + } else { + dataLogicReceipts.deleteSharedTicket(id); + currentTicket = id; + panelticket.setActiveTicket(ticket, null); + fireTicketSelectionChanged(ticket.getId()); + } + } + + private void fireTicketSelectionChanged(String ticketId) { + EventListener[] l = listeners.getListeners(ActionListener.class); + ActionEvent e = null; + for (EventListener l1 : l) { + if (e == null) { + e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, ticketId); + } + ((ActionListener) l1).actionPerformed(e); + } + } + + @Override + public void loadSupplierss() throws BasicException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + private class SelectedSupplierAction implements ActionListener { + + private final String ticketId; + + public SelectedSupplierAction(String ticketId) { + this.ticketId = ticketId; + } + + @Override + public void actionPerformed(ActionEvent e) { + try { + if (ticketId != null) { + setActiveTicket(ticketId); + } + } catch (BasicException ex) { + new MessageInf(ex).show(OrderSupplierList.this); + } + } + } + + class SupplierComparator implements Comparator<SharedTicketInfo> { + + Map<SharedTicketInfo, SupplierInfoExt> base; + + public SupplierComparator(Map<SharedTicketInfo, SupplierInfoExt> base) { + this.base = base; + } + + @Override + public int compare(SharedTicketInfo a, SharedTicketInfo b) { + String nameA = base.get(a).getName(); + String nameB = base.get(b).getName(); + + if (nameA.compareToIgnoreCase(nameB) < 0) { + return -1; + } else { + return 1; + } + } + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanelSuppliers = new javax.swing.JPanel(); + + setMinimumSize(new java.awt.Dimension(256, 560)); + setPreferredSize(new java.awt.Dimension(256, 560)); + setLayout(new java.awt.BorderLayout()); + + jPanelSuppliers.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPanelSuppliers.setLayout(new java.awt.CardLayout()); + add(jPanelSuppliers, java.awt.BorderLayout.CENTER); + }// </editor-fold>//GEN-END:initComponents + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanelSuppliers; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/suppliers/SupplierInfo.java b/src/main/java/com/unicenta/pos/suppliers/SupplierInfo.java new file mode 100644 index 0000000..e44caaa --- /dev/null +++ b/src/main/java/com/unicenta/pos/suppliers/SupplierInfo.java @@ -0,0 +1,178 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.suppliers; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.IKeyed; +import com.unicenta.pos.util.StringUtils; +import java.io.Serializable; + +/** @author Jack Gerrard */ + + +public class SupplierInfo implements Serializable, IKeyed { + + private static final long serialVersionUID = 9093257536541L; + + protected String m_sID; + protected String m_sSearchkey; + protected String m_sTaxid; + protected String m_sName; + protected String m_sPostal; + protected String m_sPhone; + protected String m_sEmail; + + /** Creates a new instance of SupplierInfo + * @param id */ + public SupplierInfo(String id) { + + m_sID = id; + m_sSearchkey = null; + m_sTaxid = null; + m_sName = null; + m_sPostal = null; + m_sPhone = null; + m_sEmail = null; + } + + public SupplierInfo(String id, String searchkey, String name) { + m_sID = id; + m_sSearchkey = searchkey; + m_sName = name; + } + + /** + * + * @return + */ + @Override + public Object getKey() { + return m_sID; + } + + /** + * + * @param dr + * @throws BasicException + */ + public void readValues(DataRead dr) throws BasicException { + m_sID = dr.getString(1); + m_sName = dr.getString(2); + } + + /** + * + * @return id string + */ + public String getID() { + return m_sID; + } + public void setID(String sID) { + m_sID = sID; + } + + + /** + * + * @return taxid string + */ + + public String getTaxid() { + return m_sTaxid; + } + public void setTaxid(String sTaxid) { + m_sTaxid = sTaxid; + } + public String printTaxid() { + return StringUtils.encodeXML(m_sTaxid); + } + + + /** + * + * @return searchkey string + */ + public String getSearchkey() { + return m_sSearchkey; + } + public void setSearchkey(String sSearchkey) { + m_sSearchkey = sSearchkey; + } + + /** + * + * @return name string + */ + public String getName() { + return m_sName; + } + public void setName(String sName) { + m_sName = sName; + } + + /** + * + * @return postal/zip code string + */ + public String getPostal() { + return m_sPostal; + } + public void setPostal(String sPostal) { + m_sPostal = sPostal; + } + + /** + * + * @return Primary Telephone string + */ + public String getPhone() { + return m_sPhone; + } + public void setPhone(String sPhone) { + m_sPhone = sPhone; + } + + /** + * + * @return email string + */ + public String getEmail() { + return m_sEmail; + } + + public void setEmail(String sEmail) { + m_sEmail = sEmail; + } + + /** + * + * @return + */ + public String printName() { + return StringUtils.encodeXML(m_sName); + } + + @Override + public String toString() { + return getName(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/suppliers/SupplierInfoExt.java b/src/main/java/com/unicenta/pos/suppliers/SupplierInfoExt.java new file mode 100644 index 0000000..65b5b7c --- /dev/null +++ b/src/main/java/com/unicenta/pos/suppliers/SupplierInfoExt.java @@ -0,0 +1,272 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.suppliers; + +import com.unicenta.format.Formats; +import com.unicenta.pos.util.RoundUtils; +import java.util.Date; + +/** + * + * @author JG uniCenta + */ +public class SupplierInfoExt extends SupplierInfo { + + protected String suppliertaxid; + protected String suppliervatid; + protected String notes; + protected boolean visible; + protected String card; + protected Double maxdebt; + protected Date curdate; + protected Double curdebt; + protected String firstname; + protected String lastname; + protected String email; + protected String phone; + protected String phone2; + protected String fax; + protected String address; + protected String address2; + protected String postal; + protected String city; + protected String region; + protected String country; + + /** Creates a new instance of SupplierInfoExt + * @param id */ + public SupplierInfoExt(String id) { + super(id); + } + + public String getSupplierTaxID() { + return suppliertaxid; + } + public void setSupplierTAXID(String suppliertaxid) { + this.suppliertaxid = suppliertaxid; + } + public String printSupplierTaxID() { + return Formats.STRING.formatValue(suppliertaxid); + } + + public String getSupplierVATID() { + return suppliervatid; + } + public void setSupplierVATID(String suppliervatid) { + this.suppliervatid = suppliervatid; + } + public String printSupplierVATID() { + return Formats.STRING.formatValue(suppliervatid); + } + + public String getNotes() { + return notes; + } + public void setNotes(String notes) { + this.notes = notes; + } + + public boolean isVisible() { + return visible; + } + public void setVisible(boolean visible) { + this.visible = visible; + } + + public Double getMaxdebt() { + return maxdebt; + } + public void setMaxdebt(Double maxdebt) { + this.maxdebt = maxdebt; + } + public String printMaxDebt() { + return Formats.CURRENCY.formatValue(RoundUtils.getValue(getMaxdebt())); + } + + public Date getCurdate() { + return curdate; + } + public void setCurdate(Date curdate) { + this.curdate = curdate; + } + public String printCurDate() { + return Formats.DATE.formatValue(getCurdate()); + } + + public Double getCurdebt() { + return curdebt; + } + public void setCurdebt(Double curdebt) { + this.curdebt = curdebt; + } + public String printCurDebt() { + return Formats.CURRENCY.formatValue(RoundUtils.getValue(getCurdebt())); + } + + + /** + * + * @param amount + * @param d + */ + public void updateCurDebt(Double amount, Date d) { + + curdebt = curdebt == null ? amount : curdebt + amount; + curdate = (new Date()); + + if (RoundUtils.compare(curdebt, 0.0) > 0) { + if (curdate == null) { + curdate = d; + } + } else if (RoundUtils.compare(curdebt, 0.0) == 0) { + curdebt = null; + curdate = null; + } else { // < 0 + curdate = null; + } + } + + public String getFirstname() { + return firstname; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public String getLastname() { + return lastname; + } + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + @Override + public String getEmail() { + return email; + } + + @Override + public void setEmail(String email) { + this.email = email; + } + + @Override + public String getPhone() { + return phone; + } + @Override + public void setPhone(String phone) { + this.phone = phone; + } + public String printPhone() { + return Formats.STRING.formatValue(phone); + } + + public String getPhone2() { + return phone2; + } + public void setPhone2(String phone2) { + this.phone2 = phone2; + } + + public String getFax() { + return fax; + } + public void setFax(String fax) { + this.fax = fax; + } + + /** + * + * @return supplier's address line 1 string + */ + public String getAddress() { + return address; + } + public void setAddress(String address) { + this.address = address; + } + public String printAddress() { + return Formats.STRING.formatValue(address); + } + + /** + * + * @return supplier's address line 2 string + */ + public String getAddress2() { + return address2; + } + public void setAddress2(String address2) { + this.address2 = address2; + } + + /** + * + * @return supplier's postal/zip code string + */ + @Override + public String getPostal() { + return postal; + } + @Override + public void setPostal(String postal) { + this.postal = postal; + } + public String printPostal() { + return Formats.STRING.formatValue(postal); + } + + /** + * + * @return supplier's address city string + */ + public String getCity() { + return city; + } + public void setCity(String city) { + this.city = city; + } + + /** + * + * @return supplier's address region/state/county string + */ + public String getRegion() { + return region; + } + public void setRegion(String region) { + this.region = region; + } + + /** + * + * @return supplier's address country string + */ + public String getCountry() { + return country; + } + public void setCountry(String country) { + this.country = country; + } + +} diff --git a/src/main/java/com/unicenta/pos/suppliers/SupplierInfoGlobal.java b/src/main/java/com/unicenta/pos/suppliers/SupplierInfoGlobal.java new file mode 100644 index 0000000..7883319 --- /dev/null +++ b/src/main/java/com/unicenta/pos/suppliers/SupplierInfoGlobal.java @@ -0,0 +1,83 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +// + +// For BrowseEditableData + +package com.unicenta.pos.suppliers; + +import com.unicenta.data.user.BrowsableEditableData; + +/** + * + * @author Jack Gerrard + */ +public class SupplierInfoGlobal { + + private static SupplierInfoGlobal INSTANCE; + private SupplierInfoExt supplierInfoExt; + private BrowsableEditableData editableData; + + private SupplierInfoGlobal() { + } + + /** + * + * @return + */ + public static SupplierInfoGlobal getInstance() { + if (INSTANCE == null) { + INSTANCE = new SupplierInfoGlobal(); + } + + return INSTANCE; + } + + /** + * + * @return + */ + public SupplierInfoExt getSupplierInfoExt() { + return supplierInfoExt; + } + + /** + * + * @param supplierInfoExt + */ + public void setSupplierInfoExt(SupplierInfoExt supplierInfoExt) { + this.supplierInfoExt = supplierInfoExt; + } + + /** + * + * @return + */ + public BrowsableEditableData getEditableData() { + return editableData; +} + + /** + * + * @param editableData + */ + public void setEditableData(BrowsableEditableData editableData) { + this.editableData = editableData; + } +} diff --git a/src/main/java/com/unicenta/pos/suppliers/SupplierRenderer.java b/src/main/java/com/unicenta/pos/suppliers/SupplierRenderer.java new file mode 100644 index 0000000..65cd41b --- /dev/null +++ b/src/main/java/com/unicenta/pos/suppliers/SupplierRenderer.java @@ -0,0 +1,49 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.suppliers; + +import java.awt.Component; +import javax.swing.DefaultListCellRenderer; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JList; + +/** + * + * @author Jack Gerrard + */ +public class SupplierRenderer extends DefaultListCellRenderer { + + private Icon icosupplier; + + /** Creates a new instance of SupplierRenderer */ + public SupplierRenderer() { + + icosupplier = new ImageIcon(getClass().getClassLoader().getResource("com/unicenta/images/supplier_sml.png")); + } + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, null, index, isSelected, cellHasFocus); + setText(value.toString()); + setIcon(icosupplier); + return this; + } +} diff --git a/src/main/java/com/unicenta/pos/suppliers/SupplierTicketSelector.java b/src/main/java/com/unicenta/pos/suppliers/SupplierTicketSelector.java new file mode 100644 index 0000000..3a19161 --- /dev/null +++ b/src/main/java/com/unicenta/pos/suppliers/SupplierTicketSelector.java @@ -0,0 +1,46 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.unicenta.pos.suppliers; + +import com.unicenta.basic.BasicException; +import java.awt.Component; +import java.awt.event.ActionListener; + +/** + * + * @author JG uniCenta - outline/prep for uniCenta mobile + eCommerce connector + */ +public interface SupplierTicketSelector { + + /** + * + * @throws BasicException + */ + public void loadSupplierss() throws BasicException; + + /** + * + * @param value + */ + public void setComponentEnabled(boolean value); + + /** + * + * @return + */ + public Component getComponent(); + + /** + * + * @param l + */ + public void addActionListener(ActionListener l); + + /** + * + * @param l + */ + public void removeActionListener(ActionListener l); +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/suppliers/SupplierTransaction.java b/src/main/java/com/unicenta/pos/suppliers/SupplierTransaction.java new file mode 100644 index 0000000..2020440 --- /dev/null +++ b/src/main/java/com/unicenta/pos/suppliers/SupplierTransaction.java @@ -0,0 +1,171 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.suppliers; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.SerializerRead; +import lombok.extern.slf4j.Slf4j; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * + * @author Jack Gerrard + * Used in Supplier's transactions tab to display all this Supplier's + * ticketline values + */ +@Slf4j +public class SupplierTransaction { + + Date transactionDate; + String productName; + String unit; + Double price; + Integer reason; + + String supplierId; + + /** + * Main method to return all supplier's transactions from StockDiary + */ + public SupplierTransaction() { + } + + /** + * + * @param transactionDate + * @param productName + * @param unit + * @param price + * @param reason + * @param sId + */ + public SupplierTransaction(Date transactionDate, String productName, String unit, Double price, Integer reason, String sId) { + this.transactionDate = transactionDate; + this.productName = productName; + this.unit = unit; + this.price = price; + this.reason = reason; + + this.supplierId = sId; + } + + + /** + * + * @return ticket's transaction date + */ + public Date getTransactionDate() { + return transactionDate; + } + public void setTransactionDate(Date transactionDate) { + this.transactionDate = transactionDate; + } + + /** + * + * @return product name string + */ + public String getProductName() { + return productName; + } + public void setProductName(String productName) { + this.productName = productName; + } + + /** + * + * @return quantity string value + */ + public String getUnit() { + return unit; + } + public void setUnit(String unit) { + this.unit = unit; + } + /** + * + * @return price value + */ + public Double getPrice() { + return price; + } + public void setPrice(Double price) { + this.price = price; + } + + /** + * + * @return + */ + public Integer getReason() { + return reason; + } + public void setReason(Integer reason) { + this.reason = reason; + } + + + /** + * + * @return supplier's account name string + */ + public String getSupplierId() { + return supplierId; + } + public void setSupplierId(String supplierId) { + this.supplierId = supplierId; + } + + + /** + * + * @return stockdiary for this supplier + */ + public static SerializerRead getSerializerRead() { + return new SerializerRead() { + + @Override + public Object readValues(DataRead dr) throws BasicException { + + String dateValue = dr.getString(1); + String productName = dr.getString(2); + String unit = dr.getString(3); + Double price = dr.getDouble(4); + Integer reason = dr.getInt(5); + + String supplierId = dr.getString(6); + + + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); + Date date = null; + try { + date = formatter.parse(dateValue); + } catch (ParseException ex) { + log.error(ex.getMessage()); + } + return new SupplierTransaction(date, productName, unit, price, reason, supplierId); + } + }; + } +} diff --git a/src/main/java/com/unicenta/pos/suppliers/SuppliersPanel.java b/src/main/java/com/unicenta/pos/suppliers/SuppliersPanel.java new file mode 100644 index 0000000..4b5d389 --- /dev/null +++ b/src/main/java/com/unicenta/pos/suppliers/SuppliersPanel.java @@ -0,0 +1,134 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.suppliers; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ListCellRendererBasic; +import com.unicenta.data.loader.ComparatorCreator; +import com.unicenta.data.loader.TableDefinition; +import com.unicenta.data.loader.Vectorer; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.data.user.ListProvider; +import com.unicenta.data.user.ListProviderCreator; +import com.unicenta.data.user.SaveProvider; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.panels.JPanelTable; +import javax.swing.ListCellRenderer; + +/** + * + * @author Jack Gerrard + */ +public class SuppliersPanel extends JPanelTable { + + private TableDefinition tsuppliers; + private SuppliersView jeditor; + + /** Creates a new instance of SuppliersPanel */ + public SuppliersPanel() { + SupplierInfoGlobal.getInstance().setEditableData(bd); + } + + /** + * + */ + @Override + protected void init() { + DataLogicSuppliers dlSuppliers = (DataLogicSuppliers) app.getBean("com.unicenta.pos.suppliers.DataLogicSuppliers"); + tsuppliers = dlSuppliers.getTableSuppliers(); + jeditor = new SuppliersView(app, dirty); + + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + jeditor.activate(); + super.activate(); + } + + /** + * + * @return + */ + @Override + public ListProvider getListProvider() { + return new ListProviderCreator(tsuppliers); + } + + /** + * + * @return + */ + @Override + public SaveProvider getSaveProvider() { + return new SaveProvider(tsuppliers, new int[] { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}); + } + + /** + * + * @return + */ + @Override + public Vectorer getVectorer() { + return tsuppliers.getVectorerBasic(new int[]{1, 2, 3, 4}); + } + + /** + * + * @return + */ + @Override + public ComparatorCreator getComparatorCreator() { + return tsuppliers.getComparatorCreator(new int[] {1, 2, 3, 4}); + } + + /** + * + * @return + */ + @Override + public ListCellRenderer getListCellRenderer() { + return new ListCellRendererBasic(tsuppliers.getRenderStringBasic(new int[]{3})); + } + + /** + * + * @return + */ + @Override + public EditorRecord getEditor() { + return jeditor; + } + + /** + * + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.SuppliersManagement"); + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/suppliers/SuppliersView.form b/src/main/java/com/unicenta/pos/suppliers/SuppliersView.form new file mode 100644 index 0000000..64b71ba --- /dev/null +++ b/src/main/java/com/unicenta/pos/suppliers/SuppliersView.form @@ -0,0 +1,1050 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.5" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[1000, 600]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jTabbedPane1" min="-2" max="-2" attributes="0"/> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="jLabel3" min="-2" max="-2" attributes="1"/> + <Component id="jLabel7" alignment="0" max="32767" attributes="1"/> + <Component id="jLabel9" alignment="0" max="32767" attributes="1"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Group type="102" attributes="1"> + <Component id="m_jTaxID" min="-2" max="-2" attributes="2"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="jLabel8" min="-2" pref="87" max="-2" attributes="0"/> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Component id="m_jSearchkey" min="-2" pref="136" max="-2" attributes="2"/> + </Group> + <Component id="m_jName" alignment="0" min="-2" pref="395" max="-2" attributes="2"/> + <Component id="m_jVATID" min="-2" max="-2" attributes="2"/> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" alignment="0" groupAlignment="0" max="-2" attributes="0"> + <Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="1"/> + <Component id="jLabel1" alignment="0" max="32767" attributes="1"/> + </Group> + <Component id="jLabel4" min="-2" max="-2" attributes="1"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jVisible" alignment="0" min="-2" pref="21" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="txtMaxdebt" min="-2" max="-2" attributes="0"/> + <Component id="txtCurdebt" alignment="0" min="-2" max="-2" attributes="1"/> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="txtCurdate" min="-2" max="-2" attributes="1"/> + <Component id="jLabel6" alignment="0" min="-2" max="-2" attributes="1"/> + </Group> + </Group> + </Group> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel7" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel8" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jSearchkey" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jTaxID" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel9" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jVATID" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel4" min="-2" max="-2" attributes="0"/> + <Component id="m_jVisible" alignment="0" min="-2" pref="25" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtMaxdebt" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel6" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="txtCurdate" min="-2" max="-2" attributes="0"/> + <Group type="103" alignment="0" groupAlignment="3" attributes="0"> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtCurdebt" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jTabbedPane1" min="-2" max="-2" attributes="0"/> + <EmptySpace pref="48" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel7"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/info.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.suppliertaxid" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="jLabel7MouseClicked"/> + </Events> + </Component> + <Component class="javax.swing.JTextField" name="m_jTaxID"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="CustomersView_m_jTaxID"/> + </AuxValues> + </Component> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.searchkeym" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jSearchkey"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.supplier" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 25]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.visible" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 25]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="m_jVisible"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.maxdebt" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 25]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtMaxdebt"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.curdebt" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 25]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtCurdebt"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.curdate" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtCurdate"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Container class="javax.swing.JTabbedPane" name="jTabbedPane1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[650, 300]"/> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription"> + <JTabbedPaneConstraints tabName="Contact"> + <Property name="tabTitle" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.contact" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </JTabbedPaneConstraints> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel15" min="-2" pref="110" max="-2" attributes="1"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="txtLastName" min="-2" max="-2" attributes="2"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel14" min="-2" pref="110" max="-2" attributes="2"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="txtFax" min="-2" max="-2" attributes="2"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel16" alignment="0" min="-2" pref="110" max="-2" attributes="1"/> + <Component id="jLabel17" alignment="0" min="-2" pref="110" max="-2" attributes="1"/> + <Component id="jLabel18" alignment="0" min="-2" pref="110" max="-2" attributes="1"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="txtPhone" min="-2" max="-2" attributes="2"/> + <Component id="txtEmail" min="-2" max="-2" attributes="2"/> + <Component id="txtPhone2" min="-2" max="-2" attributes="1"/> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel19" min="-2" pref="110" max="-2" attributes="1"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="txtFirstName" min="-2" max="-2" attributes="1"/> + </Group> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="webBtnMail" min="-2" pref="89" max="-2" attributes="0"/> + <EmptySpace pref="216" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel19" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtFirstName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel15" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtLastName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel16" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtEmail" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="webBtnMail" alignment="3" min="-2" pref="31" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel17" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtPhone" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel18" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtPhone2" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="txtFax" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel14" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" pref="57" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel19"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.firstname" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="alignmentX" type="float" value="0.5"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtFirstName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel15"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.lastname" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtLastName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel16"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.email" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtEmail"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel17"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.phone" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtPhone"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel18"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.phone2" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtPhone2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel14"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.fax" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtFax"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.button.WebButton" name="webBtnMail"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/mail24.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.email" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[90, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="webBtnMailActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription"> + <JTabbedPaneConstraints tabName="Address"> + <Property name="tabTitle" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.locationaddress" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </JTabbedPaneConstraints> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="jLabel20" min="-2" max="-2" attributes="1"/> + <Component id="jLabel24" alignment="0" min="-2" max="-2" attributes="1"/> + <Component id="jLabel23" alignment="0" min="-2" max="-2" attributes="1"/> + <Component id="jLabel21" alignment="0" min="-2" max="-2" attributes="1"/> + <Component id="jLabel13" alignment="0" min="-2" max="-2" attributes="1"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="txtCity" alignment="0" max="32767" attributes="1"/> + <Component id="txtAddress" alignment="0" max="32767" attributes="1"/> + <Component id="txtAddress2" alignment="0" max="32767" attributes="1"/> + <Component id="txtRegion" alignment="0" max="32767" attributes="1"/> + <Component id="txtCountry" alignment="0" max="32767" attributes="1"/> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="txtPostal" min="-2" pref="89" max="-2" attributes="0"/> + <Component id="jLabel22" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel13" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtAddress" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel21" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtAddress2" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel23" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtCity" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel22" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel24" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtRegion" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtPostal" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel20" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtCountry" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel13"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.address" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtAddress"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel20"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.country" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtCountry"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel21"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.address2" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtAddress2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel22"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.postal" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtPostal"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel23"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.city" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtCity"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel24"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.region" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="txtRegion"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[535, 0]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription"> + <JTabbedPaneConstraints tabName="Transactions"> + <Property name="tabTitle" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.SupplierTransactions" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + </JTabbedPaneConstraints> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="10" max="-2" attributes="0"/> + <Component id="jScrollPane3" min="-2" pref="622" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jBtnShowTrans" min="-2" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="jLblTranCount" max="32767" attributes="0"/> + </Group> + </Group> + <EmptySpace pref="13" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jBtnShowTrans" min="-2" max="-2" attributes="0"/> + <Component id="jLblTranCount" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Component id="jScrollPane3" min="-2" pref="233" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="jBtnShowTrans"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.SupplierTrans" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value=""/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnShowTransActionPerformed"/> + </Events> + </Component> + <Container class="javax.swing.JScrollPane" name="jScrollPane3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JTable" name="jTableSupplierTransactions"> + <Properties> + <Property name="autoCreateRowSorter" type="boolean" value="true"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor"> + <Table columnCount="5" rowCount="100"> + <Column editable="true" title="Date" type="java.lang.Object"/> + <Column editable="true" title="Product" type="java.lang.Object"/> + <Column editable="true" title="Qty" type="java.lang.Object"/> + <Column editable="true" title="Price" type="java.lang.Object"/> + <Column editable="true" title="Reason" type="java.lang.Object"/> + </Table> + </Property> + <Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor"> + <TableColumnModel selectionModel="0"> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + </TableColumnModel> + </Property> + <Property name="gridColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="cc" red="66" type="rgb"/> + </Property> + <Property name="opaque" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[375, 200]"/> + </Property> + <Property name="rowHeight" type="int" value="25"/> + <Property name="showVerticalLines" type="boolean" value="false"/> + <Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor"> + <TableHeader reorderingAllowed="true" resizingAllowed="true"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JLabel" name="jLblTranCount"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription"> + <JTabbedPaneConstraints tabName="Notes"> + <Property name="tabTitle" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.notes" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </JTabbedPaneConstraints> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jScrollPane1" min="-2" pref="458" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jScrollPane1" pref="247" max="32767" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Container class="javax.swing.JScrollPane" name="jScrollPane1"> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JTextArea" name="m_jNotes"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 0]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Component class="javax.swing.JLabel" name="jLabel9"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.suppliervatid" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[140, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jVATID"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="CustomersView_m_jTaxID"/> + </AuxValues> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/suppliers/SuppliersView.java b/src/main/java/com/unicenta/pos/suppliers/SuppliersView.java new file mode 100644 index 0000000..f341009 --- /dev/null +++ b/src/main/java/com/unicenta/pos/suppliers/SuppliersView.java @@ -0,0 +1,1336 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.suppliers; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.BeanFactoryException; +import com.unicenta.pos.inventory.MovementReason; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.JTableHeader; +import java.awt.*; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +/** + * + * @author Jack Gerrard + */ +@Slf4j +public final class SuppliersView extends javax.swing.JPanel implements EditorRecord { + + private static final long serialVersionUID = 1L; + private Object m_oId; + +// private SentenceList m_sentcat; + private List<SupplierTransaction> supplierTransactionList; + private TransactionTableModel transactionModel; + + private DirtyManager m_Dirty; + private DataLogicSuppliers dlSuppliers; + + private AppView appView; + private SupplierInfo supplierInfo; + + /** Creates new form SuppliersView + * @param app + * @param dirty */ + public SuppliersView(AppView app, DirtyManager dirty) { + try { + setAppView(app); + dlSuppliers = (DataLogicSuppliers) app.getBean("com.unicenta.pos.suppliers.DataLogicSuppliers"); + + initComponents(); + + m_Dirty = dirty; + m_jTaxID.getDocument().addDocumentListener(dirty); + m_jVATID.getDocument().addDocumentListener(dirty); + m_jSearchkey.getDocument().addDocumentListener(dirty); + m_jName.getDocument().addDocumentListener(dirty); + + m_jNotes.getDocument().addDocumentListener(dirty); + txtMaxdebt.getDocument().addDocumentListener(dirty); + m_jVisible.addActionListener(dirty); + + txtFirstName.getDocument().addDocumentListener(dirty); + txtLastName.getDocument().addDocumentListener(dirty); + txtEmail.getDocument().addDocumentListener(dirty); + txtPhone.getDocument().addDocumentListener(dirty); + txtPhone2.getDocument().addDocumentListener(dirty); + txtFax.getDocument().addDocumentListener(dirty); + + txtAddress.getDocument().addDocumentListener(dirty); + txtAddress2.getDocument().addDocumentListener(dirty); + txtPostal.getDocument().addDocumentListener(dirty); + txtCity.getDocument().addDocumentListener(dirty); + txtRegion.getDocument().addDocumentListener(dirty); + txtCountry.getDocument().addDocumentListener(dirty); + + init(); + } catch (BeanFactoryException ex) { + log.error(ex.getMessage()); + } + } + + private void init() { + writeValueEOF(); + } + + /** + * Instantiate object + * @throws BasicException + */ + @SuppressWarnings("unchecked") + public void activate() throws BasicException { + + String sId = null; + } + + /** + * Refresh object + */ + @Override + public void refresh() { + jLblTranCount.setText(null); + } + + /** + * Write EOF + */ + @Override + public void writeValueEOF() { + m_oId = null; + m_jTaxID.setText(null); + m_jVATID.setText(null); + m_jSearchkey.setText(null); + m_jName.setText(null); + m_jNotes.setText(null); + txtMaxdebt.setText(null); + txtCurdebt.setText(null); + txtCurdate.setText(null); + m_jVisible.setSelected(false); + + txtFirstName.setText(null); + txtLastName.setText(null); + txtEmail.setText(null); + txtPhone.setText(null); + txtPhone2.setText(null); + txtFax.setText(null); + txtAddress.setText(null); + txtAddress2.setText(null); + txtPostal.setText(null); + txtCity.setText(null); + txtRegion.setText(null); + txtCountry.setText(null); + + m_jTaxID.setEnabled(false); + m_jVATID.setEnabled(false); + m_jSearchkey.setEnabled(false); + m_jName.setEnabled(false); + m_jNotes.setEnabled(false); + txtMaxdebt.setEnabled(false); + txtCurdebt.setEnabled(false); + txtCurdate.setEnabled(false); + m_jVisible.setEnabled(false); + + txtFirstName.setEnabled(false); + txtLastName.setEnabled(false); + txtEmail.setEnabled(false); + txtPhone.setEnabled(false); + txtPhone2.setEnabled(false); + txtFax.setEnabled(false); + + txtAddress.setEnabled(false); + txtAddress2.setEnabled(false); + txtPostal.setEnabled(false); + txtCity.setEnabled(false); + txtRegion.setEnabled(false); + txtCountry.setEnabled(false); + + jTableSupplierTransactions.setEnabled(false); + + repaint(); + refresh(); + } + + @Override + public void writeValueInsert() { + m_oId = null; + m_jTaxID.setText(null); + m_jVATID.setText(null); + m_jSearchkey.setText(null); + m_jName.setText(null); + txtMaxdebt.setText(null); + txtCurdebt.setText(null); + txtCurdate.setText(null); + + txtFirstName.setText(null); + txtLastName.setText(null); + txtPhone.setText(null); + txtPhone2.setText(null); + txtEmail.setText(null); + + txtFax.setText(null); + txtAddress.setText(null); + txtAddress2.setText(null); + txtPostal.setText(null); + txtCity.setText(null); + txtRegion.setText(null); + txtCountry.setText(null); + + m_jNotes.setText(null); + m_jVisible.setSelected(true); + + m_jTaxID.setEnabled(true); + m_jVATID.setEnabled(true); + m_jSearchkey.setEnabled(true); + m_jName.setEnabled(true); + + txtFirstName.setEnabled(true); + txtLastName.setEnabled(true); + txtEmail.setEnabled(true); + webBtnMail.setEnabled(true); + txtPhone.setEnabled(true); + txtPhone2.setEnabled(true); + txtFax.setEnabled(true); + + txtAddress.setEnabled(true); + txtAddress2.setEnabled(true); + txtPostal.setEnabled(true); + txtCity.setEnabled(true); + txtRegion.setEnabled(true); + txtCountry.setEnabled(true); + + m_jNotes.setEnabled(true); + txtMaxdebt.setEnabled(true); + txtCurdebt.setEnabled(true); + txtCurdate.setEnabled(true); + m_jVisible.setEnabled(true); + jTableSupplierTransactions.setEnabled(false); + + repaint(); + refresh(); + } + + /** + * Delete from object + * @param value + */ + @Override + public void writeValueDelete(Object value) { + + Object[] supplier = (Object[]) value; + m_oId = supplier[0]; + m_jSearchkey.setText((String) supplier[1]); + m_jTaxID.setText((String) supplier[2]); + m_jName.setText((String) supplier[3]); + txtMaxdebt.setText(Formats.CURRENCY.formatValue(supplier[4])); + + txtAddress.setText(Formats.STRING.formatValue(supplier[5])); + txtAddress2.setText(Formats.STRING.formatValue(supplier[6])); + txtPostal.setText(Formats.STRING.formatValue(supplier[7])); + txtCity.setText(Formats.STRING.formatValue(supplier[8])); + txtRegion.setText(Formats.STRING.formatValue(supplier[9])); + txtCountry.setText(Formats.STRING.formatValue(supplier[10])); + + txtFirstName.setText(Formats.STRING.formatValue(supplier[11])); + txtLastName.setText(Formats.STRING.formatValue(supplier[12])); + txtEmail.setText(Formats.STRING.formatValue(supplier[13])); + txtPhone.setText(Formats.STRING.formatValue(supplier[14])); + txtPhone2.setText(Formats.STRING.formatValue(supplier[15])); + txtFax.setText(Formats.STRING.formatValue(supplier[16])); + + m_jNotes.setText((String) supplier[17]); + m_jVisible.setSelected(((Boolean) supplier[18])); + + txtCurdate.setText(Formats.DATE.formatValue(supplier[19])); + txtCurdebt.setText(Formats.CURRENCY.formatValue(supplier[20])); + + m_jVATID.setText((String) supplier[21]); + + m_jTaxID.setEnabled(false); + m_jVATID.setEnabled(false); + m_jSearchkey.setEnabled(false); + m_jName.setEnabled(false); + m_jNotes.setEnabled(false); + txtMaxdebt.setEnabled(false); + txtCurdebt.setEnabled(false); + txtCurdate.setEnabled(false); + m_jVisible.setEnabled(false); + + txtFirstName.setEnabled(false); + txtLastName.setEnabled(false); + txtEmail.setEnabled(false); + webBtnMail.setEnabled(false); + txtPhone.setEnabled(false); + txtPhone2.setEnabled(false); + txtFax.setEnabled(false); + + txtAddress.setEnabled(false); + txtAddress2.setEnabled(false); + txtPostal.setEnabled(false); + txtCity.setEnabled(false); + txtRegion.setEnabled(false); + txtCountry.setEnabled(false); + + transactionModel = new TransactionTableModel(getTransactionOfName((String) m_oId)); + jTableSupplierTransactions.setModel(transactionModel); + jTableSupplierTransactions.setEnabled(false); + + repaint(); + refresh(); + + } + + /** + * Edit object + * @param value + */ + @Override + public void writeValueEdit(Object value) { + Object[] supplier = (Object[]) value; + m_oId = supplier[0]; + m_jSearchkey.setText((String) supplier[1]); + m_jTaxID.setText((String) supplier[2]); + m_jName.setText((String) supplier[3]); + txtMaxdebt.setText(Formats.CURRENCY.formatValue(supplier[4])); + + txtAddress.setText(Formats.STRING.formatValue(supplier[5])); + txtAddress2.setText(Formats.STRING.formatValue(supplier[6])); + txtPostal.setText(Formats.STRING.formatValue(supplier[7])); + txtCity.setText(Formats.STRING.formatValue(supplier[8])); + txtRegion.setText(Formats.STRING.formatValue(supplier[9])); + txtCountry.setText(Formats.STRING.formatValue(supplier[10])); + txtFirstName.setText(Formats.STRING.formatValue(supplier[11])); + txtLastName.setText(Formats.STRING.formatValue(supplier[12])); + txtEmail.setText(Formats.STRING.formatValue(supplier[13])); + txtPhone.setText(Formats.STRING.formatValue(supplier[14])); + txtPhone2.setText(Formats.STRING.formatValue(supplier[15])); + txtFax.setText(Formats.STRING.formatValue(supplier[16])); + + m_jNotes.setText((String) supplier[17]); + m_jVisible.setSelected(((Boolean) supplier[18])); + txtCurdate.setText(Formats.DATE.formatValue(supplier[19])); + txtCurdebt.setText(Formats.CURRENCY.formatValue(supplier[20])); + + m_jVATID.setText((String) supplier[21]); + + m_jSearchkey.setEnabled(true); + m_jTaxID.setEnabled(true); + m_jName.setEnabled(true); + txtMaxdebt.setEnabled(true); + + txtAddress.setEnabled(true); + txtAddress2.setEnabled(true); + txtPostal.setEnabled(true); + txtCity.setEnabled(true); + txtRegion.setEnabled(true); + txtCountry.setEnabled(true); + + txtFirstName.setEnabled(true); + txtLastName.setEnabled(true); + txtEmail.setEnabled(true); + webBtnMail.setEnabled(true); + txtPhone.setEnabled(true); + txtPhone2.setEnabled(true); + txtFax.setEnabled(true); + + m_jNotes.setEnabled(true); + m_jVisible.setEnabled(true); + txtCurdebt.setEnabled(true); + txtCurdate.setEnabled(true); + m_jVATID.setEnabled(true); + + jTableSupplierTransactions.setVisible(false); + jTableSupplierTransactions.setEnabled(true); + resetTranxTable(); + + txtCurdate.repaint(); + txtCurdebt.repaint(); + jTableSupplierTransactions.repaint(); + repaint(); + refresh(); + } + +public void resetTranxTable() { + + jTableSupplierTransactions.getColumnModel().getColumn(0).setPreferredWidth(100); + jTableSupplierTransactions.getColumnModel().getColumn(1).setPreferredWidth(225); + jTableSupplierTransactions.getColumnModel().getColumn(2).setPreferredWidth(30); + jTableSupplierTransactions.getColumnModel().getColumn(3).setPreferredWidth(50); + jTableSupplierTransactions.getColumnModel().getColumn(4).setPreferredWidth(55); + + // set font for headers + Font f = new Font("Arial", Font.BOLD, 14); + JTableHeader header = jTableSupplierTransactions.getTableHeader(); + header.setFont(f); + + jTableSupplierTransactions.getTableHeader().setReorderingAllowed(true); + jTableSupplierTransactions.setAutoCreateRowSorter(true); + + jTableSupplierTransactions.repaint(); + + +} + + + /** + * Create object + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + Object[] supplier = new Object[23]; + supplier[0] = m_oId == null ? UUID.randomUUID().toString() : m_oId; + supplier[1] = m_jSearchkey.getText(); + supplier[2] = m_jTaxID.getText(); + supplier[3] = m_jName.getText(); + supplier[4] = Formats.CURRENCY.parseValue(txtMaxdebt.getText(), 0.0); + supplier[5] = Formats.STRING.parseValue(txtAddress.getText()); + supplier[6] = Formats.STRING.parseValue(txtAddress2.getText()); + supplier[7] = Formats.STRING.parseValue(txtPostal.getText()); + supplier[8] = Formats.STRING.parseValue(txtCity.getText()); + supplier[9] = Formats.STRING.parseValue(txtRegion.getText()); + supplier[10] = Formats.STRING.parseValue(txtCountry.getText()); + supplier[11] = Formats.STRING.parseValue(txtFirstName.getText()); + supplier[12] = Formats.STRING.parseValue(txtLastName.getText()); + supplier[13] = Formats.STRING.parseValue(txtEmail.getText()); + supplier[14] = Formats.STRING.parseValue(txtPhone.getText()); + supplier[15] = Formats.STRING.parseValue(txtPhone2.getText()); + supplier[16] = Formats.STRING.parseValue(txtFax.getText()); + supplier[17] = m_jNotes.getText(); + supplier[18] = m_jVisible.isSelected(); + supplier[19] = Formats.TIMESTAMP.parseValue(txtCurdate.getText()); + supplier[20] = Formats.CURRENCY.parseValue(txtCurdebt.getText()); + supplier[21] = m_jVATID.getText(); + + supplier[22] = (Object)getAppView(); + + repaint(); + refresh(); + + return supplier; + } + + public AppView getAppView() { + return appView; + } + + public void setAppView(AppView appView) { + this.appView = appView; + } + + @Override + public Component getComponent() { + return this; + } + + private List<SupplierTransaction> getTransactionOfName(String sId) { + + try { + supplierTransactionList = dlSuppliers.getSuppliersTransactionList(sId); + + + } catch (BasicException ex) { + log.error(ex.getMessage()); + } + + List<SupplierTransaction> supplierList = new ArrayList<>(); + + for (SupplierTransaction supplierTransaction : supplierTransactionList) { + String supplierId = supplierTransaction.getSupplierId(); + if (supplierId.equals(sId)) { + supplierList.add(supplierTransaction); + } + } + + txtCurdate.repaint(); + txtCurdebt.repaint(); + + repaint(); + refresh(); + + return supplierList; + } + + class TransactionTableModel extends AbstractTableModel { +String dte = AppLocal.getIntString("label.suptblHeaderCol1"); +String prd = AppLocal.getIntString("label.suptblHeaderCol2"); +String qty = AppLocal.getIntString("label.suptblHeaderCol3"); +String pri = AppLocal.getIntString("label.suptblHeaderCol4"); +String rsn = AppLocal.getIntString("label.suptblHeaderCol5"); + + + List<SupplierTransaction> transactionList; + String[] columnNames = {dte, prd, qty, pri, rsn}; + public Double Tamount; + + public TransactionTableModel(List<SupplierTransaction> list) { + transactionList = list; + } + + @Override + public int getColumnCount() { + return 5; + } + + @Override + public int getRowCount() { + return transactionList.size(); + } + + // this method is called to set the value of each cell + @Override + public Object getValueAt(int row, int column) { + SupplierTransaction supplierTransaction = transactionList.get(row); + + jTableSupplierTransactions.setRowHeight(25); + + switch (column) { + + case 0: + Date transactionDate = supplierTransaction.getTransactionDate(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); + String formattedDate = sdf.format(transactionDate); + return formattedDate; + case 1: + return supplierTransaction.getProductName(); + case 2: + return supplierTransaction.getUnit(); + case 3: + Double price = supplierTransaction.getPrice(); + DecimalFormat df = new DecimalFormat("#.##"); + String formattedAmount = df.format(price); + return formattedAmount; + case 4: + Integer reason = supplierTransaction.getReason(); + String s = String.valueOf(reason); + + if (s.equals("1")) { + s = MovementReason.IN_PURCHASE.toString(); + } + if (s.equals("2")) { + s = MovementReason.IN_REFUND.toString(); + } + if (s.equals("4")) { + s = MovementReason.IN_MOVEMENT.toString(); + } + if (s.equals("-1")) { + s = MovementReason.OUT_SALE.toString(); + } + if (s.equals("-2")) { + s = MovementReason.OUT_REFUND.toString(); + } + if (s.equals("-3")) { + s = MovementReason.OUT_BREAK.toString(); + } + if (s.equals("-4")) { + s = MovementReason.OUT_MOVEMENT.toString(); + } + if (s.equals("-5")) { + s = MovementReason.OUT_SAMPLE.toString(); + } + if (s.equals("-6")) { + s = MovementReason.OUT_FREE.toString(); + } + if (s.equals("-7")) { + s = MovementReason.OUT_USED.toString(); + } + if (s.equals("-8")) { + s = MovementReason.OUT_SUBTRACT.toString(); + } + return s; + + default: + return ""; + + } + } + + @Override + public String getColumnName(int col) { + return columnNames[col]; + } + } + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel7 = new javax.swing.JLabel(); + m_jTaxID = new javax.swing.JTextField(); + jLabel8 = new javax.swing.JLabel(); + m_jSearchkey = new javax.swing.JTextField(); + jLabel3 = new javax.swing.JLabel(); + m_jName = new javax.swing.JTextField(); + jLabel4 = new javax.swing.JLabel(); + m_jVisible = new javax.swing.JCheckBox(); + jLabel1 = new javax.swing.JLabel(); + txtMaxdebt = new javax.swing.JTextField(); + jLabel2 = new javax.swing.JLabel(); + txtCurdebt = new javax.swing.JTextField(); + jLabel6 = new javax.swing.JLabel(); + txtCurdate = new javax.swing.JTextField(); + jTabbedPane1 = new javax.swing.JTabbedPane(); + jPanel1 = new javax.swing.JPanel(); + jLabel19 = new javax.swing.JLabel(); + txtFirstName = new javax.swing.JTextField(); + jLabel15 = new javax.swing.JLabel(); + txtLastName = new javax.swing.JTextField(); + jLabel16 = new javax.swing.JLabel(); + txtEmail = new javax.swing.JTextField(); + jLabel17 = new javax.swing.JLabel(); + txtPhone = new javax.swing.JTextField(); + jLabel18 = new javax.swing.JLabel(); + txtPhone2 = new javax.swing.JTextField(); + jLabel14 = new javax.swing.JLabel(); + txtFax = new javax.swing.JTextField(); + webBtnMail = new com.alee.laf.button.WebButton(); + jPanel2 = new javax.swing.JPanel(); + jLabel13 = new javax.swing.JLabel(); + txtAddress = new javax.swing.JTextField(); + jLabel20 = new javax.swing.JLabel(); + txtCountry = new javax.swing.JTextField(); + jLabel21 = new javax.swing.JLabel(); + txtAddress2 = new javax.swing.JTextField(); + jLabel22 = new javax.swing.JLabel(); + txtPostal = new javax.swing.JTextField(); + jLabel23 = new javax.swing.JLabel(); + txtCity = new javax.swing.JTextField(); + jLabel24 = new javax.swing.JLabel(); + txtRegion = new javax.swing.JTextField(); + jPanel4 = new javax.swing.JPanel(); + jBtnShowTrans = new javax.swing.JButton(); + jScrollPane3 = new javax.swing.JScrollPane(); + jTableSupplierTransactions = new javax.swing.JTable(); + jLblTranCount = new javax.swing.JLabel(); + jPanel3 = new javax.swing.JPanel(); + jScrollPane1 = new javax.swing.JScrollPane(); + m_jNotes = new javax.swing.JTextArea(); + jLabel9 = new javax.swing.JLabel(); + m_jVATID = new javax.swing.JTextField(); + + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + setPreferredSize(new java.awt.Dimension(1000, 600)); + + jLabel7.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel7.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/info.png"))); // NOI18N + jLabel7.setText(AppLocal.getIntString("label.suppliertaxid")); // NOI18N + jLabel7.setMaximumSize(new java.awt.Dimension(150, 30)); + jLabel7.setMinimumSize(new java.awt.Dimension(140, 25)); + jLabel7.setPreferredSize(new java.awt.Dimension(150, 30)); + jLabel7.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + jLabel7MouseClicked(evt); + } + }); + + m_jTaxID.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jTaxID.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel8.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel8.setText(AppLocal.getIntString("label.searchkeym")); // NOI18N + + m_jSearchkey.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSearchkey.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.supplier")); // NOI18N + jLabel3.setMaximumSize(new java.awt.Dimension(140, 25)); + jLabel3.setMinimumSize(new java.awt.Dimension(140, 25)); + jLabel3.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.visible")); // NOI18N + jLabel4.setMaximumSize(new java.awt.Dimension(140, 25)); + jLabel4.setMinimumSize(new java.awt.Dimension(140, 25)); + jLabel4.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jVisible.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.maxdebt")); // NOI18N + jLabel1.setMaximumSize(new java.awt.Dimension(140, 25)); + jLabel1.setMinimumSize(new java.awt.Dimension(140, 25)); + jLabel1.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtMaxdebt.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtMaxdebt.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + txtMaxdebt.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.curdebt")); // NOI18N + jLabel2.setMaximumSize(new java.awt.Dimension(140, 25)); + jLabel2.setMinimumSize(new java.awt.Dimension(140, 25)); + jLabel2.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtCurdebt.setEditable(false); + txtCurdebt.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtCurdebt.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + txtCurdebt.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLabel6.setText(AppLocal.getIntString("label.curdate")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtCurdate.setEditable(false); + txtCurdate.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtCurdate.setHorizontalAlignment(javax.swing.JTextField.CENTER); + txtCurdate.setPreferredSize(new java.awt.Dimension(150, 30)); + + jTabbedPane1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTabbedPane1.setPreferredSize(new java.awt.Dimension(650, 300)); + + jPanel1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + + jLabel19.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel19.setText(AppLocal.getIntString("label.firstname")); // NOI18N + jLabel19.setAlignmentX(0.5F); + jLabel19.setPreferredSize(new java.awt.Dimension(0, 30)); + + txtFirstName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtFirstName.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLabel15.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel15.setText(AppLocal.getIntString("label.lastname")); // NOI18N + jLabel15.setPreferredSize(new java.awt.Dimension(0, 30)); + + txtLastName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtLastName.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLabel16.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel16.setText(AppLocal.getIntString("label.email")); // NOI18N + jLabel16.setPreferredSize(new java.awt.Dimension(0, 30)); + + txtEmail.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtEmail.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLabel17.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel17.setText(AppLocal.getIntString("label.phone")); // NOI18N + jLabel17.setPreferredSize(new java.awt.Dimension(0, 30)); + + txtPhone.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtPhone.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLabel18.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel18.setText(AppLocal.getIntString("label.phone2")); // NOI18N + jLabel18.setPreferredSize(new java.awt.Dimension(0, 30)); + + txtPhone2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtPhone2.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLabel14.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel14.setText(AppLocal.getIntString("label.fax")); // NOI18N + jLabel14.setPreferredSize(new java.awt.Dimension(0, 30)); + + txtFax.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtFax.setPreferredSize(new java.awt.Dimension(200, 30)); + + webBtnMail.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/mail24.png"))); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + webBtnMail.setText(bundle.getString("button.email")); // NOI18N + webBtnMail.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + webBtnMail.setPreferredSize(new java.awt.Dimension(90, 30)); + webBtnMail.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + webBtnMailActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel15, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(txtLastName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel14, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(txtFax, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel16, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel17, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel18, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(txtPhone, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtEmail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtPhone2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel19, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(txtFirstName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(webBtnMail, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(216, Short.MAX_VALUE)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel19, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtFirstName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel15, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtLastName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel16, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtEmail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(webBtnMail, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel17, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtPhone, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel18, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtPhone2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(txtFax, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel14, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(57, 57, 57)) + ); + + jTabbedPane1.addTab(AppLocal.getIntString("label.contact"), jPanel1); // NOI18N + + jLabel13.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel13.setText(AppLocal.getIntString("label.address")); // NOI18N + jLabel13.setPreferredSize(new java.awt.Dimension(110, 30)); + + txtAddress.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtAddress.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLabel20.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel20.setText(AppLocal.getIntString("label.country")); // NOI18N + jLabel20.setPreferredSize(new java.awt.Dimension(110, 30)); + + txtCountry.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtCountry.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLabel21.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel21.setText(AppLocal.getIntString("label.address2")); // NOI18N + jLabel21.setPreferredSize(new java.awt.Dimension(110, 30)); + + txtAddress2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtAddress2.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLabel22.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel22.setText(AppLocal.getIntString("label.postal")); // NOI18N + jLabel22.setPreferredSize(new java.awt.Dimension(110, 30)); + + txtPostal.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtPostal.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel23.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel23.setText(AppLocal.getIntString("label.city")); // NOI18N + jLabel23.setPreferredSize(new java.awt.Dimension(110, 30)); + + txtCity.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtCity.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLabel24.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel24.setText(AppLocal.getIntString("label.region")); // NOI18N + jLabel24.setPreferredSize(new java.awt.Dimension(110, 30)); + + txtRegion.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtRegion.setPreferredSize(new java.awt.Dimension(200, 30)); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jLabel20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel24, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel23, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(txtCity, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(txtAddress, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(txtAddress2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(txtRegion, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(txtCountry, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(18, 18, 18) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(txtPostal, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel22, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtAddress, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtAddress2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel23, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtCity, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel22, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel24, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtRegion, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtPostal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtCountry, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + + jTabbedPane1.addTab(AppLocal.getIntString("label.locationaddress"), jPanel2); // NOI18N + + jPanel4.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jPanel4.setPreferredSize(new java.awt.Dimension(535, 0)); + + jBtnShowTrans.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jBtnShowTrans.setText(bundle.getString("button.SupplierTrans")); // NOI18N + jBtnShowTrans.setToolTipText(""); + jBtnShowTrans.setPreferredSize(new java.awt.Dimension(140, 30)); + jBtnShowTrans.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnShowTransActionPerformed(evt); + } + }); + + jScrollPane3.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + + jTableSupplierTransactions.setAutoCreateRowSorter(true); + jTableSupplierTransactions.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jTableSupplierTransactions.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null}, + {null, null, null, null, null} + }, + new String [] { + "Date", "Product", "Qty", "Price", "Reason" + } + )); + jTableSupplierTransactions.setGridColor(new java.awt.Color(102, 204, 255)); + jTableSupplierTransactions.setOpaque(false); + jTableSupplierTransactions.setPreferredSize(new java.awt.Dimension(375, 200)); + jTableSupplierTransactions.setRowHeight(25); + jTableSupplierTransactions.setShowVerticalLines(false); + jScrollPane3.setViewportView(jTableSupplierTransactions); + + jLblTranCount.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblTranCount.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLblTranCount.setOpaque(true); + jLblTranCount.setPreferredSize(new java.awt.Dimension(50, 30)); + + javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); + jPanel4.setLayout(jPanel4Layout); + jPanel4Layout.setHorizontalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addGap(10, 10, 10) + .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 622, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jBtnShowTrans, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(jLblTranCount, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addContainerGap(13, Short.MAX_VALUE)) + ); + jPanel4Layout.setVerticalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jBtnShowTrans, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblTranCount, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 233, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + jTabbedPane1.addTab(bundle.getString("label.SupplierTransactions"), jPanel4); // NOI18N + + m_jNotes.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jNotes.setPreferredSize(new java.awt.Dimension(0, 0)); + jScrollPane1.setViewportView(m_jNotes); + + javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); + jPanel3.setLayout(jPanel3Layout); + jPanel3Layout.setHorizontalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 458, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel3Layout.setVerticalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 247, Short.MAX_VALUE) + .addContainerGap()) + ); + + jTabbedPane1.addTab(AppLocal.getIntString("label.notes"), jPanel3); // NOI18N + + jLabel9.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel9.setText(AppLocal.getIntString("label.suppliervatid")); // NOI18N + jLabel9.setMaximumSize(new java.awt.Dimension(150, 30)); + jLabel9.setMinimumSize(new java.awt.Dimension(140, 25)); + jLabel9.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jVATID.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jVATID.setPreferredSize(new java.awt.Dimension(150, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel7, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel9, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(layout.createSequentialGroup() + .addComponent(m_jTaxID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jSearchkey, javax.swing.GroupLayout.PREFERRED_SIZE, 136, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, 395, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jVATID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jVisible, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(txtMaxdebt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtCurdebt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(txtCurdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jSearchkey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jTaxID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jVATID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jVisible, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtMaxdebt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(txtCurdate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtCurdebt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(48, Short.MAX_VALUE)) + ); + }// </editor-fold>//GEN-END:initComponents + + private void webBtnMailActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_webBtnMailActionPerformed + + if(!"".equals(txtEmail.getText())) { + Desktop desktop; + + if (Desktop.isDesktopSupported() + && (desktop = Desktop.getDesktop()).isSupported(Desktop.Action.MAIL)) { + URI mailto = null; + try { + mailto = new URI("mailto:" + + txtEmail.getText()); + } catch (URISyntaxException ex) { + log.error(ex.getMessage()); + } + try { + desktop.mail(mailto); + } catch (IOException ex) { + log.error(ex.getMessage()); + } + } else { + JOptionPane.showMessageDialog(this, + AppLocal.getIntString("message.email"), + "Email", JOptionPane.INFORMATION_MESSAGE); + } + } + + }//GEN-LAST:event_webBtnMailActionPerformed + + private void jBtnShowTransActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnShowTransActionPerformed + String cId = m_oId.toString(); + if (cId != null) { + transactionModel = new TransactionTableModel(getTransactionOfName(cId)); + jTableSupplierTransactions.setModel(transactionModel); + if (transactionModel.getRowCount()> 0){ + jTableSupplierTransactions.setVisible(true); + String TranCount = String.valueOf(transactionModel.getRowCount()); + jLblTranCount.setText(TranCount + " for " + m_jName.getText()); + }else{ + jTableSupplierTransactions.setVisible(false); + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.nosupptranx"), + "Transactions", JOptionPane.INFORMATION_MESSAGE); + } + resetTranxTable(); + } + }//GEN-LAST:event_jBtnShowTransActionPerformed + + private void jLabel7MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabel7MouseClicked + + if (evt.getClickCount() == 2) { + String uuidString = m_oId.toString(); + StringSelection stringSelection = new StringSelection(uuidString); + Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard(); + clpbrd.setContents(stringSelection, null); + + JOptionPane.showMessageDialog(null, + AppLocal.getIntString("message.uuidcopy")); + } + }//GEN-LAST:event_jLabel7MouseClicked + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jBtnShowTrans; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel13; + private javax.swing.JLabel jLabel14; + private javax.swing.JLabel jLabel15; + private javax.swing.JLabel jLabel16; + private javax.swing.JLabel jLabel17; + private javax.swing.JLabel jLabel18; + private javax.swing.JLabel jLabel19; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel20; + private javax.swing.JLabel jLabel21; + private javax.swing.JLabel jLabel22; + private javax.swing.JLabel jLabel23; + private javax.swing.JLabel jLabel24; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JLabel jLabel9; + private javax.swing.JLabel jLblTranCount; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JScrollPane jScrollPane3; + private javax.swing.JTabbedPane jTabbedPane1; + private javax.swing.JTable jTableSupplierTransactions; + private javax.swing.JTextField m_jName; + private javax.swing.JTextArea m_jNotes; + private javax.swing.JTextField m_jSearchkey; + private javax.swing.JTextField m_jTaxID; + private javax.swing.JTextField m_jVATID; + private javax.swing.JCheckBox m_jVisible; + private javax.swing.JTextField txtAddress; + private javax.swing.JTextField txtAddress2; + private javax.swing.JTextField txtCity; + private javax.swing.JTextField txtCountry; + private javax.swing.JTextField txtCurdate; + private javax.swing.JTextField txtCurdebt; + private javax.swing.JTextField txtEmail; + private javax.swing.JTextField txtFax; + private javax.swing.JTextField txtFirstName; + private javax.swing.JTextField txtLastName; + private javax.swing.JTextField txtMaxdebt; + private javax.swing.JTextField txtPhone; + private javax.swing.JTextField txtPhone2; + private javax.swing.JTextField txtPostal; + private javax.swing.JTextField txtRegion; + private com.alee.laf.button.WebButton webBtnMail; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/ticket/CardInfo.java b/src/main/java/com/unicenta/pos/ticket/CardInfo.java new file mode 100644 index 0000000..e05fa41 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/CardInfo.java @@ -0,0 +1,72 @@ + +package com.unicenta.pos.ticket; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.IKeyed; +import com.unicenta.data.loader.ImageUtils; +import com.unicenta.data.loader.SerializerRead; +import java.awt.image.*; + +public class CardInfo implements IKeyed { + + private static final long serialVersionUID = 1612339444103L; + private String m_sID; + private String m_sCardName; + private double m_Charges; + + /** Creates new CategoryInfo */ + public CardInfo(String id, String name, double charges) { + m_sID = id; + m_sCardName = name; + m_Charges = charges; + } + + @Override + public Object getKey() { + return m_sID; + } + + public void setID(String sID) { + m_sID = sID; + } + + public String getID() { + return m_sID; + } + + public String getName() { + return m_sCardName; + } + + public void setName(String sName) { + m_sCardName = sName; + } + + @Override + public String toString() { + return m_sCardName; + } + + public static SerializerRead getSerializerRead() { + return new SerializerRead() {@Override + public Object readValues(DataRead dr) throws BasicException { + return new CardInfo(dr.getString(1), dr.getString(2), dr.getDouble(3)); + }}; + } + + + /** + * @return the m_Charges + */ + public double getM_Charges() { + return m_Charges; + } + + /** + * @param m_Charges the m_Charges to set + */ + public void setM_Charges(double m_Charges) { + this.m_Charges = m_Charges; + } +} diff --git a/src/main/java/com/unicenta/pos/ticket/CategoryFilter.form b/src/main/java/com/unicenta/pos/ticket/CategoryFilter.form new file mode 100644 index 0000000..b45df9d --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/CategoryFilter.form @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[400, 50]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel1" min="-2" max="-2" attributes="1"/> + <EmptySpace min="-2" pref="5" max="-2" attributes="0"/> + <Component id="m_jCategory" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jCategory" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JComboBox" name="m_jCategory"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodcategory" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/ticket/CategoryFilter.java b/src/main/java/com/unicenta/pos/ticket/CategoryFilter.java new file mode 100644 index 0000000..18af4bb --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/CategoryFilter.java @@ -0,0 +1,167 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.loader.QBFCompareEnum; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.loader.SerializerWrite; +import com.unicenta.data.loader.SerializerWriteBasic; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.reports.ReportEditorCreator; +import java.awt.Component; +import java.util.List; + +/** + * + * @author JG uniCenta + */ +public class CategoryFilter extends javax.swing.JPanel implements ReportEditorCreator { + + private SentenceList m_sentcat; + private ComboBoxValModel m_CategoryModel; + + /** Creates new form JQBFProduct */ + public CategoryFilter() { + + initComponents(); + } + + /** + * + * @param app + */ + @Override + public void init(AppView app) { + + DataLogicSales dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + + m_sentcat = dlSales.getCategoriesList(); + m_CategoryModel = new ComboBoxValModel(); + + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + + List catlist = m_sentcat.list(); + catlist.add(0, null); + m_CategoryModel = new ComboBoxValModel(catlist); + m_jCategory.setModel(m_CategoryModel); + } + + /** + * + * @return + */ + @Override + public SerializerWrite getSerializerWrite() { + return new SerializerWriteBasic( + new Datas[] { + Datas.OBJECT, Datas.STRING + } + ); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + return new Object[] { + m_CategoryModel.getSelectedKey() == null + ? QBFCompareEnum.COMP_NONE + : QBFCompareEnum.COMP_EQUALS, + m_CategoryModel.getSelectedKey(), + + QBFCompareEnum.COMP_NONE, null }; + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jCategory = new javax.swing.JComboBox(); + jLabel1 = new javax.swing.JLabel(); + + setPreferredSize(new java.awt.Dimension(400, 50)); + + m_jCategory.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCategory.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.prodcategory")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(150, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(5, 5, 5) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JComboBox m_jCategory; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/ticket/CategoryFilter_1.form b/src/main/java/com/unicenta/pos/ticket/CategoryFilter_1.form new file mode 100644 index 0000000..2245838 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/CategoryFilter_1.form @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[400, 50]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel1" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCategory" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCategory" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JComboBox" name="m_jCategory"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodcategory" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/ticket/CategoryFilter_1.java b/src/main/java/com/unicenta/pos/ticket/CategoryFilter_1.java new file mode 100644 index 0000000..42a70b4 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/CategoryFilter_1.java @@ -0,0 +1,167 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.loader.QBFCompareEnum; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.loader.SerializerWrite; +import com.unicenta.data.loader.SerializerWriteBasic; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.reports.ReportEditorCreator; +import java.awt.Component; +import java.util.List; + +/** + * + * @author JG uniCenta + */ +public class CategoryFilter_1 extends javax.swing.JPanel implements ReportEditorCreator { + + private SentenceList m_sentcat; + private ComboBoxValModel m_CategoryModel; + + /** Creates new form JQBFProduct */ + public CategoryFilter_1() { + + initComponents(); + } + + /** + * + * @param app + */ + @Override + public void init(AppView app) { + + DataLogicSales dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + + m_sentcat = dlSales.getCategoriesList_1(); + m_CategoryModel = new ComboBoxValModel(); + + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + + List catlist = m_sentcat.list(); + catlist.add(0, null); + m_CategoryModel = new ComboBoxValModel(catlist); + m_jCategory.setModel(m_CategoryModel); + } + + /** + * + * @return + */ + @Override + public SerializerWrite getSerializerWrite() { + return new SerializerWriteBasic( + new Datas[] { + Datas.OBJECT, Datas.STRING + } + ); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + return new Object[] { + m_CategoryModel.getSelectedKey() == null + ? QBFCompareEnum.COMP_NONE + : QBFCompareEnum.COMP_EQUALS, + m_CategoryModel.getSelectedKey(), + + QBFCompareEnum.COMP_NONE, null }; + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jCategory = new javax.swing.JComboBox(); + jLabel1 = new javax.swing.JLabel(); + + setPreferredSize(new java.awt.Dimension(400, 50)); + + m_jCategory.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCategory.setPreferredSize(new java.awt.Dimension(200, 30)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.prodcategory")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(150, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JComboBox m_jCategory; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/ticket/CategoryInfo.java b/src/main/java/com/unicenta/pos/ticket/CategoryInfo.java new file mode 100644 index 0000000..5f990e4 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/CategoryInfo.java @@ -0,0 +1,172 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.IKeyed; +import com.unicenta.data.loader.ImageUtils; +import com.unicenta.data.loader.SerializerRead; +import java.awt.image.*; + +/** + * + * @author Adrian + * @version + */ +public class CategoryInfo implements IKeyed { + + private static final long serialVersionUID = 8612449444103L; + private String m_sID; + private String m_sName; + private String m_sTextTip; + private BufferedImage m_Image; + private Boolean m_bCatShowName; + + /** Creates new CategoryInfo + * @param id + * @param name + * @param image + * @param texttip + * @param catshowname */ + public CategoryInfo(String id, String name, BufferedImage image, String texttip, Boolean catshowname) { + m_sID = id; + m_sName = name; + m_Image = image; + m_sTextTip = texttip; + m_bCatShowName = catshowname; + } + + /** + * + * @return + */ + @Override + public Object getKey() { + return m_sID; + } + + /** + * + * @param sID + */ + public void setID(String sID) { + m_sID = sID; + } + + /** + * + * @return + */ + public String getID() { + return m_sID; + } + + /** + * + * @return + */ + public String getName() { + return m_sName; + } + + /** + * + * @param sName + */ + public void setName(String sName) { + m_sName = sName; + } + + + /** + * + * @return + */ + public String getTextTip() { + return m_sTextTip; + } + + /** + * + * @param sName + */ + public void setTextTip(String sName) { + m_sTextTip = sName; + } + + /** + * + * @return + */ + public Boolean getCatShowName() { + return m_bCatShowName; + } + + /** + * + * @param bcatshowname + */ + public void setCatShowName(Boolean bcatshowname) { + m_bCatShowName = bcatshowname; + } + + + + + + // ******************************* + + /** + * + * @return + */ + + public BufferedImage getImage() { + return m_Image; + } + + /** + * + * @param img + */ + public void setImage(BufferedImage img) { + m_Image = img; + } + + @Override + public String toString() { + return m_sName; + } + + /** + * + * @return + */ + public static SerializerRead getSerializerRead() { + return new SerializerRead() { + @Override + public Object readValues(DataRead dr) throws BasicException { + return new CategoryInfo(dr.getString(1), + dr.getString(2), ImageUtils.readImage(dr.getBytes(3)), + dr.getString(4),dr.getBoolean(5)); + }}; + } +} diff --git a/src/main/java/com/unicenta/pos/ticket/FindTicketsInfo.java b/src/main/java/com/unicenta/pos/ticket/FindTicketsInfo.java new file mode 100644 index 0000000..8780f5c --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/FindTicketsInfo.java @@ -0,0 +1,97 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.SerializableRead; +import com.unicenta.format.Formats; +import java.util.Date; + +/** + * + * @author Mikel irurita + */ +public class FindTicketsInfo implements SerializableRead { + + private int ticketid; + private int tickettype; + private Date date; + private String name; + private String customer; + private double total; + private int ticketstatus; + + public FindTicketsInfo() { + + } + + /** + * + * @param dr + * @throws BasicException + */ + @Override + public void readValues(DataRead dr) throws BasicException { + + ticketid = dr.getInt(1); + tickettype = dr.getInt(2); + date = dr.getTimestamp(3); + name = dr.getString(4); + customer = dr.getString(5); + total = (dr.getObject(6) == null) ? 0.0 : dr.getDouble(6); + ticketstatus = dr.getInt(7); + } + + @Override + public String toString(){ + + String sCustomer = (customer==null) ? "" : customer; + + String sHtml = "<tr><td width=\"75\">"+ "["+ ticketid +"]" +"</td>" + + "<td width=\"75\">"+ Formats.TIMESTAMP.formatValue(date) +"</td>" + + "<td align=\"right\" width=\"100\">"+ Formats.CURRENCY.formatValue(total) +"</td>"+ + "<td align=\"left\" width=\"100\">"+ sCustomer +"</td>" + + "<td align=\"left\" width=\"100\">"+ Formats.STRING.formatValue(name) +"</td></tr>"; + + return sHtml; + } + + /** + * + * @return + */ + public int getTicketId(){ + return this.ticketid; + } + + /** + * + * @return + */ + public int getTicketType(){ + return this.tickettype; + } + + public int getTicketStatus() { + return this.ticketstatus; + } + +} diff --git a/src/main/java/com/unicenta/pos/ticket/FindTicketsRenderer.java b/src/main/java/com/unicenta/pos/ticket/FindTicketsRenderer.java new file mode 100644 index 0000000..03790e8 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/FindTicketsRenderer.java @@ -0,0 +1,69 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +import java.awt.Component; +import javax.swing.DefaultListCellRenderer; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JList; + +/** + * + * @author Mikel Irurita + */ +public class FindTicketsRenderer extends DefaultListCellRenderer { + + private final Icon icoTicketNormal; + private final Icon icoTicketRefund; + private final Icon icoTicketRefunded; + /** + * + */ + public static final int RECEIPT_NORMAL = 0; + public static final int RECEIPT_REFUND = 1; + + /** Creates a new instance of TicketRenderer */ + public FindTicketsRenderer() { + this.icoTicketNormal = new ImageIcon(getClass().getClassLoader().getResource("com/unicenta/images/pay.png")); + this.icoTicketRefund = new ImageIcon(getClass().getClassLoader().getResource("com/unicenta/images/refundit.png")); + this.icoTicketRefunded = new ImageIcon(getClass().getClassLoader().getResource("com/unicenta/images/cancel.png")); + } + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, null, index, isSelected, cellHasFocus); + + int ticketType = ((FindTicketsInfo)value).getTicketType(); + int ticketStatus = ((FindTicketsInfo)value).getTicketStatus(); + + setText("<html><table>" + value.toString() +"</table></html>"); + + if (ticketType == RECEIPT_NORMAL) { + setIcon(icoTicketNormal); + } else if (ticketType == RECEIPT_REFUND) { + setIcon(icoTicketRefund); + } else if (ticketType == RECEIPT_NORMAL && ticketStatus > 0) { + setIcon(icoTicketRefunded); + } + + return this; + } +} diff --git a/src/main/java/com/unicenta/pos/ticket/HostInfo.java b/src/main/java/com/unicenta/pos/ticket/HostInfo.java new file mode 100644 index 0000000..bc47a59 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/HostInfo.java @@ -0,0 +1,76 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package com.unicenta.pos.ticket; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.IKeyed; +import com.unicenta.data.loader.SerializerRead; + +public class HostInfo implements IKeyed { + + //MONEY HOST HOSTSEQUENCE DATESTART DATEEND + //private static final long serialVersionUID = 8612449444103L; + private String m_sMoney; + private String m_sHost; + private String m_Hostsequence; + + /** Creates new CategoryInfo + * @param money + * @param host + * @param hostsequence */ + public HostInfo(String money, String host, String hostsequence) { + + m_sMoney = host; // hack to search by hostname + m_sHost = host; + m_Hostsequence = hostsequence; + } + + @Override + public Object getKey() { + return m_sMoney; + } + + public String getHostsequence() { + return m_Hostsequence; + } + + public void setHostsequence(String m_Hostsequence) { + this.m_Hostsequence = m_Hostsequence; + } + + public String getHost() { + return m_sHost; + } + + public void setHost(String m_sHost) { + this.m_sHost = m_sHost; + } + + public String getMoney() { + return m_sMoney; + } + + public void setMoney(String m_sMoney) { + this.m_sMoney = m_sMoney; + } + + @Override + public String toString() { + return m_sHost; + } + + public static SerializerRead getSerializerRead() { + return new SerializerRead() { + @Override + public Object readValues(DataRead dr) throws BasicException { + return new HostInfo(dr.getString(1), dr.getString(2), dr.getString(3)); + } + }; + } +} + diff --git a/src/main/java/com/unicenta/pos/ticket/LocationFilterSales.form b/src/main/java/com/unicenta/pos/ticket/LocationFilterSales.form new file mode 100644 index 0000000..b4baa58 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/LocationFilterSales.form @@ -0,0 +1,242 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[370, 170]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel3" min="-2" pref="110" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="10" max="-2" attributes="0"/> + <Component id="m_jCboPriceSell" min="-2" pref="150" max="-2" attributes="0"/> + <EmptySpace min="10" pref="10" max="-2" attributes="0"/> + <Component id="m_jPriceSell" min="-2" pref="130" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel1" min="-2" pref="110" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="10" max="-2" attributes="0"/> + <Component id="m_jtxtBarCode" min="-2" pref="290" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel5" min="-2" pref="110" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="10" max="-2" attributes="0"/> + <Component id="m_jtxtName" min="-2" pref="290" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel2" min="-2" pref="110" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="10" max="-2" attributes="0"/> + <Component id="m_jCategory" min="-2" pref="260" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel4" min="-2" pref="110" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="10" max="-2" attributes="0"/> + <Component id="m_jCboPriceBuy" min="-2" pref="150" max="-2" attributes="0"/> + <EmptySpace min="10" pref="10" max="-2" attributes="0"/> + <Component id="m_jPriceBuy" min="-2" pref="130" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="32767" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <Component id="m_jtxtBarCode" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="5" pref="5" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel5" min="-2" max="-2" attributes="0"/> + <Component id="m_jtxtName" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="5" pref="5" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jCategory" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="5" pref="5" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jCboPriceBuy" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="m_jPriceBuy" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="5" pref="5" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jCboPriceSell" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="m_jPriceSell" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodname" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jtxtName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodcategory" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCategory"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodpricebuy" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCboPriceBuy"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jCboPriceBuyActionPerformed"/> + </Events> + </Component> + <Component class="com.unicenta.editor.JEditorCurrency" name="m_jPriceBuy"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodpricesell" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCboPriceSell"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorCurrency" name="m_jPriceSell"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jtxtBarCode"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodbarcode" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/ticket/LocationFilterSales.java b/src/main/java/com/unicenta/pos/ticket/LocationFilterSales.java new file mode 100644 index 0000000..edb1484 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/LocationFilterSales.java @@ -0,0 +1,288 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +import java.util.List; +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.gui.ListQBFModelNumber; +import com.unicenta.data.loader.QBFCompareEnum; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.user.EditorCreator; +import com.unicenta.editor.JEditorKeys; +import com.unicenta.editor.JEditorString; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSales; + +/** + * + * @author JG uniCenta + */ +public class LocationFilterSales extends javax.swing.JPanel implements EditorCreator { + + private SentenceList m_sentcat; + private ComboBoxValModel m_CategoryModel; + + /** Creates new form ProductFilterSales + * @param dlSales + * @param jKeys */ + public LocationFilterSales(DataLogicSales dlSales, JEditorKeys jKeys) { + initComponents(); + + // El modelo de categorias + m_sentcat = dlSales.getCategoriesList(); + m_CategoryModel = new ComboBoxValModel(); + +// m_jCboPriceBuy.setModel(new ListQBFModelNumber()); + m_jCboPriceBuy.setModel(ListQBFModelNumber.getMandatoryNumber()); + m_jPriceBuy.addEditorKeys(jKeys); + +// m_jCboPriceSell.setModel(new ListQBFModelNumber()); + m_jCboPriceSell.setModel(ListQBFModelNumber.getMandatoryNumber()); + m_jPriceSell.addEditorKeys(jKeys); + + m_jtxtName.addEditorKeys(jKeys); + + m_jtxtBarCode.addEditorKeys(jKeys); + } + + /** + * + */ + public void activate() { + + m_jtxtBarCode.reset(); + m_jtxtBarCode.setEditModeEnum(JEditorString.MODE_123); + m_jtxtName.reset(); + m_jPriceBuy.reset(); + m_jPriceSell.reset(); + m_jtxtName.activate(); + + try { + List catlist = m_sentcat.list(); + catlist.add(0, null); + m_CategoryModel = new ComboBoxValModel(catlist); + m_jCategory.setModel(m_CategoryModel); + } catch (BasicException eD) { + // no hay validacion + } + } + + /** + * + * @return + * @throws BasicException + */ + public Object createValue() throws BasicException { + + Object[] afilter = new Object[10]; + + // Nombre + if (m_jtxtName.getText() == null || m_jtxtName.getText().equals("")) { + afilter[0] = QBFCompareEnum.COMP_NONE; + afilter[1] = null; + } else { + afilter[0] = QBFCompareEnum.COMP_RE; + afilter[1] = "%" + m_jtxtName.getText() + "%"; + } + + // Precio de compra + afilter[3] = m_jPriceBuy.getDoubleValue(); + afilter[2] = afilter[3] == null ? QBFCompareEnum.COMP_NONE : m_jCboPriceBuy.getSelectedItem(); + + // Precio de venta + afilter[5] = m_jPriceSell.getDoubleValue(); + afilter[4] = afilter[5] == null ? QBFCompareEnum.COMP_NONE : m_jCboPriceSell.getSelectedItem(); + + // Categoria + if (m_CategoryModel.getSelectedKey() == null) { + afilter[6] = QBFCompareEnum.COMP_NONE; + afilter[7] = null; + } else { + afilter[6] = QBFCompareEnum.COMP_EQUALS; + afilter[7] = m_CategoryModel.getSelectedKey(); + } + + // el codigo de barras + if (m_jtxtBarCode.getText() == null || m_jtxtBarCode.getText().equals("")) { + afilter[8] = QBFCompareEnum.COMP_NONE; + afilter[9] = null; + } else{ + afilter[8] = QBFCompareEnum.COMP_RE; + afilter[9] = "%" + m_jtxtBarCode.getText() + "%"; + } + + return afilter; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel5 = new javax.swing.JLabel(); + m_jtxtName = new com.unicenta.editor.JEditorString(); + jLabel2 = new javax.swing.JLabel(); + m_jCategory = new javax.swing.JComboBox(); + jLabel4 = new javax.swing.JLabel(); + m_jCboPriceBuy = new javax.swing.JComboBox(); + m_jPriceBuy = new com.unicenta.editor.JEditorCurrency(); + jLabel3 = new javax.swing.JLabel(); + m_jCboPriceSell = new javax.swing.JComboBox(); + m_jPriceSell = new com.unicenta.editor.JEditorCurrency(); + m_jtxtBarCode = new com.unicenta.editor.JEditorString(); + jLabel1 = new javax.swing.JLabel(); + + setPreferredSize(new java.awt.Dimension(370, 170)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.prodname")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(0, 30)); + + m_jtxtName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jtxtName.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.prodcategory")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(0, 30)); + + m_jCategory.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCategory.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.prodpricebuy")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(0, 30)); + + m_jCboPriceBuy.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCboPriceBuy.setPreferredSize(new java.awt.Dimension(0, 30)); + m_jCboPriceBuy.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jCboPriceBuyActionPerformed(evt); + } + }); + + m_jPriceBuy.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPriceBuy.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.prodpricesell")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(0, 30)); + + m_jCboPriceSell.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCboPriceSell.setPreferredSize(new java.awt.Dimension(0, 30)); + + m_jPriceSell.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPriceSell.setPreferredSize(new java.awt.Dimension(0, 30)); + + m_jtxtBarCode.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jtxtBarCode.setMaximumSize(new java.awt.Dimension(100, 25)); + m_jtxtBarCode.setPreferredSize(new java.awt.Dimension(0, 30)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.prodbarcode")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(0, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(m_jCboPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(m_jPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, 130, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(m_jtxtBarCode, javax.swing.GroupLayout.PREFERRED_SIZE, 290, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(m_jtxtName, javax.swing.GroupLayout.PREFERRED_SIZE, 290, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, 260, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(m_jCboPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(m_jPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, 130, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jtxtBarCode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(5, 5, 5) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jtxtName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(5, 5, 5) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(5, 5, 5) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jCboPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(m_jPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(5, 5, 5) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jCboPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(m_jPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + ); + }// </editor-fold>//GEN-END:initComponents + + private void m_jCboPriceBuyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jCboPriceBuyActionPerformed + + }//GEN-LAST:event_m_jCboPriceBuyActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JComboBox m_jCategory; + private javax.swing.JComboBox m_jCboPriceBuy; + private javax.swing.JComboBox m_jCboPriceSell; + private com.unicenta.editor.JEditorCurrency m_jPriceBuy; + private com.unicenta.editor.JEditorCurrency m_jPriceSell; + private com.unicenta.editor.JEditorString m_jtxtBarCode; + private com.unicenta.editor.JEditorString m_jtxtName; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/ticket/ProductFilter.form b/src/main/java/com/unicenta/pos/ticket/ProductFilter.form new file mode 100644 index 0000000..09bc099 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/ProductFilter.form @@ -0,0 +1,265 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[976, 125]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel1" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCategory" min="-2" max="-2" attributes="1"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel5" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jBarcode" max="32767" attributes="0"/> + <EmptySpace min="-2" pref="2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel2" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCboName" max="32767" attributes="1"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel4" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCboPriceBuy" min="-2" max="-2" attributes="2"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jPriceBuy" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel3" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCboPriceSell" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jPriceSell" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="m_jName" min="-2" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="jBtnReset" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace pref="189" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="2" attributes="0"> + <Component id="jLabel1" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="m_jCategory" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="jLabel4" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="m_jCboPriceBuy" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="m_jPriceBuy" alignment="2" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="2" attributes="0"> + <Component id="jLabel5" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="m_jBarcode" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="jLabel3" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="m_jCboPriceSell" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="m_jPriceSell" alignment="2" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="2" attributes="0"> + <Component id="jLabel2" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="m_jCboName" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="m_jName" alignment="2" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace pref="12" max="32767" attributes="0"/> + </Group> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace max="32767" attributes="0"/> + <Component id="jBtnReset" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodcategory" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCategory"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodbarcode" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jBarcode"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodname" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCboName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[330, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodpricebuy" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCboPriceBuy"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jPriceBuy"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodpricesell" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCboPriceSell"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jPriceSell"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jBtnReset"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/reload.png"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnResetActionPerformed"/> + </Events> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/ticket/ProductFilter.java b/src/main/java/com/unicenta/pos/ticket/ProductFilter.java new file mode 100644 index 0000000..3f9119b --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/ProductFilter.java @@ -0,0 +1,318 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.gui.ListQBFModelNumber; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.loader.QBFCompareEnum; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.loader.SerializerWrite; +import com.unicenta.data.loader.SerializerWriteBasic; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.reports.ReportEditorCreator; +import java.awt.Component; +import java.util.List; + +/** + * + * @author JG uniCenta + */ +public class ProductFilter extends javax.swing.JPanel implements ReportEditorCreator { + + private SentenceList m_sentcat; + private ComboBoxValModel m_CategoryModel; + +// private SentenceList m_sentsup; +// private ComboBoxValModel m_SupplierModel; + + /** Creates new form JQBFProduct */ + public ProductFilter() { + + initComponents(); + } + + /** + * + * @param app + */ + @Override + public void init(AppView app) { + + DataLogicSales dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + + m_sentcat = dlSales.getCategoriesList(); + m_CategoryModel = new ComboBoxValModel(); + + m_jCboName.setModel(ListQBFModelNumber.getMandatoryString()); + m_jCboPriceBuy.setModel(ListQBFModelNumber.getMandatoryNumber()); + m_jCboPriceSell.setModel(ListQBFModelNumber.getMandatoryNumber()); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + + List catlist = m_sentcat.list(); + catlist.add(0, null); + m_CategoryModel = new ComboBoxValModel(catlist); + m_jCategory.setModel(m_CategoryModel); + + } + + /** + * + * @return + */ + @Override + public SerializerWrite getSerializerWrite() { + return new SerializerWriteBasic( + new Datas[] { + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.DOUBLE, + Datas.OBJECT, Datas.DOUBLE, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING}); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + if (m_jBarcode.getText() == null || m_jBarcode.getText().equals("")) { + + return new Object[] { + m_jCboName.getSelectedItem(), m_jName.getText(), + m_jCboPriceBuy.getSelectedItem(), Formats.CURRENCY.parseValue(m_jPriceBuy.getText()), + m_jCboPriceSell.getSelectedItem(), Formats.CURRENCY.parseValue(m_jPriceSell.getText()), + m_CategoryModel.getSelectedKey() == null ? QBFCompareEnum.COMP_NONE : QBFCompareEnum.COMP_EQUALS, m_CategoryModel.getSelectedKey(), +// m_SupplierModel.getSelectedKey() == null ? QBFCompareEnum.COMP_NONE : QBFCompareEnum.COMP_EQUALS, m_SupplierModel.getSelectedKey(), + QBFCompareEnum.COMP_NONE, null + }; + } else { + return new Object[] { + QBFCompareEnum.COMP_NONE, null, + QBFCompareEnum.COMP_NONE, null, + QBFCompareEnum.COMP_NONE, null, + QBFCompareEnum.COMP_NONE, null, + QBFCompareEnum.COMP_EQUALS, m_jBarcode.getText() + }; + } + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel1 = new javax.swing.JLabel(); + m_jCategory = new javax.swing.JComboBox(); + jLabel5 = new javax.swing.JLabel(); + m_jBarcode = new javax.swing.JTextField(); + jLabel2 = new javax.swing.JLabel(); + m_jCboName = new javax.swing.JComboBox(); + m_jName = new javax.swing.JTextField(); + jLabel4 = new javax.swing.JLabel(); + m_jCboPriceBuy = new javax.swing.JComboBox(); + m_jPriceBuy = new javax.swing.JTextField(); + jLabel3 = new javax.swing.JLabel(); + m_jCboPriceSell = new javax.swing.JComboBox(); + m_jPriceSell = new javax.swing.JTextField(); + jBtnReset = new javax.swing.JButton(); + + setPreferredSize(new java.awt.Dimension(976, 125)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.prodcategory")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jCategory.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCategory.setPreferredSize(new java.awt.Dimension(250, 30)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.prodbarcode")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jBarcode.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jBarcode.setPreferredSize(new java.awt.Dimension(250, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.prodname")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jCboName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCboName.setPreferredSize(new java.awt.Dimension(250, 30)); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(330, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.prodpricebuy")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jCboPriceBuy.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCboPriceBuy.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jPriceBuy.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPriceBuy.setPreferredSize(new java.awt.Dimension(60, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.prodpricesell")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jCboPriceSell.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCboPriceSell.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jPriceSell.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPriceSell.setPreferredSize(new java.awt.Dimension(60, 30)); + + jBtnReset.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jBtnReset.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reload.png"))); // NOI18N + jBtnReset.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnResetActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jBarcode, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(2, 2, 2)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCboName, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCboPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCboPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(jBtnReset))) + .addContainerGap(189, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCboPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jBarcode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCboPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCboName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(12, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jBtnReset) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + private void jBtnResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnResetActionPerformed + m_jBarcode.setText(null); + m_jCategory.setSelectedIndex(0); + m_jCboName.setSelectedIndex(0); + m_jCboPriceBuy.setSelectedIndex(0); + m_jCboPriceSell.setSelectedIndex(0); + m_jName.setText(null); + m_jPriceBuy.setText(null); + m_jPriceSell.setText(null); + }//GEN-LAST:event_jBtnResetActionPerformed + + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jBtnReset; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JTextField m_jBarcode; + private javax.swing.JComboBox m_jCategory; + private javax.swing.JComboBox m_jCboName; + private javax.swing.JComboBox m_jCboPriceBuy; + private javax.swing.JComboBox m_jCboPriceSell; + private javax.swing.JTextField m_jName; + private javax.swing.JTextField m_jPriceBuy; + private javax.swing.JTextField m_jPriceSell; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/ticket/ProductFilter1.form b/src/main/java/com/unicenta/pos/ticket/ProductFilter1.form new file mode 100644 index 0000000..e02df0d --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/ProductFilter1.form @@ -0,0 +1,204 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[946, 50]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel2" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCboName" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jName" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel1" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCategory" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel5" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jBarcode" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel3" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCboUnits" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jUnits" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jBtnReset" min="-2" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jBtnReset" min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCboName" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jName" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCategory" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jBarcode" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCboUnits" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jUnits" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JTextField" name="m_jBarcode"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodbarcode" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodcategory" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodname" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCategory"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCboName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.produnits" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCboUnits"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jUnits"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[50, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jBtnReset"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/reload.png"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnResetActionPerformed"/> + </Events> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/ticket/ProductFilter1.java b/src/main/java/com/unicenta/pos/ticket/ProductFilter1.java new file mode 100644 index 0000000..5a55ee9 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/ProductFilter1.java @@ -0,0 +1,269 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.gui.ListQBFModelNumber; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.loader.QBFCompareEnum; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.loader.SerializerWrite; +import com.unicenta.data.loader.SerializerWriteBasic; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.reports.ReportEditorCreator; +import java.awt.Component; +import java.util.List; + +/** + * + * @author JG uniCenta + */ +public class ProductFilter1 extends javax.swing.JPanel implements ReportEditorCreator { + + private SentenceList m_sentcat; + private ComboBoxValModel m_CategoryModel; + + /** Creates new form JQBFProduct */ + public ProductFilter1() { + + initComponents(); + } + + /** + * + * @param app + */ + public void init(AppView app) { + + DataLogicSales dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + + m_sentcat = dlSales.getCategoriesList(); + m_CategoryModel = new ComboBoxValModel(); + m_jCboName.setModel(ListQBFModelNumber.getMandatoryString()); + m_jCboUnits.setModel(ListQBFModelNumber.getMandatoryString()); + + } + + /** + * + * @throws BasicException + */ + public void activate() throws BasicException { + + List catlist = m_sentcat.list(); + catlist.add(0, null); + m_CategoryModel = new ComboBoxValModel(catlist); + m_jCategory.setModel(m_CategoryModel); + } + + /** + * + * @return + */ + public SerializerWrite getSerializerWrite() { + return new SerializerWriteBasic( + new Datas[] { + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING}); + } + + /** + * + * @return + */ + public Component getComponent() { + return this; + } + + /** + * + * @return + * @throws BasicException + */ + public Object createValue() throws BasicException { + + if (m_jBarcode.getText() == null || m_jBarcode.getText().equals("")) { + + return new Object[] { + m_jCboName.getSelectedItem(), m_jName.getText(), + m_CategoryModel.getSelectedKey() == null + ? QBFCompareEnum.COMP_NONE + : QBFCompareEnum.COMP_EQUALS, m_CategoryModel.getSelectedKey(), + QBFCompareEnum.COMP_NONE, null, + m_jCboUnits.getSelectedItem(), m_jUnits.getText() + }; + } else { + // Filtro por codigo de barras. + return new Object[] { + QBFCompareEnum.COMP_NONE, null, + QBFCompareEnum.COMP_NONE, null, + QBFCompareEnum.COMP_RE, "%" + m_jBarcode.getText() + "%", + QBFCompareEnum.COMP_NONE, null + }; + } + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jBarcode = new javax.swing.JTextField(); + jLabel5 = new javax.swing.JLabel(); + jLabel1 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + m_jCategory = new javax.swing.JComboBox(); + m_jCboName = new javax.swing.JComboBox(); + m_jName = new javax.swing.JTextField(); + jLabel3 = new javax.swing.JLabel(); + m_jCboUnits = new javax.swing.JComboBox(); + m_jUnits = new javax.swing.JTextField(); + jBtnReset = new javax.swing.JButton(); + + setPreferredSize(new java.awt.Dimension(946, 50)); + + m_jBarcode.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jBarcode.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.prodbarcode")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(70, 30)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.prodcategory")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(70, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.prodname")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(70, 30)); + + m_jCategory.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCategory.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jCboName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCboName.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.produnits")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(50, 30)); + + m_jCboUnits.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCboUnits.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jUnits.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jUnits.setPreferredSize(new java.awt.Dimension(50, 30)); + + jBtnReset.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jBtnReset.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reload.png"))); // NOI18N + jBtnReset.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnResetActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCboName, 0, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jBarcode, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCboUnits, 0, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jUnits, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jBtnReset) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jBtnReset) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCboName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jBarcode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCboUnits, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jUnits, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + private void jBtnResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnResetActionPerformed + m_jBarcode.setText(null); + m_jCategory.setSelectedIndex(0); + m_jCboName.setSelectedIndex(0); + m_jCboUnits.setSelectedIndex(0); + m_jName.setText(null); + m_jUnits.setText(null); + }//GEN-LAST:event_jBtnResetActionPerformed + + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jBtnReset; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel5; + private javax.swing.JTextField m_jBarcode; + private javax.swing.JComboBox m_jCategory; + private javax.swing.JComboBox m_jCboName; + private javax.swing.JComboBox m_jCboUnits; + private javax.swing.JTextField m_jName; + private javax.swing.JTextField m_jUnits; + // End of variables declaration//GEN-END:variables + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/ticket/ProductFilter2.form b/src/main/java/com/unicenta/pos/ticket/ProductFilter2.form new file mode 100644 index 0000000..93a40cd --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/ProductFilter2.form @@ -0,0 +1,278 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[976, 100]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel1" min="-2" pref="66" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCategory" min="-2" pref="46" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel4" min="-2" pref="74" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCboPriceBuy" min="-2" pref="36" max="-2" attributes="2"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jPriceBuy" min="-2" pref="50" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel3" min="-2" pref="50" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCboPriceSell" min="-2" pref="42" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jPriceSell" min="-2" pref="36" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="1" attributes="0"> + <Component id="jLabel2" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCboName" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jName" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel5" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jBarcode" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jBtnReset" min="-2" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="2" attributes="0"> + <Component id="jBtnReset" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="m_jBarcode" alignment="2" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" alignment="0" groupAlignment="3" attributes="0"> + <Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCboPriceBuy" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jPriceBuy" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCboPriceSell" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jPriceSell" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="103" alignment="0" groupAlignment="3" attributes="0"> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCategory" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <Group type="102" attributes="0"> + <EmptySpace min="12" pref="12" max="-2" attributes="0"/> + <Component id="m_jName" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <EmptySpace min="11" pref="11" max="-2" attributes="0"/> + <Component id="m_jCboName" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <EmptySpace min="11" pref="11" max="-2" attributes="0"/> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <EmptySpace min="11" pref="11" max="-2" attributes="0"/> + <Component id="jLabel5" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JTextField" name="m_jBarcode"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodbarcode" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodcategory" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodname" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCategory"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCboName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodpricebuy" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodpricesell" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCboPriceBuy"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCboPriceSell"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jPriceBuy"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jPriceSell"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jBtnReset"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/reload.png"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnResetActionPerformed"/> + </Events> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/ticket/ProductFilter2.java b/src/main/java/com/unicenta/pos/ticket/ProductFilter2.java new file mode 100644 index 0000000..a703195 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/ProductFilter2.java @@ -0,0 +1,321 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.gui.ListQBFModelNumber; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.loader.QBFCompareEnum; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.loader.SerializerWrite; +import com.unicenta.data.loader.SerializerWriteBasic; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.reports.ReportEditorCreator; +import java.awt.Component; +import java.util.List; + +/** + * + * @author JG uniCenta + */ +public class ProductFilter2 extends javax.swing.JPanel implements ReportEditorCreator { + + private SentenceList m_sentcat; + private ComboBoxValModel m_CategoryModel; + + /** Creates new form JQBFProduct */ + public ProductFilter2() { + + initComponents(); + } + + /** + * + * @param app + */ + public void init(AppView app) { + + DataLogicSales dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + + m_sentcat = dlSales.getCategoriesList(); + m_CategoryModel = new ComboBoxValModel(); + + m_jCboName.setModel(ListQBFModelNumber.getMandatoryString()); + m_jCboPriceBuy.setModel(ListQBFModelNumber.getMandatoryNumber()); + m_jCboPriceSell.setModel(ListQBFModelNumber.getMandatoryNumber()); + } + + /** + * + * @throws BasicException + */ + public void activate() throws BasicException { + + List catlist = m_sentcat.list(); + catlist.add(0, null); + m_CategoryModel = new ComboBoxValModel(catlist); + m_jCategory.setModel(m_CategoryModel); + } + + /** + * + * @return + */ + public SerializerWrite getSerializerWrite() { + return new SerializerWriteBasic( + new Datas[] { + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.DOUBLE, + Datas.OBJECT, Datas.DOUBLE, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING}); + } + + /** + * + * @return + */ + public Component getComponent() { + return this; + } + + /** + * + * @return + * @throws BasicException + */ + public Object createValue() throws BasicException { + + if (m_jBarcode.getText() == null || m_jBarcode.getText().equals("")) { + + return new Object[] { + m_jCboName.getSelectedItem(), m_jName.getText(), + m_jCboPriceBuy.getSelectedItem(), Formats.CURRENCY.parseValue(m_jPriceBuy.getText()), + m_jCboPriceSell.getSelectedItem(), Formats.CURRENCY.parseValue(m_jPriceSell.getText()), + m_CategoryModel.getSelectedKey() == null ? QBFCompareEnum.COMP_NONE : QBFCompareEnum.COMP_EQUALS, m_CategoryModel.getSelectedKey(), + QBFCompareEnum.COMP_NONE, null + }; + } else { + // Filtro por codigo de barras. + return new Object[] { + QBFCompareEnum.COMP_NONE, null, + QBFCompareEnum.COMP_NONE, null, + QBFCompareEnum.COMP_NONE, null, + QBFCompareEnum.COMP_NONE, null, + QBFCompareEnum.COMP_EQUALS, m_jBarcode.getText() + }; + } + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jBarcode = new javax.swing.JTextField(); + jLabel5 = new javax.swing.JLabel(); + jLabel1 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + m_jCategory = new javax.swing.JComboBox(); + m_jCboName = new javax.swing.JComboBox(); + m_jName = new javax.swing.JTextField(); + jLabel4 = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + m_jCboPriceBuy = new javax.swing.JComboBox(); + m_jCboPriceSell = new javax.swing.JComboBox(); + m_jPriceBuy = new javax.swing.JTextField(); + m_jPriceSell = new javax.swing.JTextField(); + jBtnReset = new javax.swing.JButton(); + + setPreferredSize(new java.awt.Dimension(976, 100)); + + m_jBarcode.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jBarcode.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.prodbarcode")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.prodcategory")); // NOI18N + jLabel1.setEnabled(false); + jLabel1.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.prodname")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jCategory.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCategory.setEnabled(false); + m_jCategory.setPreferredSize(new java.awt.Dimension(250, 30)); + + m_jCboName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCboName.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.prodpricebuy")); // NOI18N + jLabel4.setEnabled(false); + jLabel4.setPreferredSize(new java.awt.Dimension(110, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.prodpricesell")); // NOI18N + jLabel3.setEnabled(false); + jLabel3.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jCboPriceBuy.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCboPriceBuy.setEnabled(false); + m_jCboPriceBuy.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jCboPriceSell.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCboPriceSell.setEnabled(false); + m_jCboPriceSell.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jPriceBuy.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPriceBuy.setEnabled(false); + m_jPriceBuy.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jPriceSell.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPriceSell.setEnabled(false); + m_jPriceSell.setPreferredSize(new java.awt.Dimension(150, 30)); + + jBtnReset.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jBtnReset.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reload.png"))); // NOI18N + jBtnReset.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnResetActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 66, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 74, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCboPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCboPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCboName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jBarcode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jBtnReset) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jBtnReset) + .addComponent(m_jBarcode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCboPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCboPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addGroup(layout.createSequentialGroup() + .addGap(12, 12, 12) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addGap(11, 11, 11) + .addComponent(m_jCboName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addGap(11, 11, 11) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addGap(11, 11, 11) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + private void jBtnResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnResetActionPerformed + m_jBarcode.setText(null); + m_jCategory.setSelectedIndex(0); + m_jCboName.setSelectedIndex(0); + m_jCboPriceBuy.setSelectedIndex(0); + m_jCboPriceSell.setSelectedIndex(0); + m_jName.setText(null); + m_jPriceBuy.setText(null); + m_jPriceSell.setText(null); + }//GEN-LAST:event_jBtnResetActionPerformed + + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jBtnReset; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JTextField m_jBarcode; + private javax.swing.JComboBox m_jCategory; + private javax.swing.JComboBox m_jCboName; + private javax.swing.JComboBox m_jCboPriceBuy; + private javax.swing.JComboBox m_jCboPriceSell; + private javax.swing.JTextField m_jName; + private javax.swing.JTextField m_jPriceBuy; + private javax.swing.JTextField m_jPriceSell; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/ticket/ProductFilter3.form b/src/main/java/com/unicenta/pos/ticket/ProductFilter3.form new file mode 100644 index 0000000..0c28f17 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/ProductFilter3.form @@ -0,0 +1,291 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[976, 100]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" max="-2" attributes="0"> + <Group type="102" alignment="1" attributes="0"> + <Component id="jLabel2" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCboName" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jName" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel1" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCategory" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel6" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jSupplier" min="-2" max="-2" attributes="1"/> + </Group> + <Group type="102" alignment="1" attributes="0"> + <Component id="jLabel5" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jBarcode" min="-2" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + <Component id="jLabel4" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCboPriceBuy" min="-2" max="-2" attributes="2"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jPriceBuy" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel3" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCboPriceSell" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jPriceSell" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Component id="jBtnReset" min="-2" max="-2" attributes="0"/> + <EmptySpace pref="59" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" attributes="0"> + <Component id="jBtnReset" min="-2" max="-2" attributes="0"/> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" alignment="0" groupAlignment="3" attributes="0"> + <Component id="jLabel6" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jSupplier" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCboName" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jName" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCategory" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" alignment="0" groupAlignment="3" attributes="0"> + <Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jBarcode" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCboPriceBuy" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jPriceBuy" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCboPriceSell" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jPriceSell" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JTextField" name="m_jBarcode"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodbarcode" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodcategory" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodname" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCategory"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCboName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodpricebuy" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodpricesell" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCboPriceBuy"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCboPriceSell"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jPriceBuy"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jPriceSell"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodsupplier" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jSupplier"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jBtnReset"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/reload.png"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnResetActionPerformed"/> + </Events> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/ticket/ProductFilter3.java b/src/main/java/com/unicenta/pos/ticket/ProductFilter3.java new file mode 100644 index 0000000..64cc9c8 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/ProductFilter3.java @@ -0,0 +1,344 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.gui.ListQBFModelNumber; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.loader.QBFCompareEnum; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.loader.SerializerWrite; +import com.unicenta.data.loader.SerializerWriteBasic; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.reports.ReportEditorCreator; +import com.unicenta.pos.suppliers.DataLogicSuppliers; +import java.awt.Component; +import java.util.List; + +/** + * + * @author JG uniCenta + */ +public class ProductFilter3 extends javax.swing.JPanel implements ReportEditorCreator { + + private SentenceList m_sentcat; + private ComboBoxValModel m_CategoryModel; + + private SentenceList m_sentsup; + private ComboBoxValModel m_SupplierModel; + + /** Creates new form JQBFProduct */ + public ProductFilter3() { + + initComponents(); + } + + /** + * + * @param app + */ + @Override + public void init(AppView app) { + + DataLogicSales dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + DataLogicSuppliers dlSuppliers = (DataLogicSuppliers) app.getBean("com.unicenta.pos.suppliers.DataLogicSuppliers"); + + m_sentcat = dlSales.getCategoriesList(); + m_CategoryModel = new ComboBoxValModel(); + + m_sentsup = dlSuppliers.getSupplierList(); + m_SupplierModel = new ComboBoxValModel(); + + m_jCboName.setModel(ListQBFModelNumber.getMandatoryString()); + m_jCboPriceBuy.setModel(ListQBFModelNumber.getMandatoryNumber()); + m_jCboPriceSell.setModel(ListQBFModelNumber.getMandatoryNumber()); + } + + /** + * + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + + List catlist = m_sentcat.list(); + catlist.add(0, null); + m_CategoryModel = new ComboBoxValModel(catlist); + m_jCategory.setModel(m_CategoryModel); + + List suplist = m_sentsup.list(); + suplist.add(0, null); + m_SupplierModel = new ComboBoxValModel(suplist); + m_jSupplier.setModel(m_SupplierModel); + } + + /** + * + * @return + */ + @Override + public SerializerWrite getSerializerWrite() { + return new SerializerWriteBasic( + new Datas[] { + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.DOUBLE, + Datas.OBJECT, Datas.DOUBLE, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING}); + } + + /** + * + * @return + */ + @Override + public Component getComponent() { + return this; + } + + /** + * + * @return + * @throws BasicException + */ + @Override + public Object createValue() throws BasicException { + + if (m_jBarcode.getText() == null || m_jBarcode.getText().equals("")) { + + return new Object[] { + m_jCboName.getSelectedItem(), m_jName.getText(), + m_jCboPriceBuy.getSelectedItem(), Formats.CURRENCY.parseValue(m_jPriceBuy.getText()), + m_jCboPriceSell.getSelectedItem(), Formats.CURRENCY.parseValue(m_jPriceSell.getText()), + m_CategoryModel.getSelectedKey() == null ? QBFCompareEnum.COMP_NONE : QBFCompareEnum.COMP_EQUALS, m_CategoryModel.getSelectedKey(), + m_SupplierModel.getSelectedKey() == null ? QBFCompareEnum.COMP_NONE : QBFCompareEnum.COMP_EQUALS, m_SupplierModel.getSelectedKey(), + QBFCompareEnum.COMP_NONE, null + }; + } else { + return new Object[] { + QBFCompareEnum.COMP_NONE, null, + QBFCompareEnum.COMP_NONE, null, + QBFCompareEnum.COMP_NONE, null, + QBFCompareEnum.COMP_NONE, null, + QBFCompareEnum.COMP_NONE, null, + QBFCompareEnum.COMP_EQUALS, m_jBarcode.getText() + }; + } + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jBarcode = new javax.swing.JTextField(); + jLabel5 = new javax.swing.JLabel(); + jLabel1 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + m_jCategory = new javax.swing.JComboBox(); + m_jCboName = new javax.swing.JComboBox(); + m_jName = new javax.swing.JTextField(); + jLabel4 = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + m_jCboPriceBuy = new javax.swing.JComboBox(); + m_jCboPriceSell = new javax.swing.JComboBox(); + m_jPriceBuy = new javax.swing.JTextField(); + m_jPriceSell = new javax.swing.JTextField(); + jLabel6 = new javax.swing.JLabel(); + m_jSupplier = new javax.swing.JComboBox(); + jBtnReset = new javax.swing.JButton(); + + setPreferredSize(new java.awt.Dimension(976, 100)); + + m_jBarcode.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jBarcode.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.prodbarcode")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.prodcategory")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.prodname")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jCategory.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCategory.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jCboName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCboName.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.prodpricebuy")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.prodpricesell")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jCboPriceBuy.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCboPriceBuy.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jCboPriceSell.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCboPriceSell.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jPriceBuy.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPriceBuy.setPreferredSize(new java.awt.Dimension(60, 30)); + + m_jPriceSell.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPriceSell.setPreferredSize(new java.awt.Dimension(60, 30)); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel6.setText(AppLocal.getIntString("label.prodsupplier")); // NOI18N + jLabel6.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jSupplier.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jSupplier.setPreferredSize(new java.awt.Dimension(150, 30)); + + jBtnReset.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jBtnReset.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reload.png"))); // NOI18N + jBtnReset.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnResetActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCboName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jSupplier, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jBarcode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCboPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCboPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jBtnReset) + .addContainerGap(59, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jBtnReset) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jSupplier, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCboName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jBarcode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCboPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCboPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + private void jBtnResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnResetActionPerformed + m_jBarcode.setText(null); + m_jCategory.setSelectedIndex(0); + m_jCboName.setSelectedIndex(0); + m_jCboPriceBuy.setSelectedIndex(0); + m_jCboPriceSell.setSelectedIndex(0); + m_jName.setText(null); + m_jPriceBuy.setText(null); + m_jPriceSell.setText(null); + }//GEN-LAST:event_jBtnResetActionPerformed + + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jBtnReset; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JTextField m_jBarcode; + private javax.swing.JComboBox m_jCategory; + private javax.swing.JComboBox m_jCboName; + private javax.swing.JComboBox m_jCboPriceBuy; + private javax.swing.JComboBox m_jCboPriceSell; + private javax.swing.JTextField m_jName; + private javax.swing.JTextField m_jPriceBuy; + private javax.swing.JTextField m_jPriceSell; + private javax.swing.JComboBox m_jSupplier; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/ticket/ProductFilter4.form b/src/main/java/com/unicenta/pos/ticket/ProductFilter4.form new file mode 100644 index 0000000..d686077 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/ProductFilter4.form @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[946, 50]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel2" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCboName" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jName" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel1" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCategory" min="-2" max="-2" attributes="1"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel5" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jBarcode" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jBtnReset" min="-2" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jBtnReset" min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCboName" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jName" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCategory" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jBarcode" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JTextField" name="m_jBarcode"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodbarcode" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodcategory" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodname" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCategory"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCboName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jBtnReset"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/reload.png"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnResetActionPerformed"/> + </Events> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/ticket/ProductFilter4.java b/src/main/java/com/unicenta/pos/ticket/ProductFilter4.java new file mode 100644 index 0000000..288a8e8 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/ProductFilter4.java @@ -0,0 +1,236 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.gui.ListQBFModelNumber; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.loader.QBFCompareEnum; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.loader.SerializerWrite; +import com.unicenta.data.loader.SerializerWriteBasic; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSales; +import com.unicenta.pos.reports.ReportEditorCreator; +import java.awt.Component; +import java.util.List; + +/** + * + * @author JG uniCenta + */ +public class ProductFilter4 extends javax.swing.JPanel implements ReportEditorCreator { + + private SentenceList m_sentcat; + private ComboBoxValModel m_CategoryModel; + + /** Creates new form JQBFProduct */ + public ProductFilter4() { + + initComponents(); + } + + /** + * + * @param app + */ + public void init(AppView app) { + + DataLogicSales dlSales = (DataLogicSales) app.getBean("com.unicenta.pos.forms.DataLogicSales"); + + m_sentcat = dlSales.getCategoriesList(); + m_CategoryModel = new ComboBoxValModel(); + m_jCboName.setModel(ListQBFModelNumber.getMandatoryString()); + } + + /** + * + * @throws BasicException + */ + public void activate() throws BasicException { + + List catlist = m_sentcat.list(); + catlist.add(0, null); + m_CategoryModel = new ComboBoxValModel(catlist); + m_jCategory.setModel(m_CategoryModel); + } + + /** + * + * @return + */ + public SerializerWrite getSerializerWrite() { + return new SerializerWriteBasic( + new Datas[] { + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING, + Datas.OBJECT, Datas.STRING}); + } + + /** + * + * @return + */ + public Component getComponent() { + return this; + } + + /** + * + * @return + * @throws BasicException + */ + public Object createValue() throws BasicException { + + if (m_jBarcode.getText() == null || m_jBarcode.getText().equals("")) { + + return new Object[] { + m_jCboName.getSelectedItem(), m_jName.getText(), + m_CategoryModel.getSelectedKey() == null + ? QBFCompareEnum.COMP_NONE + : QBFCompareEnum.COMP_EQUALS, m_CategoryModel.getSelectedKey(), + QBFCompareEnum.COMP_NONE, null + }; + } else { + // Filtro por codigo de barras. + return new Object[] { + QBFCompareEnum.COMP_NONE, null, + QBFCompareEnum.COMP_NONE, null, + QBFCompareEnum.COMP_RE, "%" + m_jBarcode.getText() + "%" + }; + } + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + m_jBarcode = new javax.swing.JTextField(); + jLabel5 = new javax.swing.JLabel(); + jLabel1 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + m_jCategory = new javax.swing.JComboBox(); + m_jCboName = new javax.swing.JComboBox(); + m_jName = new javax.swing.JTextField(); + jBtnReset = new javax.swing.JButton(); + + setPreferredSize(new java.awt.Dimension(946, 50)); + + m_jBarcode.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jBarcode.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.prodbarcode")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.prodcategory")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.prodname")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jCategory.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCategory.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jCboName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCboName.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jName.setPreferredSize(new java.awt.Dimension(150, 30)); + + jBtnReset.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jBtnReset.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reload.png"))); // NOI18N + jBtnReset.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnResetActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCboName, 0, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jBarcode, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jBtnReset) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jBtnReset) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCboName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jBarcode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + private void jBtnResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnResetActionPerformed + m_jBarcode.setText(null); + m_jCategory.setSelectedIndex(0); + m_jCboName.setSelectedIndex(0); + m_jName.setText(null); + }//GEN-LAST:event_jBtnResetActionPerformed + + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jBtnReset; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel5; + private javax.swing.JTextField m_jBarcode; + private javax.swing.JComboBox m_jCategory; + private javax.swing.JComboBox m_jCboName; + private javax.swing.JTextField m_jName; + // End of variables declaration//GEN-END:variables + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/ticket/ProductFilterSales.form b/src/main/java/com/unicenta/pos/ticket/ProductFilterSales.form new file mode 100644 index 0000000..bd1c51b --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/ProductFilterSales.form @@ -0,0 +1,276 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[410, 200]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="-2" pref="10" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jtxtBarCode" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jBtnReset" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="41" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCategory" min="-2" pref="240" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="1" attributes="0"> + <Component id="jLabel5" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jtxtName" min="-2" pref="270" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="64" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel4" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCboPriceBuy" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jPriceBuy" pref="0" max="32767" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jCboPriceSell" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="m_jPriceSell" pref="0" max="32767" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="10" pref="10" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <Component id="m_jtxtBarCode" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel5" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jBtnReset" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="3" max="-2" attributes="0"/> + <Component id="m_jtxtName" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="m_jCategory" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="5" pref="5" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCboPriceBuy" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="m_jPriceBuy" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="5" pref="5" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCboPriceSell" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="m_jPriceSell" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodname" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jtxtName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodcategory" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCategory"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[250, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodpricebuy" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCboPriceBuy"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_jCboPriceBuyActionPerformed"/> + </Events> + </Component> + <Component class="com.unicenta.editor.JEditorCurrency" name="m_jPriceBuy"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodpricesell" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="m_jCboPriceSell"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorCurrency" name="m_jPriceSell"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.unicenta.editor.JEditorString" name="m_jtxtBarCode"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 25]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[230, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.prodbarcode" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jBtnReset"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/reload.png"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jBtnResetActionPerformed"/> + </Events> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/ticket/ProductFilterSales.java b/src/main/java/com/unicenta/pos/ticket/ProductFilterSales.java new file mode 100644 index 0000000..d7da5ad --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/ProductFilterSales.java @@ -0,0 +1,322 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +import java.util.List; +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.gui.ListQBFModelNumber; +import com.unicenta.data.loader.QBFCompareEnum; +import com.unicenta.data.loader.SentenceList; +import com.unicenta.data.user.EditorCreator; +import com.unicenta.editor.JEditorKeys; +import com.unicenta.editor.JEditorString; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.DataLogicSales; + +/** + * + * @author JG uniCenta + */ +public class ProductFilterSales extends javax.swing.JPanel implements EditorCreator { + + private SentenceList m_sentcat; + private ComboBoxValModel m_CategoryModel; + + /** Creates new form ProductFilterSales + * @param dlSales + * @param jKeys */ + public ProductFilterSales(DataLogicSales dlSales, JEditorKeys jKeys) { + initComponents(); + + // El modelo de categorias + m_sentcat = dlSales.getCategoriesList(); + m_CategoryModel = new ComboBoxValModel(); + +// m_jCboPriceBuy.setModel(new ListQBFModelNumber()); + m_jCboPriceBuy.setModel(ListQBFModelNumber.getMandatoryNumber()); + m_jPriceBuy.addEditorKeys(jKeys); + +// m_jCboPriceSell.setModel(new ListQBFModelNumber()); + m_jCboPriceSell.setModel(ListQBFModelNumber.getMandatoryNumber()); + m_jPriceSell.addEditorKeys(jKeys); + + m_jtxtName.addEditorKeys(jKeys); + + m_jtxtBarCode.addEditorKeys(jKeys); + } + + /** + * + */ + public void activate() { + + m_jtxtBarCode.reset(); + m_jtxtBarCode.setEditModeEnum(JEditorString.MODE_123); + m_jtxtName.reset(); + m_jPriceBuy.reset(); + m_jPriceSell.reset(); + m_jtxtName.activate(); + + try { + List catlist = m_sentcat.list(); + catlist.add(0, null); + m_CategoryModel = new ComboBoxValModel(catlist); + m_jCategory.setModel(m_CategoryModel); + } catch (BasicException eD) { + // no hay validacion + } + } + + /** + * + * @return + * @throws BasicException + */ + public Object createValue() throws BasicException { + + Object[] afilter = new Object[10]; + + // Nombre + if (m_jtxtName.getText() == null || m_jtxtName.getText().equals("")) { + afilter[0] = QBFCompareEnum.COMP_NONE; + afilter[1] = null; + } else { + afilter[0] = QBFCompareEnum.COMP_RE; + afilter[1] = "%" + m_jtxtName.getText() + "%"; + } + + // Precio de compra + afilter[3] = m_jPriceBuy.getDoubleValue(); + afilter[2] = afilter[3] == null ? QBFCompareEnum.COMP_NONE : m_jCboPriceBuy.getSelectedItem(); + + // Precio de venta + afilter[5] = m_jPriceSell.getDoubleValue(); + afilter[4] = afilter[5] == null ? QBFCompareEnum.COMP_NONE : m_jCboPriceSell.getSelectedItem(); + + // Categoria + if (m_CategoryModel.getSelectedKey() == null) { + afilter[6] = QBFCompareEnum.COMP_NONE; + afilter[7] = null; + } else { + afilter[6] = QBFCompareEnum.COMP_EQUALS; + afilter[7] = m_CategoryModel.getSelectedKey(); + } + + // el codigo de barras + if (m_jtxtBarCode.getText() == null || m_jtxtBarCode.getText().equals("")) { + afilter[8] = QBFCompareEnum.COMP_NONE; + afilter[9] = null; + } else{ + afilter[8] = QBFCompareEnum.COMP_RE; + afilter[9] = "%" + m_jtxtBarCode.getText() + "%"; + } + + return afilter; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel5 = new javax.swing.JLabel(); + m_jtxtName = new com.unicenta.editor.JEditorString(); + jLabel2 = new javax.swing.JLabel(); + m_jCategory = new javax.swing.JComboBox(); + jLabel4 = new javax.swing.JLabel(); + m_jCboPriceBuy = new javax.swing.JComboBox(); + m_jPriceBuy = new com.unicenta.editor.JEditorCurrency(); + jLabel3 = new javax.swing.JLabel(); + m_jCboPriceSell = new javax.swing.JComboBox(); + m_jPriceSell = new com.unicenta.editor.JEditorCurrency(); + m_jtxtBarCode = new com.unicenta.editor.JEditorString(); + jLabel1 = new javax.swing.JLabel(); + jBtnReset = new javax.swing.JButton(); + + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + setPreferredSize(new java.awt.Dimension(410, 200)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.prodname")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jtxtName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jtxtName.setPreferredSize(new java.awt.Dimension(250, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.prodcategory")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jCategory.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCategory.setPreferredSize(new java.awt.Dimension(250, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setText(AppLocal.getIntString("label.prodpricebuy")); // NOI18N + jLabel4.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jCboPriceBuy.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCboPriceBuy.setPreferredSize(new java.awt.Dimension(150, 30)); + m_jCboPriceBuy.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + m_jCboPriceBuyActionPerformed(evt); + } + }); + + m_jPriceBuy.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPriceBuy.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.prodpricesell")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(110, 30)); + + m_jCboPriceSell.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCboPriceSell.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jPriceSell.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jPriceSell.setPreferredSize(new java.awt.Dimension(150, 30)); + + m_jtxtBarCode.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jtxtBarCode.setMaximumSize(new java.awt.Dimension(100, 25)); + m_jtxtBarCode.setPreferredSize(new java.awt.Dimension(230, 30)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setText(AppLocal.getIntString("label.prodbarcode")); // NOI18N + jLabel1.setPreferredSize(new java.awt.Dimension(110, 30)); + + jBtnReset.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jBtnReset.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reload.png"))); // NOI18N + jBtnReset.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jBtnResetActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(10, 10, 10) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jtxtBarCode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jBtnReset) + .addGap(41, 41, 41)) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, 240, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jtxtName, javax.swing.GroupLayout.PREFERRED_SIZE, 270, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(64, 64, 64))) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCboPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jCboPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(m_jPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))) + .addContainerGap()))) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(10, 10, 10) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jtxtBarCode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jBtnReset) + .addGap(3, 3, 3) + .addComponent(m_jtxtName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCategory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(5, 5, 5) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCboPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(m_jPriceBuy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(5, 5, 5) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCboPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(m_jPriceSell, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + private void m_jCboPriceBuyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_jCboPriceBuyActionPerformed + + }//GEN-LAST:event_m_jCboPriceBuyActionPerformed + + private void jBtnResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnResetActionPerformed + m_jtxtBarCode.setText(null); + m_jCategory.setSelectedIndex(0); + m_jCboPriceBuy.setSelectedIndex(0); + m_jCboPriceSell.setSelectedIndex(0); + m_jtxtName.setText(null); + m_jPriceBuy.setDoubleValue(null); + m_jPriceSell.setDoubleValue(null); + }//GEN-LAST:event_jBtnResetActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jBtnReset; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JComboBox m_jCategory; + private javax.swing.JComboBox m_jCboPriceBuy; + private javax.swing.JComboBox m_jCboPriceSell; + private com.unicenta.editor.JEditorCurrency m_jPriceBuy; + private com.unicenta.editor.JEditorCurrency m_jPriceSell; + private com.unicenta.editor.JEditorString m_jtxtBarCode; + private com.unicenta.editor.JEditorString m_jtxtName; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/ticket/ProductInfo.java b/src/main/java/com/unicenta/pos/ticket/ProductInfo.java new file mode 100644 index 0000000..6011ce9 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/ProductInfo.java @@ -0,0 +1,124 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.IKeyed; +import com.unicenta.data.loader.SerializerRead; + +/** + * + * @author Jack + * @version + */ +public class ProductInfo implements IKeyed { + + private static final long serialVersionUID = 8712449444103L; + private String m_sID; + private String m_sRef; + private String m_sCode; + private String m_sName; + + /** Creates new ProductInfo + * @param id + * @param ref + * @param code + * @param name */ + public ProductInfo(String id, String ref, String code, String name) { + m_sID = id; + m_sRef = ref; + m_sCode = code; + m_sName = name; + } + + /** + * + * @return + */ + @Override + public Object getKey() { + return m_sID; + } + + /** + * + * @param sID + */ + public void setID(String sID) { + m_sID = sID; + } + public String getID() { + return m_sID; + } + + /** + * + * @return + */ + public String getRef() { + return m_sRef; + } + public void setRef(String sRef) { + m_sRef = sRef; + } + + + /** + * + * @return + */ + public String getCode() { + return m_sCode; + } + public void setCode(String sCode) { + m_sCode = sCode; + } + + /** + * + * @return + */ + public String getName() { + return m_sName; + } + public void setName(String sName) { + m_sName = sName; + } + + + @Override + public String toString() { + return m_sName; + } + + /** + * + * @return + */ + public static SerializerRead getSerializerRead() { + return new SerializerRead() { + @Override + public Object readValues(DataRead dr) throws BasicException { + return new ProductInfo(dr.getString(1), dr.getString(2), + dr.getString(3), dr.getString(4)); + }}; + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/ticket/ProductInfoEdit.java b/src/main/java/com/unicenta/pos/ticket/ProductInfoEdit.java new file mode 100644 index 0000000..c44edf3 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/ProductInfoEdit.java @@ -0,0 +1,207 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +import java.awt.image.BufferedImage; +import java.util.Properties; + +/** + * + * @author adrianromero + * Created on 21 de marzo de 2007, 21:28 + * + */ +public class ProductInfoEdit { + + /** + * + */ + protected String m_ID; + protected String m_sRef; + protected String m_sCode; + protected String m_sCodeType; + protected String m_sName; + protected double m_dPriceBuy; + protected double m_dPriceSell; + protected String m_sCategoryID; + protected String m_sTaxID; + protected String attributeuseid; + protected Double m_dStockCost; + protected Double m_dStockVolume; + protected BufferedImage m_Image; + protected boolean m_bCom; + protected boolean m_bScale; + protected boolean m_bKitchen; + protected boolean m_bPrintKB; + protected boolean m_bSendStatus; + protected boolean m_bService; + protected Properties attributes; + protected String m_sDisplay; + protected boolean m_bVprice; + protected boolean m_bVerpatrib; + protected String m_sTextTip; + protected boolean m_bWarranty; + protected double m_dStockUnits; + + protected Integer m_iCatalogOrder; + + protected String m_sSupplierID; + protected String m_sUomID; + + protected String m_sDatePick; + + + /** Creates a new instance of ProductInfoEdit */ + public ProductInfoEdit() { + m_ID = null; + m_sRef = "0000"; + m_sCode = "0000"; + m_sCodeType = null; + m_sName = null; + m_dPriceBuy = 0.0; + m_dPriceSell = 0.0; + m_sCategoryID = null; + m_sTaxID = null; + attributeuseid = null; + m_dStockCost = null; + m_dStockVolume = null; + m_Image = null; + m_bCom = false; + m_bScale = false; + m_bKitchen = false; + m_bPrintKB = false; + m_bSendStatus = false; + m_bService = false; + attributes = new Properties(); + m_sDisplay = null; + m_bVprice = false; + m_bVerpatrib = false; + m_sTextTip = null; + m_bWarranty = false; + m_dStockUnits = 0.0; + + m_iCatalogOrder = null; + + m_sSupplierID = null; + m_sUomID= null; + + m_sDatePick=null; + } + + /** + * + * @return + */ + public final String getID() { + return m_ID; + } + public final void setID(String id) { + m_ID = id; + } + + public final String getReference(){ + return m_sRef; + } + public final void setReference(String sRef){ + m_sRef = sRef; + } + + public final String getCode(){ + return m_sCode; + } + public final void setCode(String sCode){ + m_sCode = sCode; + } + + public final String getName() { + return m_sName; + } + public final void setName(String sName){ + m_sName = sName; + } + + public final boolean isCom() { + return m_bCom; + } + public final void setCom(boolean bValue){ + m_bCom = bValue; + } + + public final boolean isScale() { + return m_bScale; + } + public final void setScale(boolean bValue){ + m_bScale = bValue; + } + + public final String getCategoryID() { + return m_sCategoryID; + } + public final void setCategoryID(String sCategoryID) { + m_sCategoryID = sCategoryID; + } + + public final String getTaxID() { + return m_sTaxID; + } + public final void setTaxID(String sTaxID) { + m_sTaxID = sTaxID; + } + + public final String getAttributeUseID() { + return attributeuseid; + } + public final void setAttributeUseID(String value) { + attributeuseid = value; + } + + public final double getPriceBuy(){ + return m_dPriceBuy; + } + public final void setPriceBuy(double dPrice) { + m_dPriceBuy = dPrice; + } + + public final double getPriceSell(){ + return m_dPriceSell; + } + public final void setPriceSell(double dPrice) { + m_dPriceSell = dPrice; + } + + public BufferedImage getImage() { + return m_Image; + } + public void setImage(BufferedImage img) { + m_Image = img; + } + + @Override + public final String toString() { + return m_sRef + " - " + m_sName; + } + + public final String getDatePick(){ + return m_sDatePick; + } + public final void setDatePick(String sDatePick){ + m_sDatePick = sDatePick; + } +} diff --git a/src/main/java/com/unicenta/pos/ticket/ProductInfoExt.java b/src/main/java/com/unicenta/pos/ticket/ProductInfoExt.java new file mode 100644 index 0000000..dedcbe3 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/ProductInfoExt.java @@ -0,0 +1,384 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +package com.unicenta.pos.ticket; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.ImageUtils; +import com.unicenta.data.loader.SerializerRead; +import java.util.Properties; +import com.unicenta.format.Formats; +import java.awt.image.BufferedImage; +import java.util.Date; + +/** + * + * @author adrianromero + * + */ +public class ProductInfoExt { + + private static final long serialVersionUID = 7587696873036L; + + protected String m_ID; + protected String m_sRef; + protected String m_sCode; + protected String m_sCodetype; + protected String m_sName; + protected double m_dPriceBuy; + protected double m_dPriceSell; + protected String categoryid; + protected String taxcategoryid; + protected String attributesetid; + protected double m_stockCost; + protected double m_stockVolume; + protected BufferedImage m_Image; + protected boolean m_bCom; + protected boolean m_bScale; + protected boolean m_bConstant; + protected boolean m_bPrintKB; + protected boolean m_bSendStatus; + private boolean m_bService; + protected Properties attributes; + protected String m_sDisplay; + protected boolean m_bVprice; + protected boolean m_bVerpatrib; + protected String m_sTextTip; + protected boolean m_bWarranty; + public double m_dStockUnits; + public String m_sPrinter; + public String supplierid; + private String uomid; + protected String memodate; + + public ProductInfoExt() { + m_ID = null; + m_sRef = "0000"; + m_sCode = "0000"; + m_sCodetype = null; + m_sName = null; + m_dPriceBuy = 0.0; + m_dPriceSell = 0.0; + categoryid = null; + taxcategoryid = null; + attributesetid = null; + m_stockCost = 0.0; + m_stockVolume = 0.0; + m_Image = null; + m_bCom = false; + m_bScale = false; + m_bConstant = false; + m_bPrintKB = false; + m_bSendStatus = false; + m_bService = false; + attributes = new Properties(); + m_sDisplay = null; + m_bVprice = false; + m_bVerpatrib = false; + m_sTextTip = null; + m_bWarranty = false; + m_dStockUnits = 0.0; + m_sPrinter = null; + supplierid = "0"; + uomid = "0"; + memodate = null; + } + + /** + * + * @return + */ + public final String getID() { + return m_ID; + } + public final void setID(String id) { + m_ID = id; + } + + public final String getReference() { + return m_sRef; + } + public final void setReference(String sRef) { + m_sRef = sRef; + } + + public final String getCode() { + return m_sCode; + } + public final void setCode(String sCode) { + m_sCode = sCode; + } + + public final String getCodetype() { + return m_sCodetype; + } + public final void setCodetype(String sCodetype) { + m_sCodetype = sCodetype; + } + + public final String getName() { + return m_sName; + } + public final void setName(String sName) { + m_sName = sName; + } + + public final double getPriceBuy() { + return m_dPriceBuy; + } + public final void setPriceBuy(double dPrice) { + m_dPriceBuy = dPrice; + } + + public final double getPriceSell() { + return m_dPriceSell; + } + public final void setPriceSell(double dPrice) { + m_dPriceSell = dPrice; + } + + public final String getCategoryID() { + return categoryid; + } + public final void setCategoryID(String sCategoryID) { + categoryid = sCategoryID; + } + + public final String getTaxCategoryID() { + return taxcategoryid; + } + public final void setTaxCategoryID(String value) { + taxcategoryid = value; + } + + public final String getAttributeSetID() { + return attributesetid; + } + public final void setAttributeSetID(String value) { + attributesetid = value; + } + + public final double getStockCost() { + return m_stockCost; + } + public final void setStockCost(double dPrice) { + m_stockCost = dPrice; + } + + public final double getStockVolume() { + return m_stockVolume; + } + public final void setStockVolume(double dStockVolume) { + m_stockVolume = dStockVolume; + } + + public BufferedImage getImage() { + return m_Image; + } + public void setImage(BufferedImage img) { + m_Image = img; + } + + public final boolean isCom() { + return m_bCom; + } + public final void setCom(boolean bValue) { + m_bCom = bValue; + } + + public final boolean isScale() { + return m_bScale; + } + public final void setScale(boolean bValue) { + m_bScale = bValue; + } + + public final boolean isConstant() { + return m_bConstant; + } + public final void setConstant(boolean bValue) { + m_bConstant = bValue; + } + + public final boolean isPrintKB() { + return m_bPrintKB; + } + public final void setPrintKB(boolean bValue) { + m_bPrintKB = bValue; + } + + public final boolean isSendStatus() { + return m_bSendStatus; + } + public final void setSendStatus(boolean bValue) { + m_bSendStatus = bValue; + } + + public final boolean isService() { + return m_bService; + } + public final void setService(boolean bValue) { + m_bService = bValue; + } + + public String getProperty(String key) { + return attributes.getProperty(key); + } + public String getProperty(String key, String defaultvalue) { + return attributes.getProperty(key, defaultvalue); + } + public void setProperty(String key, String value) { + attributes.setProperty(key, value); + } + public Properties getProperties() { + return attributes; + } + + public final String getDisplay() { + return m_sDisplay; + } + public final void setDisplay(String sDisplay) { + m_sDisplay = sDisplay; + } + + public final boolean isVprice() { + return m_bVprice; + } + + public final boolean isVerpatrib() { + return m_bVerpatrib; + } + + public final String getTextTip() { + return m_sTextTip; + } + public final void setTextTip(String value) { + m_sTextTip = value; + } + + public final boolean getWarranty() { + return m_bWarranty; + } + public final void setWarranty(boolean bValue) { + m_bWarranty = bValue; + } + + public final Double getStockUnits() { + return m_dStockUnits; + } + public final void setStockUnits(double dStockUnits) { + m_dStockUnits = dStockUnits; + } + + public String printPriceSell() { + return Formats.CURRENCY.formatValue(getPriceSell()); + } + + public final double getPriceSellTax(TaxInfo tax) { + return m_dPriceSell * (1.0 + tax.getRate()); + } + public String printPriceSellTax(TaxInfo tax) { + return Formats.CURRENCY.formatValue(getPriceSellTax(tax)); + } + + public final String getPrinter() { + return m_sPrinter; + } + public final void setPrinter(String value) { + m_sPrinter = value; + } + + public final String getSupplierID() { + return supplierid; + } + public final void setSupplierID(String sSupplierID) { + supplierid = sSupplierID; + } + + public final String getUomID() { + return uomid; + } + public final void setUomID(String sUomID) { + uomid = sUomID; + } + + /** + * + * @return memo date string + */ + public String getMemoDate() { + return memodate; + } + public void setMemoDate(String memodate) { + this.memodate = memodate; + } + public String printMemoDate() { + return Formats.STRING.formatValue(memodate); + } + + /** + * + * @return + */ + public static SerializerRead getSerializerRead() { + return new SerializerRead() { + @Override + public Object readValues(DataRead dr) throws BasicException { + ProductInfoExt product = new ProductInfoExt(); + product.m_ID = dr.getString(1); + product.m_sRef = dr.getString(2); + product.m_sCode = dr.getString(3); + product.m_sCodetype = dr.getString(4); + product.m_sName = dr.getString(5); + product.m_dPriceBuy = dr.getDouble(6); + product.m_dPriceSell = dr.getDouble(7); + product.categoryid = dr.getString(8); + product.taxcategoryid = dr.getString(9); + product.attributesetid = dr.getString(10); + product.m_stockCost = dr.getDouble(11); + product.m_stockVolume = dr.getDouble(12); + product.m_Image = ImageUtils.readImage(dr.getBytes(13)); + product.m_bCom = dr.getBoolean(14); + product.m_bScale = dr.getBoolean(15); + product.m_bConstant = dr.getBoolean(16); + product.m_bPrintKB = dr.getBoolean(17); + product.m_bSendStatus = dr.getBoolean(18); + product.m_bService = dr.getBoolean(19); + product.attributes = ImageUtils.readProperties(dr.getBytes(20)); + product.m_sDisplay = dr.getString(21); + product.m_bVprice = dr.getBoolean(22); + product.m_bVerpatrib = dr.getBoolean(23); + product.m_sTextTip = dr.getString(24); + product.m_bWarranty = dr.getBoolean(25); + product.m_dStockUnits = dr.getDouble(26); + product.m_sPrinter = dr.getString(27); + product.supplierid = dr.getString(28); + product.uomid = dr.getString(29); + product.memodate = dr.getString(30); + + return product; + } + }; + } + + @Override + public final String toString() { + return m_sRef + " - " + m_sName; + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/ticket/ProductRenderer.java b/src/main/java/com/unicenta/pos/ticket/ProductRenderer.java new file mode 100644 index 0000000..f231534 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/ProductRenderer.java @@ -0,0 +1,64 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +import com.unicenta.format.Formats; +import com.unicenta.pos.util.ThumbNailBuilder; +import java.awt.*; +import javax.swing.*; + +/** + * + * @author uniCenta 2017 + * + */ +public class ProductRenderer extends DefaultListCellRenderer { + + ThumbNailBuilder tnbprod; + + /** Creates a new instance of ProductRenderer */ + public ProductRenderer() { +// tnbprod = new ThumbNailBuilder(48,48, "com/unicenta/images/package.png"); + tnbprod = new ThumbNailBuilder(48,48, "com/unicenta/images/null.png"); + + + } + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, null, index, isSelected, cellHasFocus); + + ProductInfoExt prod = (ProductInfoExt) value; + + if (prod != null) { + + setText("<html><center>" + + prod.getReference() + + " - " + + prod.getName() + " - " + Formats.CURRENCY.formatValue(prod.getPriceSell()) +// + "<br>" + prod.getStockUnits() + " | " + Formats.DATE.formatValue(prod.getMemoDate()) + " | " + prod.getPriceSellTax(tax) + ); + + Image img = tnbprod.getThumbNail(prod.getImage()); + setIcon(img == null ? null :new ImageIcon(img)); + } + return this; + } +} diff --git a/src/main/java/com/unicenta/pos/ticket/ProductVectorer.java b/src/main/java/com/unicenta/pos/ticket/ProductVectorer.java new file mode 100644 index 0000000..b3c722c --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/ProductVectorer.java @@ -0,0 +1,69 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +import com.unicenta.format.Formats; +import com.unicenta.data.loader.Vectorer; +import com.unicenta.basic.BasicException; +import com.unicenta.pos.forms.AppLocal; +/** + * + * @author adrian + */ +public class ProductVectorer implements Vectorer { + + private static String[] m_sHeaders = { + AppLocal.getIntString("label.prodref"), + AppLocal.getIntString("label.prodbarcode"), + AppLocal.getIntString("label.prodname"), + AppLocal.getIntString("label.prodpricebuy"), + AppLocal.getIntString("label.prodpricesell") + }; + + /** Creates a new instance of ProductVectorer */ + public ProductVectorer() { + } + + /** + * + * @return + * @throws BasicException + */ + public String[] getHeaders() throws BasicException { + return m_sHeaders; + } + + /** + * + * @param obj + * @return + * @throws BasicException + */ + public String[] getValues(Object obj) throws BasicException { + ProductInfoExt myprod = (ProductInfoExt) obj; + String[] m_sValues = new String[5]; + m_sValues[0] = Formats.STRING.formatValue(myprod.getReference()); + m_sValues[1] = Formats.STRING.formatValue(myprod.getCode()); + m_sValues[2] = Formats.STRING.formatValue(myprod.getName()); + m_sValues[3] = Formats.CURRENCY.formatValue(new Double(myprod.getPriceBuy())); + m_sValues[4] = Formats.CURRENCY.formatValue(new Double(myprod.getPriceSell())); + return m_sValues; + } +} diff --git a/src/main/java/com/unicenta/pos/ticket/ProviderInfo.java b/src/main/java/com/unicenta/pos/ticket/ProviderInfo.java new file mode 100644 index 0000000..0495641 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/ProviderInfo.java @@ -0,0 +1,72 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +/** + * + * @author JG uniCenta + */ +public class ProviderInfo { + + private int m_iProviderID; + private String m_sName; + + /** Creates new Provider */ + public ProviderInfo() { + m_iProviderID = 0; + m_sName = ""; + } + + /** + * + * @return + */ + public int getProviderID() { + return m_iProviderID; + } + + /** + * + * @param iProviderID + */ + public void setProviderID(int iProviderID) { + m_iProviderID = iProviderID; + } + + /** + * + * @return + */ + public String getName() { + return m_sName; + } + + /** + * + * @param sName + */ + public void setName(String sName) { + m_sName = sName; + } + + public String toString(){ + return m_sName; + } +} diff --git a/src/main/java/com/unicenta/pos/ticket/SalesDetailInfo.java b/src/main/java/com/unicenta/pos/ticket/SalesDetailInfo.java new file mode 100644 index 0000000..ce63426 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/SalesDetailInfo.java @@ -0,0 +1,130 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2017 +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +//***************************************************************************** + +package com.unicenta.pos.ticket; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.IKeyed; +import com.unicenta.data.loader.SerializerRead; +import com.unicenta.format.Formats; + +/** + * + * @author Adrian + * @version + */ +public class SalesDetailInfo implements IKeyed { + + private static final long serialVersionUID = 8612449444103L; + private String productName; + private int lineNO; + + /** + * + * @return + */ + public int getLineNO() { + return lineNO; + } + + /** + * + * @param lineNO + */ + public void setLineNO(int lineNO) { + this.lineNO = lineNO; + } + + /** + * + * @return + */ + public double getPrice() { + return price; + } + + /** + * + * @return + */ + public String printPrice() { + return Formats.CURRENCY.formatValue(price); + } + + /** + * + * @param price + */ + public void setPrice(double price) { + this.price = price; + } + + /** + * + * @return + */ + public String getProductName() { + return productName; + } + + /** + * + * @param productName + */ + public void setProductName(String productName) { + this.productName = productName; + } + private double price; + + /** Creates new CategoryInfo + * @param lineNo + * @param productName + * @param price */ + public SalesDetailInfo(int lineNo, String productName, double price) { + this.lineNO = lineNo; + this.productName = productName; + this.price = price; + } + + /** + * + * @return + */ + public static SerializerRead getSerializerRead() { + return new SerializerRead() { + @Override + public Object readValues(DataRead dr) throws BasicException { + return new SalesDetailInfo( + dr.getInt(1), + dr.getString(2), + dr.getDouble(3)); + }}; + } + + /** + * + * @return + */ + @Override + public Object getKey() { + return getLineNO(); + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/ticket/SalesDetailInfo_1.java b/src/main/java/com/unicenta/pos/ticket/SalesDetailInfo_1.java new file mode 100644 index 0000000..145fdd2 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/SalesDetailInfo_1.java @@ -0,0 +1,129 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2017 +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +//***************************************************************************** + +package com.unicenta.pos.ticket; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.IKeyed; +import com.unicenta.data.loader.SerializerRead; +import com.unicenta.format.Formats; + +/** + * + * @author Adrian + * @version + */ +public class SalesDetailInfo_1 implements IKeyed { + + private static final long serialVersionUID = 8612449444103L; + private String productName; + private int lineNO; + + /** + * + * @return + */ + public int getLineNO() { + return lineNO; + } + + /** + * + * @param lineNO + */ + public void setLineNO(int lineNO) { + this.lineNO = lineNO; + } + + /** + * + * @return + */ + public double getPrice() { + return price; + } + + /** + * + * @return + */ + public String printPrice() { + return Formats.CURRENCY.formatValue(price); + } + + /** + * + * @param price + */ + public void setPrice(double price) { + this.price = price; + } + + /** + * + * @return + */ + public String getProductName() { + return productName; + } + + /** + * + * @param productName + */ + public void setProductName(String productName) { + this.productName = productName; + } + private double price; + + /** Creates new CategoryInfo + * @param lineNo + * @param productName + * @param price */ + public SalesDetailInfo_1(int lineNo, String productName, double price) { + this.lineNO = lineNo; + this.productName = productName; + this.price = price; + } + + /** + * + * @return + */ + public static SerializerRead getSerializerRead() { + return new SerializerRead() {@Override + public Object readValues(DataRead dr) throws BasicException { + return new SalesDetailInfo( + dr.getInt(1), + dr.getString(2), + dr.getDouble(3)); + }}; + } + + /** + * + * @return + */ + @Override + public Object getKey() { + return getLineNO(); + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/ticket/Signumprovider.java b/src/main/java/com/unicenta/pos/ticket/Signumprovider.java new file mode 100644 index 0000000..0d164fd --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/Signumprovider.java @@ -0,0 +1,68 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2017 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +import java.util.*; + +/** + * + * @author JG uniCenta + */ +public class Signumprovider { + + private Set m_positives = new HashSet(); + private Set m_negatives = new HashSet(); + + /** Creates a new instance of Signumprovider */ + public Signumprovider() { + } + + /** + * + * @param key + */ + public void addPositive(Object key) { + m_positives.add(key); + } + + /** + * + * @param key + */ + public void addNegative(Object key) { + m_negatives.add(key); + } + + /** + * + * @param key + * @param value + * @return + */ + public Double correctSignum(Object key, Double value) { + if (m_positives.contains(key)) { + return value.doubleValue() < 0.0 ? new Double(-value.doubleValue()) : value; + } else if (m_negatives.contains(key)) { + return value.doubleValue() > 0.0 ? new Double(-value.doubleValue()) : value; + } else { + return value; + } + } +} diff --git a/src/main/java/com/unicenta/pos/ticket/TaxInfo.java b/src/main/java/com/unicenta/pos/ticket/TaxInfo.java new file mode 100644 index 0000000..c34b198 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/TaxInfo.java @@ -0,0 +1,213 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2017 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +import com.unicenta.data.loader.IKeyed; +import java.io.Serializable; + +/** + * + * @author adrianromero + */ +public class TaxInfo implements Serializable, IKeyed { + + private static final long serialVersionUID = -2705212098856473043L; + private String id; + private String name; + private String taxcategoryid; // Product + private String taxcustcategoryid; // Customer + private String parentid; + + private double rate; + private boolean cascade; + private Integer order; + + /** Creates new TaxInfo + * @param id + * @param name + * @param taxcategoryid + * @param taxcustcategoryid + * @param rate + * @param cascade + * @param parentid + * @param order */ + public TaxInfo(String id, String name, String taxcategoryid, String taxcustcategoryid, + String parentid, double rate, boolean cascade, Integer order) { + this.id = id; + this.name = name; + this.taxcategoryid = taxcategoryid; + this.taxcustcategoryid = taxcustcategoryid; + this.parentid = parentid; + + this.rate = rate; + this.cascade = cascade; + this.order = order; + } + + /** + * + * @return + */ + @Override + public Object getKey() { + return id; + } + + /** + * + * @param value + */ + public void setID(String value) { + id = value; + } + + /** + * + * @return + */ + public String getId() { + return id; + } + + /** + * + * @return + */ + public String getName() { + return name; + } + + /** + * + * @param value + */ + public void setName(String value) { + name = value; + } + + /** + * The Product's + * @return + */ + public String getTaxCategoryID() { + return taxcategoryid; + } + + /** + * + * @param value + */ + public void setTaxCategoryID(String value) { + taxcategoryid = value; + } + + /** + * The Customer + * @return + */ + public String getTaxCustCategoryID() { + return taxcustcategoryid; + } + + /** + * + * @param value + */ + public void setTaxCustCategoryID(String value) { + taxcustcategoryid = value; + } + + /** + * + * @return + */ + public String getParentID() { + return parentid; + } + + /** + * + * @param value + */ + public void setParentID(String value) { + parentid = value; + } + + /** + * + * @return + */ + public double getRate() { + return rate; + } + + /** + * + * @param value + */ + public void setRate(double value) { + rate = value; + } + + /** + * + * @return + */ + public boolean isCascade() { + return cascade; + } + + /** + * + * @param value + */ + public void setCascade(boolean value) { + cascade = value; + } + + /** + * + * @return + */ + public Integer getOrder() { + return order; + } + + /** + * + * @return + */ + public Integer getApplicationOrder() { + return order == null ? Integer.MAX_VALUE : order.intValue(); + } + + /** + * + * @param value + */ + public void setOrder(Integer value) { + order = value; + } + + @Override + public String toString(){ + return name; + } +} diff --git a/src/main/java/com/unicenta/pos/ticket/TicketInfo.java b/src/main/java/com/unicenta/pos/ticket/TicketInfo.java new file mode 100644 index 0000000..9d1b984 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/TicketInfo.java @@ -0,0 +1,773 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +package com.unicenta.pos.ticket; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.LocalRes; +import com.unicenta.data.loader.SerializableRead; +import com.unicenta.format.Formats; +import com.unicenta.pos.customers.CustomerInfoExt; +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.payment.PaymentInfo; +import com.unicenta.pos.payment.PaymentInfoMagcard; +import com.unicenta.pos.payment.PaymentInfoTicket; +import com.unicenta.pos.util.StringUtils; +import java.io.*; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * + * @author adrianromero + */ +public final class TicketInfo implements SerializableRead, Externalizable { + + private static final long serialVersionUID = 2765650092387265178L; + + public static final int RECEIPT_NORMAL = 0; + public static final int RECEIPT_REFUND = 1; + public static final int RECEIPT_PAYMENT = 2; + public static final int RECEIPT_NOSALE = 3; + +// JG Jun 2017 - contain partial/full refunds + public static final int REFUND_NOT = 0; // is a non-refunded ticket + public static final int REFUND_PARTIAL = 1; + public static final int REFUND_ALL = 2; + + private static final DateFormat m_dateformat = new SimpleDateFormat("hh:mm"); + + private String m_sHost; + private String m_sId; + private int tickettype; + private int m_iTicketId; + private int m_iPickupId; + private java.util.Date m_dDate; + private Properties attributes; + private UserInfo m_User; + private Double multiply; + private CustomerInfoExt m_Customer; + private String m_sActiveCash; + private List<TicketLineInfo> m_aLines; + private List<PaymentInfo> payments; + private List<TicketTaxInfo> taxes; + private final String m_sResponse; + private String loyaltyCardNumber; + private Boolean oldTicket; + private boolean tip; + private PaymentInfoTicket m_paymentInfo; + private boolean m_isProcessed; + private final String m_locked; + private Double nsum; + private int ticketstatus; + + private static String Hostname; + + public static void setHostname(String name) { + Hostname=name; + } + + public static String getHostname() { + return Hostname; + } + + /** Creates new TicketModel */ + public TicketInfo() { + m_sId = UUID.randomUUID().toString(); + tickettype = RECEIPT_NORMAL; + m_iTicketId = 0; // incrementamos + m_dDate = new Date(); + attributes = new Properties(); + m_User = null; + m_Customer = null; + m_sActiveCash = null; + m_aLines = new ArrayList<>(); + payments = new ArrayList<>(); + taxes = null; + m_sResponse = null; + oldTicket=false; + + AppConfig config = new AppConfig(new File(new File( + System.getProperty("user.home")), AppLocal.APP_ID + ".properties")); + config.load(); + tip = Boolean.valueOf(config.getProperty("machine.showTip")); + m_isProcessed = false; + m_locked = null; + ticketstatus = 0; + } + + @Override + public void writeExternal(ObjectOutput out) throws IOException { + out.writeObject(m_sId); + out.writeInt(tickettype); + out.writeInt(m_iTicketId); + out.writeObject(m_Customer); + out.writeObject(m_dDate); + out.writeObject(attributes); + out.writeObject(m_aLines); + + out.writeInt(ticketstatus); + } + + @Override + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + m_sId = (String) in.readObject(); + tickettype = in.readInt(); + m_iTicketId = in.readInt(); + m_Customer = (CustomerInfoExt) in.readObject(); + m_dDate = (Date) in.readObject(); + attributes = (Properties) in.readObject(); + m_aLines = (List<TicketLineInfo>) in.readObject(); + m_User = null; + m_sActiveCash = null; + payments = new ArrayList<>(); // JG June 2102 diamond inference + taxes = null; + + ticketstatus = in.readInt(); + } + + /** + * + * @param dr + * @throws BasicException + */ + @Override + public void readValues(DataRead dr) throws BasicException { + m_sId = dr.getString(1); + tickettype = dr.getInt(2); + m_iTicketId = dr.getInt(3); + m_dDate = dr.getTimestamp(4); + m_sActiveCash = dr.getString(5); + try { + byte[] img = dr.getBytes(6); + if (img != null) { + attributes.loadFromXML(new ByteArrayInputStream(img)); + } + } catch (IOException e) { + } + m_User = new UserInfo(dr.getString(7), dr.getString(8)); + m_Customer = new CustomerInfoExt(dr.getString(9)); + m_aLines = new ArrayList<>(); + payments = new ArrayList<>(); + taxes = null; + + ticketstatus = dr.getInt(10); + } + + /** + * + * @return + */ + public TicketInfo copyTicket() { + TicketInfo t = new TicketInfo(); + + t.tickettype = tickettype; + t.m_iTicketId = m_iTicketId; + t.m_dDate = m_dDate; + t.m_sActiveCash = m_sActiveCash; + t.attributes = (Properties) attributes.clone(); + t.m_User = m_User; + t.m_Customer = m_Customer; + + t.m_aLines = new ArrayList<>(); // JG June 2102 diamond inference + m_aLines.forEach((l) -> { + t.m_aLines.add(l.copyTicketLine()); + }); + t.refreshLines(); + + t.payments = new LinkedList<>(); // JG June 2102 diamond inference + payments.forEach((p) -> { + t.payments.add(p.copyPayment()); + }); + t.oldTicket=oldTicket; + // taxes are not copied, must be calculated again. + + t.ticketstatus = ticketstatus; + + return t; + } + + public String getId() { + return m_sId; + } + + public int getTicketType() { + return tickettype; + } + public void setTicketType(int tickettype) { + this.tickettype = tickettype; + } + + public int getTicketId() { + return m_iTicketId; + } + public void setTicketId(int iTicketId) { + m_iTicketId = iTicketId; + } + + public int getTicketStatus() { + return ticketstatus; + } + public void setTicketStatus(int ticketstatus) { + if (m_iTicketId >0) { + this.ticketstatus = m_iTicketId; + }else{ + this.ticketstatus = ticketstatus; + } + } + + public void setPickupId(int iTicketId) { + m_iPickupId = iTicketId; + } + + public int getPickupId() { + return m_iPickupId; + } + + public String getName(Object info) { +// JG Aug 2014 - Add User info + List<String> name = new ArrayList<>(); + + String nameprop = getProperty("name"); + if (nameprop != null) { + name.add(nameprop); + } + + if (m_User != null) { + name.add(m_User.getName()); + } + + if (info == null) { + if (m_iTicketId == 0) { + name.add("(" + m_dateformat.format(m_dDate) + " " + + Long.toString(m_dDate.getTime() % 1000) + ")"); + } else { + name.add(Integer.toString(m_iTicketId)); + } + } else { + name.add(info.toString()); + } + + if (m_Customer != null) { + name.add(m_Customer.getName()); + } + + return org.apache.commons.lang.StringUtils.join(name, " - "); + } + + public String getName() { + return getName(null); + } + + public java.util.Date getDate() { + return m_dDate; + } + + public void setDate(java.util.Date dDate) { + m_dDate = dDate; + } + + public String getHost() { + AppConfig m_config_host = new AppConfig(new File((System.getProperty("user.home")), + AppLocal.APP_ID + ".properties")); + m_config_host.load(); + String machineHostname =(m_config_host.getProperty("machine.hostname")); + m_config_host = null; + return machineHostname; + } + + public UserInfo getUser() { + return m_User; + } + + public void setUser(UserInfo value) { + m_User = value; + } + + public CustomerInfoExt getCustomer() { + return m_Customer; + } + + public void setCustomer(CustomerInfoExt value) { + m_Customer = value; + } + + public String getCustomerId() { + if (m_Customer == null) { + return null; + } else { + return m_Customer.getId(); + } + } + + public String getTransactionID(){ + return (getPayments().size()>0) + ? ( getPayments().get(getPayments().size()-1) ).getTransactionID() + : StringUtils.getCardNumber(); //random transaction ID + } + + public String getReturnMessage(){ + return ( (getPayments().get(getPayments().size()-1)) instanceof PaymentInfoMagcard ) + ? ((PaymentInfoMagcard)(getPayments().get(getPayments().size()-1))).getReturnMessage() + : LocalRes.getIntString("button.OK"); + } + + public void setActiveCash(String value) { + m_sActiveCash = value; + } + + public String getActiveCash() { + return m_sActiveCash; + } + + public String getProperty(String key) { + return attributes.getProperty(key); + } + + public String getProperty(String key, String defaultvalue) { + return attributes.getProperty(key, defaultvalue); + } + + public void setProperty(String key, String value) { + attributes.setProperty(key, value); + } + + public Properties getProperties() { + return attributes; + } + + public TicketLineInfo getLine(int index) { + return m_aLines.get(index); + } + + public void addLine(TicketLineInfo oLine) { + oLine.setTicket(m_sId, m_aLines.size()); + m_aLines.add(oLine); + } + + public void insertLine(int index, TicketLineInfo oLine) { + m_aLines.add(index, oLine); + refreshLines(); + } + + public void setLine(int index, TicketLineInfo oLine) { + oLine.setTicket(m_sId, index); + m_aLines.set(index, oLine); + } + + public void removeLine(int index) { + m_aLines.remove(index); + refreshLines(); + + } + + public void refreshLines() { + for (int i = 0; i < m_aLines.size(); i++) { + getLine(i).setTicket(m_sId, i); + } + } + + public int getLinesCount() { + return m_aLines.size(); + } + + public double getArticlesCount() { + double dArticles = 0.0; + TicketLineInfo oLine; + + for (Iterator<TicketLineInfo> i = m_aLines.iterator(); i.hasNext();) { + oLine = i.next(); + dArticles += oLine.getMultiply(); + } + + return dArticles; + } + + public double getSubTotal() { + double sum = 0.0; + sum = m_aLines.stream().map((line) -> + line.getSubValue()).reduce(sum, (accumulator, _item) -> + accumulator + _item); + return sum; + } + + public double getTax() { + + double sum = 0.0; + if (hasTaxesCalculated()) { + for (TicketTaxInfo tax : taxes) { + sum += tax.getTax(); // Taxes are already rounded... + nsum = sum; + } + } else { + sum = m_aLines.stream().map((line) -> + line.getTax()).reduce(sum, (accumulator, _item) -> + accumulator + _item); + } + return sum; + } + + public double getTotal() { + return getSubTotal() + getTax(); + + } + + public double getServiceCharge() { + return (getTotal() + getTax()); + + } + + public double getTotalPaid() { + double sum = 0.0; + sum = payments.stream().filter((p) -> + (!"debtpaid".equals(p.getName()))).map((p) -> + p.getTotal()).reduce(sum, (accumulator, _item) -> + accumulator + _item); + return sum; + } + + public double getTendered() { + return getTotalPaid(); + } + + public List<TicketLineInfo> getLines() { + return m_aLines; + } + + public void setLines(List<TicketLineInfo> l) { + m_aLines = l; + } + + public List<PaymentInfo> getPayments() { + return payments; + } + + public void setPayments(List<PaymentInfo> l) { + payments = l; + } + + public void resetPayments() { + payments = new ArrayList<>(); // JG June 2102 diamond inference + } + + public List<TicketTaxInfo> getTaxes() { + return taxes; + } + + public boolean hasTaxesCalculated() { + return taxes != null; + } + + public void setTaxes(List<TicketTaxInfo> l) { + taxes = l; + } + + public void resetTaxes() { + taxes = null; + } + + public void setTip(boolean tips) { + tip = tips; + } + + public boolean hasTip() { + return tip; + } + + public void setIsProcessed(boolean isP) { + m_isProcessed = isP; + } + + public TicketTaxInfo getTaxLine(TaxInfo tax) { + + for (TicketTaxInfo taxline : taxes) { + if (tax.getId().equals(taxline.getTaxInfo().getId())) { + return taxline; + } + } + + return new TicketTaxInfo(tax); + } + + public TicketTaxInfo[] getTaxLines() { + + Map<String, TicketTaxInfo> m = new HashMap<>(); + + TicketLineInfo oLine; + for (Iterator<TicketLineInfo> i = m_aLines.iterator(); i.hasNext();) { + oLine = i.next(); + + TicketTaxInfo t = m.get(oLine.getTaxInfo().getId()); + if (t == null) { + t = new TicketTaxInfo(oLine.getTaxInfo()); + m.put(t.getTaxInfo().getId(), t); + } + t.add(oLine.getSubValue()); + } + + // return dSuma; + Collection<TicketTaxInfo> avalues = m.values(); + return avalues.toArray(new TicketTaxInfo[avalues.size()]); + } + + public String printId() { + + AppConfig m_config = new AppConfig(new File( + (System.getProperty("user.home")), AppLocal.APP_ID + ".properties")); + m_config.load(); + String receiptSize =(m_config.getProperty("till.receiptsize")); + String receiptPrefix =(m_config.getProperty("till.receiptprefix")); + + m_config =null; + + if (m_iTicketId > 0) { + String tmpTicketId=Integer.toString(m_iTicketId); + if (receiptSize == null || (Integer.parseInt(receiptSize) <= tmpTicketId.length())){ + if (receiptPrefix != null){ + tmpTicketId=receiptPrefix+tmpTicketId; + } + return tmpTicketId; + } + while (tmpTicketId.length()<Integer.parseInt(receiptSize)){ + tmpTicketId="0"+tmpTicketId; + } + if (receiptPrefix != null){ + tmpTicketId=receiptPrefix+tmpTicketId; + } + return tmpTicketId; + } else { + return ""; + } + } + + public String printDate() { + return Formats.TIMESTAMP.formatValue(m_dDate); + } + + public String printUser() { + return m_User == null ? "" : m_User.getName(); + + } + + public String printHost() { + return m_sHost; + } + + +// Added JDL 28.05.13 for loyalty card functions + + /** + * + */ + public void clearCardNumber(){ + loyaltyCardNumber=null; + } + + /** + * + * @param cardNumber + */ + public void setLoyaltyCardNumber(String cardNumber){ + loyaltyCardNumber=cardNumber; + } + + /** + * + * @return + */ + public String getLoyaltyCardNumber(){ + return (loyaltyCardNumber); + } + + public String printCustomer() { + return m_Customer == null ? "" : m_Customer.getName(); + } + + public String printPhone1() { + return m_Customer == null ? "" : m_Customer.getPhone1(); + } + + public String printArticlesCount() { + return Formats.DOUBLE.formatValue(getArticlesCount()); + } + + public String printSubTotal() { + return Formats.CURRENCY.formatValue(getSubTotal()); + } + + public String printTax() { + return Formats.CURRENCY.formatValue(getTax()); + } + + public String printTotal() { + return Formats.CURRENCY.formatValue(getTotal()); + } + + public String printTotalPaid() { + return Formats.CURRENCY.formatValue(getTotalPaid()); + } + + public String printTendered() { + return Formats.CURRENCY.formatValue(getTendered()); + } + + public String VoucherReturned(){ + return Formats.CURRENCY.formatValue(getTotalPaid()- getTotal()); + } + + public boolean getOldTicket() { + return (oldTicket); + } + + public void setOldTicket(Boolean otState) { + oldTicket = otState; + } + + public String getTicketHeaderFooterData(String data) { + AppConfig m_config = new AppConfig(new File((System.getProperty("user.home")) + , AppLocal.APP_ID + ".properties")); + m_config.load(); + String row =(m_config.getProperty("tkt."+data)); + + return row; + } + + public String printTicketHeaderLine1() { + String lineData = getTicketHeaderFooterData("header1"); + + if(lineData != null) { + return lineData; + } else { + return ""; + } + } + + public String printTicketHeaderLine2() { + String lineData = getTicketHeaderFooterData("header2"); + + if(lineData != null) { + return lineData; + } else { + return ""; + } + } + + public String printTicketHeaderLine3() { + String lineData = getTicketHeaderFooterData("header3"); + + if(lineData != null) { + return lineData; + } else { + return ""; + } + } + + public String printTicketHeaderLine4() { + String lineData = getTicketHeaderFooterData("header4"); + + if(lineData != null) { + return lineData; + } else { + return ""; + } + } + + public String printTicketHeaderLine5() { + String lineData = getTicketHeaderFooterData("header5"); + + if(lineData != null) { + return lineData; + } else { + return ""; + } + } + + public String printTicketHeaderLine6() { + String lineData = getTicketHeaderFooterData("header6"); + + if(lineData != null) { + return lineData; + } else { + return ""; + } + } + + public String printTicketFooterLine1() { + String lineData = getTicketHeaderFooterData("footer1"); + + if(lineData != null) { + return lineData; + } else { + return ""; + } + } + + public String printTicketFooterLine2() { + String lineData = getTicketHeaderFooterData("footer2"); + + if(lineData != null) { + return lineData; + } else { + return ""; + } + } + + public String printTicketFooterLine3() { + String lineData = getTicketHeaderFooterData("footer3"); + + if(lineData != null) { + return lineData; + } else { + return ""; + } + } + + public String printTicketFooterLine4() { + String lineData = getTicketHeaderFooterData("footer4"); + + if(lineData != null) { + return lineData; + } else { + return ""; + } + } + + public String printTicketFooterLine5() { + String lineData = getTicketHeaderFooterData("footer5"); + + if(lineData != null) { + return lineData; + } else { + return ""; + } + } + + public String printTicketFooterLine6() { + String lineData = getTicketHeaderFooterData("footer6"); + + if(lineData != null) { + return lineData; + } else { + return ""; + } + } + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/ticket/TicketLineInfo.java b/src/main/java/com/unicenta/pos/ticket/TicketLineInfo.java new file mode 100644 index 0000000..c241957 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/TicketLineInfo.java @@ -0,0 +1,484 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.DataWrite; +import com.unicenta.data.loader.SerializableRead; +import com.unicenta.data.loader.SerializableWrite; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.util.StringUtils; +import java.io.*; +import java.util.Properties; + +/** + * + * @author adrianromero + */ +public class TicketLineInfo implements SerializableWrite, SerializableRead, Serializable { + + private static final long serialVersionUID = 6608012948284450199L; + private String m_sTicket; + private int m_iLine; + private double multiply; + private double price; + private TaxInfo tax; + private Properties attributes; + private String productid; + private String attsetinstid; + private Boolean updated = false; + + private double newprice = 0.0; + + /** Creates new TicketLineInfo + * @param productid + * @param dMultiply + * @param dPrice + * @param tax + * @param props */ + public TicketLineInfo(String productid, double dMultiply, double dPrice, TaxInfo tax, Properties props) { + init(productid, null, dMultiply, dPrice, tax, props); + } + + /** + * + * @param productid + * @param dMultiply + * @param dPrice + * @param tax + */ + public TicketLineInfo(String productid, double dMultiply, double dPrice, TaxInfo tax) { + init(productid, null, dMultiply, dPrice, tax, new Properties()); + } + + /** + * Example: Call from script.TotalDiscount event + * @param productid + * @param productname + * @param producttaxcategory + * @param productprinter + * @param dMultiply + * @param dPrice + * @param tax + */ + public TicketLineInfo(String productid, String productname, String producttaxcategory, String productprinter, double dMultiply, double dPrice, TaxInfo tax) { + Properties props = new Properties(); + props.setProperty("product.name", productname); + props.setProperty("product.taxcategoryid", producttaxcategory); + props.setProperty("product.printer", productprinter); //added to props as may introduce printer redirect + + init(productid, null, dMultiply, dPrice, tax, props); + } + + /** + * Example: Call from script.LineDiscount event + * @param productname + * @param producttaxcategory + * @param productprinter //added to props as may introduce printer redirect + * @param dMultiply + * @param dPrice + * @param tax + */ + public TicketLineInfo(String productname, String producttaxcategory, String productprinter, double dMultiply, double dPrice, TaxInfo tax) { + + Properties props = new Properties(); + props.setProperty("product.name", productname); + props.setProperty("product.taxcategoryid", producttaxcategory); + props.setProperty("product.printer", productprinter); + + init(null, null, dMultiply, dPrice, tax, props); + } + + /** + * + */ + public TicketLineInfo() { + init(null, null, 0.0, 0.0, null, new Properties()); + } + + /** + * + * @param product + * @param dMultiply + * @param dPrice + * @param tax + * @param attributes + */ + public TicketLineInfo(ProductInfoExt product, double dMultiply, double dPrice, TaxInfo tax, Properties attributes) { + + String pid; + + if (product == null) { + pid = null; + tax = null; + } else { + pid = product.getID(); + attributes.setProperty("product.name", product.getName()); + attributes.setProperty("product.reference", product.getReference()); + attributes.setProperty("product.code", product.getCode()); + + if (product.getMemoDate() == null) { + attributes.setProperty("product.memodate", "1900-01-01 00:00:01"); + } else { + attributes.setProperty("product.memodate", product.getMemoDate()); + } + + attributes.setProperty("product.com", product.isCom() ? "true" : "false"); + attributes.setProperty("product.constant", product.isConstant() ? "true" : "false"); + + if (product.getPrinter() != null) { + attributes.setProperty("product.printer", product.getPrinter()); + } else { + attributes.setProperty("product.printer", "1"); + } + + attributes.setProperty("product.service", product.isService() ? "true" : "false"); + attributes.setProperty("product.vprice", product.isVprice() ? "true" : "false"); + attributes.setProperty("product.verpatrib", product.isVerpatrib() ? "true" : "false"); + + if (product.getTextTip() != null) { + attributes.setProperty("product.texttip", product.getTextTip()); + } + + attributes.setProperty("product.warranty", product.getWarranty()? "true" : "false"); + + if (product.getAttributeSetID() != null) { + attributes.setProperty("product.attsetid", product.getAttributeSetID()); + } + + attributes.setProperty("product.taxcategoryid", product.getTaxCategoryID()); + + if (product.getCategoryID() != null) { + attributes.setProperty("product.categoryid", product.getCategoryID()); + } + + if ("true".equals(attributes.getProperty("ticket.updated"))) { + attributes.setProperty("ticket.updated", "false"); + } else { + attributes.setProperty("ticket.updated", "true"); + } + } + + init(pid, null, dMultiply, dPrice, tax, attributes); + } + + /** + * + * @param oProduct + * @param dPrice + * @param tax + * @param attributes + */ + public TicketLineInfo(ProductInfoExt oProduct, double dPrice, TaxInfo tax, Properties attributes) { + this(oProduct, 1.0, dPrice, tax, attributes); + } + + /** + * + * @param line + */ + public TicketLineInfo(TicketLineInfo line) { + init(line.productid, line.attsetinstid, line.multiply, line.price, + line.tax, (Properties) line.attributes.clone()); + } + + private void init(String productid, String attsetinstid, double dMultiply, double dPrice, TaxInfo tax, Properties attributes) { + + this.productid = productid; + this.attsetinstid = attsetinstid; + multiply = dMultiply; + price = dPrice; + this.tax = tax; + this.attributes = attributes; + + m_sTicket = null; + m_iLine = -1; + } + + void setTicket(String ticket, int line) { + m_sTicket = ticket; + m_iLine = line; + } + + /** + * + * @param dp + * @throws BasicException + */ + @Override + public void writeValues(DataWrite dp) throws BasicException { + dp.setString(1, m_sTicket); + dp.setInt(2, m_iLine); + dp.setString(3, productid); + dp.setString(4, attsetinstid); + dp.setDouble(5, multiply); + dp.setDouble(6, price); + dp.setString(7, tax.getId()); + + try { + ByteArrayOutputStream o = new ByteArrayOutputStream(); + attributes.storeToXML(o, AppLocal.APP_NAME, "UTF-8"); + dp.setBytes(8, o.toByteArray()); + } catch (IOException e) { + dp.setBytes(8, null); + } + } + + /** + * + * @param dr + * @throws BasicException + */ + @Override + public void readValues(DataRead dr) throws BasicException { + m_sTicket = dr.getString(1); + m_iLine = dr.getInt(2); + productid = dr.getString(3); + attsetinstid = dr.getString(4); + multiply = dr.getDouble(5); + price = dr.getDouble(6); + tax = new TaxInfo( + dr.getString(7), + dr.getString(8), + dr.getString(9), + dr.getString(10), + dr.getString(11), + dr.getDouble(12), + dr.getBoolean(13), + dr.getInt(14)); + attributes = new Properties(); + + try { + byte[] img = dr.getBytes(15); + if (img != null) { + attributes.loadFromXML(new ByteArrayInputStream(img)); + } + } catch (IOException e) { + } + } + + /** + * + * @return + */ + public TicketLineInfo copyTicketLine() { + TicketLineInfo l = new TicketLineInfo(); + l.productid = productid; + l.attsetinstid = attsetinstid; + l.multiply = multiply; + l.price = price; + l.tax = tax; + l.attributes = (Properties) attributes.clone(); + + return l; + } + + /** + * + * @return + */ + public int getTicketLine() { + return m_iLine; + } +// These are the Lookups + public String getProductID() { + return productid; + } + public String getProductCategoryID() { + return (attributes.getProperty("product.categoryid")); + } + public String getProductAttSetId() { + return attributes.getProperty("product.attsetid"); + } + public String getProductAttSetInstId() { + return attsetinstid; + } + public String getProductAttSetInstDesc() { + return attributes.getProperty("product.attsetdesc", ""); + } + public String getProductTaxCategoryID() { + return (attributes.getProperty("product.taxcategoryid")); + } + public String getTicketUpdated() { + return (attributes.getProperty("ticket.updated")); + } + public TaxInfo getTaxInfo() { + return tax; + } + public void setTaxInfo(TaxInfo oTaxInfo) { + tax = oTaxInfo; + } + +// These appear on Printed TicketLine + public String getProductName() { + return attributes.getProperty("product.name"); + } + public String getProductMemoDate() { + return attributes.getProperty("product.memodate"); + } + public double getPrice() { + return price; + } + public double getMultiply() { + return multiply; + } + public double getTaxRate() { + return tax == null ? 0.0 : tax.getRate(); + } + public double getNewPrice() { + newprice = price * (1.0 + getTaxRate()); + return price; + } + public String getProductPrinter() { + return attributes.getProperty("product.printer"); + } + +// These are the Summaries + public double getPriceTax() { + return price * (1.0 + getTaxRate()); + } + + public Properties getProperties() { + return attributes; + } + public String getProperty(String key) { + return attributes.getProperty(key); + } + public String getProperty(String key, String defaultvalue) { + return attributes.getProperty(key, defaultvalue); + } + +// These are Ticket Totals + public double getTax() { + return price * multiply * getTaxRate(); + } + public double getValue() { + return price * multiply * (1.0 + getTaxRate()); + } + public double getSubValue() { + return price * multiply; + } + +// SETTERS + public void setPrice(double dValue) { + price = dValue; + } + public void setPriceTax(double dValue) { + price = dValue / (1.0 + getTaxRate()); + } + public void setMultiply(double dValue) { + multiply = dValue; + } + public void setProperty(String key, String value) { + attributes.setProperty(key, value); + } + public void setProductTaxCategoryID(String taxID){ + attributes.setProperty("product.taxcategoryid",taxID); + } + public void setProductAttSetInstId(String value) { + attsetinstid = value; + } + public void setProductAttSetInstDesc(String value) { + if (value == null) { + attributes.remove(value); + } else { + attributes.setProperty("product.attsetdesc", value); + } + } + public void setTicketUpdated(String key, String value){ + attributes.setProperty("ticket.updated",value); + } + public void setProductPrinter(String value) { + if (value == null) { + attributes.remove(value); + } else { + attributes.setProperty("product.printer", value); + } + } + + /** + * + * @return + */ + // Print to actual ${ticketline + public String printReference() { + return StringUtils.encodeXML(attributes.getProperty("product.reference")); + } + public String printCode() { + return StringUtils.encodeXML(attributes.getProperty("product.code")); + } + public String printName() { + return StringUtils.encodeXML(attributes.getProperty("product.name")); + } + public String printProductMemoDate() { + return StringUtils.encodeXML(attributes.getProperty("product.memodate")); + } + public String printPrice() { + return Formats.CURRENCY.formatValue(getPrice()); + } + public String printPriceTax() { + return Formats.CURRENCY.formatValue(getPriceTax()); + } + public String printMultiply() { + return Formats.DOUBLE.formatValue(multiply); + } + public String printValue() { + return Formats.CURRENCY.formatValue(getValue()); + } + public String printTaxRate() { + return Formats.PERCENT.formatValue(getTaxRate()); + } + public String printSubValue() { + return Formats.CURRENCY.formatValue(getSubValue()); + } + public String printTax() { + return Formats.CURRENCY.formatValue(getTax()); + } + public String printTextTip() { + return attributes.getProperty("product.texttip"); + } + public String printPrinter() { + return StringUtils.encodeXML(attributes.getProperty("product.printer")); + } + public boolean isProductCom() { + return "true".equals(attributes.getProperty("product.com")); + } + public boolean isProductService() { + return "true".equals(attributes.getProperty("product.service")); + } + public boolean isProductVprice() { + return "true".equals(attributes.getProperty("product.vprice")); + } + public boolean isProductVerpatrib() { + return "true".equals(attributes.getProperty("product.verpatrib")); + } + public boolean isProductWarranty() { + return "true".equals(attributes.getProperty("product.warranty")); + } + public boolean getUpdated() { + return "true".equals(attributes.getProperty("ticket.updated")); + } + public void setUpdated(Boolean value) { + updated = value; + } + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/ticket/TicketLineInfo1.java b/src/main/java/com/unicenta/pos/ticket/TicketLineInfo1.java new file mode 100644 index 0000000..ae65855 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/TicketLineInfo1.java @@ -0,0 +1,637 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2017 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.DataWrite; +import com.unicenta.data.loader.SerializableRead; +import com.unicenta.data.loader.SerializableWrite; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.util.StringUtils; +import java.io.*; +import java.util.Properties; + +/** + * + * @author adrianromero + */ +public class TicketLineInfo1 implements SerializableWrite, SerializableRead, Serializable { + + private static final long serialVersionUID = 6608012948284450199L; + private String m_sTicket; + private int m_iLine; + private double multiply; + private double price; + private TaxInfo tax; + private Properties attributes; + private String productid; + private String attsetinstid; + + /** Creates new TicketLineInfo + * @param productid + * @param dMultiply + * @param dPrice + * @param tax + * @param props */ + public TicketLineInfo1(String productid, double dMultiply, double dPrice, TaxInfo tax, Properties props) { + init(productid, null, dMultiply, dPrice, tax, props); + } + + /** + * + * @param productid + * @param dMultiply + * @param dPrice + * @param tax + */ + public TicketLineInfo1(String productid, double dMultiply, double dPrice, TaxInfo tax) { + init(productid, null, dMultiply, dPrice, tax, new Properties()); + } + + /** + * + * @param productid + * @param productname + * @param producttaxcategory + * @param dMultiply + * @param dPrice + * @param tax + */ + public TicketLineInfo1(String productid, String productname, String producttaxcategory, double dMultiply, double dPrice, TaxInfo tax) { + Properties props = new Properties(); + props.setProperty("product.name", productname); + props.setProperty("product.taxcategoryid", producttaxcategory); + init(productid, null, dMultiply, dPrice, tax, props); + } + + /** + * + * @param productname + * @param producttaxcategory + * @param dMultiply + * @param dPrice + * @param tax + */ + public TicketLineInfo1(String productname, String producttaxcategory, double dMultiply, double dPrice, TaxInfo tax) { + + Properties props = new Properties(); + props.setProperty("product.name", productname); + props.setProperty("product.taxcategoryid", producttaxcategory); + init(null, null, dMultiply, dPrice, tax, props); + } + + /** + * + */ + public TicketLineInfo1() { + init(null, null, 0.0, 0.0, null, new Properties()); + } + + /** + * + * @param product + * @param dMultiply + * @param dPrice + * @param tax + * @param attributes + */ + public TicketLineInfo1(ProductInfoExt product, double dMultiply, double dPrice, TaxInfo tax, Properties attributes) { + + String pid; + + if (product == null) { + pid = null; + } else { + pid = product.getID(); + attributes.setProperty("product.name", product.getName()); + attributes.setProperty("product.com", product.isCom() ? "true" : "false"); + attributes.setProperty("product.constant", product.isConstant() ? "true" : "false"); + attributes.setProperty("product.printer", product.getPrinter()); + attributes.setProperty("product.service", product.isService() ? "true" : "false"); + attributes.setProperty("product.vprice", product.isVprice() ? "true" : "false"); + attributes.setProperty("product.verpatrib", product.isVerpatrib() ? "true" : "false"); + + if (product.getTextTip() != null) { + attributes.setProperty("product.texttip", product.getTextTip()); + } + + attributes.setProperty("product.warranty", product.getWarranty()? "true" : "false"); + + if (product.getAttributeSetID() != null) { + attributes.setProperty("product.attsetid", product.getAttributeSetID()); + } + attributes.setProperty("product.taxcategoryid", product.getTaxCategoryID()); + + if (product.getCategoryID() != null) { + attributes.setProperty("product.categoryid", product.getCategoryID()); + } + } + init(pid, null, dMultiply, dPrice, tax, attributes); + } + + /** + * + * @param oProduct + * @param dPrice + * @param tax + * @param attributes + */ + public TicketLineInfo1(ProductInfoExt oProduct, double dPrice, TaxInfo tax, Properties attributes) { + this(oProduct, 1.0, dPrice, tax, attributes); + } + + /** + * + * @param line + */ + public TicketLineInfo1(TicketLineInfo1 line) { + init(line.productid, line.attsetinstid, line.multiply, line.price, line.tax, (Properties) line.attributes.clone()); + } + + private void init(String productid, String attsetinstid, double dMultiply, double dPrice, TaxInfo tax, Properties attributes) { + + this.productid = productid; + this.attsetinstid = attsetinstid; + multiply = dMultiply; + price = dPrice; + this.tax = tax; + this.attributes = attributes; + + m_sTicket = null; + m_iLine = -1; + } + + void setTicket(String ticket, int line) { + m_sTicket = ticket; + m_iLine = line; + } + + /** + * + * @param dp + * @throws BasicException + */ + @Override + public void writeValues(DataWrite dp) throws BasicException { + dp.setString(1, m_sTicket); + dp.setInt(2, new Integer(m_iLine)); + dp.setString(3, productid); + dp.setString(4, attsetinstid); + + dp.setDouble(5, new Double(multiply)); + dp.setDouble(6, new Double(price)); + + dp.setString(7, tax.getId()); + try { + ByteArrayOutputStream o = new ByteArrayOutputStream(); + attributes.storeToXML(o, AppLocal.APP_NAME, "UTF-8"); + dp.setBytes(8, o.toByteArray()); + } catch (IOException e) { + dp.setBytes(8, null); + } + } + + /** + * + * @param dr + * @throws BasicException + */ + @Override + public void readValues(DataRead dr) throws BasicException { + m_sTicket = dr.getString(1); + m_iLine = dr.getInt(2).intValue(); + productid = dr.getString(3); + attsetinstid = dr.getString(4); + multiply = dr.getDouble(5); + price = dr.getDouble(6); + tax = new TaxInfo( + dr.getString(7), + dr.getString(8), + dr.getString(9), + dr.getString(10), + dr.getString(11), + dr.getDouble(12), + dr.getBoolean(13), + dr.getInt(14)); + attributes = new Properties(); + try { + byte[] img = dr.getBytes(15); + if (img != null) { + attributes.loadFromXML(new ByteArrayInputStream(img)); + } + } catch (IOException e) { + } + } + + /** + * + * @return + */ + public TicketLineInfo1 copyTicketLine() { + TicketLineInfo1 l = new TicketLineInfo1(); + l.productid = productid; + l.attsetinstid = attsetinstid; + l.multiply = multiply; + l.price = price; + l.tax = tax; + l.attributes = (Properties) attributes.clone(); + return l; + } + + /** + * + * @return + */ + public int getTicketLine() { + return m_iLine; + } + + /** + * + * @return + */ + public String getProductID() { + return productid; + } + + /** + * + * @return + */ + public String getProductName() { + return attributes.getProperty("product.name"); + } + + /** + * + * @return + */ + public String getProductPrinter() { + return attributes.getProperty("product.printer"); + } + + /** + * + * @return + */ + public String getProductAttSetId() { + return attributes.getProperty("product.attsetid"); + } + + /** + * + * @return + */ + public String getProductAttSetInstDesc() { + return attributes.getProperty("product.attsetdesc", ""); + } + + /** + * + * @param value + */ + public void setProductAttSetInstDesc(String value) { + if (value == null) { + attributes.remove(value); + } else { + attributes.setProperty("product.attsetdesc", value); + } + } + + /** + * + * @return + */ + public String getProductAttSetInstId() { + return attsetinstid; + } + + /** + * + * @param value + */ + public void setProductAttSetInstId(String value) { + attsetinstid = value; + } + + /** + * + * @return + */ + public boolean isProductCom() { + return "true".equals(attributes.getProperty("product.com")); + } + + /** + * + * @return + */ + public String getProductTaxCategoryID() { + return (attributes.getProperty("product.taxcategoryid")); + } + + /** + * + * @param taxID + */ + public void setProductTaxCategoryID(String taxID){ + attributes.setProperty("product.taxcategoryid",taxID); + } + + /** + * + * @return + */ + public String getProductCategoryID() { + return (attributes.getProperty("product.categoryid")); + } + + /** + * + * @return + */ + public double getMultiply() { + return multiply; + } + + /** + * + * @param dValue + */ + public void setMultiply(double dValue) { + multiply = dValue; + } + + /** + * + * @return + */ + public double getPrice() { + return price; + } + + /** + * + * @param dValue + */ + public void setPrice(double dValue) { + price = dValue; + } + + /** + * + * @return + */ + public double getPriceTax() { + return price * (1.0 + getTaxRate()); + } + + /** + * + * @param dValue + */ + public void setPriceTax(double dValue) { + price = dValue / (1.0 + getTaxRate()); + } + + /** + * + * @return + */ + public TaxInfo getTaxInfo() { + return tax; + } + + /** + * + * @param value + */ + public void setTaxInfo(TaxInfo value) { + tax = value; + } + + /** + * + * @param key + * @return + */ + public String getProperty(String key) { + return attributes.getProperty(key); + } + + /** + * + * @param key + * @param defaultvalue + * @return + */ + public String getProperty(String key, String defaultvalue) { + return attributes.getProperty(key, defaultvalue); + } + + /** + * + * @param key + * @param value + */ + public void setProperty(String key, String value) { + attributes.setProperty(key, value); + } + + /** + * + * @return + */ + public Properties getProperties() { + return attributes; + } + + /** + * + * @return + */ + public double getTaxRate() { + return tax == null ? 0.0 : tax.getRate(); + } + + /** + * + * @return + */ + public double getSubValue() { + return price * multiply; + } + + /** + * + * @return + */ + public double getTax() { + return price * multiply * getTaxRate(); + } + + /** + * + * @return + */ + public double getValue() { + return price * multiply * (1.0 + getTaxRate()); + } + + /** + * + * @return + */ + public String printName() { + return StringUtils.encodeXML(attributes.getProperty("product.name")); + } + + /** + * + * @return + */ + public String printPrinter() { + return StringUtils.encodeXML(attributes.getProperty("product.printer")); + } + + /** + * + * @return + */ + public String printMultiply() { + return Formats.DOUBLE.formatValue(multiply); + } + + /** + * + * @return + */ + public String printPrice() { + return Formats.CURRENCY.formatValue(getPrice()); + } + + /** + * + * @return + */ + public String printPriceTax() { + return Formats.CURRENCY.formatValue(getPriceTax()); + } + + /** + * + * @return + */ + public String printTax() { + return Formats.CURRENCY.formatValue(getTax()); + } + + /** + * + * @return + */ + public String printTaxRate() { + return Formats.PERCENT.formatValue(getTaxRate()); + } + + /** + * + * @return + */ + public String printSubValue() { + return Formats.CURRENCY.formatValue(getSubValue()); + } + + /** + * + * @return + */ + public String printValue() { + return Formats.CURRENCY.formatValue(getValue()); + } +// ADDED JG 20.12.10 - Kitchen Print + + /** + * + * @return + */ + public boolean isProductConstant() { + return "true".equals(attributes.getProperty("product.constant")); +} +// *** +// ADDED JG 25.06.11 - Is Service + + /** + * + * @return + */ + public boolean isProductService() { + return "true".equals(attributes.getProperty("product.service")); +} +// Added JDL 19.12.12 - Variable price product + + /** + * + * @return + */ + public boolean isProductVprice() { + return "true".equals(attributes.getProperty("product.vprice")); +// + +} + +// Added JDL 09.02.13 for Chris + + /** + * + * @return + */ + public boolean isProductVerpatrib() { + return "true".equals(attributes.getProperty("product.verpatrib")); +// + +} + +// Added JDL 09.04.12 - Variable price product + + /** + * + * @return + */ + public String printTextTip() { + return attributes.getProperty("product.texttip"); +// + +} + +// Added JDL 09.02.13 + + /** + * + * @return + */ + public boolean isProductWarranty() { + return "true".equals(attributes.getProperty("product.warranty")); +// + + } +} diff --git a/src/main/java/com/unicenta/pos/ticket/TicketTaxInfo.java b/src/main/java/com/unicenta/pos/ticket/TicketTaxInfo.java new file mode 100644 index 0000000..d8f1ea4 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/TicketTaxInfo.java @@ -0,0 +1,108 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2017 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.ticket; + +import com.unicenta.format.Formats; + +/** + * + * @author JG uniCenta + */ +public class TicketTaxInfo { + + private TaxInfo tax; + + private double subtotal; + private double taxtotal; + + /** Creates a new instance of TicketTaxInfo + * @param tax */ + public TicketTaxInfo(TaxInfo tax) { + this.tax = tax; + + subtotal = 0.0; + taxtotal = 0.0; + } + + /** + * + * @return + */ + public TaxInfo getTaxInfo() { + return tax; + } + + /** + * + * @param dValue + */ + public void add(double dValue) { + subtotal += dValue; + taxtotal = subtotal * tax.getRate(); + } + + /** + * + * @return + */ + public double getSubTotal() { + return subtotal; + } + + /** + * + * @return + */ + public double getTax() { + return taxtotal; + } + + /** + * + * @return + */ + public double getTotal() { + return subtotal + taxtotal; + } + + /** + * + * @return + */ + public String printSubTotal() { + return Formats.CURRENCY.formatValue(getSubTotal()); + } + + /** + * + * @return + */ + public String printTax() { + return Formats.CURRENCY.formatValue(getTax()); + } + + /** + * + * @return + */ + public String printTotal() { + return Formats.CURRENCY.formatValue(getTotal()); + } +} diff --git a/src/main/java/com/unicenta/pos/ticket/UserInfo.java b/src/main/java/com/unicenta/pos/ticket/UserInfo.java new file mode 100644 index 0000000..d4404b6 --- /dev/null +++ b/src/main/java/com/unicenta/pos/ticket/UserInfo.java @@ -0,0 +1,56 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2017 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +package com.unicenta.pos.ticket; + +import java.io.Serializable; + +/** + * + * @author adrianromero + */ +public class UserInfo implements Serializable { + + private static final long serialVersionUID = 7537578737839L; + private String m_sId; + private String m_sName; + + /** Creates a new instance of UserInfoBasic + * @param id + * @param name */ + public UserInfo(String id, String name) { + m_sId = id; + m_sName = name; + } + + /** + * + * @return + */ + public String getId() { + return m_sId; + } + + /** + * + * @return + */ + public String getName() { + return m_sName; + } +} diff --git a/src/main/java/com/unicenta/pos/transfer/Transfer.form b/src/main/java/com/unicenta/pos/transfer/Transfer.form new file mode 100644 index 0000000..5e5503c --- /dev/null +++ b/src/main/java/com/unicenta/pos/transfer/Transfer.form @@ -0,0 +1,1109 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.8" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" red="ff" type="rgb"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[900, 425]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel9" min="0" pref="0" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel5" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="cbSource" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel2" max="-2" attributes="0"/> + <Component id="jLabel12" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jtxtDbType" min="-2" max="-2" attributes="0"/> + <Component id="jtxtDbServerPort" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel18" alignment="0" max="-2" attributes="0"/> + <Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jtxtDbDriver" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Component id="jtxtDbDriverLib" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jbtnDbDriverLib" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="366" max="-2" attributes="0"/> + <Component id="jbtnReset" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="jbtnConnect" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Component id="txtDbUser" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel4" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Component id="txtDbPass" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="jTransferPanel" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel6" min="-2" pref="202" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jlblSource" min="-2" pref="316" max="-2" attributes="0"/> + </Group> + <Component id="jLabel16" alignment="0" min="-2" pref="278" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel8" min="-2" pref="125" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="webPBar" min="-2" pref="109" max="-2" attributes="0"/> + <EmptySpace min="20" max="32767" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <EmptySpace min="18" pref="18" max="-2" attributes="0"/> + <Component id="jScrollPane1" max="32767" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="webPBar" min="-2" pref="32" max="-2" attributes="0"/> + <Component id="jLabel8" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="jLabel6" alignment="1" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="jlblSource" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel16" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="cbSource" min="-2" max="-2" attributes="0"/> + <Component id="jLabel5" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" alignment="0" groupAlignment="2" attributes="0"> + <Component id="jLabel18" alignment="2" min="-2" max="-2" attributes="0"/> + <Component id="jtxtDbDriverLib" alignment="2" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="jbtnDbDriverLib" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jtxtDbDriver" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jtxtDbType" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel12" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jtxtDbServerPort" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtDbUser" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="txtDbPass" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jbtnConnect" min="-2" max="-2" attributes="0"/> + <Component id="jbtnReset" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Component id="jLabel9" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Component id="jTransferPanel" min="-2" max="-2" attributes="0"/> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + </Group> + <Component id="jScrollPane1" alignment="0" max="32767" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.DbType" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel18"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.dbdriverlib" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.DbDriver" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 30]"/> + </Property> + </Properties> + <AccessibilityProperties> + <Property name="AccessibleContext.accessibleName" type="java.lang.String" value="DBDriver"/> + </AccessibilityProperties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="text" type="java.lang.String" value="Type"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.DbUser" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.DbPassword" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="33" green="33" red="33" type="rgb"/> + </Property> + <Property name="text" type="java.lang.String" value="Currently connected to :"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.combobox.WebComboBox" name="cbSource"> + <Properties> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="33" green="33" red="33" type="rgb"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.transferfromdb" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbSourceActionPerformed"/> + </Events> + </Component> + <Component class="com.alee.laf.text.WebTextField" name="jtxtDbDriverLib"> + <Properties> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="33" green="33" red="33" type="rgb"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tootltip.transferlib" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[360, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jbtnDbDriverLib"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/fileopen.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.openfile" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[64, 32]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[64, 32]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[60, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.text.WebTextField" name="jtxtDbDriver"> + <Properties> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="33" green="33" red="33" type="rgb"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tootltip.transferclass" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[360, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.text.WebTextField" name="jtxtDbType"> + <Properties> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="33" green="33" red="33" type="rgb"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tootltip.transferdbtype" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.text.WebTextField" name="txtDbUser"> + <Properties> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="33" green="33" red="33" type="rgb"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.dbuser" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[125, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.text.WebPasswordField" name="txtDbPass"> + <Properties> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="33" green="33" red="33" type="rgb"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.dbpassword" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[125, 30]"/> + </Property> + </Properties> + </Component> + <Container class="javax.swing.JScrollPane" name="jScrollPane1"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + <Property name="verticalScrollBarPolicy" type="int" value="22"/> + <Property name="viewportBorder" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="cc" green="cc" red="cc" type="rgb"/> + </LineBorder> + </Border> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="13" style="0"/> + </Property> + <Property name="horizontalScrollBar" type="javax.swing.JScrollBar" editor="org.netbeans.modules.form.ComponentChooserEditor"> + <ComponentRef name="null"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[200, 350]"/> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JTextArea" name="txtOut"> + <Properties> + <Property name="columns" type="int" value="20"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="99" red="0" type="rgb"/> + </Property> + <Property name="rows" type="int" value="5"/> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.transfertxtout" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="null"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="99" red="0" type="rgb"/> + </Property> + <Property name="text" type="java.lang.String" value="PROGRESS"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jlblSource"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="99" red="0" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel9"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.DbUser" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jbtnConnect"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/btn1.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="Button.Test" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.dbtest" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="actionCommand" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="Button.Test" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="horizontalTextPosition" type="int" value="4"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnConnectjButtonTestConnectionActionPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="JPanelConfigDatabase_jButtonTest"/> + </AuxValues> + </Component> + <Component class="com.alee.laf.progressbar.WebProgressBar" name="webPBar"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="13" style="0"/> + </Property> + <Property name="highlightDarkWhite" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="0" green="0" red="cc" type="rgb"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[240, 30]"/> + </Property> + <Property name="progressBottomColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="99" red="0" type="rgb"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.text.WebTextField" name="jtxtDbServerPort"> + <Properties> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="33" green="33" red="33" type="rgb"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tootltip.servernameport" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[360, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel12"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="labelServerPort" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 30]"/> + </Property> + </Properties> + </Component> + <Container class="javax.swing.JPanel" name="jTransferPanel"> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel7" max="-2" attributes="0"/> + <Component id="jtxtDbName" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" pref="7" max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" max="-2" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jlblVersion" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel11" min="-2" pref="100" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jlblDBSize" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Component id="jbtnSet" min="-2" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + <Component id="jbtnTransfer" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Component id="jbtnReset1" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jLabel13" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jCBSchema" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="jLabel15" max="32767" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="webMemoryBar" min="-2" pref="125" max="-2" attributes="0"/> + <Component id="jLabel10" pref="0" max="32767" attributes="0"/> + </Group> + </Group> + <Group type="102" attributes="0"> + <Component id="jLabel14" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jtxtDbParams" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel15" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel10" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel13" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jCBSchema" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="webMemoryBar" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jtxtDbParams" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel14" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jlblVersion" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="jLabel11" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="jLabel7" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="jlblDBSize" alignment="1" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jbtnTransfer" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jbtnSet" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jtxtDbName" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="jbtnReset1" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel13"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.DbSource" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="jCBSchema"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tootltip.transferdbname" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[360, 30]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/> + </AuxValues> + </Component> + <Component class="javax.swing.JLabel" name="jLabel14"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.DBParameters" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.text.WebTextField" name="jtxtDbParams"> + <Properties> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="33" green="33" red="33" type="rgb"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tootltip.transferdbparams" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[360, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel7"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="text" type="java.lang.String" value="DB Version"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jlblVersion"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="16" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="cc" red="0" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.transferdbversion" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="ff" green="cc" red="0" type="rgb"/> + </LineBorder> + </Border> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[125, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel11"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="text" type="java.lang.String" value="DB Size"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jlblDBSize"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="16" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="cc" red="0" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.transferdbsize" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="ff" green="cc" red="0" type="rgb"/> + </LineBorder> + </Border> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[120, 30]"/> + </Property> + </Properties> + </Component> + <Component class="com.alee.laf.text.WebTextField" name="jtxtDbName"> + <Properties> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="33" green="33" red="33" type="rgb"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tootltip.transferdbname" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="opaque" type="boolean" value="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 0]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jbtnTransfer"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/btn3.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.transfer" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.transferdb" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="horizontalTextPosition" type="int" value="4"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 33]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 33]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnTransferActionPerformed"/> + </Events> + </Component> + <Component class="com.alee.extended.statusbar.WebMemoryBar" name="webMemoryBar"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="99" green="99" red="99" type="rgb"/> + </Property> + <Property name="text" type="java.lang.String" value="Text"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="usedBorderColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="cc" green="cc" red="0" type="rgb"/> + </Property> + <Property name="usedFillColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="cc" red="0" type="rgb"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel10"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="66" green="66" red="66" type="rgb"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="text" type="java.lang.String" value="Memory State"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel15"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="99" red="0" type="rgb"/> + </Property> + <Property name="text" type="java.lang.String" value="CHOOSE DATABASE TO TRANSFER FROM"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jbtnSet"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/btn2.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.setTransfer" replaceFormat="AppLocal.getIntString("button.setTransfer")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.checkTransfer" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="horizontalAlignment" type="int" value="2"/> + <Property name="horizontalTextPosition" type="int" value="4"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 33]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 33]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[160, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnSetActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jbtnReset1"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/reload.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.transferReset" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 33]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 33]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnReset1ActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JButton" name="jbtnReset"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/reload.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.transferReset" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 33]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[70, 33]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jbtnResetActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel16"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="18" style="0"/> + </Property> + <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="99" green="99" red="99" type="rgb"/> + </Property> + <Property name="text" type="java.lang.String" value="SET SERVER TO CONNECT TO"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/transfer/Transfer.java b/src/main/java/com/unicenta/pos/transfer/Transfer.java new file mode 100644 index 0000000..3901ec9 --- /dev/null +++ b/src/main/java/com/unicenta/pos/transfer/Transfer.java @@ -0,0 +1,3018 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2016 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.transfer; + + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.JMessageDialog; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.loader.BatchSentence; +import com.unicenta.data.loader.BatchSentenceResource; +import com.unicenta.data.loader.Session; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.pos.config.PanelConfig; +import com.unicenta.pos.forms.*; +import com.unicenta.pos.util.AltEncrypter; +import com.unicenta.pos.util.DirectoryEvent; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.*; +import java.awt.*; +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.sql.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.regex.Matcher; + +/** + * @author JG uniCenta + */ +@Slf4j +public final class Transfer extends JPanel implements JPanelView { + + private DirtyManager dirty = new DirtyManager(); + private AppConfig config; + private AppProperties m_props; + private Properties m_propsdb = null; + + private List<PanelConfig> m_panelconfig; + + private Connection con_source; + private Connection con_target; + + private String sDB_source; + private String sDB_target; + + private Session session_source; + private Session session_target; + + private ResultSet rs; + + private Statement stmt_source; + private Statement stmt_target; + private PreparedStatement pstmt; + private String SQL; + + private String source_version; + + private String ticketsnum; + private String ticketsnumRefund; + private String ticketsnumPayment; + + private String targetCreate = ""; + private String targetFKadd = ""; + private String targetFKdrop = ""; + + ArrayList<String> stringList = new ArrayList<>(); + + public String strOut = ""; + + // the db connection session + private Session s; + private Connection con; + private Session session; + private boolean m_bInTransaction; + + String db_url = null; + String db_schema = null; + String db_options = null; + String db_user = null; + String db_password = null; + + /** + * Creates new form JPaneldbTransfer + * + * @param oApp + */ + public Transfer(AppView oApp) { + this(oApp.getProperties()); + } + + /** + * @param props + */ + public Transfer(AppProperties props) { + + initComponents(); + + config = new AppConfig(props.getConfigFile()); + m_props = props; + m_panelconfig = new ArrayList<>(); + config.load(); + + m_panelconfig.stream().forEach((c) -> { + c.loadProperties(config); + }); + + jtxtDbDriverLib.getDocument().addDocumentListener(dirty); + jtxtDbDriver.getDocument().addDocumentListener(dirty); + jtxtDbType.getDocument().addDocumentListener(dirty); + txtDbPass.getDocument().addDocumentListener(dirty); + txtDbUser.getDocument().addDocumentListener(dirty); + txtOut.getDocument().addDocumentListener(dirty); + + jbtnDbDriverLib.addActionListener(new DirectoryEvent(jtxtDbDriverLib)); + + cbSource.addActionListener(dirty); + + cbSource.addItem("MySQL"); + cbSource.addItem("PostgreSQL"); + cbSource.addItem("Derby"); + + stringList.add("Transfer Ready..." + "\n"); + txtOut.setText(stringList.get(0)); + + webPBar.setIndeterminate(true); + webPBar.setStringPainted(true); + webPBar.setString("Waiting..."); + webPBar.setVisible(false); + + jTransferPanel.setVisible(false); + jbtnTransfer.setEnabled(false); + jbtnReset.setEnabled(true); + + } + + /** + * @return + */ + @Override + public JComponent getComponent() { + return this; + } + + /** + * @return + */ + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.Transfer"); + } + + /** + * @return + */ + public Boolean getSource() { + + String db_url2 = jtxtDbType.getText() + + jtxtDbServerPort.getText() + + jtxtDbName.getText() + + jtxtDbParams.getText(); + String db_user2 = txtDbUser.getText(); + char[] pass = txtDbPass.getPassword(); + String db_password2 = new String(pass); + + Properties connectionProps = new Properties(); + connectionProps.put("user", db_user2); + connectionProps.put("password", db_password2); + + try { + Class.forName(jtxtDbDriver.getText()); + + ClassLoader cloader = new URLClassLoader( + new URL[]{ + new File(jtxtDbDriverLib.getText()).toURI().toURL() + }); + DriverManager.registerDriver( + new DriverWrapper((Driver) Class.forName(jtxtDbDriver.getText(), + true, cloader).newInstance())); + con_source = (Connection) DriverManager.getConnection( + db_url2, db_user2, db_password2); + + session_source = new Session(db_url2, db_user2, db_password2); + sDB_source = con_source.getMetaData().getDatabaseProductName(); + + txtOut.append("Connected to Source OK" + "\n"); + jbtnTransfer.setEnabled(true); + + return (true); + + } catch (ClassNotFoundException + | MalformedURLException + | InstantiationException + | IllegalAccessException + | SQLException e) { + + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_DANGER, + AppLocal.getIntString("database.UnableToConnect"), + e)); + return (false); + } + + } + + + /** + * @return + */ + @SuppressWarnings("empty-statement") + public Boolean createTargetDB() { +// Transfer is into current MySQL database in unicentaopos.properties + + targetCreate = "/com/unicenta/pos/scripts/" + sDB_target + "-create-transfer.sql"; + targetFKadd = "/com/unicenta/pos/scripts/MySQL-FKeys.sql"; + targetFKdrop = "/com/unicenta/pos/scripts/MySQL-dropFKeys.sql"; + + if ("".equals(targetCreate)) { + return (false); + } + + try { + BatchSentence bsentence = new BatchSentenceResource(session_target, targetCreate); + bsentence = new BatchSentenceResource(session_target, targetFKdrop); + + bsentence.putParameter("APP_ID", Matcher.quoteReplacement(AppLocal.APP_ID)); + bsentence.putParameter("APP_NAME", Matcher.quoteReplacement(AppLocal.APP_NAME)); + bsentence.putParameter("APP_VERSION", Matcher.quoteReplacement(AppLocal.APP_VERSION)); + + java.util.List l = bsentence.list(); + + if (l.size() > 0) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("transfer.warning"), + l.toArray(new Throwable[l.size()]))); + } else { + + txtOut.append("Connected to Target OK" + "\n"); + txtOut.revalidate(); + txtOut.repaint(); + } + + } catch (BasicException e) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_DANGER, + AppLocal.getIntString("transfer.warningnodefault"), + e)); + session_source.close(); + } finally { + } + + return (true); + } + + /** + * @return + */ + public Boolean FKeys() { + if ("".equals(targetFKadd)) { + return (false); + } + try { + txtOut.append("Adding Foreign Keys" + "\n"); + webPBar.setString("Adding Keys..."); + webPBar.setBgBottom(Color.MAGENTA); + BatchSentence bsentence = new BatchSentenceResource(session_target, targetFKadd); + + java.util.List l = bsentence.list(); + if (l.size() > 0) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("transfer.warning"), + l.toArray(new Throwable[l.size()]))); + txtOut.append("Foreign Key error" + "\n"); + } else { + txtOut.append("Foreign Keys completed" + "\n"); + } + + } catch (BasicException e) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_DANGER, + AppLocal.getIntString("database.ScriptNotFound"), + e)); + session_source.close(); + } finally { + } + txtOut.revalidate(); + txtOut.repaint(); + return (true); + + } + + /** + * @throws BasicException + */ + @Override + public void activate() throws BasicException { + /* + * Repeating this block as Transfer can be run externally + */ + + if ("true".equals(m_props.getProperty("db.multi"))) { + ImageIcon icon = new ImageIcon("/com/unicenta/images/unicentaopos.png"); + Object[] dbs = { + "0 - " + m_props.getProperty("db.name"), + "1 - " + m_props.getProperty("db1.name")}; + + Object s = (Object) JOptionPane.showInputDialog( + null, AppLocal.getIntString("message.databasechoose"), + "Selection", JOptionPane.OK_OPTION, + icon, dbs, m_props.getProperty("db.name")); + + if (s.toString().startsWith("1")) { + db_url = (m_props.getProperty("db1.URL")); + db_schema = (m_props.getProperty("db1.schema")); + db_options = (m_props.getProperty("db1.options")); + db_user = (m_props.getProperty("db1.user")); + db_password = (m_props.getProperty("db1.password")); + if (db_user != null && db_password != null && db_password.startsWith("crypt:")) { + AltEncrypter cypher = new AltEncrypter("cypherkey" + db_user); + db_password = cypher.decrypt(db_password.substring(6)); + } + String url = db_url + db_schema + db_options; + try { + session_target = new Session(url, db_user, db_password); + con_target = DriverManager.getConnection(url, db_user, db_password); + sDB_target = con_target.getMetaData().getDatabaseProductName(); + jlblSource.setText(con_target.getCatalog()); + } catch (SQLException e) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_DANGER, + AppLocal.getIntString("database.UnableToConnect"), + e)); + } + + } else { + db_url = (m_props.getProperty("db.URL")); + db_schema = (m_props.getProperty("db.schema")); + db_options = (m_props.getProperty("db.options")); + db_user = (m_props.getProperty("db.user")); + db_password = (m_props.getProperty("db.password")); + if (db_user != null && db_password != null && db_password.startsWith("crypt:")) { + AltEncrypter cypher = new AltEncrypter("cypherkey" + db_user); + db_password = cypher.decrypt(db_password.substring(6)); + } + String url = db_url + db_schema + db_options; + try { + session_target = new Session(url, db_user, db_password); + con_target = DriverManager.getConnection(url, db_user, db_password); + sDB_target = con_target.getMetaData().getDatabaseProductName(); + jlblSource.setText(con_target.getCatalog()); + } catch (SQLException e) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_DANGER, + AppLocal.getIntString("database.UnableToConnect"), + e)); + } + } + } else { + db_url = (m_props.getProperty("db.URL")); + db_schema = (m_props.getProperty("db.schema")); + db_options = (m_props.getProperty("db.options")); + db_user = (m_props.getProperty("db.user")); + db_password = (m_props.getProperty("db.password")); + if (db_user != null && db_password != null && db_password.startsWith("crypt:")) { + AltEncrypter cypher = new AltEncrypter("cypherkey" + db_user); + db_password = cypher.decrypt(db_password.substring(6)); + } + String url = db_url + db_schema + db_options; + try { + session_target = new Session(url, db_user, db_password); + con_target = DriverManager.getConnection(url, db_user, db_password); + sDB_target = con_target.getMetaData().getDatabaseProductName(); + jlblSource.setText(con_target.getCatalog()); + } catch (SQLException e) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_DANGER, + AppLocal.getIntString("database.UnableToConnect"), + e)); + } + } + } + + /** + * @return + */ + @Override + public boolean deactivate() { + return (true); + } + + /** + * @throws java.sql.SQLException + */ + public void clearData() throws SQLException { + Statement stmt = null; + try { + this.con_target.setAutoCommit(false); + stmt = this.con_target.createStatement(); + + stmt.addBatch("DELETE FROM attributesetinstance;"); + stmt.addBatch("DELETE FROM attributeinstance;"); + stmt.addBatch("DELETE FROM attributevalue"); + stmt.addBatch("DELETE FROM attributeuse"); + stmt.addBatch("DELETE FROM attributeset"); + stmt.addBatch("DELETE FROM attribute"); + stmt.addBatch("DELETE FROM people;"); + stmt.addBatch("DELETE FROM categories;"); + stmt.addBatch("DELETE FROM taxcategories;"); + stmt.addBatch("DELETE FROM taxcustcategories;"); + stmt.addBatch("DELETE FROM taxes;"); + stmt.addBatch("DELETE FROM locations;"); + stmt.addBatch("DELETE FROM floors;"); + stmt.addBatch("DELETE FROM places;"); + stmt.addBatch("DELETE FROM shifts;"); + stmt.addBatch("DELETE FROM breaks;"); + stmt.addBatch("DELETE FROM shift_breaks;"); + stmt.addBatch("DELETE FROM closedcash;"); + stmt.addBatch("DELETE FROM csvimport;"); + stmt.addBatch("DELETE FROM customers;"); + stmt.addBatch("DELETE FROM draweropened;"); + stmt.addBatch("DELETE FROM leaves;"); + stmt.addBatch("DELETE FROM lineremoved;"); + stmt.addBatch("DELETE FROM payments;"); + stmt.addBatch("DELETE FROM products_cat;"); + stmt.addBatch("DELETE FROM products_com;"); + stmt.addBatch("DELETE FROM products;"); + stmt.addBatch("DELETE FROM receipts;"); + stmt.addBatch("DELETE FROM roles WHERE NOT ID = '0';"); + stmt.addBatch("DELETE FROM stockcurrent;"); + stmt.addBatch("DELETE FROM stockdiary;"); + stmt.addBatch("DELETE FROM stocklevel;"); + stmt.addBatch("DELETE FROM suppliers;"); + stmt.addBatch("DELETE FROM uom;"); + stmt.addBatch("DELETE FROM vouchers;"); + + stmt.addBatch("SET autocommit=0;"); + stmt.addBatch("SET unique_checks=0;"); + stmt.addBatch("SET foreign_key_checks=0;"); + + int[] updateCounts = stmt.executeBatch(); + this.con_target.commit(); + + } catch (BatchUpdateException b) { + + } catch (SQLException ex) { + + } finally { + if (stmt != null) { + stmt.close(); + } + this.con_target.setAutoCommit(true); + } + } + + public void doTransfer() throws SQLException { + + webPBar.setString("Starting..."); + webPBar.setVisible(true); + + String Dbtname = ""; + + Double Dbtversion = Double.parseDouble(jlblVersion.getText().substring(0, 3)); + + if (getSource()) { + txtOut.setVisible(true); + txtOut.append("Transfer Started..." + "\n"); + + if (createTargetDB()) { + jbtnTransfer.setEnabled(false); + + try { + stmt_source = (Statement) con_source.createStatement(); + stmt_target = (Statement) con_target.createStatement(); + + clearData(); + + this.con_target.setAutoCommit(false); + + webPBar.setString("Running..."); + + Dbtname = "attribute"; + ResultSet rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Attribute" + "\n"); + SQL = "SELECT ID, NAME FROM attribute"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO attribute (" + + "ID, NAME) " + + "VALUES (?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("NAME")); + + pstmt.executeUpdate(); + } + rs.close(); + + Dbtname = "attributevalue"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Attributevalue" + "\n"); + SQL = "SELECT ID, ATTRIBUTE_ID, VALUE FROM attributevalue"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO attributevalue (" + + "ID, ATTRIBUTE_ID, VALUE) " + + "VALUES (?, ?, ?)"; + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("ATTRIBUTE_ID")); + pstmt.setString(3, rs.getString("VALUE")); + + pstmt.executeUpdate(); + } + rs.close(); + + Dbtname = "attributeinstance"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Attributeinstance" + "\n"); + SQL = "SELECT ID, ATTRIBUTESETINSTANCE_ID, ATTRIBUTE_ID, VALUE FROM attributeinstance"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO attributeinstance (" + + "ID, ATTRIBUTESETINSTANCE_ID, ATTRIBUTE_ID, VALUE) " + + "VALUES (?, ?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("ATTRIBUTESETINSTANCE_ID")); + pstmt.setString(3, rs.getString("ATTRIBUTE_ID")); + pstmt.setString(4, rs.getString("VALUE")); + + pstmt.executeUpdate(); + } + rs.close(); + + Dbtname = "attributesetinstance"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Attributesetinstance" + "\n"); + SQL = "SELECT ID, ATTRIBUTESET_ID, DESCRIPTION FROM attributesetinstance"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO attributesetinstance (" + + "ID, ATTRIBUTESET_ID, DESCRIPTION) " + + "VALUES (?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("ATTRIBUTESET_ID")); + pstmt.setString(3, rs.getString("DESCRIPTION")); + + pstmt.executeUpdate(); + } + rs.close(); + + Dbtname = "attributeuse"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Attributeuse" + "\n"); + SQL = "SELECT ID, ATTRIBUTESET_ID, ATTRIBUTE_ID FROM attributeuse"; + rs = stmt_source.executeQuery(SQL); + +// removed LINENO as weird bug in MySQL causes Lock Timeout +// only happens to this table, no other affected + + while (rs.next()) { + SQL = "INSERT INTO attributeuse(" + + "ID, ATTRIBUTESET_ID, ATTRIBUTE_ID) " + + "VALUES (?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("ATTRIBUTESET_ID")); + pstmt.setString(3, rs.getString("ATTRIBUTE_ID")); + + pstmt.executeUpdate(); + } + rs.close(); + + Dbtname = "attributeset"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Attributeset" + "\n"); + SQL = "SELECT ID, NAME FROM attributeset"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO attributeset (" + + "ID, NAME) " + + "VALUES (?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("NAME")); + + pstmt.executeUpdate(); + } + rs.close(); +// introduced in 3.00 + if (Dbtversion >= 3.00) { + Dbtname = "breaks"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + txtOut.append("Breaks" + "\n"); + SQL = "SELECT * FROM breaks"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO breaks(" + + "ID, NAME, NOTES, VISIBLE) " + + "VALUES (?, ?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("NAME")); + pstmt.setString(3, rs.getString("NOTES")); + pstmt.setBoolean(4, rs.getBoolean("VISIBLE")); + + pstmt.executeUpdate(); + } + } else { + txtOut.append("Breaks... skipped" + "\n"); + } + rs.close(); + + Dbtname = "categories"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Categories" + "\n"); + SQL = "SELECT * FROM categories"; + rs = stmt_source.executeQuery(SQL); + + if (rs.getMetaData().getColumnCount() == 6) { + while (rs.next()) { + SQL = "INSERT INTO categories(" + + "ID, NAME, PARENTID, IMAGE, " + + "TEXTTIP, CATSHOWNAME) " + + "VALUES (?, ?, ?, ?, " + + "?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("NAME")); + pstmt.setString(3, rs.getString("PARENTID")); + pstmt.setBytes(4, rs.getBytes("IMAGE")); + pstmt.setString(5, rs.getString("TEXTTIP")); + pstmt.setBoolean(6, rs.getBoolean("CATSHOWNAME")); + + pstmt.executeUpdate(); + } + } else { + while (rs.next()) { + SQL = "INSERT INTO categories(" + + "ID, NAME, PARENTID, IMAGE) " + + "VALUES (?, ?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("NAME")); + pstmt.setString(3, rs.getString("PARENTID")); + pstmt.setBytes(4, rs.getBytes("IMAGE")); + + pstmt.executeUpdate(); + } + } + rs.close(); + + Dbtname = "closedcash"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("ClosedCash" + "\n"); + SQL = "DELETE FROM closedcash"; + pstmt = con_target.prepareStatement(SQL); + pstmt.executeUpdate(); + + SQL = "SELECT * FROM closedcash"; + rs = stmt_source.executeQuery(SQL); + + if (rs.getMetaData().getColumnCount() == 6) { + while (rs.next()) { + SQL = "INSERT INTO closedcash(" + + "MONEY, HOST, HOSTSEQUENCE, " + + "DATESTART, DATEEND, NOSALES) " + + "VALUES (?, ?, ?, " + + "?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("MONEY")); + pstmt.setString(2, rs.getString("HOST")); + pstmt.setInt(3, rs.getInt("HOSTSEQUENCE")); + pstmt.setTimestamp(4, rs.getTimestamp("DATESTART")); + pstmt.setTimestamp(5, rs.getTimestamp("DATEEND")); + pstmt.setInt(6, rs.getInt("NOSALES")); + + pstmt.executeUpdate(); + } + } else { + while (rs.next()) { + SQL = "INSERT INTO closedcash(" + + "MONEY, HOST, HOSTSEQUENCE, " + + "DATESTART, DATEEND) " + + "VALUES (?, ?, ?, " + + "?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("MONEY")); + pstmt.setString(2, rs.getString("HOST")); + pstmt.setInt(3, rs.getInt("HOSTSEQUENCE")); + pstmt.setTimestamp(4, rs.getTimestamp("DATESTART")); + pstmt.setTimestamp(5, rs.getTimestamp("DATEEND")); + + pstmt.executeUpdate(); + } + } + rs.close(); + + Dbtname = "customers"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Customers" + "\n"); + SQL = "SELECT * FROM customers"; + rs = stmt_source.executeQuery(SQL); + + if (rs.getMetaData().getColumnCount() == 27) { + while (rs.next()) { + SQL = "INSERT INTO customers(" + + "ID, SEARCHKEY, TAXID, NAME, TAXCATEGORY, " + + "CARD, MAXDEBT,ADDRESS, ADDRESS2, POSTAL, " + + "CITY, REGION, COUNTRY, FIRSTNAME, LASTNAME," + + "EMAIL, PHONE, PHONE2, FAX, NOTES, " + + "VISIBLE, CURDATE, CURDEBT, IMAGE, ISVIP, " + + "DISCOUNT, MEMODATE)" + + " VALUES (" + + "?, ?, ?, ?, ?, " + + "?, ?, ?, ?, ?, " + + "?, ?, ?, ?, ?, " + + "?, ?, ?, ?, ?, " + + "?, ?, ?, ?, ?, " + + "?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("SEARCHKEY")); + pstmt.setString(3, rs.getString("TAXID")); + pstmt.setString(4, rs.getString("NAME")); + pstmt.setString(5, rs.getString("TAXCATEGORY")); + pstmt.setString(6, rs.getString("CARD")); + pstmt.setDouble(7, rs.getDouble("MAXDEBT")); + pstmt.setString(8, rs.getString("ADDRESS")); + pstmt.setString(9, rs.getString("ADDRESS2")); + pstmt.setString(10, rs.getString("POSTAL")); + pstmt.setString(11, rs.getString("CITY")); + pstmt.setString(12, rs.getString("REGION")); + pstmt.setString(13, rs.getString("COUNTRY")); + pstmt.setString(14, rs.getString("FIRSTNAME")); + pstmt.setString(15, rs.getString("LASTNAME")); + pstmt.setString(16, rs.getString("EMAIL")); + pstmt.setString(17, rs.getString("PHONE")); + pstmt.setString(18, rs.getString("PHONE2")); + pstmt.setString(19, rs.getString("FAX")); + pstmt.setString(20, rs.getString("NOTES")); + pstmt.setBoolean(21, rs.getBoolean("VISIBLE")); + pstmt.setTimestamp(22, rs.getTimestamp("CURDATE")); + pstmt.setDouble(23, rs.getDouble("CURDEBT")); + pstmt.setBytes(24, rs.getBytes("IMAGE")); + pstmt.setBoolean(25, rs.getBoolean("ISVIP")); + pstmt.setDouble(26, rs.getDouble("DISCOUNT")); + pstmt.setTimestamp(27, rs.getTimestamp("MEMODATE")); + + pstmt.executeUpdate(); + } + } else { + while (rs.next()) { + SQL = "INSERT INTO customers(" + + "ID, SEARCHKEY, TAXID, NAME, " + + "TAXCATEGORY, CARD, MAXDEBT," + + "ADDRESS, ADDRESS2, POSTAL, CITY, " + + "REGION, COUNTRY, FIRSTNAME, LASTNAME, " + + "EMAIL, PHONE, PHONE2, FAX, " + + "NOTES, VISIBLE, CURDATE, CURDEBT)" + + " VALUES (" + + "?, ?, ?, ?, " + + "?, ?, ?, " + + "?, ?, ?, ?, " + + "?, ?, ?, ?, " + + "?, ?, ?, ?, " + + "?, ?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("SEARCHKEY")); + pstmt.setString(3, rs.getString("TAXID")); + pstmt.setString(4, rs.getString("NAME")); + pstmt.setString(5, rs.getString("TAXCATEGORY")); + pstmt.setString(6, rs.getString("CARD")); + pstmt.setDouble(7, rs.getDouble("MAXDEBT")); + pstmt.setString(8, rs.getString("ADDRESS")); + pstmt.setString(9, rs.getString("ADDRESS2")); + pstmt.setString(10, rs.getString("POSTAL")); + pstmt.setString(11, rs.getString("CITY")); + pstmt.setString(12, rs.getString("REGION")); + pstmt.setString(13, rs.getString("COUNTRY")); + pstmt.setString(14, rs.getString("FIRSTNAME")); + pstmt.setString(15, rs.getString("LASTNAME")); + pstmt.setString(16, rs.getString("EMAIL")); + pstmt.setString(17, rs.getString("PHONE")); + pstmt.setString(18, rs.getString("PHONE2")); + pstmt.setString(19, rs.getString("FAX")); + pstmt.setString(20, rs.getString("NOTES")); + pstmt.setBoolean(21, rs.getBoolean("VISIBLE")); + pstmt.setTimestamp(22, rs.getTimestamp("CURDATE")); + pstmt.setDouble(23, rs.getDouble("CURDEBT")); + + pstmt.executeUpdate(); + } + } + rs.close(); + +// introduced 3.50 + if (Dbtversion >= 3.50) { + Dbtname = "draweropened"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("DrawerOpened" + "\n"); + SQL = "SELECT * FROM draweropened"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO draweropened(" + + "OPENDATE, NAME, TICKETID) " + + "VALUES (?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("OPENDATE")); + pstmt.setString(2, rs.getString("NAME")); + pstmt.setString(3, rs.getString("TICKETID")); + + pstmt.executeUpdate(); + } + } + + Dbtname = "floors"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Floors" + "\n"); + SQL = "SELECT * FROM floors"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO floors (" + + "ID, NAME, IMAGE) " + + "VALUES (?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("NAME")); + pstmt.setBytes(3, rs.getBytes("IMAGE")); + + pstmt.executeUpdate(); + } + rs.close(); + +// introduced in 3.00 + if (Dbtversion >= 3.00) { + Dbtname = "leaves"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Leaves" + "\n"); + SQL = "SELECT * FROM leaves"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO leaves (" + + "ID, PPLID, NAME, STARTDATE, " + + "ENDDATE, NOTES) " + + "VALUES (?, ?, ?, ?, " + + "?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("PPLID")); + pstmt.setString(3, rs.getString("NAME")); + pstmt.setTimestamp(4, rs.getTimestamp("STARTDATE")); + pstmt.setTimestamp(5, rs.getTimestamp("ENDDATE")); + pstmt.setString(6, rs.getString("NOTES")); + + pstmt.executeUpdate(); + } + } else { + txtOut.append("Leaves... skipped" + "\n"); + } + rs.close(); + +// introduced in 3.70 + if (Dbtversion >= 3.70) { + Dbtname = "lineremoved"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("LineRemoved" + "\n"); + SQL = "SELECT * FROM lineremoved"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO lineremoved (" + + "REMOVEDDATE, NAME, TICKETID, " + + "PRODUCTID, PRODUCTNAME, UNITS) " + + "VALUES (?, ?, ?, " + + "?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setTimestamp(1, rs.getTimestamp("REMOVEDDATE")); + pstmt.setString(2, rs.getString("NAME")); + pstmt.setString(3, rs.getString("TICKETID")); + pstmt.setString(4, rs.getString("PRODUCTID")); + pstmt.setString(5, rs.getString("PRODUCTNAME")); + pstmt.setDouble(6, rs.getDouble("UNITS")); + + pstmt.executeUpdate(); + } + } else { + txtOut.append("Line Removed... skipped" + "\n"); + } + rs.close(); + + Dbtname = "locations"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Locations" + "\n"); + SQL = "SELECT * FROM locations"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO locations(" + + "ID, NAME, ADDRESS) " + + "VALUES (?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("NAME")); + pstmt.setString(3, rs.getString("ADDRESS")); + + pstmt.executeUpdate(); + } + rs.close(); + +// moorers introduced in 3.50 + if (Dbtversion >= 3.50) { + Dbtname = "moorers"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Moorers" + "\n"); + SQL = "SELECT * FROM moorers"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO moorers(" + + "VESSELNAME, SIZE, DAYS, POWER) " + + "VALUES (?, ?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("VESSELNAME")); + pstmt.setInt(2, rs.getInt("SIZE")); + pstmt.setInt(3, rs.getInt("DAYS")); + pstmt.setBoolean(4, rs.getBoolean("POWER")); + + pstmt.executeUpdate(); + } + } else { + txtOut.append("Moorers... skipped" + "\n"); + } + rs.close(); + + Dbtname = "payments"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Payments" + "\n"); + SQL = "SELECT * FROM payments"; + rs = stmt_source.executeQuery(SQL); + + if (Dbtversion >= 3.02) { + while (rs.next()) { + SQL = "INSERT INTO payments(" + + "ID, RECEIPT, PAYMENT, TOTAL, " + + "TRANSID, RETURNMSG, NOTES, TENDERED) " + + "VALUES (?, ?, ?, ?, " + + "?, ?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("RECEIPT")); + pstmt.setString(3, rs.getString("PAYMENT")); + pstmt.setDouble(4, rs.getDouble("TOTAL")); + pstmt.setString(5, rs.getString("TRANSID")); + pstmt.setBytes(6, rs.getBytes("RETURNMSG")); + pstmt.setString(7, rs.getString("NOTES")); + pstmt.setDouble(8, rs.getDouble("TENDERED")); + + pstmt.executeUpdate(); + } + } else { + while (rs.next()) { + SQL = "INSERT INTO payments(" + + "ID, RECEIPT, PAYMENT, TOTAL, " + + "TRANSID, RETURNMSG) " + + "VALUES (?, ?, ?, ?, " + + "?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("RECEIPT")); + pstmt.setString(3, rs.getString("PAYMENT")); + pstmt.setDouble(4, rs.getDouble("TOTAL")); + pstmt.setString(5, rs.getString("TRANSID")); + pstmt.setBytes(6, rs.getBytes("RETURNMSG")); + + pstmt.executeUpdate(); + } + } + SQL = "UPDATE payments SET payment='ccard' WHERE payment='magcard'"; + pstmt.execute(SQL); + SQL = "UPDATE payments SET payment='ccardrefund' WHERE payment='magcardrefund'"; + pstmt.execute(SQL); + SQL = "UPDATE payments SET tendered = ROUND(total,2) WHERE tendered is null"; + pstmt.execute(SQL); + + rs.close(); + + Dbtname = "people"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("People" + "\n"); + SQL = "SELECT * FROM people"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO people(" + + "ID, NAME, APPPASSWORD, CARD, " + + "ROLE, VISIBLE, IMAGE) " + + "VALUES (?, ?, ?, ?, " + + "?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("NAME")); + pstmt.setString(3, rs.getString("APPPASSWORD")); + pstmt.setString(4, rs.getString("CARD")); + pstmt.setString(5, rs.getString("ROLE")); + pstmt.setBoolean(6, rs.getBoolean("VISIBLE")); + pstmt.setBytes(7, rs.getBytes("IMAGE")); + + pstmt.executeUpdate(); + } + rs.close(); + +// pickup_number introduced in 3.50 + if (Dbtversion >= 3.50 && !jtxtDbType.getText().equals("jdbc:postgresql://")) { + Dbtname = "pickup_number"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Pickup Number" + "\n"); + SQL = "SELECT * FROM pickup_number"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO pickup_number(ID) " + + "VALUES (?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + + pstmt.executeUpdate(); + } + } else { + txtOut.append("Pickup Number... skipped" + "\n"); + } +// deliberately verbose chunk so can see diff's between PostgreSQL v9 & v10 sequence + if (Dbtversion >= 3.50 && jtxtDbType.getText().equals("jdbc:postgresql://")) { + Dbtname = "pickup_number"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + txtOut.append("Pickup Number" + "\n"); + SQL = "SELECT * FROM pickup_number"; + rs = stmt_source.executeQuery(SQL); + + String pickupNumber = null; + + while (rs.next()) { + pickupNumber = rs.getString("last_value"); + } + + if (pickupNumber != null) { + SQL = "UPDATE pickup_number SET ID=" + pickupNumber; + } else { + SQL = "UPDATE pickup_number SET ID='1'"; + } + stmt_target.executeUpdate(SQL); + } else { + txtOut.append("Pickup Number... skipped" + "\n"); + } + rs.close(); + + Dbtname = "places"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Places" + "\n"); + SQL = "SELECT * FROM places"; + rs = stmt_source.executeQuery(SQL); + + if (rs.getMetaData().getColumnCount() == 9) { + while (rs.next()) { + SQL = "INSERT INTO places (" + + "ID, NAME, X, Y, FLOOR, " + + "CUSTOMER, WAITER, TICKETID, TABLEMOVED," + + "WIDTH, HEIGHT, GUESTS, OCCUPIED) " + + "VALUES (?, ?, ?, ?, ?, " + + "?, ?, ?, ?, " + + "?, ?, ?, ? )"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("NAME")); + pstmt.setInt(3, rs.getInt("X")); + pstmt.setInt(4, rs.getInt("Y")); + pstmt.setString(5, rs.getString("FLOOR")); + pstmt.setString(6, rs.getString("CUSTOMER")); + pstmt.setString(7, rs.getString("WAITER")); + pstmt.setString(8, rs.getString("TICKETID")); + pstmt.setBoolean(9, rs.getBoolean("TABLEMOVED")); + + pstmt.setInt(10, 90); // Width + pstmt.setInt(11, 45); // Height + pstmt.setInt(12, 1); // Guests + pstmt.setTimestamp(13, null); // Occupied + + pstmt.executeUpdate(); + } + } else { + while (rs.next()) { + SQL = "INSERT INTO places (" + + "ID, NAME, X, Y, FLOOR) " + + "VALUES (?, ?, ?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("NAME")); + pstmt.setInt(3, rs.getInt("X")); + pstmt.setInt(4, rs.getInt("Y")); + pstmt.setString(5, rs.getString("FLOOR")); + + pstmt.executeUpdate(); + } + } + rs.close(); + + Dbtname = "products"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Products" + "\n"); + SQL = "SELECT * FROM products"; + rs = stmt_source.executeQuery(SQL); + + switch (rs.getMetaData().getColumnCount()) { + case 30: + while (rs.next()) { + SQL = "INSERT INTO products(" + + "ID, REFERENCE, CODE, CODETYPE, NAME, " + + "PRICEBUY, PRICESELL, CATEGORY, TAXCAT, ATTRIBUTESET_ID, " + + "STOCKCOST, STOCKVOLUME, IMAGE, ISCOM, ISSCALE, " + + "ISCONSTANT, PRINTKB, SENDSTATUS, ISSERVICE, ATTRIBUTES, " + + "DISPLAY, ISVPRICE, ISVERPATRIB, TEXTTIP, WARRANTY, " + + "STOCKUNITS, PRINTTO, SUPPLIER, UOM, MEMODATE) " + + "VALUES (?, ?, ?, ?, ?, " + + "?, ?, ?, ?, ?," + + "?, ?, ?, ?, ?," + + "?, ?, ?, ?, ?, " + + "?, ?, ?, ?, ?, " + + "?, ?, ?, ? ,?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("REFERENCE")); + pstmt.setString(3, rs.getString("CODE")); + pstmt.setString(4, rs.getString("CODETYPE")); + pstmt.setString(5, rs.getString("NAME")); + pstmt.setDouble(6, rs.getDouble("PRICEBUY")); + pstmt.setDouble(7, rs.getDouble("PRICESELL")); + pstmt.setString(8, rs.getString("CATEGORY")); + pstmt.setString(9, rs.getString("TAXCAT")); + pstmt.setString(10, rs.getString("ATTRIBUTESET_ID")); + pstmt.setDouble(11, rs.getDouble("STOCKCOST")); + pstmt.setDouble(12, rs.getDouble("STOCKVOLUME")); + pstmt.setBytes(13, rs.getBytes("IMAGE")); + pstmt.setBoolean(14, rs.getBoolean("ISCOM")); + pstmt.setBoolean(15, rs.getBoolean("ISSCALE")); + pstmt.setBoolean(16, rs.getBoolean("ISCONSTANT")); + pstmt.setBoolean(17, rs.getBoolean("PRINTKB")); + pstmt.setBoolean(18, rs.getBoolean("SENDSTATUS")); + pstmt.setBoolean(19, rs.getBoolean("ISSERVICE")); + pstmt.setBytes(20, rs.getBytes("ATTRIBUTES")); + pstmt.setString(21, rs.getString("DISPLAY")); + pstmt.setBoolean(22, rs.getBoolean("ISVPRICE")); + pstmt.setBoolean(23, rs.getBoolean("ISVERPATRIB")); + pstmt.setString(24, rs.getString("TEXTTIP")); + pstmt.setBoolean(25, rs.getBoolean("WARRANTY")); + pstmt.setDouble(26, rs.getDouble("STOCKUNITS")); + pstmt.setString(27, rs.getString("PRINTTO")); + pstmt.setString(28, rs.getString("SUPPLIER")); + pstmt.setString(29, rs.getString("UOM")); + pstmt.setTimestamp(30, rs.getTimestamp("MEMODATE")); + + pstmt.executeUpdate(); + } + break; + case 29: + while (rs.next()) { + SQL = "INSERT INTO products(" + + "ID, REFERENCE, CODE, CODETYPE, NAME, " + + "PRICEBUY, PRICESELL, CATEGORY, TAXCAT, ATTRIBUTESET_ID, " + + "STOCKCOST, STOCKVOLUME, IMAGE, ISCOM, ISSCALE, " + + "ISCONSTANT, PRINTKB, SENDSTATUS, ISSERVICE, ATTRIBUTES, " + + "DISPLAY, ISVPRICE, ISVERPATRIB, TEXTTIP, WARRANTY, " + + "STOCKUNITS, PRINTTO, SUPPLIER, UOM) " + + "VALUES (?, ?, ?, ?, ?, " + + "?, ?, ?, ?, ?," + + "?, ?, ?, ?, ?," + + "?, ?, ?, ?, ?, " + + "?, ?, ?, ?, ?, " + + "?, ?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("REFERENCE")); + pstmt.setString(3, rs.getString("CODE")); + pstmt.setString(4, rs.getString("CODETYPE")); + pstmt.setString(5, rs.getString("NAME")); + pstmt.setDouble(6, rs.getDouble("PRICEBUY")); + pstmt.setDouble(7, rs.getDouble("PRICESELL")); + pstmt.setString(8, rs.getString("CATEGORY")); + pstmt.setString(9, rs.getString("TAXCAT")); + pstmt.setString(10, rs.getString("ATTRIBUTESET_ID")); + pstmt.setDouble(11, rs.getDouble("STOCKCOST")); + pstmt.setDouble(12, rs.getDouble("STOCKVOLUME")); + pstmt.setBytes(13, rs.getBytes("IMAGE")); + pstmt.setBoolean(14, rs.getBoolean("ISCOM")); + pstmt.setBoolean(15, rs.getBoolean("ISSCALE")); + pstmt.setBoolean(16, rs.getBoolean("ISCONSTANT")); + pstmt.setBoolean(17, rs.getBoolean("PRINTKB")); + pstmt.setBoolean(18, rs.getBoolean("SENDSTATUS")); + pstmt.setBoolean(19, rs.getBoolean("ISSERVICE")); + pstmt.setBytes(20, rs.getBytes("ATTRIBUTES")); + pstmt.setString(21, rs.getString("DISPLAY")); + pstmt.setBoolean(22, rs.getBoolean("ISVPRICE")); + pstmt.setBoolean(23, rs.getBoolean("ISVERPATRIB")); + pstmt.setString(24, rs.getString("TEXTTIP")); + pstmt.setBoolean(25, rs.getBoolean("WARRANTY")); + pstmt.setDouble(26, rs.getDouble("STOCKUNITS")); + pstmt.setString(27, rs.getString("PRINTTO")); + pstmt.setString(28, rs.getString("SUPPLIER")); + pstmt.setString(29, rs.getString("UOM")); + + pstmt.executeUpdate(); + } + break; + default: + while (rs.next()) { + SQL = "INSERT INTO products(" + + "ID, REFERENCE, CODE, CODETYPE, NAME, " + + "PRICEBUY, PRICESELL, CATEGORY, TAXCAT, " + + "ATTRIBUTESET_ID, STOCKCOST, STOCKVOLUME, IMAGE, " + + "ISCOM, ISSCALE, ATTRIBUTES, DISPLAY) " + + "VALUES (?, ?, ?, ?, ?, " + + "?, ?, ?, ?, " + + "?, ?, ?, ?, " + + "?, ?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("REFERENCE")); + pstmt.setString(3, rs.getString("CODE")); + pstmt.setString(4, rs.getString("CODETYPE")); + pstmt.setString(5, rs.getString("NAME")); + pstmt.setDouble(6, rs.getDouble("PRICEBUY")); + pstmt.setDouble(7, rs.getDouble("PRICESELL")); + pstmt.setString(8, rs.getString("CATEGORY")); + pstmt.setString(9, rs.getString("TAXCAT")); + pstmt.setString(10, rs.getString("ATTRIBUTESET_ID")); + pstmt.setDouble(11, rs.getDouble("STOCKCOST")); + pstmt.setDouble(12, rs.getDouble("STOCKVOLUME")); + pstmt.setBytes(13, rs.getBytes("IMAGE")); + pstmt.setBoolean(14, rs.getBoolean("ISCOM")); + pstmt.setBoolean(15, rs.getBoolean("ISSCALE")); + pstmt.setBytes(16, rs.getBytes("ATTRIBUTES")); + pstmt.setString(17, "<html><center>" + rs.getString("NAME")); + + pstmt.executeUpdate(); + } + break; + } + SQL = "UPDATE products set supplier = '0' WHERE supplier is null"; + pstmt.execute(SQL); + rs.close(); + + Dbtname = "products_cat"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Products_Cat" + "\n"); + SQL = "SELECT * FROM products_cat"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO products_cat(" + + "PRODUCT, CATORDER) " + + "VALUES (?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("PRODUCT")); + pstmt.setInt(2, rs.getInt("CATORDER")); + + pstmt.executeUpdate(); + } + rs.close(); + + Dbtname = "products_com"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Products_Com" + "\n"); + SQL = "SELECT * FROM products_com"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO products_com(" + + "ID, PRODUCT, PRODUCT2) " + + "VALUES (?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("PRODUCT")); + pstmt.setString(3, rs.getString("PRODUCT2")); + + pstmt.executeUpdate(); + } + rs.close(); + + Dbtname = "receipts"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Receipts" + "\n"); + SQL = "SELECT * FROM receipts"; + rs = stmt_source.executeQuery(SQL); + + if (rs.getMetaData().getColumnCount() == 5) { + while (rs.next()) { + SQL = "INSERT INTO receipts(" + + "ID, MONEY, DATENEW, " + + "ATTRIBUTES, PERSON) " + + "VALUES (?, ?, ?, " + + "?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("MONEY")); + pstmt.setTimestamp(3, rs.getTimestamp("DATENEW")); + pstmt.setBytes(4, rs.getBytes("ATTRIBUTES")); + pstmt.setString(5, rs.getString("PERSON")); + + pstmt.executeUpdate(); + } + } else { + while (rs.next()) { + SQL = "INSERT INTO receipts(" + + "ID, MONEY, DATENEW, ATTRIBUTES) " + + "VALUES (?, ?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("MONEY")); + pstmt.setTimestamp(3, rs.getTimestamp("DATENEW")); + pstmt.setBytes(4, rs.getBytes("ATTRIBUTES")); + + pstmt.executeUpdate(); + } + } + rs.close(); + + Dbtname = "reservation_customers"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Reservation_Customers" + "\n"); + SQL = "SELECT * FROM reservation_customers"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO reservation_customers(" + + "ID, CUSTOMER) " + + "VALUES (?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("CUSTOMER")); + + pstmt.executeUpdate(); + } + rs.close(); + + Dbtname = "reservations"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + txtOut.append("Reservations" + "\n"); + SQL = "SELECT * FROM reservations"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO reservations(" + + "ID, CREATED, DATENEW, TITLE, " + + "CHAIRS, ISDONE, DESCRIPTION) " + + "VALUES (?, ?, ?, ?, " + + "?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setTimestamp(2, rs.getTimestamp("CREATED")); + pstmt.setTimestamp(3, rs.getTimestamp("DATENEW")); + pstmt.setString(4, rs.getString("TITLE")); + pstmt.setInt(5, rs.getInt("CHAIRS")); + pstmt.setBoolean(6, rs.getBoolean("ISDONE")); + pstmt.setString(7, rs.getString("DESCRIPTION")); + + pstmt.executeUpdate(); + } + rs.close(); + + Dbtname = "roles"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Roles" + "\n"); + SQL = "SELECT * FROM roles WHERE NOT ID='0' "; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO roles(" + + "ID, NAME, PERMISSIONS) " + + "VALUES (?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("NAME")); + pstmt.setBytes(3, rs.getBytes("PERMISSIONS")); + + pstmt.executeUpdate(); + } + rs.close(); + +// introduced in 3.00 + if (Dbtversion >= 3.00) { + Dbtname = "shift_breaks"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Shift_breaks" + "\n"); + SQL = "SELECT * FROM shift_breaks"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO shift_breaks(" + + "ID, SHIFTID, BREAKID, " + + "STARTTIME, ENDTIME) " + + "VALUES (?, ?, ?, " + + "?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("SHIFTID")); + pstmt.setString(3, rs.getString("BREAKID")); + pstmt.setTimestamp(4, rs.getTimestamp("STARTTIME")); + pstmt.setTimestamp(5, rs.getTimestamp("ENDTIME")); + + pstmt.executeUpdate(); + } + } else { + txtOut.append("Shift Breaks... skipped" + "\n"); + } + rs.close(); + +// introduced in 3.00 + if (Dbtversion >= 3.00) { + Dbtname = "shifts"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Shifts" + "\n"); + SQL = "SELECT * FROM shifts"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO shifts(" + + "ID, STARTSHIFT, ENDSHIFT, PPLID) " + + "VALUES (?, ?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setTimestamp(2, rs.getTimestamp("STARTSHIFT")); + pstmt.setTimestamp(3, rs.getTimestamp("ENDSHIFT")); + pstmt.setString(4, rs.getString("PPLID")); + + pstmt.executeUpdate(); + } + } else { + txtOut.append("Shifts... skipped" + "\n"); + } + rs.close(); + + Dbtname = "stockcurrent"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + txtOut.append("Stockcurrent" + "\n"); + SQL = "SELECT * FROM stockcurrent"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO stockcurrent(" + + "LOCATION, PRODUCT, " + + "ATTRIBUTESETINSTANCE_ID, UNITS) " + + "VALUES (?, ?, " + + "?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("LOCATION")); + pstmt.setString(2, rs.getString("PRODUCT")); + pstmt.setString(3, rs.getString("ATTRIBUTESETINSTANCE_ID")); + pstmt.setDouble(4, rs.getDouble("UNITS")); + + pstmt.executeUpdate(); + } + rs.close(); + + Dbtname = "stockdiary"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + txtOut.append("Stockdiary" + "\n"); + SQL = "SELECT * FROM stockdiary"; + rs = stmt_source.executeQuery(SQL); + if (rs.getMetaData().getColumnCount() == 9) { + while (rs.next()) { + SQL = "INSERT INTO stockdiary(" + + "ID, DATENEW, REASON, LOCATION, " + + "PRODUCT, ATTRIBUTESETINSTANCE_ID, UNITS, " + + "PRICE, APPUSER) " + + "VALUES (?, ?, ?, ?, " + + "?, ?, ?, " + + "?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setTimestamp(2, rs.getTimestamp("DATENEW")); + pstmt.setInt(3, rs.getInt("REASON")); + pstmt.setString(4, rs.getString("LOCATION")); + pstmt.setString(5, rs.getString("PRODUCT")); + pstmt.setString(6, rs.getString("ATTRIBUTESETINSTANCE_ID")); + pstmt.setDouble(7, rs.getDouble("UNITS")); + pstmt.setDouble(8, rs.getDouble("PRICE")); + pstmt.setString(9, rs.getString("APPUSER")); + + pstmt.executeUpdate(); + } + } else { + while (rs.next()) { + SQL = "INSERT INTO stockdiary(" + + "ID, DATENEW, REASON, LOCATION, " + + "PRODUCT, ATTRIBUTESETINSTANCE_ID, UNITS, " + + "PRICE) " + + "VALUES (?, ?, ?, ?, " + + "?, ?, ?, " + + "?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setTimestamp(2, rs.getTimestamp("DATENEW")); + pstmt.setInt(3, rs.getInt("REASON")); + pstmt.setString(4, rs.getString("LOCATION")); + pstmt.setString(5, rs.getString("PRODUCT")); + pstmt.setString(6, rs.getString("ATTRIBUTESETINSTANCE_ID")); + pstmt.setDouble(7, rs.getDouble("UNITS")); + pstmt.setDouble(8, rs.getDouble("PRICE")); + + pstmt.executeUpdate(); + } + } + rs.close(); + + Dbtname = "stocklevel"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + txtOut.append("Stocklevel" + "\n"); + SQL = "SELECT * FROM stocklevel"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO stocklevel(" + + "ID, LOCATION, PRODUCT, " + + "STOCKSECURITY, STOCKMAXIMUM) " + + "VALUES (?, ?, ?, " + + "?, ?)"; + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("LOCATION")); + pstmt.setString(3, rs.getString("PRODUCT")); + pstmt.setDouble(4, rs.getDouble("STOCKSECURITY")); + pstmt.setDouble(5, rs.getDouble("STOCKMAXIMUM")); + pstmt.executeUpdate(); + } + rs.close(); + +// introduced in 4 + if (Dbtversion >= 4.00) { + Dbtname = "suppliers"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Suppliers" + "\n"); + SQL = "SELECT * FROM suppliers"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO suppliers(" + + "ID, SEARCHKEY, TAXID, NAME, MAXDEBT," + + "ADDRESS, ADDRESS2, POSTAL, CITY, " + + "REGION, COUNTRY, FIRSTNAME, LASTNAME, " + + "EMAIL, PHONE, PHONE2, FAX, " + + "NOTES, VISIBLE, CURDATE, CURDEBT, VATID)" + + " VALUES (" + + "?, ?, ?, ?, ?," + + "?, ?, ?, ?," + + "?, ?, ?, ?, " + + "?, ?, ?, ?, " + + "?, ?, ?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("SEARCHKEY")); + pstmt.setString(3, rs.getString("TAXID")); + pstmt.setString(4, rs.getString("NAME")); + pstmt.setDouble(5, rs.getDouble("MAXDEBT")); + pstmt.setString(6, rs.getString("ADDRESS")); + pstmt.setString(7, rs.getString("ADDRESS2")); + pstmt.setString(8, rs.getString("POSTAL")); + pstmt.setString(9, rs.getString("CITY")); + pstmt.setString(10, rs.getString("REGION")); + pstmt.setString(11, rs.getString("COUNTRY")); + pstmt.setString(12, rs.getString("FIRSTNAME")); + pstmt.setString(13, rs.getString("LASTNAME")); + pstmt.setString(14, rs.getString("EMAIL")); + pstmt.setString(15, rs.getString("PHONE")); + pstmt.setString(16, rs.getString("PHONE2")); + pstmt.setString(17, rs.getString("FAX")); + pstmt.setString(18, rs.getString("NOTES")); + pstmt.setBoolean(19, rs.getBoolean("VISIBLE")); + pstmt.setTimestamp(20, rs.getTimestamp("CURDATE")); + pstmt.setDouble(21, rs.getDouble("CURDEBT")); + pstmt.setString(22, rs.getString("VATID")); + + pstmt.executeUpdate(); + } + } else { + SQL = "INSERT INTO suppliers(" + + "ID, NAME, SEARCHKEY)" + + " VALUES ('0', 'uniCenta', 'unicenta')"; + pstmt.executeUpdate(SQL); + txtOut.append("Added Supplier... uniCenta" + "\n"); + } + rs.close(); + + Dbtname = "taxcategories"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + txtOut.append("TaxCategories" + "\n"); + SQL = "SELECT * FROM taxcategories"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO taxcategories(" + + "ID, NAME) " + + "VALUES (?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("NAME")); + + pstmt.executeUpdate(); + } + rs.close(); + + Dbtname = "taxcustcategories"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + txtOut.append("Tax Customer Categories" + "\n"); + SQL = "SELECT * FROM taxcustcategories"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO taxcustcategories(" + + "ID, NAME) " + + "VALUES (?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("NAME")); + + pstmt.executeUpdate(); + } + rs.close(); + + Dbtname = "taxes"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + txtOut.append("Taxes" + "\n"); + SQL = "SELECT * FROM taxes"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO taxes(" + + "ID, NAME, CATEGORY, CUSTCATEGORY, " + + "PARENTID, RATE, RATECASCADE, RATEORDER) " + + "VALUES (?, ?, ?, ?, " + + "?, ?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("NAME")); + pstmt.setString(3, rs.getString("CATEGORY")); + pstmt.setString(4, rs.getString("CUSTCATEGORY")); + pstmt.setString(5, rs.getString("PARENTID")); + pstmt.setDouble(6, rs.getDouble("RATE")); + pstmt.setBoolean(7, rs.getBoolean("RATECASCADE")); + pstmt.setInt(8, rs.getInt("RATEORDER")); + + pstmt.executeUpdate(); + } + rs.close(); + + Dbtname = "taxlines"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + txtOut.append("TaxLines" + "\n"); + SQL = "SELECT * FROM taxlines"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO taxlines(" + + "ID, RECEIPT, TAXID, BASE, AMOUNT) " + + "VALUES (?, ?, ?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("RECEIPT")); + pstmt.setString(3, rs.getString("TAXID")); + pstmt.setDouble(4, rs.getDouble("BASE")); + pstmt.setDouble(5, rs.getDouble("AMOUNT")); + + pstmt.executeUpdate(); + } + rs.close(); + + Dbtname = "thirdparties"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + txtOut.append("ThirdParties" + "\n"); + SQL = "SELECT * FROM thirdparties"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO thirdparties(" + + "ID, CIF, NAME, ADDRESS, " + + "CONTACTCOMM, CONTACTFACT, PAYRULE, FAXNUMBER, " + + "PHONENUMBER, MOBILENUMBER, EMAIL, " + + "WEBPAGE, NOTES) " + + "VALUES (?, ?, ?, ?, " + + "?, ?, ?, ?, " + + "?, ?, ?, " + + "?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setString(2, rs.getString("CIF")); + pstmt.setString(3, rs.getString("NAME")); + pstmt.setString(4, rs.getString("ADDRESS")); + pstmt.setString(5, rs.getString("CONTACTCOMM")); + pstmt.setString(6, rs.getString("CONTACTFACT")); + pstmt.setString(7, rs.getString("PAYRULE")); + pstmt.setString(8, rs.getString("FAXNUMBER")); + pstmt.setString(9, rs.getString("PHONENUMBER")); + pstmt.setString(10, rs.getString("MOBILENUMBER")); + pstmt.setString(11, rs.getString("EMAIL")); + pstmt.setString(12, rs.getString("WEBPAGE")); + pstmt.setString(13, rs.getString("NOTES")); + + pstmt.executeUpdate(); + } + rs.close(); + + Dbtname = "ticketlines"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + txtOut.append("TicketLines" + "\n"); + SQL = "SELECT * FROM ticketlines"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO ticketlines(" + + "TICKET, LINE, PRODUCT, ATTRIBUTESETINSTANCE_ID, " + + "UNITS, PRICE, TAXID, ATTRIBUTES) " + + "VALUES (?, ?, ?, ?, " + + "?, ?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("TICKET")); + pstmt.setInt(2, rs.getInt("LINE")); + pstmt.setString(3, rs.getString("PRODUCT")); + pstmt.setString(4, rs.getString("ATTRIBUTESETINSTANCE_ID")); + pstmt.setDouble(5, rs.getDouble("UNITS")); + pstmt.setDouble(6, rs.getDouble("PRICE")); + pstmt.setString(7, rs.getString("TAXID")); + pstmt.setBytes(8, rs.getBytes("ATTRIBUTES")); + + pstmt.executeUpdate(); + } + rs.close(); + + Dbtname = "tickets"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + txtOut.append("Tickets" + "\n"); + SQL = "SELECT * FROM tickets"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO tickets(" + + "ID, TICKETTYPE, TICKETID, " + + "PERSON, CUSTOMER, STATUS) " + + "VALUES (?, ?, ?, " + + "?, ?, ?)"; + + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("ID")); + pstmt.setInt(2, rs.getInt("TICKETTYPE")); + pstmt.setInt(3, rs.getInt("TICKETID")); + pstmt.setString(4, rs.getString("PERSON")); + pstmt.setString(5, rs.getString("CUSTOMER")); + pstmt.setInt(6, rs.getInt("STATUS")); + + pstmt.executeUpdate(); + } + rs.close(); + + if (Dbtversion >= 3.50 && !jtxtDbType.getText().equals("jdbc:postgresql://")) { + Dbtname = "ticketsnum"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + txtOut.append("Tickets Number" + "\n"); + SQL = "SELECT * FROM ticketsnum"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + ticketsnum = rs.getString("ID"); + } + if (ticketsnum != null) { + SQL = "UPDATE ticketsnum SET ID= " + ticketsnum; + } else { + SQL = "UPDATE ticketsnum SET ID='1'"; + } + stmt_target.executeUpdate(SQL); + } else { + txtOut.append("Ticket Number... skipped" + "\n"); + } +// deliberately verbose chunk so can see diff's between PostgreSQL v9 & v10 + if (Dbtversion >= 3.50 && jtxtDbType.getText().equals("jdbc:postgresql://")) { + Dbtname = "ticketsnum"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + txtOut.append("Tickets Number" + "\n"); + SQL = "SELECT * FROM ticketsnum"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + ticketsnum = rs.getString("last_value"); + } + if (ticketsnum != null) { + SQL = "UPDATE ticketsnum SET ID= " + ticketsnum; + } else { + SQL = "UPDATE ticketsnum SET ID='1'"; + } + stmt_target.executeUpdate(SQL); + } else { + txtOut.append("Ticket Number... skipped" + "\n"); + } + rs.close(); + + if (Dbtversion >= 3.50 && !jtxtDbType.getText().equals("jdbc:postgresql://")) { + Dbtname = "ticketsnum_payment"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + txtOut.append("Tickets Number Payments" + "\n"); + SQL = "SELECT * FROM ticketsnum_payment"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + ticketsnumPayment = rs.getString("ID"); + } + if (ticketsnumPayment != null) { + SQL = "UPDATE ticketsnum_payment SET ID= " + ticketsnumPayment; + } else { + SQL = "UPDATE ticketsnum_payment SET ID='1'"; + } + stmt_target.executeUpdate(SQL); + } else { + txtOut.append("Ticket Payment... skipped" + "\n"); + } +// deliberately verbose chunk so can see diff's between PostgreSQL v9 & v10 sequence + if (Dbtversion >= 3.50 && jtxtDbType.getText().equals("jdbc:postgresql://")) { + Dbtname = "ticketsnum_payment"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + txtOut.append("Tickets Number Payments" + "\n"); + SQL = "SELECT * FROM ticketsnum_payment"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + ticketsnumPayment = rs.getString("last_value"); + } + if (ticketsnumPayment != null) { + SQL = "UPDATE ticketsnum_payment SET ID= " + ticketsnumPayment; + } else { + SQL = "UPDATE ticketsnum_payment SET ID='1'"; + } + stmt_target.executeUpdate(SQL); + } else { + txtOut.append("Ticket Number Payments... skipped" + "\n"); + } + rs.close(); + + if (Dbtversion >= 3.50 && !jtxtDbType.getText().equals("jdbc:postgresql://")) { + Dbtname = "ticketsnum_refund"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + txtOut.append("Tickets Number Refunds" + "\n"); + SQL = "SELECT * FROM ticketsnum_refund"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + ticketsnumRefund = rs.getString("ID"); + } + if (ticketsnumRefund != null) { + SQL = "UPDATE ticketsnum_refund SET ID= " + ticketsnumRefund; + } else { + SQL = "UPDATE ticketsnum_refund SET ID='1'"; + } + stmt_target.executeUpdate(SQL); + } else { + txtOut.append("Ticket Refund... skipped" + "\n"); + } +// deliberately verbose chunk so can see diff's between PostgreSQL v9 & v10 sequence + if (Dbtversion >= 3.50 && jtxtDbType.getText().equals("jdbc:postgresql://")) { + Dbtname = "ticketsnum_payment"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + txtOut.append("Tickets Number Refunds" + "\n"); + SQL = "SELECT * FROM ticketsnum_refund"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + ticketsnumRefund = rs.getString("last_value"); + } + if (ticketsnumRefund != null) { + SQL = "UPDATE ticketsnum_refund SET ID= " + ticketsnumRefund; + } else { + SQL = "UPDATE ticketsnum_refund SET ID='1'"; + } + stmt_target.executeUpdate(SQL); + } else { + txtOut.append("Ticket Refund... skipped" + "\n"); + } + rs.close(); + +// introduced in 4 + if (Dbtversion >= 4.00) { + Dbtname = "uom"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + txtOut.append("UOM" + "\n"); + SQL = "SELECT * FROM uom"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO uom(" + + "id, name) " + + "VALUES (?, ?)"; + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("id")); + pstmt.setString(2, rs.getString("name")); + + pstmt.executeUpdate(); + } + } else { + SQL = "INSERT INTO uom(" + + "ID, NAME)" + + " VALUES ('0', 'Each')"; + + pstmt.executeUpdate(SQL); + txtOut.append("Added UOM... Each" + "\n"); + } + + if (Dbtversion >= 4.00) { + Dbtname = "vouchers"; + rs = con_source.getMetaData().getTables(null, null, Dbtname, null); + + txtOut.append("Vouchers" + "\n"); + SQL = "SELECT * FROM vouchers"; + rs = stmt_source.executeQuery(SQL); + + while (rs.next()) { + SQL = "INSERT INTO vouchers(" + + "id, voucher_number, customer, " + + "amount, status) " + + "VALUES (?, ?, ?, " + + "?, ?)"; + pstmt = con_target.prepareStatement(SQL); + pstmt.setString(1, rs.getString("id")); + pstmt.setString(2, rs.getString("voucher_number")); + pstmt.setString(3, rs.getString("customer")); + pstmt.setDouble(4, rs.getDouble("amount")); + pstmt.setString(5, rs.getString("status")); + + pstmt.executeUpdate(); + } + } else { + txtOut.append("Vouchers... skipped" + "\n"); + } + rs.close(); + + try { + this.con_target.setAutoCommit(true); + } catch (SQLException ex) { + log.error(ex.getMessage()); + } + +// Add ForeignKeys + JOptionPane.showMessageDialog(this + , AppLocal.getIntString("message.transfercomplete") + , AppLocal.getIntString("message.transfermessage") + , JOptionPane.WARNING_MESSAGE); + + FKeys(); + txtOut.append("Data Transfer Complete" + "\n"); + + webPBar.setString("Finished!"); + webPBar.setBgBottom(Color.GREEN); + jbtnTransfer.setEnabled(true); + + JOptionPane.showMessageDialog(this + , AppLocal.getIntString("message.indexcomplete") + , AppLocal.getIntString("message.transfermessage") + , JOptionPane.WARNING_MESSAGE); + + } catch (SQLException | HeadlessException e) { + session_source.close(); + + JMessageDialog.showMessage(this, new MessageInf(MessageInf.SGN_WARNING, SQL, e)); + } + } else { + JFrame frame = new JFrame(); + JOptionPane.showMessageDialog(frame + , AppLocal.getIntString("message.transfernotsupported") + , AppLocal.getIntString("message.transfermessage") + , JOptionPane.WARNING_MESSAGE); + } + + SQL = "COMMIT;\n" + + "SET autocommit=1;\n" + + "SET unique_checks=1;\n" + + "SET foreign_key_checks=1;"; + pstmt.executeUpdate(SQL); + + session_source.close(); + } + } + + public void fillSchema() { + /* Use existing session credentials but declare new session and connection + * to keep separated from current session instance as database could + * be a different server + */ + + if (jCBSchema.getItemCount() >= 1) { + jCBSchema.removeAllItems(); + } + + try { + String driverlib = jtxtDbDriverLib.getText(); + String driver = jtxtDbDriver.getText(); + String url = jtxtDbType.getText() + + jtxtDbServerPort.getText() + + jtxtDbName.getText() + + jtxtDbParams.getText(); + String user = txtDbUser.getText(); + String password = new String(txtDbPass.getPassword()); + + ClassLoader cloader = new URLClassLoader(new URL[]{ + new File(driverlib).toURI().toURL() + }); + + DriverManager.registerDriver( + new DriverWrapper((Driver) + Class.forName(driver, true, cloader).newInstance())); + + Session session1 = new Session(url, user, password); + + if (jtxtDbType.getText().equals("jdbc:postgresql://")) { + Connection connection1 = DriverManager.getConnection(url, user, password); + Statement st = connection1.createStatement(); + ResultSet rs = st.executeQuery("SELECT datname FROM pg_database WHERE datistemplate = false;"); + while (rs.next()) { + jCBSchema.addItem(rs.getString("datname")); + } + } else { + Connection connection1 = session1.getConnection(); + ResultSet rs = connection1.getMetaData().getCatalogs(); + while (rs.next()) { + jCBSchema.addItem(rs.getString("TABLE_CAT")); + } + } + + jCBSchema.setEnabled(true); + jCBSchema.setSelectedIndex(0); + } catch (MalformedURLException | ClassNotFoundException | SQLException + | InstantiationException | IllegalAccessException ex) { + log.error(ex.getMessage()); + } + } + + public void reset() { +// Main Panel + jtxtDbDriver.setText("com.mysql.jdbc.Driver"); + jtxtDbType.setText("jdbc:mysql://"); + jtxtDbServerPort.setText("localhost:3306/"); + txtDbUser.setText(null); + txtDbPass.setText(null); + jbtnConnect.setEnabled(true); + +// TransferPanel + jCBSchema.removeAllItems(); + jtxtDbName.setText(null); + jtxtDbParams.setText("?zeroDateTimeBehavior=convertToNull"); + jlblVersion.setText(null); + jlblDBSize.setText(null); + + jTransferPanel.setVisible(false); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel5 = new javax.swing.JLabel(); + jLabel18 = new javax.swing.JLabel(); + jLabel1 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + jLabel6 = new javax.swing.JLabel(); + cbSource = new com.alee.laf.combobox.WebComboBox(); + jtxtDbDriverLib = new com.alee.laf.text.WebTextField(); + jbtnDbDriverLib = new javax.swing.JButton(); + jtxtDbDriver = new com.alee.laf.text.WebTextField(); + jtxtDbType = new com.alee.laf.text.WebTextField(); + txtDbUser = new com.alee.laf.text.WebTextField(); + txtDbPass = new com.alee.laf.text.WebPasswordField(); + jScrollPane1 = new javax.swing.JScrollPane(); + txtOut = new javax.swing.JTextArea(); + jLabel8 = new javax.swing.JLabel(); + jlblSource = new javax.swing.JLabel(); + jLabel9 = new javax.swing.JLabel(); + jbtnConnect = new javax.swing.JButton(); + webPBar = new com.alee.laf.progressbar.WebProgressBar(); + jtxtDbServerPort = new com.alee.laf.text.WebTextField(); + jLabel12 = new javax.swing.JLabel(); + jTransferPanel = new javax.swing.JPanel(); + jLabel13 = new javax.swing.JLabel(); + jCBSchema = new javax.swing.JComboBox<>(); + jLabel14 = new javax.swing.JLabel(); + jtxtDbParams = new com.alee.laf.text.WebTextField(); + jLabel7 = new javax.swing.JLabel(); + jlblVersion = new javax.swing.JLabel(); + jLabel11 = new javax.swing.JLabel(); + jlblDBSize = new javax.swing.JLabel(); + jtxtDbName = new com.alee.laf.text.WebTextField(); + jbtnTransfer = new javax.swing.JButton(); + webMemoryBar = new com.alee.extended.statusbar.WebMemoryBar(); + jLabel10 = new javax.swing.JLabel(); + jLabel15 = new javax.swing.JLabel(); + jbtnSet = new javax.swing.JButton(); + jbtnReset1 = new javax.swing.JButton(); + jbtnReset = new javax.swing.JButton(); + jLabel16 = new javax.swing.JLabel(); + + setBackground(new java.awt.Color(255, 255, 255)); + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + setPreferredSize(new java.awt.Dimension(900, 425)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setForeground(new java.awt.Color(102, 102, 102)); + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("pos_messages"); // NOI18N + jLabel5.setText(bundle.getString("label.DbType")); // NOI18N + jLabel5.setMaximumSize(new java.awt.Dimension(150, 30)); + jLabel5.setMinimumSize(new java.awt.Dimension(150, 30)); + jLabel5.setPreferredSize(new java.awt.Dimension(160, 30)); + + jLabel18.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel18.setForeground(new java.awt.Color(102, 102, 102)); + jLabel18.setText(AppLocal.getIntString("label.dbdriverlib")); // NOI18N + jLabel18.setMaximumSize(new java.awt.Dimension(150, 30)); + jLabel18.setMinimumSize(new java.awt.Dimension(150, 30)); + jLabel18.setPreferredSize(new java.awt.Dimension(160, 30)); + + jLabel1.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel1.setForeground(new java.awt.Color(102, 102, 102)); + jLabel1.setText(AppLocal.getIntString("label.DbDriver")); // NOI18N + jLabel1.setMaximumSize(new java.awt.Dimension(150, 30)); + jLabel1.setMinimumSize(new java.awt.Dimension(150, 30)); + jLabel1.setPreferredSize(new java.awt.Dimension(160, 30)); + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setForeground(new java.awt.Color(102, 102, 102)); + jLabel2.setText("Type"); + jLabel2.setMaximumSize(new java.awt.Dimension(150, 30)); + jLabel2.setMinimumSize(new java.awt.Dimension(150, 30)); + jLabel2.setPreferredSize(new java.awt.Dimension(160, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setForeground(new java.awt.Color(102, 102, 102)); + jLabel3.setText(AppLocal.getIntString("label.DbUser")); // NOI18N + jLabel3.setMaximumSize(new java.awt.Dimension(150, 30)); + jLabel3.setMinimumSize(new java.awt.Dimension(150, 30)); + jLabel3.setPreferredSize(new java.awt.Dimension(160, 30)); + + jLabel4.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel4.setForeground(new java.awt.Color(102, 102, 102)); + jLabel4.setText(AppLocal.getIntString("label.DbPassword")); // NOI18N + jLabel4.setMaximumSize(new java.awt.Dimension(150, 30)); + jLabel4.setMinimumSize(new java.awt.Dimension(150, 30)); + jLabel4.setPreferredSize(new java.awt.Dimension(100, 30)); + + jLabel6.setFont(new java.awt.Font("Arial", 0, 18)); // NOI18N + jLabel6.setForeground(new java.awt.Color(51, 51, 51)); + jLabel6.setText("Currently connected to :"); + jLabel6.setPreferredSize(new java.awt.Dimension(150, 30)); + + cbSource.setForeground(new java.awt.Color(51, 51, 51)); + cbSource.setToolTipText(bundle.getString("tooltip.transferfromdb")); // NOI18N + cbSource.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + cbSource.setPreferredSize(new java.awt.Dimension(150, 30)); + cbSource.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + cbSourceActionPerformed(evt); + } + }); + + jtxtDbDriverLib.setForeground(new java.awt.Color(51, 51, 51)); + jtxtDbDriverLib.setToolTipText(bundle.getString("tootltip.transferlib")); // NOI18N + jtxtDbDriverLib.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtDbDriverLib.setPreferredSize(new java.awt.Dimension(360, 30)); + + jbtnDbDriverLib.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/fileopen.png"))); // NOI18N + jbtnDbDriverLib.setToolTipText(bundle.getString("tooltip.openfile")); // NOI18N + jbtnDbDriverLib.setMaximumSize(new java.awt.Dimension(64, 32)); + jbtnDbDriverLib.setMinimumSize(new java.awt.Dimension(64, 32)); + jbtnDbDriverLib.setPreferredSize(new java.awt.Dimension(60, 30)); + + jtxtDbDriver.setForeground(new java.awt.Color(51, 51, 51)); + jtxtDbDriver.setToolTipText(bundle.getString("tootltip.transferclass")); // NOI18N + jtxtDbDriver.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtDbDriver.setPreferredSize(new java.awt.Dimension(360, 30)); + + jtxtDbType.setForeground(new java.awt.Color(51, 51, 51)); + jtxtDbType.setToolTipText(bundle.getString("tootltip.transferdbtype")); // NOI18N + jtxtDbType.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtDbType.setPreferredSize(new java.awt.Dimension(150, 30)); + + txtDbUser.setForeground(new java.awt.Color(51, 51, 51)); + txtDbUser.setToolTipText(bundle.getString("tooltip.dbuser")); // NOI18N + txtDbUser.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtDbUser.setPreferredSize(new java.awt.Dimension(125, 30)); + + txtDbPass.setForeground(new java.awt.Color(51, 51, 51)); + txtDbPass.setToolTipText(bundle.getString("tooltip.dbpassword")); // NOI18N + txtDbPass.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + txtDbPass.setPreferredSize(new java.awt.Dimension(125, 30)); + + jScrollPane1.setBorder(null); + jScrollPane1.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + jScrollPane1.setViewportBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(204, 204, 204))); + jScrollPane1.setFont(new java.awt.Font("Arial", 0, 13)); // NOI18N + jScrollPane1.setHorizontalScrollBar(null); + jScrollPane1.setPreferredSize(new java.awt.Dimension(200, 350)); + + txtOut.setColumns(20); + txtOut.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + txtOut.setForeground(new java.awt.Color(0, 153, 255)); + txtOut.setRows(5); + txtOut.setToolTipText(bundle.getString("tooltip.transfertxtout")); // NOI18N + txtOut.setBorder(null); + jScrollPane1.setViewportView(txtOut); + + jLabel8.setFont(new java.awt.Font("Arial", 0, 18)); // NOI18N + jLabel8.setForeground(new java.awt.Color(0, 153, 255)); + jLabel8.setText("PROGRESS"); + jLabel8.setPreferredSize(new java.awt.Dimension(150, 30)); + + jlblSource.setFont(new java.awt.Font("Arial", 0, 18)); // NOI18N + jlblSource.setForeground(new java.awt.Color(0, 153, 255)); + jlblSource.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jlblSource.setPreferredSize(new java.awt.Dimension(150, 30)); + + jLabel9.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel9.setForeground(new java.awt.Color(102, 102, 102)); + jLabel9.setText(AppLocal.getIntString("label.DbUser")); // NOI18N + jLabel9.setMaximumSize(new java.awt.Dimension(150, 30)); + jLabel9.setMinimumSize(new java.awt.Dimension(150, 30)); + jLabel9.setPreferredSize(new java.awt.Dimension(160, 30)); + + jbtnConnect.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnConnect.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn1.png"))); // NOI18N + jbtnConnect.setText(bundle.getString("Button.Test")); // NOI18N + jbtnConnect.setToolTipText(bundle.getString("tooltip.dbtest")); // NOI18N + jbtnConnect.setActionCommand(bundle.getString("Button.Test")); // NOI18N + jbtnConnect.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jbtnConnect.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT); + jbtnConnect.setPreferredSize(new java.awt.Dimension(160, 45)); + jbtnConnect.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnConnectjButtonTestConnectionActionPerformed(evt); + } + }); + + webPBar.setFont(new java.awt.Font("Arial", 0, 13)); // NOI18N + webPBar.setHighlightDarkWhite(new java.awt.Color(204, 0, 0)); + webPBar.setPreferredSize(new java.awt.Dimension(240, 30)); + webPBar.setProgressBottomColor(new java.awt.Color(0, 153, 255)); + + jtxtDbServerPort.setForeground(new java.awt.Color(51, 51, 51)); + jtxtDbServerPort.setToolTipText(bundle.getString("tootltip.servernameport")); // NOI18N + jtxtDbServerPort.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtDbServerPort.setPreferredSize(new java.awt.Dimension(360, 30)); + + jLabel12.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel12.setForeground(new java.awt.Color(102, 102, 102)); + jLabel12.setText(bundle.getString("labelServerPort")); // NOI18N + jLabel12.setMaximumSize(new java.awt.Dimension(150, 30)); + jLabel12.setMinimumSize(new java.awt.Dimension(150, 30)); + jLabel12.setPreferredSize(new java.awt.Dimension(160, 30)); + + jLabel13.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel13.setForeground(new java.awt.Color(102, 102, 102)); + jLabel13.setText(bundle.getString("label.DbSource")); // NOI18N + jLabel13.setMaximumSize(new java.awt.Dimension(150, 30)); + jLabel13.setMinimumSize(new java.awt.Dimension(150, 30)); + jLabel13.setPreferredSize(new java.awt.Dimension(160, 30)); + + jCBSchema.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jCBSchema.setToolTipText(bundle.getString("tootltip.transferdbname")); // NOI18N + jCBSchema.setEnabled(false); + jCBSchema.setPreferredSize(new java.awt.Dimension(360, 30)); + + jLabel14.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel14.setForeground(new java.awt.Color(102, 102, 102)); + jLabel14.setText(bundle.getString("label.DBParameters")); // NOI18N + jLabel14.setMaximumSize(new java.awt.Dimension(150, 30)); + jLabel14.setMinimumSize(new java.awt.Dimension(150, 30)); + jLabel14.setPreferredSize(new java.awt.Dimension(160, 30)); + + jtxtDbParams.setForeground(new java.awt.Color(51, 51, 51)); + jtxtDbParams.setToolTipText(bundle.getString("tootltip.transferdbparams")); // NOI18N + jtxtDbParams.setEnabled(false); + jtxtDbParams.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtDbParams.setPreferredSize(new java.awt.Dimension(360, 30)); + + jLabel7.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel7.setForeground(new java.awt.Color(102, 102, 102)); + jLabel7.setText("DB Version"); + jLabel7.setMaximumSize(new java.awt.Dimension(150, 30)); + jLabel7.setMinimumSize(new java.awt.Dimension(150, 30)); + jLabel7.setPreferredSize(new java.awt.Dimension(160, 30)); + + jlblVersion.setFont(new java.awt.Font("Arial", 0, 16)); // NOI18N + jlblVersion.setForeground(new java.awt.Color(0, 204, 255)); + jlblVersion.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jlblVersion.setToolTipText(bundle.getString("tooltip.transferdbversion")); // NOI18N + jlblVersion.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 204, 255))); + jlblVersion.setEnabled(false); + jlblVersion.setMaximumSize(new java.awt.Dimension(150, 30)); + jlblVersion.setMinimumSize(new java.awt.Dimension(150, 30)); + jlblVersion.setPreferredSize(new java.awt.Dimension(125, 30)); + + jLabel11.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel11.setForeground(new java.awt.Color(102, 102, 102)); + jLabel11.setText("DB Size"); + jLabel11.setMaximumSize(new java.awt.Dimension(150, 30)); + jLabel11.setMinimumSize(new java.awt.Dimension(150, 30)); + jLabel11.setPreferredSize(new java.awt.Dimension(100, 30)); + + jlblDBSize.setFont(new java.awt.Font("Arial", 0, 16)); // NOI18N + jlblDBSize.setForeground(new java.awt.Color(0, 204, 255)); + jlblDBSize.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jlblDBSize.setToolTipText(bundle.getString("tooltip.transferdbsize")); // NOI18N + jlblDBSize.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 204, 255))); + jlblDBSize.setEnabled(false); + jlblDBSize.setMaximumSize(new java.awt.Dimension(150, 30)); + jlblDBSize.setMinimumSize(new java.awt.Dimension(150, 30)); + jlblDBSize.setPreferredSize(new java.awt.Dimension(120, 30)); + + jtxtDbName.setForeground(new java.awt.Color(51, 51, 51)); + jtxtDbName.setToolTipText(bundle.getString("tootltip.transferdbname")); // NOI18N + jtxtDbName.setEnabled(false); + jtxtDbName.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jtxtDbName.setOpaque(true); + jtxtDbName.setPreferredSize(new java.awt.Dimension(0, 0)); + + jbtnTransfer.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnTransfer.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn3.png"))); // NOI18N + jbtnTransfer.setText(AppLocal.getIntString("button.transfer")); // NOI18N + jbtnTransfer.setToolTipText(bundle.getString("tooltip.transferdb")); // NOI18N + jbtnTransfer.setEnabled(false); + jbtnTransfer.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jbtnTransfer.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT); + jbtnTransfer.setMaximumSize(new java.awt.Dimension(70, 33)); + jbtnTransfer.setMinimumSize(new java.awt.Dimension(70, 33)); + jbtnTransfer.setPreferredSize(new java.awt.Dimension(160, 45)); + jbtnTransfer.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnTransferActionPerformed(evt); + } + }); + + webMemoryBar.setBackground(new java.awt.Color(153, 153, 153)); + webMemoryBar.setText("Text"); + webMemoryBar.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + webMemoryBar.setPreferredSize(new java.awt.Dimension(150, 30)); + webMemoryBar.setUsedBorderColor(new java.awt.Color(0, 204, 204)); + webMemoryBar.setUsedFillColor(new java.awt.Color(0, 204, 255)); + + jLabel10.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel10.setForeground(new java.awt.Color(102, 102, 102)); + jLabel10.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLabel10.setText("Memory State"); + jLabel10.setMaximumSize(new java.awt.Dimension(150, 30)); + jLabel10.setMinimumSize(new java.awt.Dimension(150, 30)); + jLabel10.setPreferredSize(new java.awt.Dimension(160, 30)); + + jLabel15.setFont(new java.awt.Font("Arial", 0, 18)); // NOI18N + jLabel15.setForeground(new java.awt.Color(0, 153, 255)); + jLabel15.setText("CHOOSE DATABASE TO TRANSFER FROM"); + jLabel15.setPreferredSize(new java.awt.Dimension(150, 30)); + + jbtnSet.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnSet.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/btn2.png"))); // NOI18N + jbtnSet.setText(AppLocal.getIntString("button.setTransfer")); // NOI18N + jbtnSet.setToolTipText(bundle.getString("tooltip.checkTransfer")); // NOI18N + jbtnSet.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jbtnSet.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT); + jbtnSet.setMaximumSize(new java.awt.Dimension(70, 33)); + jbtnSet.setMinimumSize(new java.awt.Dimension(70, 33)); + jbtnSet.setPreferredSize(new java.awt.Dimension(160, 45)); + jbtnSet.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnSetActionPerformed(evt); + } + }); + + jbtnReset1.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnReset1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reload.png"))); // NOI18N + jbtnReset1.setToolTipText(bundle.getString("tooltip.transferReset")); // NOI18N + jbtnReset1.setMaximumSize(new java.awt.Dimension(70, 33)); + jbtnReset1.setMinimumSize(new java.awt.Dimension(70, 33)); + jbtnReset1.setPreferredSize(new java.awt.Dimension(80, 45)); + jbtnReset1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnReset1ActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jTransferPanelLayout = new javax.swing.GroupLayout(jTransferPanel); + jTransferPanel.setLayout(jTransferPanelLayout); + jTransferPanelLayout.setHorizontalGroup( + jTransferPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jTransferPanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(jTransferPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jTransferPanelLayout.createSequentialGroup() + .addGroup(jTransferPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel7, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtDbName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(7, 7, 7) + .addGroup(jTransferPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addGroup(jTransferPanelLayout.createSequentialGroup() + .addComponent(jlblVersion, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel11, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jlblDBSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jTransferPanelLayout.createSequentialGroup() + .addComponent(jbtnSet, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jbtnTransfer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jbtnReset1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jTransferPanelLayout.createSequentialGroup() + .addGroup(jTransferPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(jTransferPanelLayout.createSequentialGroup() + .addComponent(jLabel13, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jCBSchema, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jLabel15, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jTransferPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(webMemoryBar, javax.swing.GroupLayout.PREFERRED_SIZE, 125, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel10, javax.swing.GroupLayout.PREFERRED_SIZE, 1, Short.MAX_VALUE))) + .addGroup(jTransferPanelLayout.createSequentialGroup() + .addComponent(jLabel14, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jtxtDbParams, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) + ); + jTransferPanelLayout.setVerticalGroup( + jTransferPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jTransferPanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(jTransferPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel15, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jTransferPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jCBSchema, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(webMemoryBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jTransferPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jtxtDbParams, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel14, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jTransferPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jlblVersion, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel11, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel7, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jlblDBSize, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jTransferPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jTransferPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jbtnTransfer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jbtnSet, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtDbName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jbtnReset1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + + jbtnReset.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jbtnReset.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reload.png"))); // NOI18N + jbtnReset.setToolTipText(bundle.getString("tooltip.transferReset")); // NOI18N + jbtnReset.setMaximumSize(new java.awt.Dimension(70, 33)); + jbtnReset.setMinimumSize(new java.awt.Dimension(70, 33)); + jbtnReset.setPreferredSize(new java.awt.Dimension(80, 45)); + jbtnReset.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jbtnResetActionPerformed(evt); + } + }); + + jLabel16.setFont(new java.awt.Font("Arial", 0, 18)); // NOI18N + jLabel16.setForeground(new java.awt.Color(153, 153, 153)); + jLabel16.setText("SET SERVER TO CONNECT TO"); + jLabel16.setPreferredSize(new java.awt.Dimension(150, 30)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel9, 0, 0, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cbSource, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel12, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jtxtDbType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtDbServerPort, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel18, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jtxtDbDriver, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createSequentialGroup() + .addComponent(jtxtDbDriverLib, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jbtnDbDriverLib, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addGap(366, 366, 366) + .addComponent(jbtnReset, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jbtnConnect, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createSequentialGroup() + .addComponent(txtDbUser, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtDbPass, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jTransferPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 202, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jlblSource, javax.swing.GroupLayout.PREFERRED_SIZE, 316, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jLabel16, javax.swing.GroupLayout.PREFERRED_SIZE, 278, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, 125, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(webPBar, javax.swing.GroupLayout.PREFERRED_SIZE, 109, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(layout.createSequentialGroup() + .addGap(18, 18, 18) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()))) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(webPBar, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel6, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jlblSource, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel16, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(cbSource, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel18, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtDbDriverLib, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jbtnDbDriverLib, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtDbDriver, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jtxtDbType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jtxtDbServerPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtDbUser, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtDbPass, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jbtnConnect, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jbtnReset, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jTransferPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + + jLabel1.getAccessibleContext().setAccessibleName("DBDriver"); + }// </editor-fold>//GEN-END:initComponents + + private void jbtnTransferActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnTransferActionPerformed + + if (JOptionPane.showConfirmDialog(this, + AppLocal.getIntString("message.transfer"), + AppLocal.getIntString("message.transfertitle"), + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { + + SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() { + + @Override + protected Void doInBackground() throws Exception { + webPBar.setString("Starting..."); + doTransfer(); + return null; + } + }; + + worker.execute(); + + } + System.gc(); + + }//GEN-LAST:event_jbtnTransferActionPerformed + + private void jbtnResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnResetActionPerformed + + reset(); + deactivate(); + + }//GEN-LAST:event_jbtnResetActionPerformed + + private void jbtnConnectjButtonTestConnectionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnConnectjButtonTestConnectionActionPerformed + + if (!jtxtDbName.getText().equalsIgnoreCase(jlblSource.getText())) { + try { + String driverlib = jtxtDbDriverLib.getText(); + String driver = jtxtDbDriver.getText(); + + if ("Derby".equals(cbSource.getSelectedItem())) { + jtxtDbName.setText("/unicentaopos-database"); + } + + String url = jtxtDbType.getText() + + jtxtDbServerPort.getText() + + jtxtDbName.getText() + + jtxtDbParams.getText(); + String user = txtDbUser.getText(); + String password = new String(txtDbPass.getPassword()); + + ClassLoader cloader = new URLClassLoader(new URL[]{ + new File(driverlib).toURI().toURL() + }); + + DriverManager.registerDriver( + new DriverWrapper((Driver) + Class.forName(driver, true, cloader).newInstance())); + + Session session_source = new Session(url, user, password); + Connection connection = session_source.getConnection(); + boolean isValid = (connection == null) + ? false : connection.isValid(1000); + + if (isValid) { + if (!"Derby".equals(cbSource.getSelectedItem())) { + jCBSchema.setEnabled(true); + fillSchema(); + } + + jtxtDbParams.setEnabled(true); + jlblVersion.setEnabled(true); + jlblDBSize.setEnabled(true); + jtxtDbName.setEnabled(true); + jbtnTransfer.setEnabled(true); + jbtnConnect.setEnabled(false); + + jTransferPanel.setVisible(true); + + JOptionPane.showMessageDialog(this, + AppLocal.getIntString("message.databaseconnectsuccess"), + "Connection Test" + , JOptionPane.INFORMATION_MESSAGE); + } else { + reset(); + + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, "Connection Error")); + } + } catch (InstantiationException + | IllegalAccessException + | MalformedURLException + | ClassNotFoundException e) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.databasedrivererror"), e)); + + } catch (SQLException e) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.databaseconnectionerror"), e)); + + } catch (Exception e) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, "Unknown exception", e)); + } + } else { + JOptionPane.showMessageDialog(this + , AppLocal.getIntString("message.transfercheck") + , AppLocal.getIntString("message.transfertitle") + , JOptionPane.WARNING_MESSAGE); + + jtxtDbName.setText(""); + } + + }//GEN-LAST:event_jbtnConnectjButtonTestConnectionActionPerformed + + private void cbSourceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbSourceActionPerformed + + reset(); + + String dirname = System.getProperty("dirname.path"); + dirname = dirname == null ? "./" : dirname; + + if ("Derby".equals(cbSource.getSelectedItem())) { + jtxtDbDriverLib.setText(new File(new File(dirname) + , "/lib/derby-10.10.2.0.jar").getAbsolutePath()); + jtxtDbDriver.setText("org.apache.derby.jdbc.EmbeddedDriver"); + jtxtDbType.setText("jdbc:derby:"); + jtxtDbServerPort.setText("" + new File(new File(System.getProperty("user.home")) + , "")); + jtxtDbParams.setText(""); + } else if ("PostgreSQL".equals(cbSource.getSelectedItem())) { + jtxtDbDriverLib.setText(new File(new File(dirname) + , "/lib/postgresql-9.4-1208.jdbc4.jar").getAbsolutePath()); + jtxtDbDriver.setText("org.postgresql.Driver"); + jtxtDbType.setText("jdbc:postgresql://"); + jtxtDbServerPort.setText("localhost:5432/"); + jtxtDbParams.setText(""); + } else { + jtxtDbDriverLib.setText(new File(new File(dirname) + , "/lib/mysql-connector-java-5.1.39.jar").getAbsolutePath()); + jtxtDbDriver.setText("com.mysql.jdbc.Driver"); + jtxtDbType.setText("jdbc:mysql://"); + jtxtDbServerPort.setText("localhost:3306/"); + jtxtDbParams.setText("?zeroDateTimeBehavior=convertToNull"); + } + + txtDbUser.setText(""); + txtDbPass.setText(""); + jlblVersion.setText(""); + jlblDBSize.setText(""); + }//GEN-LAST:event_cbSourceActionPerformed + + private void jbtnSetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnSetActionPerformed + String driverlib; + String driver; + String url; + String user; + String password; + String selected = null; + + driverlib = jtxtDbDriverLib.getText(); + driver = jtxtDbDriver.getText(); + + if ("Derby".equals(cbSource.getSelectedItem())) { + url = jtxtDbType.getText() + + jtxtDbServerPort.getText() + + jtxtDbParams.getText() + + jtxtDbName.getText(); + } else { + url = jtxtDbType.getText() + + jtxtDbServerPort.getText() + + jCBSchema.getSelectedItem().toString() + + jtxtDbParams.getText(); + } + + user = txtDbUser.getText(); + password = new String(txtDbPass.getPassword()); + + try { + ClassLoader cloader = new URLClassLoader(new URL[]{ + new File(driverlib).toURI().toURL() + }); + + DriverManager.registerDriver( + new DriverWrapper((Driver) + Class.forName(driver, true, cloader).newInstance())); + + Session session_source1 = new Session(url, user, password); + Connection connection = session_source1.getConnection(); + + if (!"Derby".equals(cbSource.getSelectedItem())) { + selected = jCBSchema.getSelectedItem().toString(); + if (selected != null) { + jtxtDbName.setText(selected); + } + } + + SQL = "SELECT * FROM applications"; + Statement stmt = (Statement) connection.createStatement(); + rs = stmt.executeQuery(SQL); + rs.next(); + + jlblVersion.setText(rs.getString(3)); + + if (null != jtxtDbType.getText() && jtxtDbName.getText() != null) { + switch (jtxtDbType.getText()) { + case "jdbc:mysql://": + SQL = "SELECT sum(round(((data_length + index_length) " + + "/ 1024 / 1024), 2)), LEFT(VERSION(),3) " + + "FROM information_schema.TABLES " + + "WHERE table_schema = " + "'" + selected + "'"; + rs = stmt.executeQuery(SQL); + rs.next(); + jlblDBSize.setText(rs.getString(1) + "MB"); + break; + case "jdbc:derby:": + SQL = "SELECT SUM((numallocatedpages * pagesize) /1024) /1024 " + + "FROM SYS.SYSTABLES systabs, SYS.SYSSCHEMAS sysschemas, " + + "TABLE (SYSCS_DIAG.SPACE_TABLE()) AS T2 " + + "WHERE systabs.tabletype = 'T' " + + "AND sysschemas.schemaid = systabs.schemaid " + + "AND systabs.tableid = T2.tableid"; + rs = stmt.executeQuery(SQL); + rs.next(); + jlblDBSize.setText(rs.getString(1) + "MB"); + break; + case "jdbc:postgresql://": + SQL = "SELECT pg_size_pretty(pg_database_size(" + "'" + selected + "'" + "))"; + rs = stmt.executeQuery(SQL); + rs.next(); + jlblDBSize.setText(rs.getString(1)); + break; + default: + break; + } + } + + } catch (InstantiationException | IllegalAccessException | MalformedURLException | ClassNotFoundException e) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.databasedrivererror"), e)); + } catch (SQLException e) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, + AppLocal.getIntString("message.databaseconnectionerror"), e)); + } catch (Exception e) { + JMessageDialog.showMessage(this, + new MessageInf(MessageInf.SGN_WARNING, "Unknown exception", e)); + } + }//GEN-LAST:event_jbtnSetActionPerformed + + private void jbtnReset1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnReset1ActionPerformed + + reset(); + deactivate(); + }//GEN-LAST:event_jbtnReset1ActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private com.alee.laf.combobox.WebComboBox cbSource; + private javax.swing.JComboBox<String> jCBSchema; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel10; + private javax.swing.JLabel jLabel11; + private javax.swing.JLabel jLabel12; + private javax.swing.JLabel jLabel13; + private javax.swing.JLabel jLabel14; + private javax.swing.JLabel jLabel15; + private javax.swing.JLabel jLabel16; + private javax.swing.JLabel jLabel18; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JLabel jLabel9; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JPanel jTransferPanel; + private javax.swing.JButton jbtnConnect; + private javax.swing.JButton jbtnDbDriverLib; + private javax.swing.JButton jbtnReset; + private javax.swing.JButton jbtnReset1; + private javax.swing.JButton jbtnSet; + private javax.swing.JButton jbtnTransfer; + private javax.swing.JLabel jlblDBSize; + private javax.swing.JLabel jlblSource; + private javax.swing.JLabel jlblVersion; + private com.alee.laf.text.WebTextField jtxtDbDriver; + private com.alee.laf.text.WebTextField jtxtDbDriverLib; + private com.alee.laf.text.WebTextField jtxtDbName; + private com.alee.laf.text.WebTextField jtxtDbParams; + private com.alee.laf.text.WebTextField jtxtDbServerPort; + private com.alee.laf.text.WebTextField jtxtDbType; + private com.alee.laf.text.WebPasswordField txtDbPass; + private com.alee.laf.text.WebTextField txtDbUser; + private javax.swing.JTextArea txtOut; + private com.alee.extended.statusbar.WebMemoryBar webMemoryBar; + private com.alee.laf.progressbar.WebProgressBar webPBar; + // End of variables declaration//GEN-END:variables + +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/transfer/TransferPanel.form b/src/main/java/com/unicenta/pos/transfer/TransferPanel.form new file mode 100644 index 0000000..d8c97ed --- /dev/null +++ b/src/main/java/com/unicenta/pos/transfer/TransferPanel.form @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JFrameFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="0"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[900, 450]"/> + </Property> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,27,0,0,3,-108"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> +</Form> diff --git a/src/main/java/com/unicenta/pos/transfer/TransferPanel.java b/src/main/java/com/unicenta/pos/transfer/TransferPanel.java new file mode 100644 index 0000000..b56d08e --- /dev/null +++ b/src/main/java/com/unicenta/pos/transfer/TransferPanel.java @@ -0,0 +1,115 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2017 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.transfer; + +import com.unicenta.basic.BasicException; +import com.unicenta.pos.forms.AppConfig; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppProperties; +import com.unicenta.pos.forms.JRootFrame; +import java.awt.BorderLayout; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.IOException; +import javax.imageio.ImageIO; + +/** + * + * @author Jack Gerrard + */ +public class TransferPanel extends javax.swing.JFrame { + + private Transfer config; + + /** Creates new form JFrmTransfer + * @param props */ + public TransferPanel(AppProperties props) { + initComponents(); + + try { + this.setIconImage(ImageIO.read(JRootFrame + .class.getResourceAsStream("/com/unicenta/images/favicon.png"))); + } catch (IOException e) { + } + setTitle(AppLocal.APP_NAME + " - " + + AppLocal.APP_VERSION + " - " + + AppLocal.getIntString("Menu.Configuration")); + + addWindowListener(new MyFrameListener()); + + config = new Transfer(props); + + getContentPane().add(config, BorderLayout.CENTER); + + try { + config.activate(); + } catch (BasicException e) { + } + } + + private class MyFrameListener extends WindowAdapter{ + + @Override + public void windowClosing(WindowEvent evt) { + if (config.deactivate()) { + dispose(); + } + } + @Override + public void windowClosed(WindowEvent evt) { + System.exit(0); + } + } + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE); + setPreferredSize(new java.awt.Dimension(900, 450)); + + setSize(new java.awt.Dimension(916, 539)); + setLocationRelativeTo(null); + }// </editor-fold>//GEN-END:initComponents + + /** + * @param args the command line arguments + */ + public static void main(final String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + + AppConfig config = new AppConfig(args); + config.load(); + + new TransferPanel(config).setVisible(true); + + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/util/AltEncrypter.java b/src/main/java/com/unicenta/pos/util/AltEncrypter.java new file mode 100644 index 0000000..d94ea3f --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/AltEncrypter.java @@ -0,0 +1,83 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2017 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.util; + +import java.io.UnsupportedEncodingException; +import java.security.*; +import javax.crypto.*; + +/** + * + * @author JG uniCenta + */ +public class AltEncrypter { + + private Cipher cipherDecrypt; + private Cipher cipherEncrypt; + + /** Creates a new instance of Encrypter + * @param passPhrase */ + public AltEncrypter(String passPhrase) { + + try { + SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); + sr.setSeed(passPhrase.getBytes("UTF8")); + KeyGenerator kGen = KeyGenerator.getInstance("DESEDE"); + kGen.init(168, sr); + Key key = kGen.generateKey(); + + cipherEncrypt = Cipher.getInstance("DESEDE/ECB/PKCS5Padding"); + cipherEncrypt.init(Cipher.ENCRYPT_MODE, key); + + cipherDecrypt = Cipher.getInstance("DESEDE/ECB/PKCS5Padding"); + cipherDecrypt.init(Cipher.DECRYPT_MODE, key); + } catch (UnsupportedEncodingException | NoSuchPaddingException + | NoSuchAlgorithmException | InvalidKeyException e) { + } + } + + /** + * + * @param str + * @return + */ + public String encrypt(String str) { + try { + return StringUtils.byte2hex(cipherEncrypt.doFinal(str.getBytes("UTF8"))); + } catch (UnsupportedEncodingException | BadPaddingException + | IllegalBlockSizeException e) { + } + return null; + } + + /** + * + * @param str + * @return + */ + public String decrypt(String str) { + try { + return new String(cipherDecrypt.doFinal(StringUtils.hex2byte(str)), "UTF8"); + } catch (UnsupportedEncodingException | BadPaddingException | IllegalBlockSizeException e) { + + } + return null; + } +} diff --git a/src/main/java/com/unicenta/pos/util/BarcodeImage.java b/src/main/java/com/unicenta/pos/util/BarcodeImage.java new file mode 100644 index 0000000..0610de7 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/BarcodeImage.java @@ -0,0 +1,164 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.unicenta.pos.util; + + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.image.BufferedImage; + +import org.krysalis.barcode4j.BarcodeDimension; +import org.krysalis.barcode4j.HumanReadablePlacement; +import org.krysalis.barcode4j.impl.AbstractBarcodeBean; +import org.krysalis.barcode4j.impl.codabar.CodabarBean; +import org.krysalis.barcode4j.impl.code128.Code128Bean; +import org.krysalis.barcode4j.impl.code39.Code39Bean; +import org.krysalis.barcode4j.impl.int2of5.Interleaved2Of5Bean; +import org.krysalis.barcode4j.impl.postnet.POSTNETBean; +import org.krysalis.barcode4j.impl.upcean.EAN13Bean; +import org.krysalis.barcode4j.impl.upcean.EAN8Bean; +import org.krysalis.barcode4j.impl.upcean.UPCABean; +import org.krysalis.barcode4j.impl.upcean.UPCEBean; +import org.krysalis.barcode4j.output.java2d.Java2DCanvasProvider; + +/** + * + * @author adrian + */ +public class BarcodeImage { + + /** + * + * @param value + * @return + */ + + public static Image getBarcodeCodabar(String value) { + AbstractBarcodeBean barcode = new CodabarBean(); + barcode.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM); + return getBarcode(value, barcode); + } + + /** + * + * @param value + * @return + */ + public static Image getBarcodeCode39(String value) { + AbstractBarcodeBean barcode = new Code39Bean(); + barcode.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM); + return getBarcode(value, barcode); + } + + /** + * + * @param value + * @return + */ + public static Image getBarcodeInterleaved2Of5(String value) { + AbstractBarcodeBean barcode = new Interleaved2Of5Bean(); + barcode.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM); + return getBarcode(value, barcode); + } + + /** + * + * @param value + * @return + */ + public static Image getBarcodePOSTNET(String value) { + AbstractBarcodeBean barcode = new POSTNETBean(); + barcode.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM); + return getBarcode(value, barcode); + } + + /** + * + * @param value + * @return + */ + public static Image getBarcodeUPCA(String value) { + AbstractBarcodeBean barcode = new UPCABean(); + barcode.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM); + return getBarcode(value, barcode); + } + + /** + * + * @param value + * @return + */ + public static Image getBarcodeUPCE(String value) { + AbstractBarcodeBean barcode = new UPCEBean(); + barcode.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM); + return getBarcode(value, barcode); + } + + /** + * + * @param value + * @return + */ + public static Image getBarcodeEAN13(String value) { + AbstractBarcodeBean barcode = new EAN13Bean(); + barcode.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM); + return getBarcode(value, barcode); + } + + /** + * + * @param value + * @return + */ + public static Image getBarcodeEAN8(String value) { + AbstractBarcodeBean barcode = new EAN8Bean(); + barcode.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM); + return getBarcode(value, barcode); + } + + /** + * + * @param value + * @return + */ + public static Image getBarcode128(String value) { + AbstractBarcodeBean barcode = new Code128Bean(); + barcode.setMsgPosition(HumanReadablePlacement.HRP_NONE); + return getBarcode(value, barcode); + } + + private static Image getBarcode(String value, AbstractBarcodeBean barcode) { + + barcode.setModuleWidth(1.0); + barcode.setBarHeight(40.0); + barcode.setFontSize(10.0); + barcode.setQuietZone(10.0); + barcode.doQuietZone(true); + BarcodeDimension dim = barcode.calcDimensions(value); + int width = (int) dim.getWidth(0) + 20; + int height = (int) dim.getHeight(0); + + BufferedImage imgtext = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics2D g2d = imgtext.createGraphics(); + + g2d.setColor(Color.WHITE); + g2d.fillRect(0, 0, width, height); + + g2d.setColor(Color.BLACK); + + try { + barcode.generateBarcode(new Java2DCanvasProvider(g2d, 0), value); + } catch (IllegalArgumentException e) { + g2d.drawRect(0, 0, width - 1, height - 1); + g2d.drawString(value, 2, height - 3); + } + + g2d.dispose(); + + return imgtext; + } +} diff --git a/src/main/java/com/unicenta/pos/util/Base64Encoder.java b/src/main/java/com/unicenta/pos/util/Base64Encoder.java new file mode 100644 index 0000000..411a46a --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/Base64Encoder.java @@ -0,0 +1,70 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2017 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.util; + +import java.io.UnsupportedEncodingException; +import org.apache.commons.codec.binary.Base64; + +/** + * + * @author JG uniCenta + */ +public class Base64Encoder { + + /** + * + * @param base64 + * @return + */ + public static byte[] decode(String base64) { + + try { + return Base64.decodeBase64(base64.getBytes("ASCII")); + } catch (UnsupportedEncodingException e) { + return null; + } + } + + /** + * + * @param raw + * @return + */ + public static String encode(byte[] raw) { + try { + return new String(Base64.encodeBase64(raw), "ASCII"); + } catch (UnsupportedEncodingException e) { + return null; + } + } + + /** + * + * @param raw + * @return + */ + public static String encodeChunked(byte[] raw) { + try { + return new String(Base64.encodeBase64Chunked(raw), "ASCII"); + } catch (UnsupportedEncodingException e) { + return null; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/util/DirectoryEvent.java b/src/main/java/com/unicenta/pos/util/DirectoryEvent.java new file mode 100644 index 0000000..ad70fc5 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/DirectoryEvent.java @@ -0,0 +1,75 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2017 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.util; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import javax.swing.JFileChooser; +import javax.swing.filechooser.FileFilter; +import javax.swing.text.JTextComponent; +import com.unicenta.pos.forms.AppLocal; + +/** + * + * @author JG uniCenta + */ +public class DirectoryEvent implements ActionListener { + + private JTextComponent m_jTxtField; + private JFileChooser m_fc; + + /** Creates a new instance of DirectoryChooser + * @param TxtField */ + public DirectoryEvent(JTextComponent TxtField) { + m_jTxtField = TxtField; + m_fc = new JFileChooser(); + + m_fc.resetChoosableFileFilters(); + m_fc.addChoosableFileFilter(new FileFilter() { + public boolean accept(File f) { + if (f.isDirectory()) { + return true; + } else { + String filename = f.getName(); + return filename.endsWith(".jar") + || filename.endsWith(".JAR") + || filename.endsWith(".zip") + || filename.endsWith(".ZIP"); + } + } + @Override + public String getDescription() { + return AppLocal.getIntString("filter.dbdriverlib"); + } + }); + m_fc.setFileSelectionMode(JFileChooser.FILES_ONLY ); + } + + @Override + public void actionPerformed(ActionEvent actionEvent) { + + m_fc.setCurrentDirectory(new File(m_jTxtField.getText())); + if (m_fc.showOpenDialog(m_jTxtField) == JFileChooser.APPROVE_OPTION) { + m_jTxtField.setText(m_fc.getSelectedFile().getAbsolutePath()); + } + } + +} diff --git a/src/main/java/com/unicenta/pos/util/ElapsedTimeBetweenDates.java b/src/main/java/com/unicenta/pos/util/ElapsedTimeBetweenDates.java new file mode 100644 index 0000000..4a71449 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/ElapsedTimeBetweenDates.java @@ -0,0 +1,47 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.unicenta.pos.util; + +/** + * + * @author user + */ + +import java.util.*; +import java.util.concurrent.TimeUnit; + +public class ElapsedTimeBetweenDates { + + public static void main(String []args) { + Date startDateTime = new Date(System.currentTimeMillis() - 123456789); + Date endDateTime = new Date(); + + Map<TimeUnit,Long> result = computeDiff(startDateTime, endDateTime); + System.out.println(result); + + System.out.println("Days: " + result.get(TimeUnit.DAYS)); + System.out.println("Hours: " + result.get(TimeUnit.HOURS)); + System.out.println("Minutes: " + result.get(TimeUnit.MINUTES)); + System.out.println("Seconds: " + result.get(TimeUnit.SECONDS)); + System.out.println("MilliSeconds: " + result.get(TimeUnit.MILLISECONDS)); + } + + public static Map<TimeUnit,Long> computeDiff(Date date1, Date date2) { + long diffInMilliSeconds = date2.getTime() - date1.getTime(); + List<TimeUnit> units = new ArrayList<>(EnumSet.allOf(TimeUnit.class)); + Collections.reverse(units); + Map<TimeUnit,Long> result = new LinkedHashMap<>(); + long milliSecondsRest = diffInMilliSeconds; + for (TimeUnit unit : units) { + long diff = unit.convert(milliSecondsRest,TimeUnit.MILLISECONDS); + long diffInMilliSecondsForUnit = unit.toMillis(diff); + milliSecondsRest = milliSecondsRest - diffInMilliSecondsForUnit; + result.put(unit,diff); + } + return result; + } + +} diff --git a/src/main/java/com/unicenta/pos/util/FXWeb.java b/src/main/java/com/unicenta/pos/util/FXWeb.java new file mode 100644 index 0000000..a3f10ae --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/FXWeb.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2016-2017 uniCenta <info at unicenta.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package com.unicenta.pos.util; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javafx.application.Platform; +import javafx.collections.ObservableList; +import javafx.embed.swing.JFXPanel; +import javafx.scene.Group; +import javafx.scene.Node; +import javafx.scene.Scene; +import javafx.scene.web.WebEngine; +import javafx.scene.web.WebView; +import javafx.stage.Stage; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +import com.sun.javafx.application.PlatformImpl; + +/** + * SwingFXWebView + */ +public class FXWeb extends JPanel +{ + private Stage stage; + private WebView browser; + private JFXPanel jfxPanel; + private JButton swingButton; + private WebEngine webEngine; + private Object geo; + + public FXWeb() + { + this.initComponents(); + } + + public static void main(final String... args) + { + // Run this later: + SwingUtilities.invokeLater(new Runnable() + { + @Override + public void run() + { + final JFrame frame = new JFrame(); + frame.getContentPane().add(new FXWeb()); + frame.setMinimumSize(new Dimension(640, 480)); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setVisible(true); + } + }); + } + + private void initComponents() + { + this.jfxPanel = new JFXPanel(); + this.createScene(); + this.setLayout(new BorderLayout()); + this.add(this.jfxPanel, BorderLayout.CENTER); + this.swingButton = new JButton(); + this.swingButton.addActionListener(new ActionListener() + { + + @Override + public void actionPerformed(final ActionEvent e) + { + Platform.runLater(new Runnable() + { + + @Override + public void run() + { + FXWeb.this.webEngine.reload(); + } + }); + } + }); + this.swingButton.setText("Reload"); + this.add(this.swingButton, BorderLayout.SOUTH); + } + + /** + * createScene Note: Key is that Scene needs to be created and run on + * "FX user thread" NOT on the AWT-EventQueue Thread + */ + private void createScene() + { + PlatformImpl.startup(() -> { + FXWeb.this.stage = new Stage(); + FXWeb.this.stage.setTitle("Hello Java FX"); + FXWeb.this.stage.setResizable(true); + final Group root = new Group(); + final Scene scene = new Scene(root, 80, 20); + FXWeb.this.stage.setScene(scene); + FXWeb.this.browser = new WebView(); + FXWeb.this.webEngine = FXWeb.this.browser.getEngine(); + FXWeb.this.webEngine.load("https://unicenta.com/pages/configure-unicenta-opos/"); + final ObservableList<Node> children = root.getChildren(); + children.add(FXWeb.this.browser); + FXWeb.this.jfxPanel.setScene(scene); + }); + } +} diff --git a/src/main/java/com/unicenta/pos/util/FileChooserEvent.java b/src/main/java/com/unicenta/pos/util/FileChooserEvent.java new file mode 100644 index 0000000..3eeaf51 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/FileChooserEvent.java @@ -0,0 +1,75 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2017 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.util; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import javax.swing.JFileChooser; +import javax.swing.filechooser.FileFilter; +import javax.swing.text.JTextComponent; +import com.unicenta.pos.forms.AppLocal; + +/** + * + * @author JG uniCenta + */ +public class FileChooserEvent implements ActionListener { + + private JTextComponent m_jTxtField; + private JFileChooser m_fc; + + /** Creates a new instance of FileChooser + * @param TxtField */ + public FileChooserEvent(JTextComponent TxtField) { + m_jTxtField = TxtField; + m_fc = new JFileChooser(); + + m_fc.resetChoosableFileFilters(); + m_fc.addChoosableFileFilter(new FileFilter() { + public boolean accept(File f) { + if (f.isDirectory()) { + return true; + } else { + String filename = f.getName(); + return filename.endsWith(".jpg") + || filename.endsWith(".JPG") + || filename.endsWith(".png") + || filename.endsWith(".PNG"); + } + } + @Override + public String getDescription() { + return AppLocal.getIntString("filter.imgfile"); + } + }); + m_fc.setFileSelectionMode(JFileChooser.FILES_ONLY ); + } + + @Override + public void actionPerformed(ActionEvent actionEvent) { + + m_fc.setCurrentDirectory(new File(m_jTxtField.getText())); + if (m_fc.showOpenDialog(m_jTxtField) == JFileChooser.APPROVE_OPTION) { + m_jTxtField.setText(m_fc.getSelectedFile().getAbsolutePath()); + } + } + +} diff --git a/src/main/java/com/unicenta/pos/util/FlatLookAndFeel.java b/src/main/java/com/unicenta/pos/util/FlatLookAndFeel.java new file mode 100644 index 0000000..8ec0a39 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/FlatLookAndFeel.java @@ -0,0 +1,45 @@ +package com.unicenta.pos.util; + +import com.formdev.flatlaf.FlatLaf; +import lombok.extern.slf4j.Slf4j; +import org.reflections.Reflections; +import org.reflections.scanners.SubTypesScanner; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.stream.Collectors; + +@Slf4j +public class FlatLookAndFeel { + + + public static Map<String, String> getLafs(){ + Map<String, String> lafs = new TreeMap<>(); + Set<Class> classes = findAllClassesUsingReflectionsLibrary("com.formdev.flatlaf"); + classes.forEach((Class name) -> { + try { + Field[] declaredFields = name.getDeclaredFields(); + for (Field field: declaredFields) { + if (field.getName().equals("NAME")) { + lafs.put((String)field.get(null), name.getCanonicalName()); + } + } + } catch (Exception e) { + log.error("Error getting Flat Look and Feel "+e.getMessage()); + } + }); + + + return lafs; + } + + private static Set<Class> findAllClassesUsingReflectionsLibrary(String packageName) { + Reflections reflections = new Reflections(packageName, new SubTypesScanner(false)); + return reflections.getSubTypesOf(FlatLaf.class) + .stream() + .collect(Collectors.toSet()); + } +} diff --git a/src/main/java/com/unicenta/pos/util/FtpUpload.java b/src/main/java/com/unicenta/pos/util/FtpUpload.java new file mode 100644 index 0000000..86813ae --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/FtpUpload.java @@ -0,0 +1,69 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/> + +package com.unicenta.pos.util; + +import lombok.extern.slf4j.Slf4j; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.URL; +import java.net.URLConnection; + +@Slf4j +public class FtpUpload extends Thread { + + private static final int BUFFER_SIZE = 1024; + private static String sMachine; + + @Override + public void run() { + String ftpUrl = ""; + String host = ""; + String user = ""; + String pass = ""; + + try { + sMachine = InetAddress.getLocalHost().getHostName(); + + String filePath = System.getProperty("user.home") + "/" + sMachine + ".lau"; + String uploadPath = sMachine + ".lau"; + + ftpUrl = String.format(ftpUrl, user, pass, host, uploadPath); + + URL url = new URL(ftpUrl); + URLConnection conn = url.openConnection(); + try (OutputStream outputStream = conn.getOutputStream(); + FileInputStream inputStream = new FileInputStream(filePath)) { + + byte[] buffer = new byte[BUFFER_SIZE]; + int bytesRead = -1; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + + } + + } catch (IOException ex) { + log.error(ex.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/util/Hashcypher.java b/src/main/java/com/unicenta/pos/util/Hashcypher.java new file mode 100644 index 0000000..3f6fa05 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/Hashcypher.java @@ -0,0 +1,133 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2017 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.util; + +import java.awt.Component; +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import javax.swing.ImageIcon; +import javax.swing.JOptionPane; +import com.unicenta.beans.JPasswordDialog; +import com.unicenta.pos.forms.AppLocal; + +/** + * + * @author JG uniCenta + */ +public class Hashcypher { + + + /** Creates a new instance of Hashcypher */ + public Hashcypher() { + } + + /** + * + * @param sPassword + * @param sHashPassword + * @return + */ + public static boolean authenticate(String sPassword, String sHashPassword) { + if (sHashPassword == null || sHashPassword.equals("") || sHashPassword.startsWith("empty:")) { + return sPassword == null || sPassword.equals(""); + } else if (sHashPassword.startsWith("sha1:")) { + return sHashPassword.equals(hashString(sPassword)); + } else if (sHashPassword.startsWith("plain:")) { + return sHashPassword.equals("plain:" + sPassword); + } else { + return sHashPassword.equals(sPassword); + } + } + + /** + * + * @param sPassword + * @return + */ + public static String hashString(String sPassword) { + + if (sPassword == null || sPassword.equals("")) { + return "empty:"; + } else { + try { + MessageDigest md = MessageDigest.getInstance("SHA-1"); + md.update(sPassword.getBytes("UTF-8")); + byte[] res = md.digest(); + return "sha1:" + StringUtils.byte2hex(res); + } catch (NoSuchAlgorithmException e) { + return "plain:" + sPassword; + } catch (UnsupportedEncodingException e) { + return "plain:" + sPassword; + } + } + } + + /** + * + * @param parent + * @return + */ + public static String changePassword(Component parent) { + // Show the changePassword dialogs but do not check the old password + + String sPassword = JPasswordDialog.showEditPassword(parent, + AppLocal.getIntString("label.Password"), + AppLocal.getIntString("label.passwordnew"), + new ImageIcon(Hashcypher.class.getResource("/com/unicenta/images/password.png"))); + if (sPassword != null) { + String sPassword2 = JPasswordDialog.showEditPassword(parent, + AppLocal.getIntString("label.Password"), + AppLocal.getIntString("label.passwordrepeat"), + new ImageIcon(Hashcypher.class.getResource("/com/unicenta/images/password.png"))); + if (sPassword2 != null) { + if (sPassword.equals(sPassword2)) { + return Hashcypher.hashString(sPassword); + } else { + JOptionPane.showMessageDialog(parent, AppLocal.getIntString("message.changepassworddistinct"), AppLocal.getIntString("message.title"), JOptionPane.WARNING_MESSAGE); + } + } + } + + return null; + } + + /** + * + * @param parent + * @param sOldPassword + * @return + */ + public static String changePassword(Component parent, String sOldPassword) { + + String sPassword = JPasswordDialog.showEditPassword(parent, + AppLocal.getIntString("label.Password"), + AppLocal.getIntString("label.passwordold"), + new ImageIcon(Hashcypher.class.getResource("/com/unicenta/images/password.png"))); + if (sPassword != null) { + if (Hashcypher.authenticate(sPassword, sOldPassword)) { + return changePassword(parent); + } else { + JOptionPane.showMessageDialog(parent, AppLocal.getIntString("message.BadPassword"), AppLocal.getIntString("message.title"), JOptionPane.WARNING_MESSAGE); + } + } + return null; + } +} diff --git a/src/main/java/com/unicenta/pos/util/HtmlTester.java b/src/main/java/com/unicenta/pos/util/HtmlTester.java new file mode 100644 index 0000000..24f38d3 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/HtmlTester.java @@ -0,0 +1,67 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.unicenta.pos.util; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; +import javax.swing.text.Document; +import javax.swing.text.html.HTMLEditorKit; +import javax.swing.text.html.StyleSheet; + +/** + * HTML viewer with styles,* using the JEditorPane, HTMLTester, StyleSheet, and JFrame. + * + */ +public class HtmlTester +{ + public static void main(String[] args) + { + new HtmlTester(); + } + + public HtmlTester() + { + SwingUtilities.invokeLater(() -> { + JEditorPane jEditorPane = new JEditorPane(); + jEditorPane.setEditable(false); + JScrollPane scrollPane = new JScrollPane(jEditorPane); + + HTMLEditorKit kit = new HTMLEditorKit(); + jEditorPane.setEditorKit(kit); + + StyleSheet styleSheet = kit.getStyleSheet(); + styleSheet.addRule("body {color:#000; font-family:times; margin: 4px; }"); + styleSheet.addRule("h1 {color: blue;}"); + styleSheet.addRule("h2 {color: #ff0000;}"); + styleSheet.addRule("pre {font : 12px century gothic; color : black; background-color : #fafafa; }"); + + String htmlString = "<html>\n" + + "<body>\n" + + "<h1>Welcome!</h1>\n" + + "<h2>This is an H2 header</h2>\n" + + "<p>This is some sample text</p>\n" + + "<p><a href=\"https://unicenta.com/\">uniCenta site</a></p>\n" + + "</body>\n"; + + Document doc = kit.createDefaultDocument(); + jEditorPane.setDocument(doc); + jEditorPane.setText(htmlString); + + JFrame j = new JFrame("Html Test"); + j.getContentPane().add(scrollPane, BorderLayout.CENTER); + + j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + j.setSize(new Dimension(300,200)); + + j.setLocationRelativeTo(null); + j.setVisible(true); + }); + } +} diff --git a/src/main/java/com/unicenta/pos/util/HtmlTester2.java b/src/main/java/com/unicenta/pos/util/HtmlTester2.java new file mode 100644 index 0000000..6a17d15 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/HtmlTester2.java @@ -0,0 +1,33 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.unicenta.pos.util; + +import java.net.URL; + +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.JScrollPane; + +public class HtmlTester2 { + + public static void main(String[] a)throws Exception { + JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + JEditorPane editorPane = new JEditorPane(); + + editorPane.setPage(new URL("https://unicenta.org/splasher.html")); + // Test LocalFile + + frame.add(new JScrollPane(editorPane)); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setLocationRelativeTo(null); + frame.setSize(800, 400); + + frame.setVisible(true); + } + +} diff --git a/src/main/java/com/unicenta/pos/util/HtmlTester3.form b/src/main/java/com/unicenta/pos/util/HtmlTester3.form new file mode 100644 index 0000000..cbae086 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/HtmlTester3.form @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSizePolicy" type="int" value="1"/> + <SyntheticProperty name="generateCenter" type="boolean" value="false"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jScrollPane1" pref="760" max="32767" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jScrollPane1" pref="556" max="32767" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Container class="javax.swing.JScrollPane" name="jScrollPane1"> + <AuxValues> + <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JEditorPane" name="jEditorPane1"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="page" type="java.net.URL" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="new URL("https://unicenta.org/splasher.html")" type="code"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[800, 600]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/util/HtmlTester3.java b/src/main/java/com/unicenta/pos/util/HtmlTester3.java new file mode 100644 index 0000000..5220260 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/HtmlTester3.java @@ -0,0 +1,114 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.unicenta.pos.util; + +import lombok.extern.slf4j.Slf4j; + +import java.io.IOException; +import java.net.URL; + +/** + * @author user + */ +@Slf4j +public class HtmlTester3 extends javax.swing.JDialog { + + /** + * Creates new form HtmlTester3 + * + * @param parent + * @param modal + */ + public HtmlTester3(java.awt.Frame parent, boolean modal) { + super(parent, modal); + initComponents(); + try { + jEditorPane1.setPage("https://unicenta.org/splasher.html"); + + } catch (IOException ex) { + log.error(ex.getMessage()); + } + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jScrollPane1 = new javax.swing.JScrollPane(); + jEditorPane1 = new javax.swing.JEditorPane(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + + jEditorPane1.setEditable(false); + try { + jEditorPane1.setPage(new URL("https://unicenta.org/splasher.html")); + } catch (java.io.IOException e1) { + e1.printStackTrace(); + } + jEditorPane1.setPreferredSize(new java.awt.Dimension(800, 600)); + jScrollPane1.setViewportView(jEditorPane1); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 760, Short.MAX_VALUE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 556, Short.MAX_VALUE) + .addContainerGap()) + ); + + pack(); + }// </editor-fold>//GEN-END:initComponents + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + + try { + for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { +// if ("Nimbus".equals(info.getName())) { + if ("Windows".equals(info.getName())) { + javax.swing.UIManager.setLookAndFeel(info.getClassName()); + break; + } + } + } catch (ClassNotFoundException | InstantiationException + | IllegalAccessException + | javax.swing.UnsupportedLookAndFeelException ex) { + log.error(ex.getMessage()); + } + + /* Create and display the dialog */ + java.awt.EventQueue.invokeLater(() -> { + HtmlTester3 dialog = new HtmlTester3(new javax.swing.JFrame(), true); + dialog.addWindowListener(new java.awt.event.WindowAdapter() { + @Override + public void windowClosing(java.awt.event.WindowEvent e) { + System.exit(0); + } + }); + dialog.setVisible(true); + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JEditorPane jEditorPane1; + private javax.swing.JScrollPane jScrollPane1; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/unicenta/pos/util/InactivityListener.java b/src/main/java/com/unicenta/pos/util/InactivityListener.java new file mode 100644 index 0000000..575ce83 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/InactivityListener.java @@ -0,0 +1,96 @@ +/* + * + * KEY_EVENTS + * MOUSE_EVENTS - which includes mouse motion events + * USER_EVENTS - includes KEY_EVENTS and MOUSE_EVENT (this is the default) + * + */ + +package com.unicenta.pos.util; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +/** + * + * @author JG uniCenta + */ +public class InactivityListener implements ActionListener, AWTEventListener { + + /** + * + */ + public final static long KEY_EVENTS = AWTEvent.KEY_EVENT_MASK; + + /** + * + */ + public final static long MOUSE_EVENTS = + AWTEvent.MOUSE_MOTION_EVENT_MASK + AWTEvent.MOUSE_EVENT_MASK; + + /** + * + */ + public final static long USER_EVENTS = KEY_EVENTS + MOUSE_EVENTS; + private Action action; + private int interval; + private long eventMask; + private Timer timer = new Timer(0, this); + +// Specify the inactivity interval and listen for USER_EVENTS + /** + * + * @param action + * @param seconds + */ + public InactivityListener(Action action, int seconds) { + this.action = action; + this.eventMask =USER_EVENTS; + timer.setInitialDelay(seconds); + } + + /** + * + */ + public void start() { + timer.setRepeats(false); + timer.start(); + Toolkit.getDefaultToolkit().addAWTEventListener(this, eventMask); + } + + /** + * + */ + public void stop() { + Toolkit.getDefaultToolkit().removeAWTEventListener(this); + timer.stop(); + } + +// Implement ActionListener for the Timer + public void actionPerformed(ActionEvent e) { + action.actionPerformed(e); + } + +// Implement AWTEventListener, all events are dispatched via this + public void eventDispatched(AWTEvent e) { + if (timer.isRunning()) + timer.restart(); + } + +// Implement a manually triggered restart + /** + * + */ + public void restart(){ + timer.restart(); + } + + /** + * + */ + public void setRunning() { + if (!timer.isRunning()) + timer.restart(); + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/util/JRPrinterAWT300.java b/src/main/java/com/unicenta/pos/util/JRPrinterAWT300.java new file mode 100644 index 0000000..b7fc145 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/JRPrinterAWT300.java @@ -0,0 +1,308 @@ +/* + * ============================================================================ + * GNU Lesser General Public License + * ============================================================================ + * + * JasperReports - Free Java report-generating library. + * Copyright (c) 2001-2006 JasperSoft Corporation http://www.jaspersoft.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + * + * JasperSoft Corporation + * 303 Second Street, Suite 450 North + * San Francisco, CA 94107 + * http://www.jaspersoft.com + */ + +// Portions: +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2017 uniCenta +// https://unicenta.com +// author Jack Gerrard +// This class is a copy of net.sf.jasperreports.engine.print.JRPrinterAWT +// The modifications are: +// Added to the constructor the service, instead of isDialog +// And the redesign of the design properties of the toolbar +// Nothing else. + +package com.unicenta.pos.util; + +import java.awt.Graphics; +import java.awt.HeadlessException; +import java.awt.Image; +import java.awt.image.BufferedImage; +import java.awt.print.*; +import javax.print.PrintService; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JRExporterParameter; +import net.sf.jasperreports.engine.JasperPrint; +import net.sf.jasperreports.engine.export.*; +import net.sf.jasperreports.engine.export.JRGraphics2DExporter; +import net.sf.jasperreports.engine.export.JRGraphics2DExporterParameter; +import net.sf.jasperreports.engine.util.JRGraphEnvInitializer; +import org.apache.poi.hssf.usermodel.*; + + +/** + * @author Teodor Danciu (teodord@users.sourceforge.net) + * @version $Id: JRPrinterAWT.java 2123 2008-03-12 11:00:41Z teodord $ + */ +public class JRPrinterAWT300 implements Printable +{ + + + /** + * + */ + private JasperPrint jasperPrint = null; + private int pageOffset = 0; + + + /** + * + * @param jrPrint + * @param jrPrint + * @throws net.sf.jasperreports.engine.JRException + * @throws JRException + */ + protected JRPrinterAWT300(JasperPrint jrPrint) throws JRException + { + JRGraphEnvInitializer.initializeGraphEnv(); + + jasperPrint = jrPrint; + } + + + /** + * + * @param jrPrint + * @param firstPageIndex + * @param lastPageIndex + * @param service + * @return + * @return + * @throws JRException + */ + public static boolean printPages( + JasperPrint jrPrint, + int firstPageIndex, + int lastPageIndex, + PrintService service + ) throws JRException + { + JRPrinterAWT300 printer = new JRPrinterAWT300(jrPrint); + return printer.printPages( + firstPageIndex, + lastPageIndex, + service + ); + } + + + /** + * + * @param jrPrint + * @param pageIndex + * @param zoom + * @return + * @throws JRException + */ + public static Image printPageToImage( + JasperPrint jrPrint, + int pageIndex, + float zoom + ) throws JRException + { + JRPrinterAWT300 printer = new JRPrinterAWT300(jrPrint); + return printer.printPageToImage(pageIndex, zoom); + } + + + /** + * + */ + private boolean printPages( + int firstPageIndex, + int lastPageIndex, + PrintService service + ) throws JRException + { + boolean isOK = true; + + if ( + firstPageIndex < 0 || + firstPageIndex > lastPageIndex || + lastPageIndex >= jasperPrint.getPages().size() + ) + { + throw new JRException( + "Invalid page index range : " + + firstPageIndex + " - " + + lastPageIndex + " of " + + jasperPrint.getPages().size() + ); + } + + pageOffset = firstPageIndex; + + PrinterJob printJob = PrinterJob.getPrinterJob(); + + // fix for bug ID 6255588 from Sun bug database + initPrinterJobFields(printJob); + + PageFormat pageFormat = printJob.defaultPage(); + Paper paper = pageFormat.getPaper(); + + printJob.setJobName("uniCentaReport - " + jasperPrint.getName()); + + switch (jasperPrint.getOrientationValue()) + { + case LANDSCAPE : + { + pageFormat.setOrientation(PageFormat.LANDSCAPE); + paper.setSize(jasperPrint.getPageHeight(), jasperPrint.getPageWidth()); + paper.setImageableArea( + 0, + 0, + jasperPrint.getPageHeight(), + jasperPrint.getPageWidth() + ); + break; + } + case PORTRAIT : + default : + { + pageFormat.setOrientation(PageFormat.PORTRAIT); + paper.setSize(jasperPrint.getPageWidth(), jasperPrint.getPageHeight()); + paper.setImageableArea( + 0, + 0, + jasperPrint.getPageWidth(), + jasperPrint.getPageHeight() + ); + } + } + + pageFormat.setPaper(paper); + + Book book = new Book(); + book.append(this, pageFormat, lastPageIndex - firstPageIndex + 1); + printJob.setPageable(book); + try + { + if (service == null) { + if (printJob.printDialog()) { + printJob.print(); + } + } else { + printJob.setPrintService(service); + printJob.print(); + } + } + catch (HeadlessException | PrinterException ex) + { + throw new JRException("Error printing report.", ex); + } + + return isOK; + } + + + /** + * + */ + @Override + public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException + { + if (Thread.currentThread().isInterrupted()) + { + throw new PrinterException("Current thread interrupted."); + } + + pageIndex += pageOffset; + + if ( pageIndex < 0 || pageIndex >= jasperPrint.getPages().size() ) + { + return Printable.NO_SUCH_PAGE; + } + + try + { + JRGraphics2DExporter exporter = new JRGraphics2DExporter(); + exporter.setParameter(JRExporterParameter.JASPER_PRINT, this.jasperPrint); + exporter.setParameter(JRGraphics2DExporterParameter.GRAPHICS_2D, graphics); + exporter.setParameter(JRExporterParameter.PAGE_INDEX, new Integer(pageIndex)); + exporter.exportReport(); + } + catch (JRException e) + { + throw new PrinterException(e.getMessage()); + } + + return Printable.PAGE_EXISTS; + } + + + /** + * + */ + private Image printPageToImage(int pageIndex, float zoom) throws JRException + { + Image pageImage = new BufferedImage( + (int)(jasperPrint.getPageWidth() * zoom) + 1, + (int)(jasperPrint.getPageHeight() * zoom) + 1, + BufferedImage.TYPE_INT_RGB + ); + + JRGraphics2DExporter exporter = new JRGraphics2DExporter(); + exporter.setParameter(JRExporterParameter.JASPER_PRINT, this.jasperPrint); + exporter.setParameter(JRGraphics2DExporterParameter.GRAPHICS_2D, pageImage.getGraphics()); + exporter.setParameter(JRExporterParameter.PAGE_INDEX, new Integer(pageIndex)); + exporter.setParameter(JRGraphics2DExporterParameter.ZOOM_RATIO, new Float(zoom)); + + exporter.exportReport(); + + return pageImage; + } + + + /** + * Fix for bug ID 6255588 from Sun bug database + * @param job print job that the fix applies to + */ + public static void initPrinterJobFields(PrinterJob job) + { + try + { + job.setPrintService(job.getPrintService()); + } + catch (PrinterException e) + { + } + } + + /** + * + * @param jasperPrint + * @param zoom + * @return + */ + public static long getImageSize(JasperPrint jasperPrint, float zoom) + { + int width = (int) (jasperPrint.getPageWidth() * zoom) + 1; + int height = (int) (jasperPrint.getPageHeight() * zoom) + 1; + return width * height; + } +} diff --git a/src/main/java/com/unicenta/pos/util/JRViewer400.form b/src/main/java/com/unicenta/pos/util/JRViewer400.form new file mode 100644 index 0000000..77c2bda --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/JRViewer400.form @@ -0,0 +1,567 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[450, 150]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[450, 150]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-20,0,0,2,77"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JToolBar" name="jToolBar"> + <Properties> + <Property name="floatable" type="boolean" value="false"/> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/> + <SubComponents> + <Component class="javax.swing.JButton" name="btnSave"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/filesave.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="getBundleString("save")" type="code"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnSaveActionPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="4"/> + </AuxValues> + </Component> + <Component class="javax.swing.JButton" name="btnPrint"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/yast_printer.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="getBundleString("print")" type="code"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnPrintActionPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="4"/> + </AuxValues> + </Component> + <Component class="javax.swing.JButton" name="btnReload"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/reload.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="getBundleString("reload")" type="code"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnReloadActionPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="4"/> + </AuxValues> + </Component> + <Component class="javax.swing.JToolBar$Separator" name="jSeparator1"> + </Component> + <Component class="javax.swing.JToggleButton" name="btnActualSize"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/mime.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="getBundleString("actual.size")" type="code"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnActualSizeActionPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="4"/> + </AuxValues> + </Component> + <Component class="javax.swing.JToggleButton" name="btnFitPage"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/mime2.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="getBundleString("fit.page")" type="code"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnFitPageActionPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="4"/> + </AuxValues> + </Component> + <Component class="javax.swing.JToggleButton" name="btnFitWidth"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/mime3.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="getBundleString("fit.width")" type="code"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnFitWidthActionPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="4"/> + </AuxValues> + </Component> + <Component class="javax.swing.JToolBar$Separator" name="jSeparator2"> + </Component> + <Component class="javax.swing.JButton" name="btnZoomIn"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/viewmag+.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="getBundleString("zoom.in")" type="code"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnZoomInActionPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="4"/> + </AuxValues> + </Component> + <Component class="javax.swing.JComboBox" name="cmbZoom"> + <Properties> + <Property name="editable" type="boolean" value="true"/> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="getBundleString("zoom.ratio")" type="code"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 23]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 23]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 23]"/> + </Property> + </Properties> + <Events> + <EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="cmbZoomItemStateChanged"/> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cmbZoomActionPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_CreateCodePost" type="java.lang.String" value="DefaultComboBoxModel model = new DefaultComboBoxModel(); for(int i = 0; i < zooms.length; i++) { model.addElement("" + zooms[i] + "%"); } cmbZoom.setModel(model); "/> + <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="4"/> + </AuxValues> + </Component> + <Component class="javax.swing.JButton" name="btnZoomOut"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/viewmag-.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="getBundleString("zoom.out")" type="code"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnZoomOutActionPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="4"/> + </AuxValues> + </Component> + <Component class="javax.swing.JToolBar$Separator" name="jSeparator3"> + </Component> + <Component class="javax.swing.JButton" name="btnFirst"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/2leftarrow.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="getBundleString("first.page")" type="code"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnFirstActionPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="4"/> + </AuxValues> + </Component> + <Component class="javax.swing.JButton" name="btnPrevious"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/1leftarrow.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="getBundleString("previous.page")" type="code"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnPreviousActionPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="4"/> + </AuxValues> + </Component> + <Component class="javax.swing.JTextField" name="txtGoTo"> + <Properties> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="getBundleString("go.to.page")" type="code"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 23]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 23]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 23]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="txtGoToActionPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="4"/> + </AuxValues> + </Component> + <Component class="javax.swing.JButton" name="btnNext"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/1rightarrow.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="getBundleString("next.page")" type="code"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnNextActionPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="4"/> + </AuxValues> + </Component> + <Component class="javax.swing.JButton" name="btnLast"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/2rightarrow.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="getBundleString("last.page")" type="code"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnLastActionPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="4"/> + </AuxValues> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="pnlMain"> + <Events> + <EventHandler event="componentResized" listener="java.awt.event.ComponentListener" parameters="java.awt.event.ComponentEvent" handler="pnlMainComponentResized"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JScrollPane" name="scrollPane"> + <Properties> + <Property name="horizontalScrollBarPolicy" type="int" value="32"/> + <Property name="verticalScrollBarPolicy" type="int" value="22"/> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_CreateCodePost" type="java.lang.String" value="scrollPane.getHorizontalScrollBar().setUnitIncrement(5); scrollPane.getVerticalScrollBar().setUnitIncrement(5); "/> + </AuxValues> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="pnlInScroll"> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="pnlPage"> + <Properties> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 100]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 100]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="10" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Properties> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 120]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 120]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="pnlLinks"> + <Properties> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[5, 5]"/> + </Property> + <Property name="opaque" type="boolean" value="false"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[5, 5]"/> + </Property> + </Properties> + <Events> + <EventHandler event="mousePressed" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="pnlLinksMousePressed"/> + <EventHandler event="mouseReleased" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="pnlLinksMouseReleased"/> + <EventHandler event="mouseDragged" listener="java.awt.event.MouseMotionListener" parameters="java.awt.event.MouseEvent" handler="pnlLinksMouseDragged"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="0" gridWidth="2" gridHeight="2" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout"> + <Property name="useNullLayout" type="boolean" value="true"/> + </Layout> + </Container> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="80" green="80" id="gray" palette="0" red="80" type="palette"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[5, 5]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[5, 5]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="2" gridY="1" gridWidth="1" gridHeight="1" fill="3" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + </Container> + <Container class="javax.swing.JPanel" name="jPanel6"> + <Properties> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[5, 5]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[5, 5]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + </Container> + <Container class="javax.swing.JPanel" name="jPanel7"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="80" green="80" id="gray" palette="0" red="80" type="palette"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[5, 5]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[5, 5]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="1" gridY="2" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + </Container> + <Container class="javax.swing.JPanel" name="jPanel8"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="80" green="80" id="gray" palette="0" red="80" type="palette"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[5, 5]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[5, 5]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="2" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="text" type="java.lang.String" value="jLabel1"/> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel9"> + <Properties> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[5, 5]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[5, 5]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="2" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + </Container> + <Component class="javax.swing.JLabel" name="lblPage"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" id="white" palette="0" red="ff" type="palette"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Agency FB" size="12" style="0"/> + </Property> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder/> + </Border> + </Property> + <Property name="opaque" type="boolean" value="true"/> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new PageRenderer(this);"/> + </AuxValues> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> + <GridBagConstraints gridX="0" gridY="0" gridWidth="2" gridHeight="2" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JTabbedPane" name="pnlTabs"> + <Events> + <EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="pnlTabsStateChanged"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="pnlStatus"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[59, 20]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_AddingCodePost" type="java.lang.String" value="addKeyListener(keyNavigationListener);"/> + <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="4"/> + </AuxValues> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="horizontalGap" type="int" value="0"/> + <Property name="verticalGap" type="int" value="0"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="lblStatus"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="1"/> + </Property> + <Property name="text" type="java.lang.String" value="Page i of n"/> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[59, 18]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="4"/> + </AuxValues> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/util/JRViewer400.java b/src/main/java/com/unicenta/pos/util/JRViewer400.java new file mode 100644 index 0000000..ff256b6 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/JRViewer400.java @@ -0,0 +1,2410 @@ +/* + * JasperReports - Free Java Reporting Library. + * Copyright (C) 2001 - 2014 TIBCO Software Inc. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program is part of JasperReports. + * + * JasperReports is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JasperReports is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with JasperReports. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Contributors: + * Ryan Johnson - delscovich@users.sourceforge.net + * Carlton Moore - cmoore79@users.sourceforge.net + * Petr Michalek - pmichalek@users.sourceforge.net + */ +package com.unicenta.pos.util; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.InputStream; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.text.MessageFormat; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Locale; +import java.util.Map; +import java.util.ResourceBundle; + +import javax.swing.DefaultComboBoxModel; +import javax.swing.ImageIcon; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JViewport; +import javax.swing.SwingUtilities; +import javax.swing.filechooser.FileFilter; + +import net.sf.jasperreports.engine.DefaultJasperReportsContext; +import net.sf.jasperreports.engine.ImageMapRenderable; +import net.sf.jasperreports.engine.JRConstants; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JRPrintAnchorIndex; +import net.sf.jasperreports.engine.JRPrintElement; +import net.sf.jasperreports.engine.JRPrintFrame; +import net.sf.jasperreports.engine.JRPrintHyperlink; +import net.sf.jasperreports.engine.JRPrintImage; +import net.sf.jasperreports.engine.JRPrintImageAreaHyperlink; +import net.sf.jasperreports.engine.JRPrintPage; +import net.sf.jasperreports.engine.JRPropertiesUtil; +import net.sf.jasperreports.engine.JRRuntimeException; +import net.sf.jasperreports.engine.JasperPrint; +import net.sf.jasperreports.engine.JasperPrintManager; +import net.sf.jasperreports.engine.JasperReportsContext; +import net.sf.jasperreports.engine.PrintPageFormat; +import net.sf.jasperreports.engine.PrintPart; +import net.sf.jasperreports.engine.PrintParts; +import net.sf.jasperreports.engine.Renderable; +import net.sf.jasperreports.engine.export.JRGraphics2DExporter; +import net.sf.jasperreports.engine.type.HyperlinkTypeEnum; +import net.sf.jasperreports.engine.util.JRLoader; +import net.sf.jasperreports.engine.util.LocalJasperReportsContext; +import net.sf.jasperreports.engine.util.SimpleFileResolver; +import net.sf.jasperreports.engine.xml.JRPrintXmlLoader; +import net.sf.jasperreports.export.SimpleExporterInput; +import net.sf.jasperreports.export.SimpleGraphics2DExporterOutput; +import net.sf.jasperreports.export.SimpleGraphics2DReportConfiguration; +import net.sf.jasperreports.view.JRHyperlinkListener; +import net.sf.jasperreports.view.JRSaveContributor; +import net.sf.jasperreports.view.SaveContributorUtils; +import net.sf.jasperreports.view.save.JRPrintSaveContributor; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Represents the built-in visual component for JasperReports. + * This class is different from the rest of the classes listed previously in that it is more like a + * pluggable component than a utility class. It can be used in Swing-based + * applications to view the reports generated by the JasperReports library. + * This visual component was included like a demo + * component to show how the core printing functionality can be used to display the reports + * in Swing-based applications. + * The preferred way to adapt this component to a particular application is by subclassing it. + * + * @author Teodor Danciu (teodord@users.sourceforge.net) + * @version $Id: JRViewer400.java 2160 2008-04-29 11:31:51Z lucianc $ + */ +public final class JRViewer400 extends javax.swing.JPanel implements JRHyperlinkListener +{ + private static final Log log = LogFactory.getLog(JRViewer400.class); + + private static final long serialVersionUID = JRConstants.SERIAL_VERSION_UID; + + /** + * Maximum size (in pixels) of a buffered image that would be used to render a report page. + * If rendering a report page would require an image larger than this threshold + * (i.e. image width x image height greater maximum size), the report page will be rendered directly on the viewer component. + * If this property is zero or negative, buffered images will never be user to render a report page. + * By default, this property is set to 0. + */ + public static final String VIEWER_RENDER_BUFFER_MAX_SIZE + = JRPropertiesUtil.PROPERTY_PREFIX + "viewer.render.buffer.max.size"; + + /** + * + */ + protected static final int TYPE_FILE_NAME = 1; + protected static final int TYPE_INPUT_STREAM = 2; + protected static final int TYPE_OBJECT = 3; + + /** + * The DPI of the generated report. + */ + public static final int REPORT_RESOLUTION = 72; + + protected final float MIN_ZOOM = 0.5f; + protected final float MAX_ZOOM = 10f; + protected int zooms[] = {50, 75, 100, 125, 150, 175, 200, 250, 400, 800}; + protected int defaultZoomIndex = 2; + + protected int type = TYPE_FILE_NAME; + protected boolean isXML; + protected String reportFileName; + JasperPrint jasperPrint; + private int pageIndex; + private boolean pageError; + protected float zoom; + + private JRGraphics2DExporter exporter; + + /** + * the screen resolution. + */ + private int screenResolution = REPORT_RESOLUTION; + + /** + * the zoom ration adjusted to the screen resolution. + */ + protected float realZoom; + + private DecimalFormat zoomDecimalFormat; + protected JasperReportsContext jasperReportsContext; + protected LocalJasperReportsContext localJasperReportsContext; + private ResourceBundle resourceBundle; + + private int downX; + private int downY; + + private boolean pnlTabsChangeListenerEnabled = true; + + private List<JRHyperlinkListener> hyperlinkListeners = new ArrayList<JRHyperlinkListener>(); + private Map<JPanel,JRPrintHyperlink> linksMap = new HashMap<JPanel,JRPrintHyperlink>(); + private MouseListener mouseListener = + new java.awt.event.MouseAdapter() + { + public void mouseClicked(java.awt.event.MouseEvent evt) + { + hyperlinkClicked(evt); + } + }; + + protected KeyListener keyNavigationListener = + new KeyListener() { + public void keyTyped(KeyEvent evt) + { + } + public void keyPressed(KeyEvent evt) + { + keyNavigate(evt); + } + public void keyReleased(KeyEvent evt) + { + } + }; + + protected List<JRSaveContributor> saveContributors = new ArrayList<JRSaveContributor>(); + protected File lastFolder; + protected JRSaveContributor lastSaveContributor; + + /** + * @see #JRViewer(JasperReportsContext, String, boolean, Locale, ResourceBundle) + */ + public JRViewer400(String fileName, boolean isXML) throws JRException + { + this(fileName, isXML, null); + } + + + /** + * @see #JRViewer(JasperReportsContext, InputStream, boolean, Locale, ResourceBundle) + */ + public JRViewer400(InputStream is, boolean isXML) throws JRException + { + this(is, isXML, null); + } + + + /** + * @see #JRViewer(JasperReportsContext, JasperPrint, Locale, ResourceBundle) + */ + public JRViewer400(JasperPrint jrPrint) + { + this(jrPrint, null); + } + + + /** + * @see #JRViewer(JasperReportsContext, String, boolean, Locale, ResourceBundle) + */ + public JRViewer400(String fileName, boolean isXML, Locale locale) throws JRException + { + this(fileName, isXML, locale, null); + } + + + /** + * @see #JRViewer(JasperReportsContext, InputStream, boolean, Locale, ResourceBundle) + */ + public JRViewer400(InputStream is, boolean isXML, Locale locale) throws JRException + { + this(is, isXML, locale, null); + } + + + /** Creates new form JRViewer400 + * @param jrPrint + * @param locale */ + public JRViewer400(JasperPrint jrPrint, Locale locale) + { + this(jrPrint, locale, null); + } + + + /** + * @see #JRViewer(JasperReportsContext, String, boolean, Locale, ResourceBundle) + */ + public JRViewer400(String fileName, boolean isXML, Locale locale, ResourceBundle resBundle) throws JRException + { + this( + DefaultJasperReportsContext.getInstance(), + fileName, + isXML, + locale, + resBundle + ); + } + + + /** + * @see #JRViewer(JasperReportsContext, InputStream, boolean, Locale, ResourceBundle) + */ + public JRViewer400(InputStream is, boolean isXML, Locale locale, ResourceBundle resBundle) throws JRException + { + this( + DefaultJasperReportsContext.getInstance(), + is, + isXML, + locale, + resBundle + ); + } + + + /** + * @see #JRViewer(JasperReportsContext, JasperPrint, Locale, ResourceBundle) + */ + public JRViewer400(JasperPrint jrPrint, Locale locale, ResourceBundle resBundle) + { + this( + DefaultJasperReportsContext.getInstance(), + jrPrint, + locale, + resBundle + ); + } + + + /** + * + */ + public JRViewer400( + JasperReportsContext jasperReportsContext, + String fileName, + boolean isXML, + Locale locale, + ResourceBundle resBundle + ) throws JRException + { + this.jasperReportsContext = jasperReportsContext; + + initResources(locale, resBundle); + + setScreenDetails(); + + setZooms(); + + initComponents(); + + loadReport(fileName, isXML); + + cmbZoom.setSelectedIndex(defaultZoomIndex); + + initSaveContributors(); + + addHyperlinkListener(this); + } + + + /** + * + */ + public JRViewer400( + JasperReportsContext jasperReportsContext, + InputStream is, + boolean isXML, + Locale locale, + ResourceBundle resBundle + ) throws JRException + { + this.jasperReportsContext = jasperReportsContext; + + initResources(locale, resBundle); + + setScreenDetails(); + + setZooms(); + + initComponents(); + + loadReport(is, isXML); + + cmbZoom.setSelectedIndex(defaultZoomIndex); + + initSaveContributors(); + + addHyperlinkListener(this); + } + + + /** + * + */ + public JRViewer400( + JasperReportsContext jasperReportsContext, + JasperPrint jrPrint, + Locale locale, + ResourceBundle resBundle + ) + { + this.jasperReportsContext = jasperReportsContext; + + initResources(locale, resBundle); + + setScreenDetails(); + + setZooms(); + + initComponents(); + + loadReport(jrPrint); + + cmbZoom.setSelectedIndex(defaultZoomIndex); + + initSaveContributors(); + + addHyperlinkListener(this); + } + + /** + * + * @param jrPrint + */ + public void loadJasperPrint(JasperPrint jrPrint) { + + loadReport(jrPrint); + setZoomRatio(zooms[defaultZoomIndex] / 100f); + cmbZoomItemStateChanged(null); + refreshPage(); + } + + + private void setScreenDetails() + { + screenResolution = Toolkit.getDefaultToolkit().getScreenResolution(); + } + + + /** + * + */ + public void clear() + { + emptyContainer(this); + jasperPrint = null; + } + + + /** + * + */ + protected void setZooms() + { + } + + + /** + * + */ + public void addSaveContributor(JRSaveContributor contributor) + { + saveContributors.add(contributor); + } + + + /** + * + */ + public void removeSaveContributor(JRSaveContributor contributor) + { + saveContributors.remove(contributor); + } + + + /** + * + */ + public JRSaveContributor[] getSaveContributors() + { + return saveContributors.toArray(new JRSaveContributor[saveContributors.size()]); + } + + + /** + * Replaces the save contributors with the ones provided as parameter. + */ + public void setSaveContributors(JRSaveContributor[] saveContribs) + { + this.saveContributors = new ArrayList<JRSaveContributor>(); + if (saveContribs != null) + { + this.saveContributors.addAll(Arrays.asList(saveContribs)); + } + } + + + /** + * + */ + public void addHyperlinkListener(JRHyperlinkListener listener) + { + hyperlinkListeners.add(listener); + } + + + /** + * + */ + public void removeHyperlinkListener(JRHyperlinkListener listener) + { + hyperlinkListeners.remove(listener); + } + + + /** + * + */ + public JRHyperlinkListener[] getHyperlinkListeners() + { + return hyperlinkListeners.toArray(new JRHyperlinkListener[hyperlinkListeners.size()]); + } + + + /** + * + */ + protected void initResources(Locale locale, ResourceBundle resBundle) + { + //FIXME in theory, the setLocale method could be called after current Component was created, in which case all below should be reloaded + if (locale != null) + { + setLocale(locale); + } + else + { + setLocale(Locale.getDefault()); + } + if (resBundle == null) + { + this.resourceBundle = ResourceBundle.getBundle("net/sf/jasperreports/view/viewer", getLocale()); + } + else + { + this.resourceBundle = resBundle; + } + + zoomDecimalFormat = new DecimalFormat("#.##", DecimalFormatSymbols.getInstance(getLocale())); + } + + + /** + * + */ + protected JasperReportsContext getJasperReportsContext() + { + return jasperReportsContext; + } + + + /** + * + */ + protected String getBundleString(String key) + { + return resourceBundle.getString(key); + } + + + /** + * + */ + protected void initSaveContributors() + { + List<JRSaveContributor> builtinContributors = SaveContributorUtils.createBuiltinContributors( + jasperReportsContext, getLocale(), resourceBundle); + saveContributors.addAll(builtinContributors); + } + + + /** + * + */ + public void gotoHyperlink(JRPrintHyperlink hyperlink) + { + switch(hyperlink.getHyperlinkTypeValue()) + { + case REFERENCE : + { + if (isOnlyHyperlinkListener()) + { + System.out.println("Hyperlink reference : " + hyperlink.getHyperlinkReference()); + System.out.println("Implement your own JRHyperlinkListener to manage this type of event."); + } + break; + } + case LOCAL_ANCHOR : + { + if (hyperlink.getHyperlinkAnchor() != null) + { + Map<String,JRPrintAnchorIndex> anchorIndexes = jasperPrint.getAnchorIndexes(); + JRPrintAnchorIndex anchorIndex = anchorIndexes.get(hyperlink.getHyperlinkAnchor()); + if (anchorIndex.getPageIndex() != pageIndex) + { + setPageIndex(anchorIndex.getPageIndex()); + refreshPage(); + } + Container container = pnlInScroll.getParent(); + if (container instanceof JViewport) + { + JViewport viewport = (JViewport) container; + + int newX = (int)(anchorIndex.getElementAbsoluteX() * realZoom); + int newY = (int)(anchorIndex.getElementAbsoluteY() * realZoom); + + int maxX = pnlInScroll.getWidth() - viewport.getWidth(); + int maxY = pnlInScroll.getHeight() - viewport.getHeight(); + + if (newX < 0) + { + newX = 0; + } + if (newX > maxX) + { + newX = maxX; + } + if (newY < 0) + { + newY = 0; + } + if (newY > maxY) + { + newY = maxY; + } + + viewport.setViewPosition(new Point(newX, newY)); + } + } + + break; + } + case LOCAL_PAGE : + { + int page = pageIndex + 1; + if (hyperlink.getHyperlinkPage() != null) + { + page = hyperlink.getHyperlinkPage().intValue(); + } + + if (page >= 1 && page <= jasperPrint.getPages().size() && page != pageIndex + 1) + { + setPageIndex(page - 1); + refreshPage(); + Container container = pnlInScroll.getParent(); + if (container instanceof JViewport) + { + JViewport viewport = (JViewport) container; + viewport.setViewPosition(new Point(0, 0)); + } + } + + break; + } + case REMOTE_ANCHOR : + { + if (isOnlyHyperlinkListener()) + { + System.out.println("Hyperlink reference : " + hyperlink.getHyperlinkReference()); + System.out.println("Hyperlink anchor : " + hyperlink.getHyperlinkAnchor()); + System.out.println("Implement your own JRHyperlinkListener to manage this type of event."); + } + break; + } + case REMOTE_PAGE : + { + if (isOnlyHyperlinkListener()) + { + System.out.println("Hyperlink reference : " + hyperlink.getHyperlinkReference()); + System.out.println("Hyperlink page : " + hyperlink.getHyperlinkPage()); + System.out.println("Implement your own JRHyperlinkListener to manage this type of event."); + } + break; + } + case CUSTOM : + { + if (isOnlyHyperlinkListener()) + { + System.out.println("Hyperlink of type " + hyperlink.getLinkType()); + System.out.println("Implement your own JRHyperlinkListener to manage this type of event."); + } + break; + } + case NONE : + default : + { + break; + } + } + } + + + protected boolean isOnlyHyperlinkListener() + { + int listenerCount; + if (hyperlinkListeners == null) + { + listenerCount = 0; + } + else + { + listenerCount = hyperlinkListeners.size(); + if (hyperlinkListeners.contains(this)) + { + --listenerCount; + } + } + return listenerCount == 0; + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + jToolBar = new javax.swing.JToolBar(); + btnSave = new javax.swing.JButton(); + btnPrint = new javax.swing.JButton(); + btnReload = new javax.swing.JButton(); + jSeparator1 = new javax.swing.JToolBar.Separator(); + btnActualSize = new javax.swing.JToggleButton(); + btnFitPage = new javax.swing.JToggleButton(); + btnFitWidth = new javax.swing.JToggleButton(); + jSeparator2 = new javax.swing.JToolBar.Separator(); + btnZoomIn = new javax.swing.JButton(); + cmbZoom = new javax.swing.JComboBox(); + DefaultComboBoxModel model = new DefaultComboBoxModel(); + for(int i = 0; i < zooms.length; i++) + { + model.addElement("" + zooms[i] + "%"); + } + cmbZoom.setModel(model); + btnZoomOut = new javax.swing.JButton(); + jSeparator3 = new javax.swing.JToolBar.Separator(); + btnFirst = new javax.swing.JButton(); + btnPrevious = new javax.swing.JButton(); + txtGoTo = new javax.swing.JTextField(); + btnNext = new javax.swing.JButton(); + btnLast = new javax.swing.JButton(); + pnlMain = new javax.swing.JPanel(); + scrollPane = new javax.swing.JScrollPane(); + scrollPane.getHorizontalScrollBar().setUnitIncrement(5); + scrollPane.getVerticalScrollBar().setUnitIncrement(5); + pnlInScroll = new javax.swing.JPanel(); + pnlPage = new javax.swing.JPanel(); + jPanel4 = new javax.swing.JPanel(); + pnlLinks = new javax.swing.JPanel(); + jPanel5 = new javax.swing.JPanel(); + jPanel6 = new javax.swing.JPanel(); + jPanel7 = new javax.swing.JPanel(); + jPanel8 = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + jPanel9 = new javax.swing.JPanel(); + lblPage = new PageRenderer(this); + pnlTabs = new javax.swing.JTabbedPane(); + pnlStatus = new javax.swing.JPanel(); + lblStatus = new javax.swing.JLabel(); + + setMinimumSize(new java.awt.Dimension(450, 150)); + setPreferredSize(new java.awt.Dimension(450, 150)); + setLayout(new java.awt.BorderLayout()); + + jToolBar.setFloatable(false); + jToolBar.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + + btnSave.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/filesave.png"))); // NOI18N + btnSave.setToolTipText(getBundleString("save")); + btnSave.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnSaveActionPerformed(evt); + } + }); + jToolBar.add(btnSave); + + btnPrint.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/yast_printer.png"))); // NOI18N + btnPrint.setToolTipText(getBundleString("print")); + btnPrint.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnPrintActionPerformed(evt); + } + }); + jToolBar.add(btnPrint); + + btnReload.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/reload.png"))); // NOI18N + btnReload.setToolTipText(getBundleString("reload")); + btnReload.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnReloadActionPerformed(evt); + } + }); + jToolBar.add(btnReload); + jToolBar.add(jSeparator1); + + btnActualSize.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/mime.png"))); // NOI18N + btnActualSize.setToolTipText(getBundleString("actual.size")); + btnActualSize.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnActualSizeActionPerformed(evt); + } + }); + jToolBar.add(btnActualSize); + + btnFitPage.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/mime2.png"))); // NOI18N + btnFitPage.setToolTipText(getBundleString("fit.page")); + btnFitPage.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnFitPageActionPerformed(evt); + } + }); + jToolBar.add(btnFitPage); + + btnFitWidth.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/mime3.png"))); // NOI18N + btnFitWidth.setToolTipText(getBundleString("fit.width")); + btnFitWidth.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnFitWidthActionPerformed(evt); + } + }); + jToolBar.add(btnFitWidth); + jToolBar.add(jSeparator2); + + btnZoomIn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/viewmag+.png"))); // NOI18N + btnZoomIn.setToolTipText(getBundleString("zoom.in")); + btnZoomIn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnZoomInActionPerformed(evt); + } + }); + jToolBar.add(btnZoomIn); + + cmbZoom.setEditable(true); + cmbZoom.setToolTipText(getBundleString("zoom.ratio")); + cmbZoom.setMaximumSize(new java.awt.Dimension(80, 23)); + cmbZoom.setMinimumSize(new java.awt.Dimension(80, 23)); + cmbZoom.setPreferredSize(new java.awt.Dimension(80, 23)); + cmbZoom.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + cmbZoomItemStateChanged(evt); + } + }); + cmbZoom.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + cmbZoomActionPerformed(evt); + } + }); + jToolBar.add(cmbZoom); + + btnZoomOut.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/viewmag-.png"))); // NOI18N + btnZoomOut.setToolTipText(getBundleString("zoom.out")); + btnZoomOut.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnZoomOutActionPerformed(evt); + } + }); + jToolBar.add(btnZoomOut); + jToolBar.add(jSeparator3); + + btnFirst.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/2leftarrow.png"))); // NOI18N + btnFirst.setToolTipText(getBundleString("first.page")); + btnFirst.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnFirstActionPerformed(evt); + } + }); + jToolBar.add(btnFirst); + + btnPrevious.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/1leftarrow.png"))); // NOI18N + btnPrevious.setToolTipText(getBundleString("previous.page")); + btnPrevious.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnPreviousActionPerformed(evt); + } + }); + jToolBar.add(btnPrevious); + + txtGoTo.setToolTipText(getBundleString("go.to.page")); + txtGoTo.setMaximumSize(new java.awt.Dimension(40, 23)); + txtGoTo.setMinimumSize(new java.awt.Dimension(40, 23)); + txtGoTo.setPreferredSize(new java.awt.Dimension(40, 23)); + txtGoTo.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + txtGoToActionPerformed(evt); + } + }); + jToolBar.add(txtGoTo); + + btnNext.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/1rightarrow.png"))); // NOI18N + btnNext.setToolTipText(getBundleString("next.page")); + btnNext.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnNextActionPerformed(evt); + } + }); + jToolBar.add(btnNext); + + btnLast.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/2rightarrow.png"))); // NOI18N + btnLast.setToolTipText(getBundleString("last.page")); + btnLast.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnLastActionPerformed(evt); + } + }); + jToolBar.add(btnLast); + + add(jToolBar, java.awt.BorderLayout.NORTH); + + pnlMain.addComponentListener(new java.awt.event.ComponentAdapter() { + public void componentResized(java.awt.event.ComponentEvent evt) { + pnlMainComponentResized(evt); + } + }); + pnlMain.setLayout(new java.awt.BorderLayout()); + + scrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); + scrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + + pnlInScroll.setLayout(new java.awt.GridBagLayout()); + + pnlPage.setMinimumSize(new java.awt.Dimension(100, 100)); + pnlPage.setPreferredSize(new java.awt.Dimension(100, 100)); + pnlPage.setLayout(new java.awt.BorderLayout()); + + jPanel4.setMinimumSize(new java.awt.Dimension(100, 120)); + jPanel4.setPreferredSize(new java.awt.Dimension(100, 120)); + jPanel4.setLayout(new java.awt.GridBagLayout()); + + pnlLinks.setMinimumSize(new java.awt.Dimension(5, 5)); + pnlLinks.setOpaque(false); + pnlLinks.setPreferredSize(new java.awt.Dimension(5, 5)); + pnlLinks.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + pnlLinksMousePressed(evt); + } + public void mouseReleased(java.awt.event.MouseEvent evt) { + pnlLinksMouseReleased(evt); + } + }); + pnlLinks.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() { + public void mouseDragged(java.awt.event.MouseEvent evt) { + pnlLinksMouseDragged(evt); + } + }); + pnlLinks.setLayout(null); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.gridheight = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + jPanel4.add(pnlLinks, gridBagConstraints); + + jPanel5.setMinimumSize(new java.awt.Dimension(5, 5)); + jPanel5.setPreferredSize(new java.awt.Dimension(5, 5)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL; + jPanel4.add(jPanel5, gridBagConstraints); + + jPanel6.setMinimumSize(new java.awt.Dimension(5, 5)); + jPanel6.setPreferredSize(new java.awt.Dimension(5, 5)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 2; + jPanel4.add(jPanel6, gridBagConstraints); + + jPanel7.setMinimumSize(new java.awt.Dimension(5, 5)); + jPanel7.setPreferredSize(new java.awt.Dimension(5, 5)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + jPanel4.add(jPanel7, gridBagConstraints); + + jPanel8.setMinimumSize(new java.awt.Dimension(5, 5)); + jPanel8.setPreferredSize(new java.awt.Dimension(5, 5)); + + jLabel1.setText("jLabel1"); + jPanel8.add(jLabel1); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 2; + jPanel4.add(jPanel8, gridBagConstraints); + + jPanel9.setMinimumSize(new java.awt.Dimension(5, 5)); + jPanel9.setPreferredSize(new java.awt.Dimension(5, 5)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 0; + jPanel4.add(jPanel9, gridBagConstraints); + + lblPage.setFont(new java.awt.Font("Agency FB", 0, 12)); // NOI18N + lblPage.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); + lblPage.setOpaque(true); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.gridheight = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + jPanel4.add(lblPage, gridBagConstraints); + + pnlPage.add(jPanel4, java.awt.BorderLayout.CENTER); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); + pnlInScroll.add(pnlPage, gridBagConstraints); + + scrollPane.setViewportView(pnlInScroll); + + pnlMain.add(scrollPane, java.awt.BorderLayout.CENTER); + + pnlTabs.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + pnlTabsStateChanged(evt); + } + }); + pnlMain.add(pnlTabs, java.awt.BorderLayout.CENTER); + + add(pnlMain, java.awt.BorderLayout.CENTER); + + pnlStatus.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + pnlStatus.setPreferredSize(new java.awt.Dimension(59, 20)); + pnlStatus.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 0, 0)); + + lblStatus.setFont(new java.awt.Font("Arial", 1, 12)); // NOI18N + lblStatus.setText("Page i of n"); + lblStatus.setMaximumSize(new java.awt.Dimension(59, 18)); + pnlStatus.add(lblStatus); + + add(pnlStatus, java.awt.BorderLayout.SOUTH); + addKeyListener(keyNavigationListener); + }// </editor-fold>//GEN-END:initComponents + + void txtGoToActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtGoToActionPerformed + try + { + int pageNumber = Integer.parseInt(txtGoTo.getText()); + if ( + pageNumber != pageIndex + 1 + && pageNumber > 0 + && pageNumber <= jasperPrint.getPages().size() + ) + { + setPageIndex(pageNumber - 1); + refreshPage(); + } + } + catch(NumberFormatException e) + { + } + }//GEN-LAST:event_txtGoToActionPerformed + + void cmbZoomItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cmbZoomItemStateChanged + // Add your handling code here: + btnActualSize.setSelected(false); + btnFitPage.setSelected(false); + btnFitWidth.setSelected(false); + }//GEN-LAST:event_cmbZoomItemStateChanged + + void pnlMainComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_pnlMainComponentResized + // Add your handling code here: + if (btnFitPage.isSelected()) + { + fitPage(); + btnFitPage.setSelected(true); + } + else if (btnFitWidth.isSelected()) + { + setRealZoomRatio(((float)pnlInScroll.getVisibleRect().getWidth() - 20f) / getPageFormat().getPageWidth()); + btnFitWidth.setSelected(true); + } + + }//GEN-LAST:event_pnlMainComponentResized + + void btnActualSizeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnActualSizeActionPerformed + // Add your handling code here: + if (btnActualSize.isSelected()) + { + btnFitPage.setSelected(false); + btnFitWidth.setSelected(false); + cmbZoom.setSelectedIndex(-1); + setZoomRatio(1); + btnActualSize.setSelected(true); + } + }//GEN-LAST:event_btnActualSizeActionPerformed + + void btnFitWidthActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFitWidthActionPerformed + // Add your handling code here: + if (btnFitWidth.isSelected()) + { + btnActualSize.setSelected(false); + btnFitPage.setSelected(false); + cmbZoom.setSelectedIndex(-1); + setRealZoomRatio(((float)pnlInScroll.getVisibleRect().getWidth() - 20f) / getPageFormat().getPageWidth()); + btnFitWidth.setSelected(true); + } + }//GEN-LAST:event_btnFitWidthActionPerformed + + void btnFitPageActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFitPageActionPerformed + // Add your handling code here: + if (btnFitPage.isSelected()) + { + btnActualSize.setSelected(false); + btnFitWidth.setSelected(false); + cmbZoom.setSelectedIndex(-1); + fitPage(); + btnFitPage.setSelected(true); + } + }//GEN-LAST:event_btnFitPageActionPerformed + + void btnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveActionPerformed + // Add your handling code here: + + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setLocale(this.getLocale()); + fileChooser.updateUI(); + for(int i = 0; i < saveContributors.size(); i++) + { + fileChooser.addChoosableFileFilter(saveContributors.get(i)); + } + + if (saveContributors.contains(lastSaveContributor)) + { + fileChooser.setFileFilter(lastSaveContributor); + } + else if (saveContributors.size() > 0) + { + fileChooser.setFileFilter(saveContributors.get(0)); + } + + if (lastFolder != null) + { + fileChooser.setCurrentDirectory(lastFolder); + } + + int retValue = fileChooser.showSaveDialog(this); + if (retValue == JFileChooser.APPROVE_OPTION) + { + FileFilter fileFilter = fileChooser.getFileFilter(); + File file = fileChooser.getSelectedFile(); + + lastFolder = file.getParentFile(); + + JRSaveContributor contributor = null; + + if (fileFilter instanceof JRSaveContributor) + { + contributor = (JRSaveContributor)fileFilter; + } + else + { + int i = 0; + while(contributor == null && i < saveContributors.size()) + { + contributor = saveContributors.get(i++); + if (!contributor.accept(file)) + { + contributor = null; + } + } + + if (contributor == null) + { + contributor = new JRPrintSaveContributor(this.jasperReportsContext, getLocale(), this.resourceBundle); + } + } + + lastSaveContributor = contributor; + + try + { + contributor.save(jasperPrint, file); + } + catch (JRException e) + { + if (log.isErrorEnabled()) + { + log.error("Save error.", e); + } + JOptionPane.showMessageDialog(this, getBundleString("error.saving")); + } + } + }//GEN-LAST:event_btnSaveActionPerformed + + void pnlLinksMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_pnlLinksMouseDragged + // Add your handling code here: + + Container container = pnlInScroll.getParent(); + if (container instanceof JViewport) + { + JViewport viewport = (JViewport) container; + Point point = viewport.getViewPosition(); + int newX = point.x - (evt.getX() - downX); + int newY = point.y - (evt.getY() - downY); + + int maxX = pnlInScroll.getWidth() - viewport.getWidth(); + int maxY = pnlInScroll.getHeight() - viewport.getHeight(); + + if (newX < 0) + { + newX = 0; + } + if (newX > maxX) + { + newX = maxX; + } + if (newY < 0) + { + newY = 0; + } + if (newY > maxY) + { + newY = maxY; + } + + viewport.setViewPosition(new Point(newX, newY)); + } + }//GEN-LAST:event_pnlLinksMouseDragged + + void pnlLinksMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_pnlLinksMouseReleased + // Add your handling code here: + pnlLinks.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); + }//GEN-LAST:event_pnlLinksMouseReleased + + void pnlLinksMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_pnlLinksMousePressed + // Add your handling code here: + pnlLinks.setCursor(new Cursor(Cursor.MOVE_CURSOR)); + + downX = evt.getX(); + downY = evt.getY(); + }//GEN-LAST:event_pnlLinksMousePressed + + void btnPrintActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnPrintActionPerformed + {//GEN-HEADEREND:event_btnPrintActionPerformed +/** // Add your handling code here: + Thread thread = new Thread(new Runnable(){ + public void run(){ + try { + btnPrint.setEnabled(false); + JRViewer400.this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + JasperPrintManager.getInstance(jasperReportsContext).print(jasperPrint, true); + } catch (Exception ex) { + if (log.isErrorEnabled()) { + log.error("Print error.", ex); + } + JOptionPane.showMessageDialog(JRViewer400.this, getBundleString("error.printing")); + } finally { + JRViewer400.this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + btnPrint.setEnabled(true); + } + } + } + ); + thread.start(); +*/ + SwingUtilities.invokeLater( new Runnable() { + public void run() { + try { + btnPrint.setEnabled(false); + JRViewer400.this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + JasperPrintManager.printReport(jasperPrint, true); + } catch (Exception ex) { + ex.printStackTrace(); + JOptionPane.showMessageDialog(JRViewer400.this, getBundleString("error.printing")); + } + finally { + JRViewer400.this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + btnPrint.setEnabled(true); + } + } + } + ); + }//GEN-LAST:event_btnPrintActionPerformed + + void btnLastActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnLastActionPerformed + {//GEN-HEADEREND:event_btnLastActionPerformed + // Add your handling code here: + setPageIndex(jasperPrint.getPages().size() - 1); + refreshPage(); + }//GEN-LAST:event_btnLastActionPerformed + + void btnNextActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnNextActionPerformed + {//GEN-HEADEREND:event_btnNextActionPerformed + // Add your handling code here: + setPageIndex(pageIndex + 1); + refreshPage(); + }//GEN-LAST:event_btnNextActionPerformed + + void btnPreviousActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnPreviousActionPerformed + {//GEN-HEADEREND:event_btnPreviousActionPerformed + // Add your handling code here: + setPageIndex(pageIndex - 1); + refreshPage(); + }//GEN-LAST:event_btnPreviousActionPerformed + + void btnFirstActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnFirstActionPerformed + {//GEN-HEADEREND:event_btnFirstActionPerformed + // Add your handling code here: + setPageIndex(0); + refreshPage(); + }//GEN-LAST:event_btnFirstActionPerformed + + void btnReloadActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnReloadActionPerformed + {//GEN-HEADEREND:event_btnReloadActionPerformed + // Add your handling code here: + if (type == TYPE_FILE_NAME) + { + try + { + loadReport(reportFileName, isXML); + } + catch (JRException e) + { + if (log.isErrorEnabled()) + { + log.error("Reload error.", e); + } + jasperPrint = null; + refreshTabs(); + setPageIndex(0); + refreshPage(); + + JOptionPane.showMessageDialog(this, getBundleString("error.loading")); + } + + forceRefresh(); + } + }//GEN-LAST:event_btnReloadActionPerformed + + protected void forceRefresh() + { + zoom = 0;//force pageRefresh() + realZoom = 0f; + setZoomRatio(1); + } + + void btnZoomInActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnZoomInActionPerformed + {//GEN-HEADEREND:event_btnZoomInActionPerformed + // Add your handling code here: + btnActualSize.setSelected(false); + btnFitPage.setSelected(false); + btnFitWidth.setSelected(false); + + int newZoomInt = (int)(100 * getZoomRatio()); + int index = Arrays.binarySearch(zooms, newZoomInt); + if (index < 0) + { + setZoomRatio(zooms[- index - 1] / 100f); + } + else if (index < cmbZoom.getModel().getSize() - 1) + { + setZoomRatio(zooms[index + 1] / 100f); + } + }//GEN-LAST:event_btnZoomInActionPerformed + + void btnZoomOutActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnZoomOutActionPerformed + {//GEN-HEADEREND:event_btnZoomOutActionPerformed + // Add your handling code here: + btnActualSize.setSelected(false); + btnFitPage.setSelected(false); + btnFitWidth.setSelected(false); + + int newZoomInt = (int)(100 * getZoomRatio()); + int index = Arrays.binarySearch(zooms, newZoomInt); + if (index > 0) + { + setZoomRatio(zooms[index - 1] / 100f); + } + else if (index < -1) + { + setZoomRatio(zooms[- index - 2] / 100f); + } + }//GEN-LAST:event_btnZoomOutActionPerformed + + void cmbZoomActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cmbZoomActionPerformed + {//GEN-HEADEREND:event_cmbZoomActionPerformed + // Add your handling code here: + float newZoom = getZoomRatio(); + + if (newZoom < MIN_ZOOM) + { + newZoom = MIN_ZOOM; + } + + if (newZoom > MAX_ZOOM) + { + newZoom = MAX_ZOOM; + } + + setZoomRatio(newZoom); + }//GEN-LAST:event_cmbZoomActionPerformed + + private void pnlTabsStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_pnlTabsStateChanged + if (pnlTabsChangeListenerEnabled) + { + ((JPanel)pnlTabs.getSelectedComponent()).add(scrollPane); + + Integer pgIdx = 0; + + Integer partIndex = pnlTabs.getSelectedIndex(); + if (partIndex > 0) + { + PrintParts parts = jasperPrint == null ? null : jasperPrint.getParts(); + + if (parts != null && parts.hasParts()) + { + partIndex = parts.startsAtZero() ? partIndex : partIndex - 1; + pgIdx = parts.getStartPageIndex(partIndex); + } + } + + setPageIndex(pgIdx); + refreshPage(); + } + }//GEN-LAST:event_pnlTabsStateChanged + +/* private void pnlTabsStateChanged(javax.swing.event.ChangeEvent evt) { + if (pnlTabsChangeListenerEnabled) + { + ((JPanel)pnlTabs.getSelectedComponent()).add(scrollPane); + + Integer pgIdx = 0; + + Integer partIndex = pnlTabs.getSelectedIndex(); + if (partIndex > 0) + { + PrintParts parts = jasperPrint == null ? null : jasperPrint.getParts(); + + if (parts != null && parts.hasParts()) + { + partIndex = parts.startsAtZero() ? partIndex : partIndex - 1; + pgIdx = parts.getStartPageIndex(partIndex); + } + } + + setPageIndex(pgIdx); + refreshPage(); + } + } +*/ + + /** + */ + void hyperlinkClicked(MouseEvent evt) + { + JPanel link = (JPanel)evt.getSource(); + JRPrintHyperlink element = linksMap.get(link); + hyperlinkClicked(element); + } + + + protected void hyperlinkClicked(JRPrintHyperlink hyperlink) + { + try + { + JRHyperlinkListener listener = null; + for(int i = 0; i < hyperlinkListeners.size(); i++) + { + listener = hyperlinkListeners.get(i); + listener.gotoHyperlink(hyperlink); + } + } + catch(JRException e) + { + if (log.isErrorEnabled()) + { + log.error("Hyperlink click error.", e); + } + JOptionPane.showMessageDialog(this, getBundleString("error.hyperlink")); + } + } + + + /** + */ + public int getPageIndex() + { + return pageIndex; + } + + + /** + */ + private void setPageIndex(int index) + { + if ( + jasperPrint != null && + jasperPrint.getPages() != null && + jasperPrint.getPages().size() > 0 + ) + { + if (index >= 0 && index < jasperPrint.getPages().size()) + { + pageIndex = index; + pageError = false; + btnFirst.setEnabled( (pageIndex > 0) ); + btnPrevious.setEnabled( (pageIndex > 0) ); + btnNext.setEnabled( (pageIndex < jasperPrint.getPages().size() - 1) ); + btnLast.setEnabled( (pageIndex < jasperPrint.getPages().size() - 1) ); + txtGoTo.setEnabled(btnFirst.isEnabled() || btnLast.isEnabled()); + txtGoTo.setText("" + (pageIndex + 1)); + lblStatus.setText( + MessageFormat.format( + getBundleString("page"), + new Object[]{Integer.valueOf(pageIndex + 1), Integer.valueOf(jasperPrint.getPages().size())} + ) + ); + + if (jasperPrint.hasParts()) + { + PrintParts parts = jasperPrint.getParts(); + int partIndex = parts.getPartIndex(pageIndex); + int tabIndex = partIndex - (parts.startsAtZero() ? 1 : 0); + if (tabIndex < pnlTabs.getComponentCount()) + { + pnlTabsChangeListenerEnabled = false; + pnlTabs.setSelectedIndex(tabIndex); + ((JPanel)pnlTabs.getSelectedComponent()).add(scrollPane); + pnlTabsChangeListenerEnabled = true; + } + } + } + } + else + { + btnFirst.setEnabled(false); + btnPrevious.setEnabled(false); + btnNext.setEnabled(false); + btnLast.setEnabled(false); + txtGoTo.setEnabled(false); + txtGoTo.setText(""); + lblStatus.setText(""); + } + } + + + /** + */ + private PrintPageFormat getPageFormat() + { + return jasperPrint.getPageFormat(pageIndex); + } + + + /** + */ + protected void loadReport(String fileName, boolean isXmlReport) throws JRException + { + if (isXmlReport) + { + jasperPrint = JRPrintXmlLoader.loadFromFile(jasperReportsContext, fileName); + } + else + { + jasperPrint = (JasperPrint)JRLoader.loadObjectFromFile(fileName); + } + + refreshTabs(); + + type = TYPE_FILE_NAME; + this.isXML = isXmlReport; + reportFileName = fileName; + + SimpleFileResolver fileResolver = new SimpleFileResolver(Arrays.asList(new File[]{new File(fileName).getParentFile(), new File(".")})); + fileResolver.setResolveAbsolutePath(true); + if (localJasperReportsContext == null) + { + localJasperReportsContext = new LocalJasperReportsContext(jasperReportsContext); + jasperReportsContext = localJasperReportsContext; + } + localJasperReportsContext.setFileResolver(fileResolver); + + btnReload.setEnabled(true); + setPageIndex(0); + } + + + /** + */ + protected void loadReport(InputStream is, boolean isXmlReport) throws JRException + { + if (isXmlReport) + { + jasperPrint = JRPrintXmlLoader.load(jasperReportsContext, is); + } + else + { + jasperPrint = (JasperPrint)JRLoader.loadObject(is); + } + + refreshTabs(); + + type = TYPE_INPUT_STREAM; + this.isXML = isXmlReport; + btnReload.setEnabled(false); + setPageIndex(0); + } + + + /** + */ + protected void loadReport(JasperPrint jrPrint) + { + jasperPrint = jrPrint; + + refreshTabs(); + + type = TYPE_OBJECT; + isXML = false; + btnReload.setEnabled(false); + setPageIndex(0); + } + + + /** + */ + protected void refreshTabs() + { + pnlTabsChangeListenerEnabled = false; + + pnlTabs.removeAll(); + pnlMain.removeAll(); + + if (jasperPrint == null || !jasperPrint.hasParts()) + { + pnlMain.add(scrollPane, java.awt.BorderLayout.CENTER); + } + else + { + PrintParts parts = jasperPrint.getParts(); + if (!parts.startsAtZero()) + { + JPanel partTab = new JPanel(); + partTab.setLayout(new BorderLayout()); + partTab.setName(jasperPrint.getName()); + pnlTabs.add(partTab); + } + + for (Iterator<Map.Entry<Integer, PrintPart>> it = parts.partsIterator(); it.hasNext();) + { + PrintPart part = it.next().getValue(); + JPanel partTab = new JPanel(); + partTab.setLayout(new BorderLayout()); + partTab.setName(part.getName()); + pnlTabs.add(partTab); + } + + pnlMain.add(pnlTabs, java.awt.BorderLayout.CENTER); + } + + pnlTabsChangeListenerEnabled = true; + } + + + /** + */ + protected void refreshPage() + { + if ( + jasperPrint == null || + jasperPrint.getPages() == null || + jasperPrint.getPages().size() == 0 + ) + { + pnlPage.setVisible(false); + btnSave.setEnabled(false); + btnPrint.setEnabled(false); + btnActualSize.setEnabled(false); + btnFitPage.setEnabled(false); + btnFitWidth.setEnabled(false); + btnZoomIn.setEnabled(false); + btnZoomOut.setEnabled(false); + cmbZoom.setEnabled(false); + + if (jasperPrint != null) + { + JOptionPane.showMessageDialog(this, getBundleString("no.pages")); + } + + return; + } + + pnlPage.setVisible(true); + btnSave.setEnabled(true); + btnPrint.setEnabled(true); + btnActualSize.setEnabled(true); + btnFitPage.setEnabled(true); + btnFitWidth.setEnabled(true); + btnZoomIn.setEnabled(zoom < MAX_ZOOM); + btnZoomOut.setEnabled(zoom > MIN_ZOOM); + cmbZoom.setEnabled(true); + + PrintPageFormat pageFormat = getPageFormat(); + + Dimension dim = new Dimension( + (int)(pageFormat.getPageWidth() * realZoom) + 8, // 2 from border, 5 from shadow and 1 extra pixel for image + (int)(pageFormat.getPageHeight() * realZoom) + 8 + ); + pnlPage.setMaximumSize(dim); + pnlPage.setMinimumSize(dim); + pnlPage.setPreferredSize(dim); + + long maxImageSize = JRPropertiesUtil.getInstance(jasperReportsContext).getLongProperty(VIEWER_RENDER_BUFFER_MAX_SIZE); + boolean renderImage; + if (maxImageSize <= 0) + { + renderImage = false; + } + else + { + long imageSize = ((int) (pageFormat.getPageWidth() * realZoom) + 1) * ((int) (pageFormat.getPageHeight() * realZoom) + 1); + renderImage = imageSize <= maxImageSize; + } + + ((PageRenderer)lblPage).setRenderImage(renderImage); + + if (renderImage) + { + setPageImage(); + } + + pnlLinks.removeAll(); + linksMap = new HashMap<JPanel,JRPrintHyperlink>(); + + createHyperlinks(); + + if (!renderImage) + { + lblPage.setIcon(null); + + pnlMain.validate(); + pnlMain.repaint(); + } + } + + + protected void setPageImage() + { + Image image; + if (pageError) + { + image = getPageErrorImage(); + } + else + { + try + { + image = JasperPrintManager.getInstance(jasperReportsContext).printToImage(jasperPrint, pageIndex, realZoom); + } + catch (Exception e) + { + if (log.isErrorEnabled()) + { + log.error("Print page to image error.", e); + } + pageError = true; + + image = getPageErrorImage(); + JOptionPane.showMessageDialog(this, java.util.ResourceBundle.getBundle("net/sf/jasperreports/view/viewer").getString("error.displaying")); + } + } + ImageIcon imageIcon = new ImageIcon(image); + lblPage.setIcon(imageIcon); + } + + protected Image getPageErrorImage() + { + PrintPageFormat pageFormat = getPageFormat(); + Image image = new BufferedImage( + (int) (pageFormat.getPageWidth() * realZoom) + 1, + (int) (pageFormat.getPageHeight() * realZoom) + 1, + BufferedImage.TYPE_INT_RGB + ); + + Graphics2D grx = (Graphics2D) image.getGraphics(); + AffineTransform transform = new AffineTransform(); + transform.scale(realZoom, realZoom); + grx.transform(transform); + + drawPageError(grx); + + return image; + } + + protected void createHyperlinks() + { + List<JRPrintPage> pages = jasperPrint.getPages(); + JRPrintPage page = pages.get(pageIndex); + createHyperlinks(page.getElements(), 0, 0); + } + + protected void createHyperlinks(List<JRPrintElement> elements, int offsetX, int offsetY) + { + if(elements != null && elements.size() > 0) + { + for(Iterator<JRPrintElement> it = elements.iterator(); it.hasNext();) + { + JRPrintElement element = it.next(); + + ImageMapRenderable imageMap = null; + if (element instanceof JRPrintImage) + { + Renderable renderer = ((JRPrintImage) element).getRenderable(); + if (renderer instanceof ImageMapRenderable) + { + imageMap = (ImageMapRenderable) renderer; + if (!imageMap.hasImageAreaHyperlinks()) + { + imageMap = null; + } + } + } + boolean hasImageMap = imageMap != null; + + JRPrintHyperlink hyperlink = null; + if (element instanceof JRPrintHyperlink) + { + hyperlink = (JRPrintHyperlink) element; + } + boolean hasHyperlink = !hasImageMap + && hyperlink != null && hyperlink.getHyperlinkTypeValue() != HyperlinkTypeEnum.NONE; + boolean hasTooltip = hyperlink != null && hyperlink.getHyperlinkTooltip() != null; + + if (hasHyperlink || hasImageMap || hasTooltip) + { + JPanel link; + if (hasImageMap) + { + Rectangle renderingArea = new Rectangle(0, 0, element.getWidth(), element.getHeight()); + link = new ImageMapPanel(renderingArea, imageMap); + } + else //hasImageMap + { + link = new JPanel(); + if (hasHyperlink) + { + link.addMouseListener(mouseListener); + } + } + + if (hasHyperlink) + { + link.setCursor(new Cursor(Cursor.HAND_CURSOR)); + } + + link.setLocation( + (int)((element.getX() + offsetX) * realZoom), + (int)((element.getY() + offsetY) * realZoom) + ); + link.setSize( + (int)(element.getWidth() * realZoom), + (int)(element.getHeight() * realZoom) + ); + link.setOpaque(false); + + String toolTip = getHyperlinkTooltip(hyperlink); + if (toolTip == null && hasImageMap) + { + toolTip = "";//not null to register the panel as having a tool tip + } + link.setToolTipText(toolTip); + + pnlLinks.add(link); + linksMap.put(link, hyperlink); + } + + if (element instanceof JRPrintFrame) + { + JRPrintFrame frame = (JRPrintFrame) element; + int frameOffsetX = offsetX + frame.getX() + frame.getLineBox().getLeftPadding().intValue(); + int frameOffsetY = offsetY + frame.getY() + frame.getLineBox().getTopPadding().intValue(); + createHyperlinks(frame.getElements(), frameOffsetX, frameOffsetY); + } + } + } + } + + + protected class ImageMapPanel extends JPanel implements MouseListener, MouseMotionListener + { + private static final long serialVersionUID = JRConstants.SERIAL_VERSION_UID; + + protected final List<JRPrintImageAreaHyperlink> imageAreaHyperlinks; + + public ImageMapPanel(Rectangle renderingArea, ImageMapRenderable imageMap) + { + try + { + imageAreaHyperlinks = imageMap.getImageAreaHyperlinks(renderingArea);//FIXMECHART + } + catch (JRException e) + { + throw new JRRuntimeException(e); + } + + addMouseListener(this); + addMouseMotionListener(this); + } + + public String getToolTipText(MouseEvent event) + { + String tooltip = null; + JRPrintImageAreaHyperlink imageMapArea = getImageMapArea(event); + if (imageMapArea != null) + { + tooltip = getHyperlinkTooltip(imageMapArea.getHyperlink()); + } + + if (tooltip == null) + { + tooltip = super.getToolTipText(event); + } + + return tooltip; + } + + public void mouseDragged(MouseEvent e) + { + pnlLinksMouseDragged(e); + } + + public void mouseMoved(MouseEvent e) + { + JRPrintImageAreaHyperlink imageArea = getImageMapArea(e); + if (imageArea != null + && imageArea.getHyperlink().getHyperlinkTypeValue() != HyperlinkTypeEnum.NONE) + { + e.getComponent().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } + else + { + e.getComponent().setCursor(Cursor.getDefaultCursor()); + } + } + + protected JRPrintImageAreaHyperlink getImageMapArea(MouseEvent e) + { + return getImageMapArea((int) (e.getX() / realZoom), (int) (e.getY() / realZoom)); + } + + protected JRPrintImageAreaHyperlink getImageMapArea(int x, int y) + { + JRPrintImageAreaHyperlink image = null; + if (imageAreaHyperlinks != null) + { + for (ListIterator<JRPrintImageAreaHyperlink> it = imageAreaHyperlinks.listIterator(imageAreaHyperlinks.size()); image == null && it.hasPrevious();) + { + JRPrintImageAreaHyperlink area = it.previous(); + if (area.getArea().containsPoint(x, y)) + { + image = area; + } + } + } + return image; + } + + public void mouseClicked(MouseEvent e) + { + JRPrintImageAreaHyperlink imageMapArea = getImageMapArea(e); + if (imageMapArea != null) + { + hyperlinkClicked(imageMapArea.getHyperlink()); + } + } + + public void mouseEntered(MouseEvent e) + { + } + + public void mouseExited(MouseEvent e) + { + } + + public void mousePressed(MouseEvent e) + { + e.getComponent().setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); + pnlLinksMousePressed(e); + } + + public void mouseReleased(MouseEvent e) + { + e.getComponent().setCursor(Cursor.getDefaultCursor()); + pnlLinksMouseReleased(e); + } + } + + + protected String getHyperlinkTooltip(JRPrintHyperlink hyperlink) + { + String toolTip; + toolTip = hyperlink.getHyperlinkTooltip(); + if (toolTip == null) + { + toolTip = getFallbackTooltip(hyperlink); + } + return toolTip; + } + + + protected String getFallbackTooltip(JRPrintHyperlink hyperlink) + { + String toolTip = null; + switch(hyperlink.getHyperlinkTypeValue()) + { + case REFERENCE : + { + toolTip = hyperlink.getHyperlinkReference(); + break; + } + case LOCAL_ANCHOR : + { + if (hyperlink.getHyperlinkAnchor() != null) + { + toolTip = "#" + hyperlink.getHyperlinkAnchor(); + } + break; + } + case LOCAL_PAGE : + { + if (hyperlink.getHyperlinkPage() != null) + { + toolTip = "#page " + hyperlink.getHyperlinkPage(); + } + break; + } + case REMOTE_ANCHOR : + { + toolTip = ""; + if (hyperlink.getHyperlinkReference() != null) + { + toolTip = toolTip + hyperlink.getHyperlinkReference(); + } + if (hyperlink.getHyperlinkAnchor() != null) + { + toolTip = toolTip + "#" + hyperlink.getHyperlinkAnchor(); + } + break; + } + case REMOTE_PAGE : + { + toolTip = ""; + if (hyperlink.getHyperlinkReference() != null) + { + toolTip = toolTip + hyperlink.getHyperlinkReference(); + } + if (hyperlink.getHyperlinkPage() != null) + { + toolTip = toolTip + "#page " + hyperlink.getHyperlinkPage(); + } + break; + } + default : + { + break; + } + } + return toolTip; + } + + + /** + */ + private void emptyContainer(Container container) + { + Component[] components = container.getComponents(); + + if (components != null) + { + for(int i = 0; i < components.length; i++) + { + if (components[i] instanceof Container) + { + emptyContainer((Container)components[i]); + } + } + } + + components = null; + container.removeAll(); + container = null; + } + + + /** + */ + private float getZoomRatio() + { + float newZoom = zoom; + + try + { + newZoom = + zoomDecimalFormat.parse( + String.valueOf(cmbZoom.getEditor().getItem()) + ).floatValue() / 100f; + } + catch(ParseException e) + { + } + + return newZoom; + } + + + /** + */ + public void setZoomRatio(float newZoom) + { + if (newZoom > 0) + { + cmbZoom.getEditor().setItem( + zoomDecimalFormat.format(newZoom * 100) + "%" + ); + + if (zoom != newZoom) + { + zoom = newZoom; + realZoom = zoom * screenResolution / REPORT_RESOLUTION; + + refreshPage(); + } + } + } + + + /** + */ + private void setRealZoomRatio(float newZoom) + { + if (newZoom > 0 && realZoom != newZoom) + { + zoom = newZoom * REPORT_RESOLUTION / screenResolution; + realZoom = newZoom; + + cmbZoom.getEditor().setItem( + zoomDecimalFormat.format(zoom * 100) + "%" + ); + + refreshPage(); + } + } + + + /** + * + */ + public void setFitWidthZoomRatio() + { + setRealZoomRatio(((float)pnlInScroll.getVisibleRect().getWidth() - 20f) / getPageFormat().getPageWidth()); + + } + + public void setFitPageZoomRatio() + { + setRealZoomRatio(((float)pnlInScroll.getVisibleRect().getHeight() - 20f) / getPageFormat().getPageHeight()); + } + + + /** + * + */ + protected JRGraphics2DExporter getGraphics2DExporter() throws JRException + { + return new JRGraphics2DExporter(jasperReportsContext); + } + + /** + * + */ + protected void paintPage(Graphics2D grx) + { + if (pageError) + { + paintPageError(grx); + return; + } + + try + { + if (exporter == null) + { + exporter = getGraphics2DExporter(); + } + else + { + exporter.reset(); + } + + exporter.setExporterInput(new SimpleExporterInput(jasperPrint)); + SimpleGraphics2DExporterOutput output = new SimpleGraphics2DExporterOutput(); + output.setGraphics2D((Graphics2D)grx.create()); + exporter.setExporterOutput(output); + SimpleGraphics2DReportConfiguration configuration = new SimpleGraphics2DReportConfiguration(); + configuration.setPageIndex(pageIndex); + configuration.setZoomRatio(realZoom); + configuration.setOffsetX(1); //lblPage border + configuration.setOffsetY(1); + exporter.setConfiguration(configuration); + exporter.exportReport(); + } + catch(Exception e) + { + if (log.isErrorEnabled()) + { + log.error("Page paint error.", e); + } + pageError = true; + + paintPageError(grx); + SwingUtilities.invokeLater(new Runnable() + { + public void run() + { + JOptionPane.showMessageDialog(JRViewer400.this, getBundleString("error.displaying")); + } + }); + } + + } + + protected void paintPageError(Graphics2D grx) + { + AffineTransform origTransform = grx.getTransform(); + + AffineTransform transform = new AffineTransform(); + transform.translate(1, 1); + transform.scale(realZoom, realZoom); + grx.transform(transform); + + try + { + drawPageError(grx); + } + finally + { + grx.setTransform(origTransform); + } + } + + protected void drawPageError(Graphics grx) + { + PrintPageFormat pageFormat = getPageFormat(); + grx.setColor(Color.white); + grx.fillRect(0, 0, pageFormat.getPageWidth() + 1, pageFormat.getPageHeight() + 1); + } + + protected void keyNavigate(KeyEvent evt) + { + boolean refresh = true; + switch (evt.getKeyCode()) + { + case KeyEvent.VK_DOWN: + case KeyEvent.VK_PAGE_DOWN: + dnNavigate(evt); + break; + case KeyEvent.VK_UP: + case KeyEvent.VK_PAGE_UP: + upNavigate(evt); + break; + case KeyEvent.VK_HOME: + homeEndNavigate(0); + break; + case KeyEvent.VK_END: + homeEndNavigate(jasperPrint.getPages().size() - 1); + break; + default: + refresh = false; + } + + if (refresh) + { + refreshPage(); + } + } + + private void dnNavigate(KeyEvent evt) + { + int bottomPosition = scrollPane.getVerticalScrollBar().getValue(); + scrollPane.dispatchEvent(evt); + if((scrollPane.getViewport().getHeight() > pnlPage.getHeight() || + scrollPane.getVerticalScrollBar().getValue() == bottomPosition) && + pageIndex < jasperPrint.getPages().size() - 1) + { + setPageIndex(pageIndex + 1); + if(scrollPane.isEnabled()) + { + scrollPane.getVerticalScrollBar().setValue(0); + } + } + } + + private void upNavigate(KeyEvent evt) + { + if((scrollPane.getViewport().getHeight() > pnlPage.getHeight() || + scrollPane.getVerticalScrollBar().getValue() == 0) && + pageIndex > 0) + { + setPageIndex(pageIndex - 1); + if(scrollPane.isEnabled()) + { + scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getMaximum()); + } + } + else + { + scrollPane.dispatchEvent(evt); + } + } + + private void homeEndNavigate(int pageNumber) + { + setPageIndex(pageNumber); + if(scrollPane.isEnabled()) + { + scrollPane.getVerticalScrollBar().setValue(0); + } + } + + /** + * + */ + private void fitPage(){ + PrintPageFormat pageFormat = getPageFormat(); + float heightRatio = ((float)pnlInScroll.getVisibleRect().getHeight() - 20f) / pageFormat.getPageHeight(); + float widthRatio = ((float)pnlInScroll.getVisibleRect().getWidth() - 20f) / pageFormat.getPageWidth(); + setRealZoomRatio(heightRatio < widthRatio ? heightRatio : widthRatio); + } + + /** + */ + class PageRenderer extends JLabel + { + private static final long serialVersionUID = JRConstants.SERIAL_VERSION_UID; + + private boolean renderImage; + JRViewer400 viewer = null; + + public PageRenderer(JRViewer400 viewer) + { + this.viewer = viewer; + } + + public void paintComponent(Graphics g) + { + if (isRenderImage()) + { + super.paintComponent(g); + } + else + { + viewer.paintPage((Graphics2D)g.create()); + } + } + + public boolean isRenderImage() + { + return renderImage; + } + + public void setRenderImage(boolean renderImage) + { + this.renderImage = renderImage; + } + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + protected javax.swing.JToggleButton btnActualSize; + protected javax.swing.JButton btnFirst; + protected javax.swing.JToggleButton btnFitPage; + protected javax.swing.JToggleButton btnFitWidth; + protected javax.swing.JButton btnLast; + protected javax.swing.JButton btnNext; + protected javax.swing.JButton btnPrevious; + protected javax.swing.JButton btnPrint; + protected javax.swing.JButton btnReload; + protected javax.swing.JButton btnSave; + protected javax.swing.JButton btnZoomIn; + protected javax.swing.JButton btnZoomOut; + protected javax.swing.JComboBox cmbZoom; + private javax.swing.JLabel jLabel1; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JPanel jPanel6; + private javax.swing.JPanel jPanel7; + private javax.swing.JPanel jPanel8; + private javax.swing.JPanel jPanel9; + private javax.swing.JToolBar.Separator jSeparator1; + private javax.swing.JToolBar.Separator jSeparator2; + private javax.swing.JToolBar.Separator jSeparator3; + private javax.swing.JToolBar jToolBar; + private javax.swing.JLabel lblPage; + protected javax.swing.JLabel lblStatus; + private javax.swing.JPanel pnlInScroll; + private javax.swing.JPanel pnlLinks; + private javax.swing.JPanel pnlMain; + private javax.swing.JPanel pnlPage; + protected javax.swing.JPanel pnlStatus; + private javax.swing.JTabbedPane pnlTabs; + private javax.swing.JScrollPane scrollPane; + protected javax.swing.JTextField txtGoTo; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/util/LabelIcon.java b/src/main/java/com/unicenta/pos/util/LabelIcon.java new file mode 100644 index 0000000..4a8df97 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/LabelIcon.java @@ -0,0 +1,82 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2017 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.util; + +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import javax.swing.Icon; +import javax.swing.JLabel; + +/** + * + * @author adrianromero + */ +public class LabelIcon extends JLabel implements Icon { + + private int iconwidth; + private int iconheight; + + /** + * + * @param width + * @param height + */ + public LabelIcon(int width, int height) { + iconwidth = width; + iconheight = height; + } + + /** + * + * @param mywidth + * @param myheight + * @return + */ + public BufferedImage getImage(int mywidth, int myheight) { + + BufferedImage imgtext = new BufferedImage(mywidth, myheight, BufferedImage.TYPE_INT_ARGB); + Graphics2D g2d = imgtext.createGraphics(); + + setBounds(0, 0, mywidth, myheight); + paint(g2d); + g2d.dispose(); + + return imgtext; + } + + public void paintIcon(Component c, Graphics g, int x, int y) { + + setBounds(0, 0, iconwidth, iconheight); + g.translate(x, y); + paint(g); + g.translate(-x, -y); + } + + public int getIconWidth() { + return iconwidth; + } + + public int getIconHeight() { + return iconheight; + } + +} diff --git a/src/main/java/com/unicenta/pos/util/LuhnAlgorithm.java b/src/main/java/com/unicenta/pos/util/LuhnAlgorithm.java new file mode 100644 index 0000000..271f574 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/LuhnAlgorithm.java @@ -0,0 +1,62 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2017 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.util; + +/** + * + * @author Mikel Irurita + */ +public class LuhnAlgorithm { + + /** Creates a new instance of LuhnAlgorithm */ + private LuhnAlgorithm() { + } + + /** + * + * @param cardNumber + * @return + */ + public static boolean checkCC(String cardNumber){ + int sum = 0; + + int flip = 0; + + if ( !StringUtils.isNumber(cardNumber) ){ + return false; + } + + for (int i = cardNumber.length() -1; i >= 0; i--) { + int k = Character.digit(cardNumber.charAt(i), 10); + flip ++; + + if ( flip % 2 == 0 ) { + k *= 2; + if (k > 9) { + k -= 9; + } + } + sum += k; + } + return (sum % 10 == 0); + } + +} + diff --git a/src/main/java/com/unicenta/pos/util/NewFXMain.java b/src/main/java/com/unicenta/pos/util/NewFXMain.java new file mode 100644 index 0000000..dca5882 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/NewFXMain.java @@ -0,0 +1,51 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.unicenta.pos.util; + +import javafx.application.Application; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.layout.StackPane; +import javafx.stage.Stage; + +/** + * + * @author user + */ +public class NewFXMain extends Application { + + @Override + public void start(Stage primaryStage) { + Button btn = new Button(); + btn.setText("Say 'Hello World'"); + btn.setOnAction(new EventHandler<ActionEvent>() { + + @Override + public void handle(ActionEvent event) { + System.out.println("Hello World!"); + } + }); + + StackPane root = new StackPane(); + root.getChildren().add(btn); + + Scene scene = new Scene(root, 300, 250); + + primaryStage.setTitle("Hello World!"); + primaryStage.setScene(scene); + primaryStage.show(); + } + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + launch(args); + } + +} diff --git a/src/main/java/com/unicenta/pos/util/NewFXSwingMain.java b/src/main/java/com/unicenta/pos/util/NewFXSwingMain.java new file mode 100644 index 0000000..fa0e1f5 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/NewFXSwingMain.java @@ -0,0 +1,98 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.unicenta.pos.util; + +import java.awt.BorderLayout; +import java.awt.Dimension; + +import com.formdev.flatlaf.FlatLightLaf; +import javafx.application.Platform; +import javafx.embed.swing.JFXPanel; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.layout.StackPane; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.JApplet; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +/** + * + * @author user + */ +@Slf4j +public class NewFXSwingMain extends JApplet { + + private static final int JFXPANEL_WIDTH_INT = 300; + private static final int JFXPANEL_HEIGHT_INT = 250; + private static JFXPanel fxContainer; + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + try { + UIManager.setLookAndFeel(new FlatLightLaf()); + } catch (Exception e) { + log.error("Error setting LAF "+e.getMessage()); + } + + JFrame frame = new JFrame("JavaFX 2 in Swing"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + JApplet applet = new NewFXSwingMain(); + applet.init(); + + frame.setContentPane(applet.getContentPane()); + + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + + applet.start(); + } + }); + } + + @Override + public void init() { + fxContainer = new JFXPanel(); + fxContainer.setPreferredSize(new Dimension(JFXPANEL_WIDTH_INT, JFXPANEL_HEIGHT_INT)); + add(fxContainer, BorderLayout.CENTER); + // create JavaFX scene + Platform.runLater(new Runnable() { + + @Override + public void run() { + createScene(); + } + }); + } + + private void createScene() { + Button btn = new Button(); + btn.setText("Say 'Hello World'"); + btn.setOnAction(new EventHandler<ActionEvent>() { + + @Override + public void handle(ActionEvent event) { + System.out.println("Hello World!"); + } + }); + StackPane root = new StackPane(); + root.getChildren().add(btn); + fxContainer.setScene(new Scene(root)); + } + +} diff --git a/src/main/java/com/unicenta/pos/util/OSValidator.java b/src/main/java/com/unicenta/pos/util/OSValidator.java new file mode 100644 index 0000000..53a0b00 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/OSValidator.java @@ -0,0 +1,76 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.unicenta.pos.util; + +/** + * + * @author JG uniCenta + */ +public class OSValidator { + + private String OS = System.getProperty("os.name").toLowerCase(); + + /** + * + */ + public OSValidator() { + + } + + /** + * + * @return + */ + public String getOS(){ + if (isWindows()) { + return("w"); + } else if (isMac()) { + return("m"); + } else if (isUnix()) { + return("l"); + } else if (isSolaris()) { + return("s"); + } else { + return("x"); + } + } + + /** + * + * @return + */ + public boolean isWindows() { + return (OS.contains("win")); + } + + /** + * + * @return + */ + public boolean isMac() { + return (OS.contains("mac")); + } + + /** + * + * @return + */ + public boolean isUnix() { + return (OS.contains("nix") || OS.contains("nux") || OS.indexOf("aix") > 0 ); + } + + /** + * + * @return + */ + public boolean isSolaris() { + return (OS.contains("sunos")); + } + + + + + +} diff --git a/src/main/java/com/unicenta/pos/util/PropertyUtils.java b/src/main/java/com/unicenta/pos/util/PropertyUtils.java new file mode 100644 index 0000000..18a4d66 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/PropertyUtils.java @@ -0,0 +1,98 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.unicenta.pos.util; + +/** +* +* @author Xibergy Systems +*/ + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +/** + * + * @author JG uniCenta + */ +public class PropertyUtils { + + private Properties m_propsconfig; + private File configFile; + private final String APP_ID = "upos-app"; + + /** + * + */ + public PropertyUtils() { + init(getDefaultConfig()); + } + + private void init(File configfile) { + this.configFile = configfile; + load(); + } + + private File getDefaultConfig() { + return new File(new File("C:\\Documents and Settings\\jack"), "unicentaopos.properties"); + } + + private void load() { + // Load Properties + try { + InputStream in = new FileInputStream(configFile); + if (in != null) { + m_propsconfig = new Properties(); + m_propsconfig.load(in); + in.close(); + } + } catch (IOException e) { + } + } + + /** + * + * @param sKey + * @return + */ + public String getProperty(String sKey) { + return m_propsconfig.getProperty(sKey); + } + + /** + * + * @return + */ + public String getDriverName() { + return m_propsconfig.getProperty("db.driver"); + } + + /** + * + * @return + */ + public String getUrl() { + return m_propsconfig.getProperty("db.URL"); + } + + /** + * + * @return + */ + public String getDBUser() { + return m_propsconfig.getProperty("db.user"); + } + + /** + * + * @return + */ + public String getDBPassword() { + String m_password = "[color=#FF0000]YourDBPassword[/color]"; + return m_password; + } +} diff --git a/src/main/java/com/unicenta/pos/util/ReportUtils.java b/src/main/java/com/unicenta/pos/util/ReportUtils.java new file mode 100644 index 0000000..f5bf5c0 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/ReportUtils.java @@ -0,0 +1,82 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2017 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + + +package com.unicenta.pos.util; + +import javax.print.DocFlavor; +import javax.print.PrintService; +import javax.print.PrintServiceLookup; + +/** + * + * @author adrianromero + */ +public class ReportUtils { + + private ReportUtils() { + } + + /** + * + * @param printername + * @return + */ + public static PrintService getPrintService(String printername) { + + // Initalize print service + + if (printername == null) { + return PrintServiceLookup.lookupDefaultPrintService(); + } else { + + if ("(Show dialog)".equals(printername)) { + return null; // null means "you have to show the print dialog" + } else if ("(Default)".equals(printername)) { + return PrintServiceLookup.lookupDefaultPrintService(); + } else { + PrintService[] pservices = + PrintServiceLookup.lookupPrintServices(DocFlavor.SERVICE_FORMATTED.PRINTABLE , null); + for (PrintService s : pservices) { + if (printername.equals(s.getName())) { + return s; + } + } + return PrintServiceLookup.lookupDefaultPrintService(); + } + } + } + + /** + * + * @return + */ + public static String[] getPrintNames() { + PrintService[] pservices = + PrintServiceLookup.lookupPrintServices(DocFlavor.SERVICE_FORMATTED.PRINTABLE , null); + + String printers[] = new String[pservices.length]; + for (int i = 0; i < pservices.length; i++) { + printers[i] = pservices[i].getName(); + } + + return printers; + } + +} diff --git a/src/main/java/com/unicenta/pos/util/ReturnInfo.java b/src/main/java/com/unicenta/pos/util/ReturnInfo.java new file mode 100644 index 0000000..2bbe5eb --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/ReturnInfo.java @@ -0,0 +1,87 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.unicenta.pos.util; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.IKeyed; +import com.unicenta.data.loader.SerializableRead; +import com.unicenta.data.loader.SerializerRead; + +/** + * + * @author JA - based on A Escartin Barcode + * 15 Dec 2013 + */ +public class ReturnInfo implements SerializableRead, IKeyed { + + private static final long serialVersionUID = 8906929819402L; + private Integer idret; + + /** + * + */ + public ReturnInfo() { + idret = null; + } + + /** + * + * @return + */ + @Override + public Object getKey() { + return idret; + } + + /** + * + * @param dr + * @throws BasicException + */ + @Override + public void readValues(DataRead dr) throws BasicException { + idret = dr.getInt(1); + } + + /** + * + * @param id + */ + public void setId(Integer id) { + idret = id; + } + + /** + * + * @return + */ + public Integer getId() { + return idret; + } + + /** + * + * @return + */ + public static SerializerRead getSerializerRead() { + return new SerializerRead() { + @Override + public Object readValues(DataRead dr) throws BasicException { + return new ReturnInfo( + dr.getInt(1)); + } + }; + } + + /** + * + * @param id + */ + public ReturnInfo(Integer id) { + this.idret = id; + } + +} diff --git a/src/main/java/com/unicenta/pos/util/RoundUtils.java b/src/main/java/com/unicenta/pos/util/RoundUtils.java new file mode 100644 index 0000000..5fc8832 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/RoundUtils.java @@ -0,0 +1,63 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2016 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.util; + +import com.unicenta.format.Formats; + +/** + * + * @author JG uniCenta + */ +public class RoundUtils { + + /** Creates a new instance of DoubleUtils */ + private RoundUtils() { + } + + /** + * + * @param dValue + * @return + */ + public static double round(double dValue) { + double fractionMultiplier = Math.pow(10.0, Formats.getCurrencyDecimals()); + return Math.rint(dValue * fractionMultiplier) / fractionMultiplier; + } + + /** + * + * @param d1 + * @param d2 + * @return + */ + public static int compare(double d1, double d2) { + + return Double.compare(round(d1), round(d2)); + } + + /** + * + * @param value + * @return + */ + public static double getValue(Double value) { + return value == null ? 0.0 : value.doubleValue(); + } +} diff --git a/src/main/java/com/unicenta/pos/util/SelectPrinter.form b/src/main/java/com/unicenta/pos/util/SelectPrinter.form new file mode 100644 index 0000000..bcd9b82 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/SelectPrinter.form @@ -0,0 +1,163 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="form.selectprintertitle" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-72,0,0,1,97"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jPanel2" min="-2" max="-2" attributes="0"/> + <Component id="jPanel8" alignment="0" min="-2" pref="345" max="-2" attributes="0"/> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jPanel1" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jPanel2" min="-2" max="-2" attributes="0"/> + <EmptySpace min="0" pref="0" max="-2" attributes="0"/> + <Component id="jPanel8" min="-2" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + <Component id="jPanel1" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel8"> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + </Container> + <Container class="javax.swing.JPanel" name="jPanel2"> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel7" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jPrinters" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel7" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jPrinters" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel7"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.MachinePrinter" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="jPrinters"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[150, 30]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel1"> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JButton" name="jcmdCancel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.cancel" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jcmdCancelActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jcmdOK"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.OK" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value=""/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jcmdOKActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/util/SelectPrinter.java b/src/main/java/com/unicenta/pos/util/SelectPrinter.java new file mode 100644 index 0000000..b5ea28b --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/SelectPrinter.java @@ -0,0 +1,228 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2016 +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.util; + +import com.unicenta.pos.forms.AppLocal; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.Window; +import javax.swing.SwingUtilities; + +/** + * + * @author adrian + */ +public class SelectPrinter extends javax.swing.JDialog { + + private String printservice; + private boolean ok; + + /** Creates new form SelectPrinter */ + private SelectPrinter(java.awt.Frame parent, boolean modal) { + super(parent, modal); + } + + /** Creates new form SelectPrinter */ + private SelectPrinter(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + } + + /** + * + * @param parent + * @param printers + * @return + */ + public static SelectPrinter getSelectPrinter(Component parent, String[] printers) { + + Window window = SwingUtilities.windowForComponent(parent); + + SelectPrinter myMsg; + if (window instanceof Frame) { + myMsg = new SelectPrinter((Frame) window, true); + } else { + myMsg = new SelectPrinter((Dialog) window, true); + } + myMsg.init(printers); + myMsg.applyComponentOrientation(parent.getComponentOrientation()); + return myMsg; + } + + private void init(String[] printers) { + + initComponents(); + + jPrinters.removeAllItems(); + jPrinters.addItem("(Default)"); + for (String name : printers) { + jPrinters.addItem(name); + } + + jPrinters.setSelectedIndex(0); + + getRootPane().setDefaultButton(jcmdOK); + + ok = false; + printservice = null; + } + + /** + * + * @return + */ + public boolean isOK() { + return ok; + } + + /** + * + * @return + */ + public String getPrintService() { + return printservice; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel8 = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + jLabel7 = new javax.swing.JLabel(); + jPrinters = new javax.swing.JComboBox(); + jPanel1 = new javax.swing.JPanel(); + jcmdCancel = new javax.swing.JButton(); + jcmdOK = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(AppLocal.getIntString("form.selectprintertitle")); // NOI18N + + jPanel8.setLayout(new java.awt.BorderLayout()); + + jLabel7.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel7.setText(AppLocal.getIntString("label.MachinePrinter")); // NOI18N + jLabel7.setPreferredSize(new java.awt.Dimension(150, 30)); + + jPrinters.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jPrinters.setPreferredSize(new java.awt.Dimension(150, 30)); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPrinters, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jPrinters, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + + jcmdCancel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + jcmdCancel.setText(AppLocal.getIntString("button.cancel")); // NOI18N + jcmdCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdCancel.setPreferredSize(new java.awt.Dimension(80, 45)); + jcmdCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdCancelActionPerformed(evt); + } + }); + jPanel1.add(jcmdCancel); + + jcmdOK.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jcmdOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jcmdOK.setText(AppLocal.getIntString("button.OK")); // NOI18N + jcmdOK.setToolTipText(""); + jcmdOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdOK.setPreferredSize(new java.awt.Dimension(80, 45)); + jcmdOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdOKActionPerformed(evt); + } + }); + jPanel1.add(jcmdOK); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jPanel8, javax.swing.GroupLayout.PREFERRED_SIZE, 345, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) + .addComponent(jPanel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + + setSize(new java.awt.Dimension(353, 184)); + setLocationRelativeTo(null); + }// </editor-fold>//GEN-END:initComponents + + private void jcmdOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdOKActionPerformed + + ok = true; + printservice = (String)jPrinters.getSelectedItem(); + dispose(); + + }//GEN-LAST:event_jcmdOKActionPerformed + + private void jcmdCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdCancelActionPerformed + + dispose(); + + }//GEN-LAST:event_jcmdCancelActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel7; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel8; + private javax.swing.JComboBox jPrinters; + private javax.swing.JButton jcmdCancel; + private javax.swing.JButton jcmdOK; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/main/java/com/unicenta/pos/util/SessionKeepAlive.java b/src/main/java/com/unicenta/pos/util/SessionKeepAlive.java new file mode 100644 index 0000000..b895ac8 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/SessionKeepAlive.java @@ -0,0 +1,32 @@ +package com.unicenta.pos.util; + +import com.unicenta.pos.forms.DataLogicSystem; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class SessionKeepAlive extends Thread { + + private int wait = 60000; + private DataLogicSystem dataLogicSystem; + private Boolean keepAlive; + + public SessionKeepAlive(DataLogicSystem dataLogicSystem) { + this.dataLogicSystem = dataLogicSystem; + keepAlive = true; + } + + @Override + public void run() { + while (keepAlive) { + try { + log.info("Session Keep alive"); + dataLogicSystem.findVersion(); + Thread.sleep(wait); + } + catch (Exception ex) { + keepAlive = false; + log.error("Exception while keeping session alive: "+ex.getMessage()); + } + } + } +} diff --git a/src/main/java/com/unicenta/pos/util/StringParser.java b/src/main/java/com/unicenta/pos/util/StringParser.java new file mode 100644 index 0000000..4ceb3bd --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/StringParser.java @@ -0,0 +1,63 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2016 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.util; + +/** + * + * @author JG uniCenta + */ +public class StringParser { + + private int currentPosition; + private int maxPosition; + private String str; + + /** Creates a new instance of StringParser + * @param str */ + public StringParser(String str) { + this.str = str; + currentPosition = 0; + maxPosition = str == null ? 0 : str.length(); + } + + /** + * + * @param c + * @return + */ + public String nextToken(char c) { + + if (currentPosition < maxPosition) { + + int start = currentPosition; + while (currentPosition < maxPosition && c != str.charAt(currentPosition)) { + currentPosition ++; + } + + if (currentPosition < maxPosition) { + return str.substring(start, currentPosition++); + } else { + return str.substring(start); + } + } else { + return ""; + } + } +} diff --git a/src/main/java/com/unicenta/pos/util/StringUtils.java b/src/main/java/com/unicenta/pos/util/StringUtils.java new file mode 100644 index 0000000..d05ff4f --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/StringUtils.java @@ -0,0 +1,170 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2016 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.util; + +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.Random; + +/** + * + * @author JG uniCenta + */ +public class StringUtils { + + private static final char [] hexchars = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + + private static final NumberFormat cardformat = new DecimalFormat("000000"); + private static final Random cardrandom = new Random(); + + /** Creates a new instance of StringUtils */ + private StringUtils() { + } + + /** + * + * @return + */ + public static String getCardNumber() { + return cardformat.format(Math.abs(System.currentTimeMillis()) % 1000000L) + + cardformat.format(Math.abs(cardrandom.nextLong()) % 1000000L); + } + + /** + * + * @param sValue + * @return + */ + public static String encodeXML(String sValue) { + + if (sValue == null) { + return null; + } else { + StringBuilder buffer = new StringBuilder(); + for (int i = 0; i < sValue.length(); i++) { + char charToCompare = sValue.charAt(i); + if (charToCompare == '&') { + buffer.append("&"); + } else if (charToCompare == '<') { + buffer.append("<"); + } else if (charToCompare == '>') { + buffer.append(">"); + } else if (charToCompare == '\"') { + buffer.append("""); + } else if (charToCompare == '\'') { + buffer.append("'"); + } else { + buffer.append(charToCompare); + } + } + return buffer.toString(); + } + } + + /** + * + * @param binput + * @return + */ + public static String byte2hex(byte[] binput) { + + StringBuilder sb = new StringBuilder(binput.length * 2); + for (int i = 0; i < binput.length; i++) { + int high = ((binput[i] & 0xF0) >> 4); + int low = (binput[i] & 0x0F); + sb.append(hexchars[high]); + sb.append(hexchars[low]); + } + return sb.toString(); + } + + /** + * + * @param sinput + * @return + */ + public static byte [] hex2byte(String sinput) { + int length = sinput.length(); + + if ((length & 0x01) != 0) { + throw new IllegalArgumentException("odd number of characters."); + } + + byte[] out = new byte[length >> 1]; + + // two characters form the hex value. + for (int i = 0, j = 0; j < length; i++) { + int f = Character.digit(sinput.charAt(j++), 16) << 4; + f = f | Character.digit(sinput.charAt(j++), 16); + out[i] = (byte) (f & 0xFF); + } + + return out; + } + + /** + * + * @param resource + * @return + * @throws IOException + */ + public static String readResource(String resource) throws IOException { + + InputStream in = StringUtils.class.getResourceAsStream(resource); + if (in == null) { + throw new FileNotFoundException(resource); + } + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int len; + while ((len = in.read(buffer)) > 0) { + out.write(buffer, 0, len); + } + byte[] data = out.toByteArray(); + + return new String(data, "UTF-8"); + } + + /** + * + * @param sCardNumber + * @return + */ + public static boolean isNumber(String sCardNumber){ + + if ( (sCardNumber==null) || (sCardNumber.equals("")) ){ + return false; + } + + for (int i = 0; i < sCardNumber.length(); i++) { + char c = sCardNumber.charAt(i); + if (c != '0' && c != '1' && c != '2' && c != '3' && c != '4' + && c != '5' && c != '6' && c != '7' && c != '8' && c != '9') { + return false; + } + } + + return true; + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/util/SwingUtils.java b/src/main/java/com/unicenta/pos/util/SwingUtils.java new file mode 100644 index 0000000..f86aa78 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/SwingUtils.java @@ -0,0 +1,152 @@ +package com.unicenta.pos.util; +import java.awt.FontMetrics; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.JDialog; +import javax.swing.Timer; + +/** + * Swing utilities methods. Based on code from: + * http://www.aurelienribon.com/blog/2012/07/tutorial-beautifying-the-dialogs-in-swing-applications/ + * + * @author Harald Barsnes + */ +public class SwingUtils { + + // @TODO: requires java 7, hence not in use at the moment, see the lines that are commented out + + /** + * Creates an animation to fade the dialog opacity from 0 to 1. Using a + * default delay of 5 ms and an increment size of 0.05. + * + * @param dialog the dialog to fade in + */ + public static void fadeIn(final JDialog dialog) { + fadeIn(dialog, 5, 0.05f); + } + + /** + * Creates an animation to fade the dialog opacity from 0 to 1. + * + * @param dialog the dialog to fade in + * @param delay the delay in ms before starting and between each change + * @param incrementSize the increment size + */ + public static void fadeIn(final JDialog dialog, int delay, final float incrementSize) { + final Timer timer = new Timer(delay, null); + timer.setRepeats(true); + timer.addActionListener(new ActionListener() { + private float opacity = 0; + + @Override + public void actionPerformed(ActionEvent e) { + opacity += incrementSize; + dialog.setOpacity(Math.min(opacity, 1)); // requires java 1.7 + if (opacity >= 1) { + timer.stop(); + } + } + }); + + dialog.setOpacity(0); // requires java 1.7 + timer.start(); + dialog.setVisible(true); + } + + /** + * Creates an animation to fade the dialog opacity from 1 to 0. Using a + * default delay of 5 ms and an increment size of 0.05. + * + * @param dialog the dialog to fade out + */ + public static void fadeOut(final JDialog dialog) { + fadeOut(dialog, 5, 0.05f); + } + + /** + * Creates an animation to fade the dialog opacity from 1 to 0, and then + * dispose. + * + * @param dialog the dialog to fade out + * @param delay the delay in ms before starting and between each change + * @param incrementSize the increment size + */ + public static void fadeOut(final JDialog dialog, int delay, final float incrementSize) { + final Timer timer = new Timer(delay, null); + timer.setRepeats(true); + timer.addActionListener(new ActionListener() { + private float opacity = 1; + + @Override + public void actionPerformed(ActionEvent e) { + opacity -= incrementSize; + dialog.setOpacity(Math.max(opacity, 0)); // requires java 1.7 + if (opacity < 0) { + timer.stop(); + dialog.dispose(); + } + } + }); + + dialog.setOpacity(1); // requires java 1.7 + timer.start(); + } + + /** + * Creates an animation to fade the dialog opacity from 0 to 1, wait at 1 + * and then fade to 0. Default initial time of 50 ms, increment size of 0.05 + * and display time of 10000 ms. + * + * @param dialog the dialog to display + */ + public static void fadeInAndOut(final JDialog dialog) { + fadeInAndOut(dialog, 50, 0.05f, 10000); + } + + /** + * Creates an animation to fade the dialog opacity from 0 to 1, wait at 1 + * and then fade to 0 and dispose. + * + * @param dialog the dialog to display + * @param delay the delay in ms before starting and between each change + * @param incrementSize the increment size + * @param displayTime the time in ms the dialog is fully visible + */ + public static void fadeInAndOut(final JDialog dialog, final int delay, final float incrementSize, final int displayTime) { + final Timer timer = new Timer(delay, null); + timer.setRepeats(true); + timer.addActionListener(new ActionListener() { + private float opacity = 0; + private boolean displayed = false; + + @Override + public void actionPerformed(ActionEvent e) { + + if (!displayed) { + opacity += incrementSize; + dialog.setOpacity(Math.min(opacity, 1)); // requires java 1.7 + if (opacity >= 1) { + timer.setDelay(displayTime); + displayed = true; + } + } else { + timer.setDelay(delay); + opacity -= incrementSize; + dialog.setOpacity(Math.max(opacity, 0)); // requires java 1.7 + if (opacity < 0) { + timer.stop(); + dialog.dispose(); + } + } + } + }); + + dialog.setOpacity(0); // requires java 1.7 + timer.start(); + dialog.setVisible(true); + } + + static FontMetrics getDefaultLabelFontMetrics() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/util/SwingWorkerExample.java b/src/main/java/com/unicenta/pos/util/SwingWorkerExample.java new file mode 100644 index 0000000..f15172e --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/SwingWorkerExample.java @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2016 uniCenta <info at unicenta.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package com.unicenta.pos.util; + +/** + * + * @author uniCenta <info at unicenta.com> + */ + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.util.ArrayList; +import java.util.concurrent.ExecutionException; + +public class SwingWorkerExample extends JFrame implements ActionListener { + + private static final long serialVersionUID = 1L; + private final JButton startButton, stopButton; + private final JScrollPane scrollPane = new JScrollPane(); + private JList listBox = null; + private final DefaultListModel listModel = new DefaultListModel(); + private final JProgressBar progressBar; + private mySwingWorker swingWorker; + + public SwingWorkerExample() { + super("SwingWorkerExample"); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + getContentPane().setLayout(new GridLayout(2, 2)); + startButton = makeButton("Start"); + stopButton = makeButton("Stop"); + stopButton.setEnabled(false); + progressBar = makeProgressBar(0, 99); + listBox = new JList(listModel); + scrollPane.setViewportView(listBox); + getContentPane().add(scrollPane); + //Display the window. + pack(); + setVisible(true); + } +//Class SwingWorker<T,V> T - the result type returned by this SwingWorker's doInBackground +//and get methods V - the type used for carrying out intermediate results by this SwingWorker's +//publish and process methods + + private class mySwingWorker extends javax.swing.SwingWorker<ArrayList<Integer>, Integer> { +//The first template argument, in this case, ArrayList<Integer>, is what s returned by doInBackground(), +//and by get(). The second template argument, in this case, Integer, is what is published with the +//publish method. It is also the data type which is stored by the java.util.List that is the parameter +//for the process method, which recieves the information published by the publish method. + + @Override + protected ArrayList<Integer> doInBackground() { +//Returns items of the type given as the first template argument to the SwingWorker class. + if (javax.swing.SwingUtilities.isEventDispatchThread()) { + System.out.println("javax.swing.SwingUtilities.isEventDispatchThread() returned true."); + } + Integer tmpValue = 1; + ArrayList<Integer> list = new ArrayList<>(); + for (int i = 0; i < 100; i++) { + for (int j = 0; j < 100; j++) { //find every 100th prime, just to make it slower + tmpValue = FindNextPrime(tmpValue); +//isCancelled() returns true if the cancel() method is invoked on this class. That is the proper way +//to stop this thread. See the actionPerformed method. + if (isCancelled()) { + System.out.println("SwingWorker - isCancelled"); + return list; + } + } +//Successive calls to publish are coalesced into a java.util.List, which is what is received by process, +//which in this case, isused to update the JProgressBar. Thus, the values passed to publish range from +//1 to 100. + publish(i); + list.add(tmpValue); + } + return list; + }//Note, always use java.util.List here, or it will use the wrong list. + + @Override + protected void process(java.util.List<Integer> progressList) { +//This method is processing a java.util.List of items given as successive arguments to the publish method. +//Note that these calls are coalesced into a java.util.List. This list holds items of the type given as the +//second template parameter type to SwingWorker. Note that the get method below has nothing to do with the +//SwingWorker get method; it is the List's get method. This would be a good place to update a progress bar. + if (!javax.swing.SwingUtilities.isEventDispatchThread()) { + System.out.println("javax.swing.SwingUtilities.isEventDispatchThread() + returned false."); + } + Integer percentComplete = progressList.get(progressList.size() - 1); + progressBar.setValue(percentComplete); + } + + @Override + protected void done() { + System.out.println("doInBackground is complete"); + if (!javax.swing.SwingUtilities.isEventDispatchThread()) { + System.out.println("javax.swing.SwingUtilities.isEventDispatchThread() + returned false."); + } + try { +//Here, the SwingWorker's get method returns an item of the same type as specified as the first type parameter +//given to the SwingWorker class. + ArrayList<Integer> results = get(); + results.stream().forEach((i) -> { + listModel.addElement(i.toString()); + }); + } catch (InterruptedException | ExecutionException e) { + System.out.println("Caught an exception: " + e); + } + startButton(); + } + + boolean IsPrime(int num) { //Checks whether a number is prime + int i; + for (i = 2; i <= num / 2; i++) { + if (num % i == 0) { + return false; + } + } + return true; + } + + protected Integer FindNextPrime(int num) { //Returns next prime number from passed arg. + do { + if (num % 2 == 0) { + num++; + } else { + num += 2; + } + } while (!IsPrime(num)); + return num; + } + } + + private JButton makeButton(String caption) { + JButton b = new JButton(caption); + b.setActionCommand(caption); + b.addActionListener(this); + getContentPane().add(b); + return b; + } + + private JProgressBar makeProgressBar(int min, int max) { + JProgressBar progressBar1 = new JProgressBar(); + progressBar1.setMinimum(min); + progressBar1.setMaximum(max); + progressBar1.setStringPainted(true); + progressBar1.setBorderPainted(true); + getContentPane().add(progressBar1); + return progressBar1; + } + + private void startButton() { + startButton.setEnabled(true); + stopButton.setEnabled(false); + System.out.println("SwingWorker - Done"); + } + + @Override + public void actionPerformed(ActionEvent e) { + if ("Start" == null ? e.getActionCommand() == null : "Start".equals(e.getActionCommand())) { + startButton.setEnabled(false); + stopButton.setEnabled(true); +// Note that it creates a new instance of the SwingWorker-derived class. Never reuse an old one. + (swingWorker = new mySwingWorker()).execute(); // new instance + } else if ("Stop" == null ? e.getActionCommand() == null : "Stop".equals(e.getActionCommand())) { + startButton.setEnabled(true); + stopButton.setEnabled(false); + swingWorker.cancel(true); // causes isCancelled to return true in doInBackground + swingWorker = null; + } + } + + public static void main(String[] args) { +// Notice that it kicks it off on the event-dispatching thread, not the main thread. + SwingUtilities.invokeLater(() -> { + SwingWorkerExample swingWorkerExample = new SwingWorkerExample(); + }); + } +} diff --git a/src/main/java/com/unicenta/pos/util/ThumbNailBuilder.java b/src/main/java/com/unicenta/pos/util/ThumbNailBuilder.java new file mode 100644 index 0000000..2dd7c64 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/ThumbNailBuilder.java @@ -0,0 +1,203 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2016 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.util; + +import java.awt.image.*; +import java.awt.*; +import javax.imageio.ImageIO; +import javax.swing.JLabel; + +/** + * + * @author JG uniCenta + */ +public class ThumbNailBuilder { + + private Image m_imgdefault; + private int m_width; + private int m_height; + + /** Creates a new instance of ThumbNailBuilder + * @param width + * @param height */ + public ThumbNailBuilder(int width, int height) { + init(width, height, null); + } + + /** + * + * @param width + * @param height + * @param imgdef + */ + public ThumbNailBuilder(int width, int height, Image imgdef) { + init(width, height, imgdef); + + } + + /** + * + * @param width + * @param height + * @param img + */ + public ThumbNailBuilder(int width, int height, String img) { + + Image defimg; + try { + init(width, height, ImageIO.read(getClass().getClassLoader().getResourceAsStream(img))); + } catch (Exception fnfe) { + init(width, height, null); + } + } + + private void init(int width, int height, Image imgdef) { + m_width = width; + m_height = height; + if (imgdef == null) { + m_imgdefault = null; + } else { + m_imgdefault = createThumbNail(imgdef); + } + } + + /** + * + * @param img + * @return + */ + public Image getThumbNail(Image img) { + + if (img == null) { + return m_imgdefault; + } else { + return createThumbNail(img); + } + } + + /** + * + * @param img + * @param text + * @return + */ + public Image getThumbNailText(Image img, String text) { + + img = getThumbNail(img); + + BufferedImage imgtext = new BufferedImage(img.getWidth(null), + img.getHeight(null), BufferedImage.TYPE_INT_ARGB); + Graphics2D g2d = imgtext.createGraphics(); + + // The text + JLabel label = new JLabel(); + label.setOpaque(false); + label.setText(text); + label.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + label.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM); + + Dimension d = label.getPreferredSize(); + label.setBounds(0, 0, imgtext.getWidth(), d.height); + + + // The background + Color c1 = new Color(0xff, 0xff, 0xff, 0x40); + Color c2 = new Color(0xff, 0xff, 0xff, 0xd0); + + Paint gpaint = new GradientPaint(new Point(0,0), c1, new Point(label.getWidth() / 2, 0), c2, true); + + g2d.drawImage(img, 0, 0, null); + g2d.translate(0, imgtext.getHeight() - label.getHeight()); + g2d.setPaint(gpaint); +// g2d.fillRect(0 , 0, imgtext.getWidth(), label.getHeight()); + label.paint(g2d); + + g2d.dispose(); + + return imgtext; + } + + private Image createThumbNail(Image img) { + + int targetw; + int targeth; + + double scalex = (double) m_width / (double) img.getWidth(null); + double scaley = (double) m_height / (double) img.getHeight(null); + if (scalex < scaley) { + targetw = m_width; + targeth = (int) (img.getHeight(null) * scalex); + } else { + targetw = (int) (img.getWidth(null) * scaley); + targeth = (int) m_height; + } + + int midw = img.getWidth(null); + int midh = img.getHeight(null); + BufferedImage midimg = null; + Graphics2D g2d = null; + + Image previmg = img; + int prevw = img.getWidth(null); + int prevh = img.getHeight(null); + + do { + if (midw > targetw) { + midw /= 2; + if (midw < targetw) { + midw = targetw; + } + } else { + midw = targetw; + } + if (midh > targeth) { + midh /= 2; + if (midh < targeth) { + midh = targeth; + } + } else { + midh = targeth; + } + if (midimg == null) { + midimg = new BufferedImage(midw, midh, BufferedImage.TYPE_INT_ARGB); + g2d = midimg.createGraphics(); + g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + } + g2d.drawImage(previmg, 0, 0, midw, midh, 0, 0, prevw, prevh, null); + prevw = midw; + prevh = midh; + previmg = midimg; + } while (midw != targetw || midh != targeth); + + g2d.dispose(); + + if (m_width != midimg.getWidth() || m_height != midimg.getHeight()) { + midimg = new BufferedImage(m_width, m_height, BufferedImage.TYPE_INT_ARGB); + int x = (m_width > targetw) ? (m_width - targetw) / 2 : 0; + int y = (m_height > targeth) ? (m_height - targeth) / 2 : 0; + g2d = midimg.createGraphics(); + g2d.drawImage(previmg, x, y, x + targetw, y + targeth, + 0, 0, targetw, targeth, null); + g2d.dispose(); + previmg = midimg; + } + return previmg; + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/util/UniBrowser.java b/src/main/java/com/unicenta/pos/util/UniBrowser.java new file mode 100644 index 0000000..bbdc858 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/UniBrowser.java @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2016 uniCenta <info at unicenta.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package com.unicenta.pos.util; + +import javafx.application.Platform; +import javafx.beans.value.ObservableValue; +import javafx.embed.swing.JFXPanel; +import javafx.scene.Scene; +import javafx.scene.web.WebEngine; +import javafx.scene.web.WebEvent; +import javafx.scene.web.WebView; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.net.MalformedURLException; +import java.net.URL; + +import static javafx.concurrent.Worker.State.FAILED; + +public class UniBrowser extends JFrame { + + private final JFXPanel jfxPanel = new JFXPanel(); + private WebEngine engine; + + private final JPanel panel = new JPanel(new BorderLayout()); + private final JLabel lblStatus = new JLabel(); + + + private final JButton btnGo = new JButton("Go"); + private final JTextField txtURL = new JTextField(); + private final JProgressBar progressBar = new JProgressBar(); + + public UniBrowser() { + super(); + initComponents(); + } + + + private void initComponents() { + createScene(); + + ActionListener al = (ActionEvent e) -> { + loadURL(txtURL.getText()); + }; + + btnGo.addActionListener(al); + txtURL.addActionListener(al); + + progressBar.setPreferredSize(new Dimension(150, 18)); + progressBar.setStringPainted(true); + + JPanel topBar = new JPanel(new BorderLayout(5, 0)); + topBar.setBorder(BorderFactory.createEmptyBorder(3, 5, 3, 5)); + topBar.add(txtURL, BorderLayout.CENTER); + topBar.add(btnGo, BorderLayout.EAST); + + JPanel statusBar = new JPanel(new BorderLayout(5, 0)); + statusBar.setBorder(BorderFactory.createEmptyBorder(3, 5, 3, 5)); + statusBar.add(lblStatus, BorderLayout.CENTER); + statusBar.add(progressBar, BorderLayout.EAST); + + panel.add(topBar, BorderLayout.NORTH); + panel.add(jfxPanel, BorderLayout.CENTER); + panel.add(statusBar, BorderLayout.SOUTH); + + getContentPane().add(panel); + + setPreferredSize(new Dimension(1024, 600)); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + pack(); + + } + + private void createScene() { + + Platform.runLater(() -> { + WebView view = new WebView(); + engine = view.getEngine(); + + engine.titleProperty().addListener((ObservableValue<? extends String> observable, String oldValue, final String newValue) -> { + SwingUtilities.invokeLater(() -> { + UniBrowser.this.setTitle(newValue); + }); + }); + + engine.setOnStatusChanged((final WebEvent<String> event) -> { + SwingUtilities.invokeLater(() -> { + lblStatus.setText(event.getData()); + }); + }); + + engine.locationProperty().addListener((ObservableValue<? extends String> ov, String oldValue, final String newValue) -> { + SwingUtilities.invokeLater(() -> { + txtURL.setText(newValue); + }); + }); + + engine.getLoadWorker().workDoneProperty().addListener((ObservableValue<? extends Number> observableValue, Number oldValue, final Number newValue) -> { + SwingUtilities.invokeLater(() -> { + progressBar.setValue(newValue.intValue()); + }); + }); + + engine.getLoadWorker() + .exceptionProperty() + .addListener((ObservableValue<? extends Throwable> o, Throwable old, final Throwable value) -> { + if (engine.getLoadWorker().getState() == FAILED) { + SwingUtilities.invokeLater(() -> { + JOptionPane.showMessageDialog( + panel, + (value != null) ? + engine.getLocation() + "\n" + value.getMessage() : + engine.getLocation() + "\nUnexpected error.", + "Loading error...", + JOptionPane.ERROR_MESSAGE); + }); + } + }); + + jfxPanel.setScene(new Scene(view)); + }); + } + + public void loadURL(final String url) { + Platform.runLater(() -> { + String tmp = toURL(url); + + if (tmp == null) { + tmp = toURL("http://" + url); + } + + engine.load(tmp); + }); + } + + private static String toURL(String str) { + try { + return new URL(str).toExternalForm(); + } catch (MalformedURLException exception) { + return null; + } + } + + + + public static void main(String args[]) { + SwingUtilities.invokeLater(() -> { + UniBrowser browser = new UniBrowser(); + browser.setVisible(true); +// browser.loadURL("https://unicenta.com/pages/configure-unicenta-opos/"); + String[] s = args; + System.out.println(s); + String strURL ="https://unicenta.com/pages/configure-unicenta-opos/"; + System.out.println("s"); + UniBrowser.toURL(strURL); + }); + } +} \ No newline at end of file diff --git a/src/main/java/com/unicenta/pos/util/ValidateBuilder.java b/src/main/java/com/unicenta/pos/util/ValidateBuilder.java new file mode 100644 index 0000000..cb51408 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/ValidateBuilder.java @@ -0,0 +1,130 @@ + +package com.unicenta.pos.util; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.format.Formats; +import java.awt.Component; +import java.util.ArrayList; +import java.util.List; + + +public class ValidateBuilder { + + public static int IS_NOT_EMPTY = 1; + public static int IS_INT = 2; + public static int IS_DOUBLE = 3; + public static int IS_CURRENCY = 4; + public static int IS_DOUBLE_NULL = 5 ; + + private List<String> listMessage ; + private Component parent; + + public ValidateBuilder(Component _parent) { + parent = _parent; + listMessage = new ArrayList<>(); + } + + public void setValidate(Object value , int tipe , String message){ + if (value==null){ + listMessage.add(message); + } + } + + public void setValidate(String value , int tipe , String message){ + if(tipe == IS_NOT_EMPTY){ + if (value.equals("")){ + listMessage.add(message); + } + }else if (tipe == IS_INT){ + if (!isInt(value)){ + listMessage.add(message); + } + }else if (tipe == IS_DOUBLE){ + if (!isDouble(value)){ + listMessage.add(message); + } + }else if (tipe == IS_CURRENCY){ + if (!isCurrency(value)){ + listMessage.add(message); + } + }else if (tipe == IS_DOUBLE_NULL){ + if (!isDoubleNull(value)){ + listMessage.add(message); + } + } + } + + private void showMessage(){ + StringBuilder sb = new StringBuilder(); + sb.append("<br>"); + for (String message : listMessage){ + sb.append(message+"<br>"); + } + MessageInf msg = new MessageInf(MessageInf.SGN_NOTICE,sb.toString() , null); + msg.show(parent); + + } + + public boolean getValid(){ + boolean isValid = true; + if (listMessage.size()>0){ + isValid= false; + showMessage(); + } + return isValid; + } + + private boolean isInt(String n) { + try { + Object a = Formats.INT.parseValue(n); + if (a!=null){ + return true; + }else{ + return false; + } + } catch (BasicException ex) { + return false; + } + } + + + private boolean isDouble(String n) { + try { + Object a = Formats.DOUBLE.parseValue(n); + if (a!=null){ + return true; + }else{ + return false; + } + } catch (BasicException ex) { + return false; + } + } + + + + private boolean isDoubleNull(String n) { + try { + Object a = Formats.DOUBLE.parseValue(n); + return true; + } catch (BasicException ex) { + return false; + } + } + + + private boolean isCurrency(String n){ + try { + Object a = Formats.CURRENCY.parseValue(n); + if (a!=null){ + return true; + }else{ + return false; + } + + } catch (BasicException ex) { + return false; + } + } +} diff --git a/src/main/java/com/unicenta/pos/util/VideoPlayer.java b/src/main/java/com/unicenta/pos/util/VideoPlayer.java new file mode 100644 index 0000000..36d2253 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/VideoPlayer.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2016 uniCenta <info at unicenta.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package com.unicenta.pos.util; + +import javafx.application.Application; +import javafx.scene.Group; +import javafx.scene.Scene; +import javafx.scene.media.Media; +import javafx.scene.media.MediaPlayer; +import javafx.scene.media.MediaView; +import javafx.stage.Stage; + +/** + * Provides JavaFX media player services + * @author uniCenta + */ + + +public class VideoPlayer extends Application { + public static void main(String[] args) { launch(args); } + private static final String MEDIA_URL = + "file:///C://temp//2017_07_14_12_20_37-ses.mp4"; // Test LocalFile + + +@Override + public void start(Stage primaryStage) { + primaryStage.setTitle("uniCenta Media Player"); + Group root = new Group(); + Scene scene = new Scene(root, 540, 310); +// create media player + Media media = new Media(MEDIA_URL); + MediaPlayer mediaPlayer = new MediaPlayer(media); + mediaPlayer.setAutoPlay(true); +// create mediaView and add media player to the viewer + MediaView mediaView = new MediaView(mediaPlayer); + ((Group)scene.getRoot()).getChildren().add(mediaView); + + primaryStage.setScene(scene); + primaryStage.show(); + } + +} diff --git a/src/main/java/com/unicenta/pos/util/uOWWatch.java b/src/main/java/com/unicenta/pos/util/uOWWatch.java new file mode 100644 index 0000000..6de3810 --- /dev/null +++ b/src/main/java/com/unicenta/pos/util/uOWWatch.java @@ -0,0 +1,151 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2016 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + + +/*--------------------------------------------------------------------------- + * Copyright (c) 1999,2000 Dallas Semiconductor Corporation, All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Dallas Semiconductor + * shall not be used except as stated in the Dallas Semiconductor + * Branding Policy. + *--------------------------------------------------------------------------- + */ + +package com.unicenta.pos.util; + +import com.dalsemi.onewire.OneWireAccessProvider; +import com.dalsemi.onewire.adapter.DSPortAdapter; +import com.dalsemi.onewire.container.OneWireContainer; +import com.dalsemi.onewire.application.monitor.*; + + +/** + * @version 0.00, 25 September 2000 + * @author DS,BA,SH + * @modified JG uniCenta October 2017 + */ +public class uOWWatch + implements DeviceMonitorEventListener { + + public static String ibuttonid; + + /** + * Method main + */ + public static void iButtonOn () { + OneWireContainer owd; + + try { + DSPortAdapter adapter = OneWireAccessProvider.getDefaultAdapter(); + + adapter.setSearchAllDevices(); + adapter.targetAllFamilies(); + adapter.setSpeed(DSPortAdapter.SPEED_REGULAR); + + uOWWatch nw = new uOWWatch(adapter); + } catch (Exception e) { + + } + + return; + } + + /** Network Monitor instance */ + private DeviceMonitor dm; + + /** + * Create a 1-Wire Network Watcher + * @param adapter for 1-Wire Network to monitor + */ + public uOWWatch (DSPortAdapter adapter) { + + dm = new DeviceMonitor(adapter); + + try { + dm.addDeviceMonitorEventListener(this); + } catch (Exception e){ } + + Thread t = new Thread(dm); + t.start(); + } + + /** + * + */ + public void killWatch() { + dm.killMonitor(); + } + + /** + * Arrival event as a NetworkMonitorEventListener + * @param devt + */ + @Override + public void deviceArrival (DeviceMonitorEvent devt) { + int i; + + for(i=0; i<devt.getDeviceCount(); i++) { + ibuttonid = devt.getAddressAsStringAt(i); + } + } + + /** + * Depart event as a NetworkMonitorEventListener + * @param devt + */ + @Override + public void deviceDeparture (DeviceMonitorEvent devt) { + int i; + + for(i=0; i<devt.getDeviceCount(); i++) + ibuttonid = ""; + } + + /** + * Depart event as a NetworkMonitorEventListener + * @param dexc + */ + @Override + public void networkException (DeviceMonitorException dexc) { + + } + + public static String getibuttonid (){ + return ibuttonid; + } + +} diff --git a/src/main/java/com/unicenta/pos/voucher/JDialogReportPanel.form b/src/main/java/com/unicenta/pos/voucher/JDialogReportPanel.form new file mode 100644 index 0000000..88e765a --- /dev/null +++ b/src/main/java/com/unicenta/pos/voucher/JDialogReportPanel.form @@ -0,0 +1,132 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="form.customertitle" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor"> + <Color id="Default Cursor"/> + </Property> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,-81,0,0,3,69"/> + <SyntheticProperty name="formSizePolicy" type="int" value="0"/> + <SyntheticProperty name="generateSize" type="boolean" value="true"/> + <SyntheticProperty name="generateCenter" type="boolean" value="true"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + </Container> + <Container class="javax.swing.JPanel" name="jPanel8"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="After"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JButton" name="jcmdOK"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="Button.OK" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jcmdOKActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jcmdCancel"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/cancel.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="Button.Cancel" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 16, 8, 16]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jcmdCancelActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JButton" name="jButton1"> + <Properties> + <Property name="text" type="java.lang.String" value="jButton1"/> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/voucher/JDialogReportPanel.java b/src/main/java/com/unicenta/pos/voucher/JDialogReportPanel.java new file mode 100644 index 0000000..e020123 --- /dev/null +++ b/src/main/java/com/unicenta/pos/voucher/JDialogReportPanel.java @@ -0,0 +1,293 @@ + +package com.unicenta.pos.voucher; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.MessageInf; +import com.unicenta.data.loader.BaseSentence; +import com.unicenta.data.loader.Datas; +import com.unicenta.data.loader.QBFBuilder; +import com.unicenta.data.loader.SerializerReadBasic; +import com.unicenta.data.loader.StaticSentence; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.reports.ReportFields; +import com.unicenta.pos.reports.ReportFieldsArray; +// import com.unicenta.pos.util.FontUtil; +import com.unicenta.pos.util.JRViewer400; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Window; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import javax.swing.*; +import net.sf.jasperreports.engine.JRDataSource; +import net.sf.jasperreports.engine.JREmptyDataSource; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperCompileManager; +import net.sf.jasperreports.engine.JasperFillManager; +import net.sf.jasperreports.engine.JasperPrint; +import net.sf.jasperreports.engine.JasperReport; +import net.sf.jasperreports.engine.design.JasperDesign; +import net.sf.jasperreports.engine.xml.JRXmlLoader; + +public abstract class JDialogReportPanel extends javax.swing.JDialog { + + + private JRViewer400 reportviewer = null; + private JasperReport jr = null; + private AppView m_App; + private List<String> paramnames = new ArrayList<>(); + private List<Datas> fielddatas = new ArrayList<>(); + private List<String> fieldnames = new ArrayList<>(); + private String sentence; + /** Creates new form JCustomerFinder */ + private JDialogReportPanel(java.awt.Frame parent, boolean modal) { + super(parent, modal); + } + + /** Creates new form JCustomerFinder */ + private JDialogReportPanel(java.awt.Dialog parent, boolean modal) { + super(parent, modal); + } + + public static JDialogReportPanel getDialog(Component parent,AppView _App,VoucherInfo voucherInfo,BufferedImage image) { + Window window = getWindow(parent); + + JDialogReportPanel myMsg; + if (window instanceof Frame) { + myMsg = new JDialogReportPanel((Frame) window, true) { + @Override + protected String getReport() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + }; + } else { + myMsg = new JDialogReportPanel((Dialog) window, true) { + @Override + protected String getReport() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + }; + } + myMsg.init(_App,voucherInfo,image); + myMsg.applyComponentOrientation(parent.getComponentOrientation()); + return myMsg; + } + + + protected BaseSentence getSentence() { + return new StaticSentence(m_App.getSession() + , new QBFBuilder(sentence, paramnames.toArray(new String[paramnames.size()])) + , null + , new SerializerReadBasic(fielddatas.toArray(new Datas[fielddatas.size()]))); + } + + + protected ReportFields getReportFields() { + return new ReportFieldsArray(fieldnames.toArray(new String[fieldnames.size()])); + } + + + private void launchreport(VoucherInfo voucherInfo,BufferedImage image) { + + + + if (jr != null) { + try { + + // Archivo de recursos + String res = "com/unicenta/reports/voucher_messages";//getResourceBundle(); + + // Parametros y los datos +// Object params = (editor == null) ? null : editor.createValue(); +// BaseSentence sql= getSentence() ; +// JRDataSource data = new JRDataSourceBasic(sql, getReportFields(), null); + + // Construyo el mapa de los parametros. + Map reportparams = new HashMap(); + reportparams.put("CUSTOMER_NAME", voucherInfo.getCustomerName()); + reportparams.put("LOGO", image); + reportparams.put("CODE", voucherInfo.getVoucherNumber()); + reportparams.put("ISSUED", new Date()); + reportparams.put("VALUE", voucherInfo.getAmount()); + if (res != null) { + reportparams.put("REPORT_RESOURCE_BUNDLE", ResourceBundle.getBundle(res)); + } + +// if (paramsreport.size()>0){ +// for (Map.Entry<String, String> entry : paramsreport.entrySet()) { +// reportparams.put(entry.getKey(), entry.getValue()); +// } +// } + + JasperPrint jp = JasperFillManager.fillReport(jr, reportparams, new JREmptyDataSource()); +// JasperExportManager.exportReportToPdfFile(jp,"E:\\report7.pdf"); + reportviewer.loadJasperPrint(jp); + + + } catch (MissingResourceException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotloadresourcedata"), e); + msg.show(this); + } catch (JRException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotfillreport"), e); + msg.show(this); + } +// catch (BasicException e) { +// MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotloadreportdata"), e); +// msg.show(this); +// } + } + } + + + + private void init(AppView _App,VoucherInfo voucherInfo,BufferedImage image) { + m_App =_App; + initComponents(); + + reportviewer = new JRViewer400(null); + + jPanel4.add(reportviewer, BorderLayout.CENTER); + + try { + jr = JasperCompileManager.compileReport("com/unicenta/reports/voucher" + ".jrxml"); +// jr = JasperCompileManager.compileReport(getClass().getResourceAsStream("reports" + "/com/unicenta/reports/voucher" + ".jrxml")); + } catch (JRException e) { + MessageInf msg = new MessageInf(MessageInf.SGN_WARNING, AppLocal.getIntString("message.cannotloadreport"), e); + msg.show(this); + jr = null; + } + + + + + launchreport(voucherInfo,image); + + + getRootPane().setDefaultButton(jcmdOK); + + + } + + /** + * + * @return + */ + protected abstract String getReport(); + + + + private static Window getWindow(Component parent) { + if (parent == null) { + return new JFrame(); + } else if (parent instanceof Frame || parent instanceof Dialog) { + return (Window) parent; + } else { + return getWindow(parent.getParent()); + } + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel3 = new javax.swing.JPanel(); + jPanel4 = new javax.swing.JPanel(); + jPanel8 = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + jcmdOK = new javax.swing.JButton(); + jcmdCancel = new javax.swing.JButton(); + jButton1 = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(AppLocal.getIntString("form.customertitle")); // NOI18N + setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + + jPanel3.setLayout(new java.awt.BorderLayout()); + + jPanel4.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + jPanel4.setLayout(new java.awt.BorderLayout()); + jPanel3.add(jPanel4, java.awt.BorderLayout.CENTER); + + jPanel8.setLayout(new java.awt.BorderLayout()); + + jcmdOK.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jcmdOK.setText(AppLocal.getIntString("Button.OK")); // NOI18N + jcmdOK.setEnabled(false); + jcmdOK.setFocusPainted(false); + jcmdOK.setFocusable(false); + jcmdOK.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdOK.setRequestFocusEnabled(false); + jcmdOK.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdOKActionPerformed(evt); + } + }); + jPanel1.add(jcmdOK); + + jcmdCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/cancel.png"))); // NOI18N + jcmdCancel.setText(AppLocal.getIntString("Button.Cancel")); // NOI18N + jcmdCancel.setFocusPainted(false); + jcmdCancel.setFocusable(false); + jcmdCancel.setMargin(new java.awt.Insets(8, 16, 8, 16)); + jcmdCancel.setRequestFocusEnabled(false); + jcmdCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jcmdCancelActionPerformed(evt); + } + }); + jPanel1.add(jcmdCancel); + + jPanel8.add(jPanel1, java.awt.BorderLayout.LINE_END); + + jButton1.setText("jButton1"); + jPanel8.add(jButton1, java.awt.BorderLayout.CENTER); + + jPanel3.add(jPanel8, java.awt.BorderLayout.SOUTH); + + getContentPane().add(jPanel3, java.awt.BorderLayout.CENTER); + + setSize(new java.awt.Dimension(837, 687)); + setLocationRelativeTo(null); + }// </editor-fold>//GEN-END:initComponents + private void jcmdOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdOKActionPerformed + + + dispose(); + + }//GEN-LAST:event_jcmdOKActionPerformed + + private void jcmdCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcmdCancelActionPerformed + + dispose(); + + }//GEN-LAST:event_jcmdCancelActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel8; + private javax.swing.JButton jcmdCancel; + private javax.swing.JButton jcmdOK; + // End of variables declaration//GEN-END:variables + + } diff --git a/src/main/java/com/unicenta/pos/voucher/VoucherEditor.form b/src/main/java/com/unicenta/pos/voucher/VoucherEditor.form new file mode 100644 index 0000000..24fcef4 --- /dev/null +++ b/src/main/java/com/unicenta/pos/voucher/VoucherEditor.form @@ -0,0 +1,251 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.6" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLblStatus" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jStatus" min="-2" max="-2" attributes="0"/> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + </Group> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="jLabel5" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="m_jNumber" min="-2" max="-2" attributes="0"/> + <Component id="m_jAmount" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Component id="jLabel3" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="m_jCustomer" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jCBCustomer" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace pref="19" max="32767" attributes="0"/> + </Group> + </Group> + </Group> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace max="32767" attributes="0"/> + <Component id="jButtonPrint" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jNumber" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jAmount" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="m_jCustomer" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jCBCustomer" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="m_jStatus" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLblStatus" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" pref="36" max="-2" attributes="0"/> + <Component id="jButtonPrint" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="21" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.Number" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jNumber"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[240, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.customer" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jCustomer"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="ff" green="ff" red="ff" type="rgb"/> + </Property> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor"> + <Color id="Text Cursor"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[240, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jAmount"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[240, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.paymenttotal" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jButtonPrint"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="12" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/printer24.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="button.print" replaceFormat="AppLocal.getIntString("button.print")"/> + </Property> + <Property name="focusPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[8, 14, 8, 14]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 45]"/> + </Property> + <Property name="requestFocusEnabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonPrintActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLblStatus"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/com/unicenta/images/ok.png"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="label.Status" replaceFormat="AppLocal.getIntString("{key}")"/> + </Property> + <Property name="horizontalTextPosition" type="int" value="10"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="m_jStatus"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[240, 30]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="jCBCustomer"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="14" style="0"/> + </Property> + <Property name="maximumRowCount" type="int" value="2"/> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="2"> + <StringItem index="0" value="Find"/> + <StringItem index="1" value="Create"/> + </StringArray> + </Property> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="pos_messages.properties" key="tooltip.vouchercustomer" replaceFormat="AppLocal.getIntString("label.voucherCustomer")"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[110, 30]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jCBCustomerActionPerformed"/> + </Events> + <AuxValues> + <AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/> + </AuxValues> + </Component> + </SubComponents> +</Form> diff --git a/src/main/java/com/unicenta/pos/voucher/VoucherEditor.java b/src/main/java/com/unicenta/pos/voucher/VoucherEditor.java new file mode 100644 index 0000000..434ef01 --- /dev/null +++ b/src/main/java/com/unicenta/pos/voucher/VoucherEditor.java @@ -0,0 +1,439 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2017 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.voucher; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.gui.ComboBoxValModel; +import com.unicenta.data.user.DirtyManager; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.customers.CustomerInfo; +import com.unicenta.pos.customers.DataLogicCustomers; +import com.unicenta.pos.customers.JCustomerFinder; +import com.unicenta.pos.customers.JDialogNewCustomer; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.forms.AppView; +import com.unicenta.pos.forms.DataLogicSystem; +import com.unicenta.pos.util.ValidateBuilder; + +import javax.swing.*; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.UUID; + +public final class VoucherEditor extends javax.swing.JPanel implements EditorRecord { + + private static final DateFormat m_simpledate = new SimpleDateFormat("MM-yy"); + private Object id; + private final DataLogicCustomers dlCustomers; + private final DataLogicSystem dlSystem; + private CustomerInfo customerInfo; + private final AppView m_app; + + private final ComboBoxValModel m_ReasonModel; + + public VoucherEditor(DirtyManager dirty,AppView app) { + m_app = app; + + initComponents(); + + dlCustomers = (DataLogicCustomers) + app.getBean("com.unicenta.pos.customers.DataLogicCustomers"); + dlSystem = (DataLogicSystem) + app.getBean("com.unicenta.pos.forms.DataLogicSystem"); + m_jNumber.getDocument().addDocumentListener(dirty); + m_jCustomer.getDocument().addDocumentListener(dirty); + m_jAmount.getDocument().addDocumentListener(dirty); + m_jStatus.getDocument().addDocumentListener(dirty); + + jButtonPrint.setVisible(false); + + m_ReasonModel = new ComboBoxValModel(); + m_ReasonModel.add(AppLocal.getIntString("cboption.find")); + m_ReasonModel.add(AppLocal.getIntString("cboption.create")); + jCBCustomer.setModel(m_ReasonModel); + jLblStatus.setIcon(null); + + writeValueEOF(); + } + + @Override + public void writeValueEOF() { + id = null; + m_jNumber.setText(null); + m_jNumber.setEnabled(false); + m_jCustomer.setText(null); + m_jCustomer.setEnabled(false); + m_jAmount.setText(null); + m_jAmount.setEnabled(false); + m_jStatus.setText(null); + m_jStatus.setEnabled(false); + + jButtonPrint.setEnabled(false); + } + + @Override + public void writeValueInsert() { + id = UUID.randomUUID().toString(); + m_jNumber.setText(generateVoucherNumber()); + m_jNumber.setEnabled(true); + m_jCustomer.setText(null); + m_jCustomer.setEnabled(true); + m_jAmount.setText(null); + m_jAmount.setEnabled(true); + m_jStatus.setText(null); + m_jStatus.setText("A"); + + jButtonPrint.setEnabled(false); + jButtonPrint.setEnabled(true); + } + + @Override + public void writeValueDelete(Object value) { + if ("A".equals(m_jStatus.getText())) { + Object[] attr = (Object[]) value; + id = attr[0]; + m_jNumber.setText(Formats.STRING.formatValue(attr[1])); + m_jNumber.setEnabled(false); +// customerInfo = dlCustomers.getCustomerInfo(attr[2].toString()); +// m_jCustomer.setText(customerInfo.getName()); + m_jCustomer.setText(Formats.STRING.formatValue(attr[2])); + m_jCustomer.setEnabled(false); + m_jAmount.setText(Formats.DOUBLE.formatValue(attr[3])); + m_jAmount.setEnabled(false); + m_jStatus.setText(Formats.STRING.formatValue(attr[4])); + m_jStatus.setEnabled(false); + jButtonPrint.setEnabled(false); + } else { + JOptionPane.showMessageDialog(this, + AppLocal.getIntString("message.voucherdelete"), + AppLocal.getIntString("Check"), + JOptionPane.WARNING_MESSAGE); + } + } + + @Override + public void writeValueEdit(Object value) { + + Object[] attr = (Object[]) value; + id = attr[0]; + m_jNumber.setText(Formats.STRING.formatValue(attr[1])); + m_jNumber.setEnabled(true); +// customerInfo = dlCustomers.getCustomerInfo(attr[2].toString()); +// m_jCustomer.setText(customerInfo.getName()); + m_jCustomer.setText(Formats.STRING.formatValue(attr[2])); + m_jCustomer.setEnabled(true); + m_jAmount.setText(Formats.DOUBLE.formatValue(attr[3])); + m_jAmount.setEnabled(true); + m_jStatus.setText(Formats.STRING.formatValue(attr[4])); + jButtonPrint.setEnabled(true); + + if (null == m_jStatus.getText()) { + jLblStatus.setIcon(null); + } else switch (m_jStatus.getText()) { + case "A": + jLblStatus.setIcon(new javax.swing.ImageIcon(getClass() + .getResource("/com/unicenta/images/OK.png"))); + m_jNumber.setEnabled(true); + m_jAmount.setEnabled(true); + m_jCustomer.setEnabled(true); + jCBCustomer.setEnabled(true); + m_jStatus.setText("A"); + break; + case "D": + jLblStatus.setIcon(new javax.swing.ImageIcon(getClass() + .getResource("/com/unicenta/images/refundit.png"))); + m_jNumber.setEnabled(false); + m_jAmount.setEnabled(false); + m_jCustomer.setEnabled(false); + jCBCustomer.setEnabled(false); + m_jStatus.setText("D"); + break; + default: + jLblStatus.setIcon(null); + break; + } + } + + @Override + public Object createValue() throws BasicException { + + Object[] attr = new Object[5]; + + attr[0] = id; + attr[1] = m_jNumber.getText(); +// attr[2] = customerInfo.getId(); + attr[2] = m_jCustomer.getText(); + attr[3] = Formats.DOUBLE.parseValue(m_jAmount.getText()); + attr[4] = m_jStatus.getText(); + + return attr; + } + + @Override + public Component getComponent() { + return this; + } + + @Override + public void refresh() { + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel2 = new javax.swing.JLabel(); + m_jNumber = new javax.swing.JTextField(); + jLabel3 = new javax.swing.JLabel(); + m_jCustomer = new javax.swing.JTextField(); + m_jAmount = new javax.swing.JTextField(); + jLabel5 = new javax.swing.JLabel(); + jButtonPrint = new javax.swing.JButton(); + jLblStatus = new javax.swing.JLabel(); + m_jStatus = new javax.swing.JTextField(); + jCBCustomer = new javax.swing.JComboBox<>(); + + setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + + jLabel2.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel2.setText(AppLocal.getIntString("label.Number")); // NOI18N + jLabel2.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jNumber.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jNumber.setPreferredSize(new java.awt.Dimension(240, 30)); + + jLabel3.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel3.setText(AppLocal.getIntString("label.customer")); // NOI18N + jLabel3.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jCustomer.setBackground(new java.awt.Color(255, 255, 255)); + m_jCustomer.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jCustomer.setCursor(new java.awt.Cursor(java.awt.Cursor.TEXT_CURSOR)); + m_jCustomer.setPreferredSize(new java.awt.Dimension(240, 30)); + + m_jAmount.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jAmount.setPreferredSize(new java.awt.Dimension(240, 30)); + + jLabel5.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLabel5.setText(AppLocal.getIntString("label.paymenttotal")); // NOI18N + jLabel5.setPreferredSize(new java.awt.Dimension(100, 30)); + + jButtonPrint.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N + jButtonPrint.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/printer24.png"))); // NOI18N + jButtonPrint.setToolTipText(AppLocal.getIntString("button.print")); // NOI18N + jButtonPrint.setFocusPainted(false); + jButtonPrint.setFocusable(false); + jButtonPrint.setMargin(new java.awt.Insets(8, 14, 8, 14)); + jButtonPrint.setPreferredSize(new java.awt.Dimension(80, 45)); + jButtonPrint.setRequestFocusEnabled(false); + jButtonPrint.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonPrintActionPerformed(evt); + } + }); + + jLblStatus.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jLblStatus.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/unicenta/images/ok.png"))); // NOI18N + jLblStatus.setText(AppLocal.getIntString("label.Status")); // NOI18N + jLblStatus.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING); + jLblStatus.setPreferredSize(new java.awt.Dimension(100, 30)); + + m_jStatus.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + m_jStatus.setPreferredSize(new java.awt.Dimension(240, 30)); + + jCBCustomer.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N + jCBCustomer.setMaximumRowCount(2); + jCBCustomer.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Find", "Create" })); + jCBCustomer.setToolTipText(AppLocal.getIntString("label.voucherCustomer")); // NOI18N + jCBCustomer.setPreferredSize(new java.awt.Dimension(110, 30)); + jCBCustomer.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jCBCustomerActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLblStatus, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jStatus, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(m_jNumber, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jAmount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(m_jCustomer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jCBCustomer, 0, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(19, Short.MAX_VALUE)))) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jButtonPrint, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jNumber, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jAmount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(m_jCustomer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jCBCustomer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(m_jStatus, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLblStatus, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(36, 36, 36) + .addComponent(jButtonPrint, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(21, 21, 21)) + ); + }// </editor-fold>//GEN-END:initComponents + +private void jButtonPrintActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonPrintActionPerformed + + try { + VoucherInfo voucherInfo = dlCustomers.getVoucherInfoAll(id.toString()); + BufferedImage image = dlSystem.getResourceAsImage("Window.Logo"); + if (voucherInfo!=null){ + JDialogReportPanel dialog = JDialogReportPanel + .getDialog(this,m_app,voucherInfo,image); + dialog.setVisible(true); + } + + } catch (BasicException ex) { + + } +}//GEN-LAST:event_jButtonPrintActionPerformed + + private void jCBCustomerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCBCustomerActionPerformed + if(jCBCustomer.getSelectedIndex() == 0){ + + JCustomerFinder finder = JCustomerFinder.getCustomerFinder(this, dlCustomers); + finder.setVisible(true); + customerInfo = finder.getSelectedCustomer() ; + + if (finder.getSelectedCustomer()!=null){ + m_jCustomer.setText(customerInfo.getName()); + } + } else { + + JDialogNewCustomer dialog = JDialogNewCustomer.getDialog(this,m_app); + dialog.setVisible(true); + + customerInfo=dialog.getSelectedCustomer(); + if (dialog.getSelectedCustomer()!=null){ + m_jCustomer.setText(customerInfo.getName()); + } + } + + }//GEN-LAST:event_jCBCustomerActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButtonPrint; + private javax.swing.JComboBox<String> jCBCustomer; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLblStatus; + private javax.swing.JTextField m_jAmount; + private javax.swing.JTextField m_jCustomer; + private javax.swing.JTextField m_jNumber; + private javax.swing.JTextField m_jStatus; + // End of variables declaration//GEN-END:variables + + public boolean isDataValid() { + ValidateBuilder validate = new ValidateBuilder(this); + validate.setValidate(m_jNumber.getText(),ValidateBuilder.IS_NOT_EMPTY, + AppLocal.getIntString("message.message.emptynumber")); + validate.setValidate(m_jCustomer.getText(),ValidateBuilder.IS_NOT_EMPTY, + AppLocal.getIntString("message.emptycustomer")); + validate.setValidate(m_jAmount.getText(),ValidateBuilder.IS_DOUBLE, + AppLocal.getIntString("message.numericamount")); + validate.setValidate(m_jStatus.getText(),ValidateBuilder.IS_NOT_EMPTY, + AppLocal.getIntString("message.emptystatus")); + return validate.getValid(); + } + + + public String generateVoucherNumber(){ + String result=""; + + try { + result = "VO-"; + String date = m_simpledate.format(new Date()); + result = result + date; + String lastNumber= (String)dlCustomers.getVoucherNumber().find(result); + int newNumber = 1 ; + + if (lastNumber!=null){ + newNumber = Integer.parseInt(lastNumber) +1; + } + result = result + "-" + getNewNumber(newNumber); + + return result; + + } catch (BasicException ex) { + } + return result; + } + + + private String getNewNumber(int newNumber){ + String newNo = newNumber + ""; + String zero = ""; + for (int i=0;i< 3 - newNo.length();i++){ + zero = zero + "0"; + } + return zero+newNo; + } +} diff --git a/src/main/java/com/unicenta/pos/voucher/VoucherInfo.java b/src/main/java/com/unicenta/pos/voucher/VoucherInfo.java new file mode 100644 index 0000000..b5deec0 --- /dev/null +++ b/src/main/java/com/unicenta/pos/voucher/VoucherInfo.java @@ -0,0 +1,147 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2017 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +package com.unicenta.pos.voucher; + +import com.unicenta.basic.BasicException; +import com.unicenta.data.loader.DataRead; +import com.unicenta.data.loader.IKeyed; +import com.unicenta.data.loader.SerializerRead; + + +public class VoucherInfo implements IKeyed { + private String id; + private String voucherNumber; + private String customerName; + private double amount; + private String status; + + public VoucherInfo() { + } + + public VoucherInfo( + String id, + String voucherNumber, + String customerName, + double amount, + String status) + { + this.id = id; + this.voucherNumber = voucherNumber; + this.customerName = customerName; + this.amount = amount; + this.status = status; + } + + + @Override + public Object getKey() { + return getId(); + } + + /** + * @return the id + */ + public String getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(String id) { + this.id = id; + } + + /** + * @return the voucherNumber + */ + public String getVoucherNumber() { + return voucherNumber; + } + + /** + * @param voucherNumber the voucherNumber to set + */ + public void setVoucherNumber(String voucherNumber) { + this.voucherNumber = voucherNumber; + } + + /** + * @return the customerName + */ + public String getCustomerName() { + return customerName; + } + + /** + * @param customerName the customerName to set + */ + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + /** + * @return the amount + */ + public double getAmount() { + return amount; + } + + /** + * @param amount the amount to set + */ + public void setAmount(double amount) { + this.amount = amount; + } + + + @Override + public String toString() { + return voucherNumber; + } + + /** + * @return the status + */ + public String getStatus() { + return status; + } + + /** + * @param status the status to set + */ + public void setStatus(String status) { + this.status = status; + } + + public static SerializerRead getSerializerRead() { + return new SerializerRead() + { + @Override + public Object readValues(DataRead dr) throws BasicException { + return new VoucherInfo( + dr.getString(1), + dr.getString(2), + dr.getString(3), + dr.getDouble(4), + dr.getString(5)); + }}; + } +} diff --git a/src/main/java/com/unicenta/pos/voucher/VoucherPanel.java b/src/main/java/com/unicenta/pos/voucher/VoucherPanel.java new file mode 100644 index 0000000..0e7ba38 --- /dev/null +++ b/src/main/java/com/unicenta/pos/voucher/VoucherPanel.java @@ -0,0 +1,49 @@ + + +package com.unicenta.pos.voucher; + +import com.unicenta.data.loader.Datas; +import com.unicenta.data.model.*; +import com.unicenta.data.user.EditorRecord; +import com.unicenta.format.Formats; +import com.unicenta.pos.forms.AppLocal; +import com.unicenta.pos.panels.JPanelTable2; + +public class VoucherPanel extends JPanelTable2 { + + private VoucherEditor editor; + + @Override + protected void init() { + row = new Row( + new Field("ID", Datas.STRING, Formats.STRING), + new Field(AppLocal.getIntString("label.Number"), Datas.STRING, Formats.STRING, true, true, true), + new Field(AppLocal.getIntString("label.customer"), Datas.STRING, Formats.STRING), + new Field(AppLocal.getIntString("label.paymenttotal"), Datas.DOUBLE, Formats.DOUBLE), + new Field(AppLocal.getIntString("label.status"), Datas.STRING, Formats.STRING) + + ); + Table table = new Table( + "vouchers", + new PrimaryKey("ID"), + new Column("VOUCHER_NUMBER"), + new Column("CUSTOMER"), + new Column("AMOUNT"), + new Column("STATUS")); + lpr = row.getListProvider(app.getSession(), table); + spr = row.getSaveProvider(app.getSession(), table); + + editor = new VoucherEditor(dirty,app); + } + + + @Override + public EditorRecord getEditor() { + return editor; + } + + @Override + public String getTitle() { + return AppLocal.getIntString("Menu.Vouchers"); + } +} diff --git a/src/main/java/net/proteanit/sql/DbUtils.java b/src/main/java/net/proteanit/sql/DbUtils.java new file mode 100644 index 0000000..d373b30 --- /dev/null +++ b/src/main/java/net/proteanit/sql/DbUtils.java @@ -0,0 +1,55 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package net.proteanit.sql; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.util.Vector; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableModel; + +/** + * + * @author JG uniCenta + */ +public class DbUtils { + + /** + * + * @param rs + * @return + */ + public static TableModel resultSetToTableModel(ResultSet rs) { + try { + ResultSetMetaData metaData = rs.getMetaData(); + int numberOfColumns = metaData.getColumnCount(); + Vector columnNames = new Vector(); + + // Get the column names + for (int column = 0; column < numberOfColumns; column++) { + columnNames.addElement(metaData.getColumnLabel(column + 1)); + } + + // Get all rows. + Vector rows = new Vector(); + + while (rs.next()) { + Vector newRow = new Vector(); + + for (int i = 1; i <= numberOfColumns; i++) { + newRow.addElement(rs.getObject(i)); + } + + rows.addElement(newRow); + } + + return new DefaultTableModel(rows, columnNames); + } catch (Exception e) { + e.printStackTrace(); + + return null; + } + } + } + diff --git a/src/main/java/org/usb4java/examples/ListDevices.java b/src/main/java/org/usb4java/examples/ListDevices.java new file mode 100644 index 0000000..68e7381 --- /dev/null +++ b/src/main/java/org/usb4java/examples/ListDevices.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2016 jack + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +/* + * Copyright (C) 2014 Klaus Reimer <k@ailis.de> + * See LICENSE.txt for licensing information. + */ + +package org.usb4java.examples; + +import org.usb4java.Context; +import org.usb4java.Device; +import org.usb4java.DeviceDescriptor; +import org.usb4java.DeviceList; +import org.usb4java.LibUsb; +import org.usb4java.LibUsbException; + +/** + * Simply lists all available USB devices. + * + * @author Klaus Reimer <k@ailis.de> + */ +public class ListDevices +{ + /** + * Main method. + * + * @param args + * Command-line arguments (Ignored) + */ + public static void main(String[] args) + { + // Create the libusb context + Context context = new Context(); + + // Initialize the libusb context + int result = LibUsb.init(context); + if (result < 0) + { + throw new LibUsbException("Unable to initialize libusb", result); + } + + // Read the USB device list + DeviceList list = new DeviceList(); + result = LibUsb.getDeviceList(context, list); + if (result < 0) + { + throw new LibUsbException("Unable to get device list", result); + } + + try + { + // Iterate over all devices and list them + for (Device device: list) + { + int address = LibUsb.getDeviceAddress(device); + int busNumber = LibUsb.getBusNumber(device); + DeviceDescriptor descriptor = new DeviceDescriptor(); + result = LibUsb.getDeviceDescriptor(device, descriptor); + if (result < 0) + { + throw new LibUsbException( + "Unable to read device descriptor", result); + } + System.out.format( + "Bus %03d, Device %03d: Vendor %04x, Product %04x%n", + busNumber, address, descriptor.idVendor(), + descriptor.idProduct()); + } + } + finally + { + // Ensure the allocated device list is freed + LibUsb.freeDeviceList(list, true); + } + + // Deinitialize the libusb context + LibUsb.exit(context); + } +} \ No newline at end of file diff --git a/src/main/resources/beans_messages.properties b/src/main/resources/beans_messages.properties new file mode 100644 index 0000000..16480aa --- /dev/null +++ b/src/main/resources/beans_messages.properties @@ -0,0 +1,7 @@ + +button.cancel=Cancel +button.OK=OK +button.Today=Today +title.calendar=Select a Date +Button.Today=Today +button.ok=OK diff --git a/src/main/resources/beans_messages_al_SQ.properties b/src/main/resources/beans_messages_al_SQ.properties new file mode 100644 index 0000000..6c53487 --- /dev/null +++ b/src/main/resources/beans_messages_al_SQ.properties @@ -0,0 +1,19 @@ +# uniCenta oPOS -Touch Friendly Point Of Sale +# Copyright (c) 2009-2013 uniCenta & previous Openbravo POS works +# This file is part of uniCenta oPOS +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +button.cancel=Anulo +button.OK=OK +button.Today=Sot +title.calendar=Zgjidhe Daten +Button.Today=Sot diff --git a/src/main/resources/beans_messages_ar.properties b/src/main/resources/beans_messages_ar.properties new file mode 100644 index 0000000..0991376 --- /dev/null +++ b/src/main/resources/beans_messages_ar.properties @@ -0,0 +1,19 @@ +# uniCenta oPOS -Touch Friendly Point Of Sale +# Copyright (c) 2009-2010 uniCenta +# This file is part of uniCenta oPOS +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +button.cancel=\u0627\u0644\u063a\u0627\u0621 \u0627\u0644\u0627\u0645\u0631 +button.OK=\u0645\u0648\u0627\u0641\u0642 +button.Today=\u0627\u0644\u064a\u0648\u0645 +title.calendar=\u062d\u062f\u062f \u0627\u0644\u064a\u0648\u0645 +button.ok=\u0645\u0648\u0627\u0641\u0642 diff --git a/src/main/resources/beans_messages_da.properties b/src/main/resources/beans_messages_da.properties new file mode 100644 index 0000000..cd7097a --- /dev/null +++ b/src/main/resources/beans_messages_da.properties @@ -0,0 +1,23 @@ +# uniCenta oPOS - Touch Friendly Point Of Sale +# Copyright (c) 2009-2016 uniCenta +# https://unicenta.com +# This file is part of uniCenta oPOS. +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +# +# Translation kindly done by Jess Larsen 2016 + +button.cancel=Annuller +button.OK=OK +button.Today=I dag +title.calendar=V\u00e6lg en dato +Button.Today=I dag +button.ok=OK diff --git a/src/main/resources/beans_messages_de.properties b/src/main/resources/beans_messages_de.properties new file mode 100644 index 0000000..e8b9935 --- /dev/null +++ b/src/main/resources/beans_messages_de.properties @@ -0,0 +1,27 @@ +# Openbravo POS is a point of sales application designed for touch screens. +# Copyright (C) 2008 Openbravo, S.L. +# http://sourceforge.net/projects/ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Translations by Sebastian Muszytowski S.Muszytowski@googlemail.com +Button.Today=Heute + +button.ok=Ok + +button.cancel=Abbrechen + +title.calendar=W\u00e4hle einen Datum +button.Today=Heute diff --git a/src/main/resources/beans_messages_el.properties b/src/main/resources/beans_messages_el.properties new file mode 100644 index 0000000..3c58047 --- /dev/null +++ b/src/main/resources/beans_messages_el.properties @@ -0,0 +1,19 @@ +# uniCenta oPOS -Touch Friendly Point Of Sale +# Copyright (c) 2009-2012 uniCenta +# This file is part of uniCenta oPOS +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +button.cancel=\u0391\u039a\u03a5\u03a1\u039f +button.ok=\u0395\u039d\u03a4\u0391\u039e\u0395\u0399 +button.Today=\u03a3\u03ae\u03bc\u03b5\u03c1\u03b1 +title.calendar=\u0395\u03c0\u03b9\u03bb\u03ad\u03be\u03c4\u03b5 \u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 +Button.Today=\u03a3\u03ae\u03bc\u03b5\u03c1\u03b1 \ No newline at end of file diff --git a/src/main/resources/beans_messages_en_US.properties b/src/main/resources/beans_messages_en_US.properties new file mode 100644 index 0000000..2dcacee --- /dev/null +++ b/src/main/resources/beans_messages_en_US.properties @@ -0,0 +1,20 @@ +# uniCenta oPOS -Touch Friendly Point Of Sale +# Copyright (c) 2009-2012 uniCenta +# This file is part of uniCenta oPOS +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +button.cancel=Cancel +button.OK=OK +button.Today=Today +title.calendar=Select a Date +Button.Today=Today +button.ok=OK diff --git a/src/main/resources/beans_messages_es.properties b/src/main/resources/beans_messages_es.properties new file mode 100644 index 0000000..4de8e39 --- /dev/null +++ b/src/main/resources/beans_messages_es.properties @@ -0,0 +1,20 @@ +# uniCenta oPOS -Touch Friendly Point Of Sale +# Copyright (c) 2009-2013 uniCenta & previous Openbravo POS works +# This file is part of uniCenta oPOS +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +title.calendar=Seleccione una fecha +button.cancel=Cancelar +Button.Today=Hoy +button.OK=Aceptar +button.Today=Hoy +button.ok=Aceptar diff --git a/src/main/resources/beans_messages_es_AR.properties b/src/main/resources/beans_messages_es_AR.properties new file mode 100644 index 0000000..3a2d915 --- /dev/null +++ b/src/main/resources/beans_messages_es_AR.properties @@ -0,0 +1,27 @@ +# Openbravo POS is a point of sales application designed for touch screens. +# Copyright (C) 2007-2009 Openbravo, S.L. +# http://sourceforge.net/projects/openbravopos +# +# This file is part of Openbravo POS. +# +# Openbravo POS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Openbravo POS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Openbravo POS. If not, see <http://www.gnu.org/licenses/>. + +Button.Today=Hoy + +button.OK=Aceptar + +button.cancel=Cancelar + +title.calendar=Seleccione una fecha +button.ok=Aceptar diff --git a/src/main/resources/beans_messages_es_MX.properties b/src/main/resources/beans_messages_es_MX.properties new file mode 100644 index 0000000..3679b4a --- /dev/null +++ b/src/main/resources/beans_messages_es_MX.properties @@ -0,0 +1,28 @@ +# Openbravo POS is a point of sales application designed for touch screens. +# Copyright (C) 2007-2009 Openbravo, S.L. +# http://sourceforge.net/projects/openbravopos +# +# Author: Juan Carlos Gast\u00e9lum +# Translation derived from Spanish Translation by Adrian Romero. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Openbravo POS. If not, see <http://www.gnu.org/licenses/>. + +Button.Today=Hoy + +button.OK=Aceptar + +button.cancel=Cancelar + +title.calendar=Seleccione una fecha +button.ok=Aceptar diff --git a/src/main/resources/beans_messages_et.properties b/src/main/resources/beans_messages_et.properties new file mode 100644 index 0000000..971dea8 --- /dev/null +++ b/src/main/resources/beans_messages_et.properties @@ -0,0 +1,20 @@ +# uniCenta oPOS -Touch Friendly Point Of Sale +# Copyright (c) 2009-2010 uniCenta +# This file is part of uniCenta oPOS +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +button.cancel=T\u00fchista +button.OK=OK +button.Today=N\u00fc\u00fcd! +title.calendar=Vali kuup\u00e4ev +Button.Today=N\u00fc\u00fcd! +button.ok=OK diff --git a/src/main/resources/beans_messages_fr.properties b/src/main/resources/beans_messages_fr.properties new file mode 100644 index 0000000..d32b27c --- /dev/null +++ b/src/main/resources/beans_messages_fr.properties @@ -0,0 +1,28 @@ +# Openbravo POS is a point of sales application designed for touch screens. +# Copyright (C) 2007-2009 Openbravo, S.L. +# http://sourceforge.net/projects/openbravopos +# +# This file is part of Openbravo POS. +# +# Openbravo POS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Openbravo POS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Openbravo POS. If not, see <http://www.gnu.org/licenses/>. + +Button.Today=Aujourd'hui + +button.OK=OK +button.ok=OK + +button.cancel=Annuler + +title.calendar=Choisir une date +button.Today=Aujourd'hui diff --git a/src/main/resources/beans_messages_hr.properties b/src/main/resources/beans_messages_hr.properties new file mode 100644 index 0000000..8d9dc6d --- /dev/null +++ b/src/main/resources/beans_messages_hr.properties @@ -0,0 +1,29 @@ +# Openbravo POS je PC kasa koja ima podr\u0161ku i za touch screen monitore. +# Copyright (C) 2007-2009 Openbravo, S.L. +# http://sourceforge.net/projects/openbravopos +# +# Preveo na hrvatski: Pro-Sistemi <http://www.pro-sistemi.com/> +# +# Ova datoteka je dio Openbravo POS sistema. +# +# Openbravo POS je besplatan software: mo\u017eete ga distribuirati i/ili +# modificirati pod uvjetima GNU General Public Licence koja je objavljena +# od strane Free Software Foundation, bilo licencne verzije 3, ili bilo +# koje kasnije verzije ( mo\u017eda u Va\u0161em slu\u010daju ). +# +# Openbravo POS se distribuira u nadi da \u0107e biti od koristi, ali +# BEZ IKAKVE GARANCIJE; \u010dak i ako je slu\u010daj da je KUPLJEN kao roba ili +# je PREPRAVLJEN radi specifi\u010dnih potreba. Pogledajte +# GNU General Public Licencu za vi\u0161e detalja o tome. +# +# Uz Openbravo POS ste trebali dobiti kopiju GNU General Public Licence. +# Ako niste, pogledajte je na <http://www.gnu.org/licenses/>. + +Button.Today=Danas + +button.OK=U redu + +button.cancel=Odustani + +title.calendar=Izaberi datum i vrijeme +button.Today=Danas diff --git a/src/main/resources/beans_messages_it.properties b/src/main/resources/beans_messages_it.properties new file mode 100644 index 0000000..fe069f3 --- /dev/null +++ b/src/main/resources/beans_messages_it.properties @@ -0,0 +1,19 @@ +# uniCenta oPOS -Touch Friendly Point Of Sale +# Copyright (c) 2009-2013 uniCenta & previous Openbravo POS works +# This file is part of uniCenta oPOS +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +button.cancel=Annulla +button.ok=OK +button.Today=Oggi +title.calendar=Seleziona una Data +Button.Today=Oggi diff --git a/src/main/resources/beans_messages_nl.properties b/src/main/resources/beans_messages_nl.properties new file mode 100644 index 0000000..bf76b0c --- /dev/null +++ b/src/main/resources/beans_messages_nl.properties @@ -0,0 +1,6 @@ +button.cancel=Annuleer +button.OK=OK +button.Today=Vandaag +title.calendar=Kies een datum +Button.Today=Vandaag +button.ok=OK diff --git a/src/main/resources/beans_messages_pt.properties b/src/main/resources/beans_messages_pt.properties new file mode 100644 index 0000000..3ba0454 --- /dev/null +++ b/src/main/resources/beans_messages_pt.properties @@ -0,0 +1,20 @@ +# uniCenta oPOS -Touch Friendly Point Of Sale +# Copyright (c) 2009-2012 uniCenta +# This file is part of uniCenta oPOS +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +Button.Today=Hoje +button.OK=Aceitar +button.cancel=Cancelar +title.calendar=Selecione uma data +button.Today=Hoje +button.ok=Aceitar diff --git a/src/main/resources/beans_messages_pt_BR.properties b/src/main/resources/beans_messages_pt_BR.properties new file mode 100644 index 0000000..5efa791 --- /dev/null +++ b/src/main/resources/beans_messages_pt_BR.properties @@ -0,0 +1,20 @@ +# uniCenta oPOS -Touch Friendly Point Of Sale +# Copyright (c) 2009-2012 uniCenta +# This file is part of uniCenta oPOS +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +Button.Today=Hoje +button.OK=OK +button.cancel=Cancelar +title.calendar=Selecione uma data +button.Today=Hoje +button.ok=OK diff --git a/src/main/resources/com/unicenta/images/.01.png b/src/main/resources/com/unicenta/images/.01.png new file mode 100644 index 0000000000000000000000000000000000000000..66ea00fbf174f233e99a9ffaffd41a2ce3f2666e GIT binary patch literal 776 zcmeAS@N?(olHy`uVBq!ia0vp^4nS<c!3HE3de_JUDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5he4R}c>anMprB-lYeY$Kep*R+Vo@qXL1JcJiC$i6iGqoq zfu5n|m1~=TikK=qT^vI)oS)9H_qdWMb1asJeR)Rj72PvlLVFHyG;tMiwJR+AxFKea z-lKPW>a!nQ5=vCqnQ`TTqezppZsFu&XFcAo9UTfg{#4C-T>J3p)1AymAI0rE-2T00 z-t*S?->cuhKYw$2>ded~8JwC?PF>R`EK<eI{Ku^|^^|V_!~4}&vv_R+Em^<CFkiRT zDh^vxac{v*eg)wzr=EUVa_h0<VgJRp>RRPM@p%gxziwbOsaYMi+V<FUe?M!NXY+1( zKag*<O{v>mW5w*S@qDC7SAL`8!~G@y&fn;EOlydoaE>A1i~RM3<FCd3rC-0X=9BG7 zUIy0ZF$c9zeOE9)DswILX?2i{!$H$;PCpe-$SQ1KZR6j?{NQmP^NfHxj-vZ9WiCHe zb}}xw(66)OVg`@4J<HD2H1DOCc6{>eQh%V$eXJ@FsBcf2SpV_er_?p)HOT8&%s>Af zq|P_Zup#s5WD)-Z;$k(YgbUn%svH&G@Qm%k$79bN*VXc`xc=IFihq#I0c)|I{IA<S zIZw!rXS$m=Lz6FI9_!){tWVn&%6ZDBJon6FusD~jBcYxU`%~`6_t@n8sqcYeEUx*R zGuBu>75?Eny>dZ~|9L)!>u*Ixj!vJK_D89C(e3?DH~!NS>z?l1f8epb+l%}oaXvsL zt-8AootX6DzD57_pJM;&Se_jye-*L)V89-Iwwd>27~<n%5_6u-JawR&^;@l80&BJ2 zN?Su)YlbH2dsp+$7c{ZyB}DLV)JvFq@Tt+NqW{u_<N222>)+hs)76*SW$ix%OsEW= Lu6{1-oD!M<-Jetw literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/.02.png b/src/main/resources/com/unicenta/images/.02.png new file mode 100644 index 0000000000000000000000000000000000000000..a2c1008c7adfb0b7aba5b4eb6f73ac4612c3eff9 GIT binary patch literal 1015 zcmeAS@N?(olHy`uVBq!ia0vp^4nS<c!3HE3de_JUDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5he4R}c>anMprB-lYeY$Kep*R+Vo@qXL1JcJiC$i6iGqoq zfu5n|m1~=TikQ<qT^vI)oS)9H&JYQdXk|{~y6DC_yQAOl$o8ZfMGh?~9Tm2ZjZ@tg z`*L-jP}_Zzms3YWOi<B_>7a?5h@nPT!a@bb2o~*)7o1o>UUWI)b?trpyHlwaoyId? z=6x(IKX3W}$$sPF_h*)^3tGw2E8^_brKosx!h|Fb4?~qD5<)>doSJPdXu>m0Tb&YZ zOAZ8-mzN9nt(vnaLg(FrcQSVxgk)a6ejUAJ(`Lu6$U`al&aMU*uU_36dR1cY-o4&4 z-gK;3y`VnTX5p(zN=Mf$xEQ#<P;F1AcGZmY-{+XQruDCw-TwWiQH@->&FLKzf2G;+ z&v>`z^2J+AJPf%rHk>uJWc=J(fAZ(!L$A&GPX(TTpb}T|&;ONlh?-u|878UUDZWPQ zLiaV+-}ilT|LvU9Pp4VFRo?ow?jHO9Rj0RV+Uo`RaQB+;de$~IzWI*dX~VuNChOMS zeHLc@B7O0Wr71h>o*sAY%1m^U%}aVd^}X{u_MQ6oz9;@@HhcW**!_3^j!pRVSn24N zh~RZQ&z}0O`29+1xK_Q@iTPWsG_=5G``+F9tg5OiOyhq0odv1Z*4E}4^;Rn?Q%iMP zbx-woi(Ec*wKD0fp<c*7{+Zf&O1r17SBNh-Uccaviie@D$@fcAIk~xWSJ%iFo!2?d znGsYcvgx?a`6tWYbS^aVoRAci@or<b(Mj12-aqY9_#&=7So&hZDHWiD7ap{J$MUB< zSvmYJv)9r~R!^@#h}ib}|E3(f`Sy#Afbo#I@MQEgjqse=pK4EpPCwuyttR~>%jmw& z@y-*g&*V%5n*60Hdt2;JyC-#r*`G?vEN0yQZTEv^r<MS<J}iq%<}GIL(b~`UFYffg zhEJ!Teq!45UGK9;>LsP4IuEjZqaOG4o-+S%JSOeF$-n5&i9tUj6^`!MkoUH|d+(PX z*Z7nfR|>P|eU$BAy>wstgPZnlXX+)s@_aEr_kZ1=H4~CzGW7C&t=4h=-}O0XuKn}h zjvM~J+hZ`dP-t5BuIuac#4i2<hK}Bvhs&abO=`VTKj=A^viBSKoPCrbxAs@p?3NdX zlN64sY<Re~>m$$l=P7T~bJBCR9iMedQdd{Ec+#RiVR6jFi<zb^LSFr2a{l=;<@6hy R3Shou@O1TaS?83{1OR<F*O>qS literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/.05.png b/src/main/resources/com/unicenta/images/.05.png new file mode 100644 index 0000000000000000000000000000000000000000..0aed539b8516ab184151157f1135153b27d1e3de GIT binary patch literal 1036 zcmeAS@N?(olHy`uVBq!ia0vp^4nS<c!3HE3de_JUDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5he4R}c>anMprB-lYeY$Kep*R+Vo@qXL1JcJiC$i6iGqoq zfu5n|m1~=TikNFWT^vI)oS)8!&*)8*IbQCp8Lkxg>AByT`5MYWpX#?>(z`O{R%@z9 z^vxx?=g!@Hc542lDJ^2E!bz80TAX&zXjL-Li_!26DypohTmF1)`tk2)e!r{Lzf%11 zW##$rzyI$2{r6t+yzhI`LysmIW-O5q3gY3^Y-<s5cIr}8JUU@Ql81+(3W{*#<kL^X z9IRvBy?b}=aNgA5lCrX};O%RKR;h6Yoe^r=%jJ5oAUyoKRH*R525;B97AJDTw-!!J z3cGNp;l2*@`cuz8@3z?Ybj$n{vz1ZI`!5!yxbgJeKcI0uKl1*;>c0QyxgCnnCY<Fz zT=G!9^xx|ueWv$&PMc`jb1#{}YV!A}X?)@QNB6h!ya}}1`pr+AyY-OQ)AUA>%TA9? z^ET8yb)OKOZ+R{IRQdA<AM*9Jm&_1j%PMb{4cN!O)37N1^w)d$?peN*u|Ks}XJS%R z#;twt*8IGB>bv6i3#sBit=7Mu^KX)Ly6$Vij09_)kHwiFHGh_w-oJc#bHGo#Cwh_7 z-v2KAJty(}thmPIKUU6X<k4K#`mAkD;5A90A;p(A?Kv%7EBm%t`kTlWN8_89*DUti z{yG0!wpugLfyMf34lY}^OcP|?iA~=Ozn8XUe~AA*;d~_TOu?t>j$N4xH?prgs4~BS z_tbh8)Aeikq^8P?11(sV7g5Y({_fZ^h45YM1;x?p{&*F<I~>NIJ_RDJ7gfAxb@tTv z&g-_YKDuL2yMy7P@sZ@G$6Y}tHm}<$_Vo9J-@NmunhVC<srqit2GQ1Eyw%iwvanhE z{-Z?&ikB?v*qnL7o~NHyOtxSBmT68vT?{C|!+z~bS{t~p(f)-|v~us`rpxbsN6PQn znNk<2_j2!I8O>v@wbt|1-YiTHusLC}!_ls^q~y$JTW0+#_V+(`rC!`;{eHrG$qchU zvY#JT?VK+HRG-$j+wI9+iT`sx=ghZ%_|@+Q|9Ri^t@poiyTraUyiq8A>%yC+Th13} zT(<xA_3K%!^}byqj}OVMD?NL|pgNT8y+loSk=)-aXF^Qbp5JTC|Iebi-gw=XZQJ~U zOFbth3EgP!{=b!9GDV9yH#s+PZTjvb{~VpqTCv?b9`(!c$Zosnr)u4J(l&CE=R3N} ZKL6;)s<Z{i?*cO`gQu&X%Q~loCIHSo<`e(` literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/.10.png b/src/main/resources/com/unicenta/images/.10.png new file mode 100644 index 0000000000000000000000000000000000000000..6715d7563ed2cd6e1fd0e8324ebbfabd683ac3d2 GIT binary patch literal 842 zcmeAS@N?(olHy`uVBq!ia0vp^4nS<c!3HE3de_JUDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5he4R}c>anMprB-lYeY$Kep*R+Vo@qXL1JcJiC$i6iGqoq zfu5n|m1~=TikNnJx;TbpI6s}?-{G4macsHADYuA)5uGBQn$p>`de6pg+Bk2C&bnRy z-|Kd-p0a7v44sKak(;&zlsSo*dP#WxYq@mgV|A(D+`i{!_l=A9U)}xV>)gtD&#gc2 zdq4O6z2bDe)0-}M7zzdTw1_Ax9`(S%EWEZQYHjn~yzc>xr+gOOe?LFTfBE&-x`$NP z`LDPWHSv+o!Uwe?^QLB+&AuJFjpujS;lr=)%~9R6HY+}MiG{buH_@YYX|Zkj*A8r9 z>~UKh`=&DMCR3f=$*Q)mh3jk|RxQ63&#t+wX;Cb*La}mwQDIZP@%Q!G`}u-=SXupL z8QzP#>l|Lad(9svqx{cz>Yi3lOwzJpK470O84*y|Xl~96)SG0>yd!(&!Gwa4pRC_b zCRs)V?GuLxS0v6{wNBx?XxNnJu3ak^+*rx{z-PbmXUEFW6Sp?hX`k;F34SQqkecyk z>8Di_YE!-|@Av#Ew`2y_d4`O%smu4vpIUurZ`dcsoZx*xHy$!(_@f{2T|Z&*CtD9g zQIXe@4Ym8~L*hh>&OcoKX%AS)lIi@3HD*%1yr=Y?-&t2)-=L;=G^B#9;s1NX?RWF! z!|ND(<u}XRfjiJ5T~aDXYyW|o(~)sM<A64IeU)k4TbVq6$GtU1Z1<{-_D7U!-0v3I z%hP_?R-};q-R<cTQ#GCQUNP{@+LdH^ty=ic?Vb7kJ^z1}PFN()wc-Dj8>>@eLT4JK z#4t<rACEp^yFq9FW7C*7C05+q7VR~Zy;k~-d&!Gd_Gv%&NN9gqb83p>b14VL?|Z`T z>}Pn(|2lPQJa^C<=KHt!4kSK3%VeEqQafvz{)dwW=fCbcS0k$F=F~NDLXyf72~OP1 d!V}N_F^QGvot&hgQ3g!v44$rjF6*2Ung9Y_ac2Mk literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/.20.png b/src/main/resources/com/unicenta/images/.20.png new file mode 100644 index 0000000000000000000000000000000000000000..79134cfbbd5bf31386cf46657c14f2484b8e4a1d GIT binary patch literal 1002 zcmeAS@N?(olHy`uVBq!ia0vp^4nS<c!3HE3de_JUDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5he4R}c>anMprB-lYeY$Kep*R+Vo@qXL1JcJiC$i6iGqoq zfu5n|m1~=TikPE3T^vI)oS)8!&*)8*IlkSat6MdEvBpZzDDR2V(-(Qhyg664*;}{M zDgD3sP79T3F&^1P%~Mp(58u_h^6p5`KbIEIPwFD8AAh#C?U#GMFTMI)*}1%V-Tv=? z*X`T?{D*D-_xD*`txlIbW(ox@Ynh^{nCgXt8JYR(_wU(NRaLhh_~hrmkG%c<&6_)m zvNnJD`t|L?eX|P>7fkv)cU9g#k4VpqUm_x26M~a@)OLxz>oz>55jj^XTrVh$OKR_H zsXBJ|xApvGrRC-J1@|OQ^-0Uf#5mtwykOaZk9phH=Ez%_AFQh_%h~A>$vGoscXka= zSlZ{t#zx*J^JC85GdLV;#(#Jr|0lue@gbF#Ks6cfdQDH7?umWMR=IliiH`C+(zDKN z)L4J$md=$uWu?4Y{jR54la_DD&I@`f_o-@iGw1so_HSa`BW9~^%hOvDqv7*rf$8yY zt4=Xz#opcD`sl|r%Xu=<&ATKEmgQ`-k_fHT3DOhu*>h0$z>IPk|5=}pZ+5&ZJ|id+ zBy3`zGP%|H-bRUh%R2dMQxBb!$*NzeBc>_NoY%*m^U3E?s@?qfhqmvu-(^Nbb7dXB zo39gG$rBVNz3#o+tZ)4XY7>urH0l0qTe39a&y?T2p<4Zpr?MuUetPZV7vpT1zVzZd z=^Ed8B36BpSh7aUB+C7;@HLY;!KM|}`|1NC#a_)jz(4h<QtH$dsf>Si|1F&;zVMmh z&k}F%(?V0*1HSkET5(jXb;{L-wC?le65%`B_xzZ3`|8!L&QImk_MQD3ck*bD<0&ua z&DYmNZri-?p463}`5nSq-y`0MEr@-(5fq6Zy0X9U`<}1dzASC;>i;MH6@?~GxGDb3 zf7|L%x$Y?&Ke(osf0<oy+%9R8<v*btDO^vaH&<%TnDY1Gk#kMARX<7VZ4W;t35+92 zZr&U5SzW>{|KGimna{t;GO<zWZ$!1>p}WTC_kWb>`&fB5G5QX-d79((eeS0sDiSlx z&PFWGy;nTvyWO+`Mw>s+T61LIncu#A^VUzLRLc)x+fUwm<CNaNp@{Q%`;F9NOTHVw zRJM_vbu<2g>3r8yQzjUxF7e^i40giJl;tw5XWab!n^F<OWldmKWbkzLb6Mw<&;$VJ C{Lrxg literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/.25.png b/src/main/resources/com/unicenta/images/.25.png new file mode 100644 index 0000000000000000000000000000000000000000..f8ead91c7b5af89100797f424f17baea8b2195e1 GIT binary patch literal 945 zcmeAS@N?(olHy`uVBq!ia0vp^4nS<c!3HE3de_JUDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5he4R}c>anMprB-lYeY$Kep*R+Vo@qXL1JcJiC$i6iGqoq zfu5n|m1~=TikKBWT^vI)oS)9{@9<5OIF`Oih+C8Mq*K?Q(_WroLKml$m<tC_)|j}< zF!IjjzxBE66qiMKE@@F&Xfkn1gikN$!YNZWIhlot9slh2{^HE{c9Y-V`F(eGmH7U1 zbMJqyyT9kXW$}62@?VcE%y_3xTX0DzB&x~FJ0O!&OV@F!>WVEaNP?2HvbOG88KTA8 zX#BLOG9=DDaLc@_yF6rHnV(^cp3JJ{+|($oFt3#<dU6Bf^@*m&4rl$gT@%-GZe)|s zS{#3n(_}aA8x65;|0~?dIcpnoBC<B51s!-Dp1`#}{_zjCJx5>v|ICtbqWRVziy7~q zZH>xR{gfZI`S@AZAKkO$(<(Vu@GwgKS2`Q6HTA5H_yqY0QUz0=O2n)y(fKYgt-axt z-^%N+PcJFt`Ox>2^ThO5oHG)3rd8aW)!KB*?_k33uPiaim0fjfvn>NHI=xMPzf4nH zxG6kg$5pE*7AM(EsvEao%#-nNa@-?(ZP(Vh4yo%8G$b3TSiDM;_|}xxv;2g09h<<4 zH>^8WRi{eud|G)k=Uj1d%KOqAfd)){3%=>}1;0vtTUH($w&IQ15950s&nEXDU<_ln zKe4BwR5jN6<R_hgo4#DFhqz4s2eL6NkLcx(_#O0JB5kLBNEvs`M%Ii9Cu#fRSv3da zjyu0`PM!Y3{c``-m$OyQvwXXyRef@v&iB?+c@1grUwk+pIZyPC%lDU@JB}8`ui)XG zwP)Sgy0l8EE4Ix20p9t2oGVton72Ig9rsj4$H~)|27Zt}tCwP$84!H+pxlNS2etkS z`<M9H1xEDhhx}^FFDY{0&->0j@XDuF)_;>sG!^2XKI5tJ(mCE>pTgUB{7y{!{?)(l z6?|S3@REC$W|s1yp52CZcJojD<Mg|5U%Rt*xqS1~>I9ZN0ryIcU+exkFTNNt<=@=5 z4omev^{hL4;;NLFO<kVaz3E>#FYGN(^#7^Ov3mcc^Ut3zdwsk0l+FX&9mi_rpB3%2 zjPzXZ-#mE(E3^Ee!e6Ha*8NHfyRL^PDZ<mI^PTVP8z+C(P=CGn4KPPBc)I$ztaD0e F0st(%tGoaJ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/.50.png b/src/main/resources/com/unicenta/images/.50.png new file mode 100644 index 0000000000000000000000000000000000000000..fd72742f45843259daefbcb3977ca4644a717d7f GIT binary patch literal 1023 zcmeAS@N?(olHy`uVBq!ia0vp^4nS<c!3HE3de_JUDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5he4R}c>anMprB-lYeY$Kep*R+Vo@qXL1JcJiC$i6iGqoq zfu5n|m1~=TikR~~T^vI)oS)9{&IooCY3uId$m`m%k*iBVBh1ysae`hK_fmztF780C zw|-q5u^Abc&DLrh5pU|?5HoM;x}dcqkj2sU!`~G<0%{bpM31sZX)OI{|I}w@-~XkP zpG-O%S###e@AECj=HH(^Ted1dV@8{ocR(hmmagMc)fHP<rcPUMNhl<$2}#gr_PKNC zZpG+rXL{`ArZ#!z@oSuS@7|pqIQi|XSFf0V8>~+*UFwv2Yr)4uB2NyR-gv=OF!u@< z^NCf5O_w^P&RTHs=&dgX&-e}P4*igLEc}7z^K%Jx*@k=f?*07W|4`km_xfyucLyrM z@7kWp{!<Fkk-Mw0SSNkKzb$#2^cC$_|Kyw|&O9}<saJkdn&GyMHcR&It=)QUf9g(V z)Aw8QG*2flH1fUhggLi_`LuJu?&w#J+NWhVmIgbf&dQiP<C6``*6B;+%6m<9${+Yd zu6u8L;8Vm3AMTo0S1+j?GYshesn?^sW9!=7oSZr5t}S@hx`xx1xzzrE!0DugM!HYr z^k#cL;N?3ut$_Cqd&+#L^A2le)+A0l>XaI_VCUgok(S&>4|tyaHjMlBXNkW1j`;=p zwbNO$@?Tb;NvY%sS;i{0Iz7(e+LE*V53AxH{S2IAx&QAil?`<s_mlZfCok9(wBYCD zO^gMnitjsaOh3Rg?YKkgQisQ{OPI^&9M0akzy90nNe*`vejMHuv0{zLr;{fc8HAVH z%=u#?=ex`M$AWj_uNL!#35A4lnZz$<f3UZBM*sgaZ(qEKcz?Yu;q8x`%;z@Sh-sZ> zJuAy%o|3YYdA7`cU$3>r6?fO<t&f*h+9}tNHto1m>dpl_t#aQ<pO!t5?=AZ(dd}gR ziR=D0{nXiikNu|ml|M%<ra#>nAnEPzf8NQYP%vg<yM%r7ZqAhA<2COa?3FAfj?_d= z*vY=4?tb-8*0WF5AJ<nJ21s&CO{mXG5k7QLVe)^*eOZf(ET1e%lzqQio>BU5sgvFO z`MrN;UE9NydoyQSsN0U~j~pYf?`u94@u7LC<LrrU<!zQRx-ZI2?LLG*ZB&bS+&t@X z%3Y3Q%xm_Etk7Yz*{aLDI^vmw-uWN58~-f7uJWIMlT}+xTEu42?C%e}H#2_TwC<+> jo+J%R=eHIHeC1#0{Wqw`{3S0ie=>Nw`njxgN@xNA3FX(o literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/1.00.png b/src/main/resources/com/unicenta/images/1.00.png new file mode 100644 index 0000000000000000000000000000000000000000..f8db435d032dc7ba71e9c686663b9aa2be722f0a GIT binary patch literal 587 zcmV-R0<`^!P)<h;3K|Lk000e1NJLTq002M$001xu1^@s6p-X%p00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02y>eSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E-^XO*0N*(00Fy6L_t(&L+y}3Zi6roMN!p*^aAa=x9fo_ zl7sXL-364cdjT3(0-51qjAv|6!js-2<3GmvRo8V7Ee`kKTIh}#ak!OM(A{(5u%x-6 zZ~Ee}gr%W3IB}TUEt$MU4syB|MsM<e<aBQg@A4m+%Uwecw$uW;w^t2aYGo>PSBy!} zMHZ$&_oNyPEo+rfrj(1&l2!?2N*aU~G!mFQ|GZY8m$zQZSUL-ZH4>A|srjf*Z8umq zUow+Jgn}B0(fRrMQq}G6?T=q?fBZXCfZVlk0);dZlyg?~<-K$P&Jh&QNKnohDxgQs ztsJ03jRfVKM*%Yh`1o^cvwVP{obxDP;{u#G)F`1$FBKs1^Et$!MhRtlj{=SY?z{jx z_dN<Y3K$na$Q^5OsBz%jJkh!DeHTzS&vfp4-vyl7)dl>|1b#k;IMgViOz*=NKuRcM zDGoJCC=*gb8B1}v#wBPcq=Yh-;&81?(9Rw-d)yMVvj@!{7X$5Wt?9#-pq(uppu-en zpuMdepu-enq21Dspg^iI&|XO=P$<<{Xt#t21vSP(yE&bO!dllr`_=}b1+8nLJFE;- ZRexY7;WWa$D3<^L002ovPDHLkV1lbz_No8? literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/10.00.png b/src/main/resources/com/unicenta/images/10.00.png new file mode 100644 index 0000000000000000000000000000000000000000..afb27f275520203a35665fd4da02acbb48d99271 GIT binary patch literal 835 zcmeAS@N?(olHy`uVBq!ia0vp^4nS<c!3HE3de_JUDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5he4R}c>anMprB-lYeY$Kep*R+Vo@qXL1JcJiC$i6iGqoq zfu5n|m1~=TikLQgx;TbpI6s|Xn=KM3(#GG^I#nqtSG_Ch7?9b)(e!}5Eu_m;puQnf z#9EY9&~!m7N7mMv{jM9f3g)yl++b^&Tb-V?IAgJb#k`&6Wpi@kHkB8%>G*wA`LO5x z-Z!?!n`iS*O<gIaVam8vZNU|mDYF`agafjeynG#2a-s@)EhtH~*G*$@Tfo;;pR-6~ z_TnRVmYdW&tla6f_h8wTw?Z1`T>F2_o^oT8qM3X^zDQj8%-!0nul@SEU*qKZ#ip^0 zPu&)5x#7C;??L@N55)Jy$S1sExbrYvwyI!Kz5nN1(tGavzdtLxWgGW`DNcoDC*;%q zG6wvrlrG=5J1-^e+LOYK{hRgm-amJD|E$*#<n@6;sQUcZYda5#Jb(Ur@4W>vTvLM7 zBo0h^ulwHRr$C*^z1?x|Ux!Wc1}Z(l@M7!Tht_4BPjhz^UoXA<N9L5OgQjW*L#O2% ztBI9OpUm#;4R~KJ{Zwed6d^N)>P7GFI91M0+kZrFK@8KBpe8nf^nYh{w_Xpp*Y+!| z{BCV$5odrGXAO(qF2AI>g?o7GS>CPPtqC^s4c~_Jn&amd@9`~WKk|$fYR^Q=xbkEB zHk$rc{bmSJCaAHj=D3}6rS!YA*M9fb9-bqjv6O{(f%%O`R-J!afDVfM@LP0wfF7fl zrXur-2Y=?i{wS_Fh5zC1C(7mZmoFC?gN><SDBJhW)~V9<tLn*8q2Dr3gMc2eYT$a8 z`mf>HsaZJ}WgaTley-e?Zt|W<W2uix!;Lv<|9<T2{kh=JcgMPE>;E{{7pR?jcHtH< zKu@Uv?fGZ;ZhtP{pZ-_3AL&G077h5Pzan1diFSRbeEX~YE|*taHpQMakkX5s*Dr3> X6?Si5R*GE(rf~*OS3j3^P6<r_M_O*_ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/100.00.png b/src/main/resources/com/unicenta/images/100.00.png new file mode 100644 index 0000000000000000000000000000000000000000..0bad2db74dba0c577b9fbac7a02d8ffc7978a664 GIT binary patch literal 1217 zcmeAS@N?(olHy`uVBq!ia0vp^4nS<c!3HE3de_JUDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5he4R}c>anMprB-lYeY$Kep*R+Vo@qXL1JcJiC$i6iGqoq zfu5n|m1~=TidYOiT^vI)oS#njUl9^2bG*Nid!fdm7|9*nho3tsYi|)(6zXV8JJtO! z;(_wi0P$DLG6Gjj>57=uC^V(%%<SrS0z1~Yy3YROxkW&Zf9cNWcLK%zvme`M{JMMJ z()ga``|9+%%^9U)^S?i<*?<53-sk_G-7)^Ys%*EcX+RIB#xWL=WTq}d#-lSDl6)Kt z)fPwyV+sd0d9CkV(V3IUKE?6E{PqxA>F`@Jp_z3)OVip{naaE06quUAJ@s7K#sBM9 z{1f;ncZ!!;gxyj7Uqt5Zcavt^571jO!ytA2*DJezS$jQ~Uo?wPYvcU0tBPX+cYU>5 zHId<H-HI(+JJde&&)wlFJpY*|htvV__<0qVYFhuTUvjJeMaA~Hd3*<N-4ypPjj3O? zTJ>3Mh&6|X*TSVg=Ga%>XIt^*Rq~Xdvp1J+PMtP?%d`pQbN{;iOIkmD@0nd@<{`Ia zG^^iaZ@&3^d&t{ghZoudH42(L+&=$T<)L}Zf=M-#?XR`U#om^$$$e_HeD9Nn)o1M- z>+Bb3q;|0R?7H)X=}Gy5rT?^_XBqc@+EMsZP%gXJ@XWNp=Wl9G-Cg?2`^0;8k)<9| z3-&!f8F<W3X}{0+IRDSr?^r~?KK3nT2Jb@4KTpn0)^({94Va>o)nInMcv+sG;(ngg zyMO1*XtweDWV?<rEgPurne4+g+tw@X=hE<+XnJ7X$C=D0^e@}a+ooO-^WA>?%1H4v z=ZvXup5@rqbN>u=2<%$H==scS`;~Xjb&^*N{C~bFx4HIh!|oMn=k=MJ!p>XQ=~+*V zXBAn>k<Vyun0roXKhIwlySJM)`-Q#zYfSQ<%s!OEk!oLBeDa$z*vhpGyAP(mInY@e z?vS+aX<>RW&pcj%lHEB^*O=V~8`L2cV7|Jx&3s#3N&oV<(`}X=PmbShccv|1?QH|~ zP3BNF3!=~O>alJ9V>Ctj^YO>LlkMI=+PLjD(60RvJ8w0f)nazlT*P)|*5^O2e>#DR zEFbn=k9vLV=L-9OFAb!fX5P1qo?XQR_TLgl)+hhZSXNDRs$-8*tq=IN@7FHd>BrxG zlUb!b??YbuO`|WyKUL)8XU9*t&kqbU^8@d`@6?|VAFxMdXZMEtUtZjrmp<2Q=cc%2 zyCc=UF+cgv+!eHhS7SlUvB=ze^Pl?85YPBzK6k$UyN^P<&%FF5XDh!(tNM+7#o2jW zwwwV|j6#?*ik1GAR?fcAdg-&{zKQ#8KK{q_BKq91#I<JCyCtJskM3r&Rom}7|E0y6 z^BQ+$T(>qiESi!i72xpm(cORU_AiZ&-hL#p>g9rxZM{;3mMgT+)iz3PlDX>9@aTVU z)|Rjx?Ba3zv;&uM-SUWEbnES^y!!#d^|sAMhZ*o@L{R?Z&;2TYc=2V2Fr6$BU<t$E M>FVdQ&MBb@0BMytSO5S3 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/1000.00.png b/src/main/resources/com/unicenta/images/1000.00.png new file mode 100644 index 0000000000000000000000000000000000000000..e462a6ee6590f25d64e8d05af1960d512de4682f GIT binary patch literal 1523 zcma)6`9Bj10N-AYM`<;5AoI#hDo5@_Ek?6v<xF&7l`Aq9GdDfj3eVXdIZ8!EwZ<IV z93Pg62y?e-bA>53pDow(_WpwRKA-RL`F=m&pTES5XeSkA4P^iTpn^Q_;3o64G8+G? zAk!zPc!<n^QEpD>0B?G==4C-H5bgp804UizH~r;hSt;WD<tPAPcl*BtcHXJFAuA8! z5Z*ZVJGXE#{*gBU5&ps9IK%LpI2|)XV?z^b&hUHLNFIZ9fO`bl&yYi_)IHTYV_e}z zq^fUe@IC!$4|yQ!!~4gdW!xh6w;zUPzAG1@Zn=^@96bu%{8x2sq&+<=AE28T``eWb z5MViKhiP12qonPlkt7+teK~ZtA@Ea^G;0-`^phJkoU}DkYP%>LGmUa-nFMKg?o#@{ z=rQT~cEdEk)ct9!+47v<AbLM}v^gkO2+bQsycn`Yi=BVZN1wzt9VmNSktpAANgPbp zr?Yj#iA1gs=Y%QN0wqS`aug!AfH_-eF;b+|ZsYTEX8nxGlg_##uxjI6$lV?zz3<#t zL;0;#G{-n+B4{`}Yh!BYk7qH;%F=*jZN26+#i9lvPE?Q<^R|7?gJa0TZ+O=q<BYF& zRb(w(0@bp46~iCG@n5@;!bb1ddcU4*Z)(fA;-^EiRRKzcg6C#zIThosUJQRNjS*&3 zS(r@-JW^jQDiMARF=P_99q4&mS~Hk9-<)l3Z8XHQ3nAJ25h0193aR#+S~IFr-I1mX zH{Lj?qckjaqWi=ttJkd*N4^OIs&hzLUFvlh!>G-t-HjFrgz`F?b~+_-YW!;DdLjgG z5m8h8a@L$O4bXT;Ot3+7L{M_a$aLtEb-JLJR&g|I2{f>X;l*^eOZP8Wf@*2Z^iXbg z^QD0C@KbAt>5iX51CV(NWdEWoJidz$Pf@#h7@HaSxcBQQQ;!Mm;qSCVpCV$UYAg!V zmjGRU5-SNbuOvb<HTFz&vj=If>lh$LyseYuGO0r7Pg1qHK!95D3#K!<E^3`L#L7Dx zdjhnI%kEqn@(P0fX%?DHr!5~J5!t1!1k{rR(O9~RP-Wm)n?dY-#*z?C!fcqZYJ_t0 z1?50UWEjEc1WdlnQRTiH?+aK;E|i)aiX-q79tlR7t*VP&-*;)Oxf#uh&hAY@m{{1) z7qoWQ59-p(3-eMhw4;(?`zEBd3{ZGVpgQlKfXyd@u(0A2OfbHT-}nqg!bfRulu}xq zH`22wO1!#}ZIxrn5vF5PK><@H-oTuM3_+y3TAzZ36)`p*9Q_+>=EdlO<#nLFgyDl$ zw#(GG$jc&ShMiWJVtw}{t>CY4c=}8*N0e@z&ugO`;*YO?(1TaRf-aWsH%NKrx<kNY z39)yAV<A6h_f7Su6MsB7n#GNuFZldGeZ-BrytRX*$*5}Ue3bm&-|H7-g+gspMqXg5 zVy+h6YX#3ds1-O!TA9qhrgVBTufDDXeRvYrILw7H?HXLPU9~W;i$*$f^;FpKzfmGS z!nymA-+SM$Tb<SO5NB*l(w+qojFB*~m^LxpWo8%scM2`Bmh8Ju`%zHtYDw*@@emhz z4={kM+NB%U`bE~G$7Yw24Rz|w_yU&R+@jrqGRtnZt^R7+dC1(!*2i`;E8LloYpSRs z3mwJgd<KQtQmFaf-FQsEg4$4XAADJ>rnjtwUggi}w``lo#hu8Qxjs#+()?16oj>*0 zF;`aZju3zaY}shz>OEDK7;dq%McB>K6~id<Az`;6hw$%6KNIZeJ10$c&&SoqSq%kj z>n})Bp9cwW@rJ1%G_T)iF|R3s1=m@>@{ZI|VW*r)s-J^if+qPsem#^=wkpYXysdh7 zjp9@bvx0DJfspMpPtQrxHzBDG>f1&y2I==8SAy2iL#Ht*nX3jI!w&N}`oZzLPiFg# yH3?3Fdv7cESMS#DUH<%hP50FS@PA=<f*3+S61b#i<})e#WB?L@c6f8nFZCbKGV7TD literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/1downarrow.png b/src/main/resources/com/unicenta/images/1downarrow.png new file mode 100644 index 0000000000000000000000000000000000000000..be595bb3f59a8d9b8ed4fee3d385991c98322d56 GIT binary patch literal 567 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP{O6e zHKN2hzo4=xGd-h(!MP|ku_UuBRlzwwH#a}8Si!NRq$o3~v?Mb>Pr)xgPZuPfT9llb zm;>Z0xTF?kmVq@CSKr;R0BD{R$h_eEw370~qEv=}#LT=BJwMkFg)(D3Q$0figD*u3 zfv&grba4#v@P0cf*6)ymNb7l_T`bcssP35Z?u6<W$KJLU7EzJ^D>{_&Kd*Chc533P z`pYbM^z|L4S$)kR7uc26e@;4i#`gJ^%S^$47fWk=<~jAo=g+Z8ijjg-ciHj9OD<h^ z=-}xes*k4j#7(>ZTBFS7js0iqqkV_&UH<NUMEPFEG<K0&jcvRlW%7@wpU7FbR>zW2 zU`x!C*-H|cTj#bPIgzhq{Bzl+ADU<Qw${E+dfjJ|<8WioTmHyZPjY7X8!6w~;i=&6 zb(pQ?>+AEXo2DyoI-~6|Ei^lvZxip*L}sUD{{od>=QQgSb4~iV)Toqw^>nYpf?;|b zr=RC_tT|i!vBP}ZB~$sAQpcD4KY!fsJ^!**c0r+X2WLENZubmJo4DqKfEthd6rH)1 z5jIabHho_lW%1FV{*2<Lf1+n)cM2@~6>R>2Z4pz$r$w$>wZH&p@O1TaS?83{1OUX6 B<^uo# literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/1leftarrow.png b/src/main/resources/com/unicenta/images/1leftarrow.png new file mode 100644 index 0000000000000000000000000000000000000000..be39dabf808e412614b3b0e8ae071016cb062237 GIT binary patch literal 603 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP{O6e zHKN2hzo4=xGd-h(!MP|ku_UuBRlzwwH#a}8Si!NRq$o3~v?Mb>Pr)xgPZuPfT9llb zm;>Z0xTF?kmVq@CSKr;R0BD{R$h_eEw370~qEv=}#LT=BJwMkFg)(D3Q$0figD*u3 zfv!*Xba4#v@Lqe>+mFdnfbD@5lludXVwOH5^G6(;9T*!K7B&4~aAYap>keW&J!WPV zJeBoWM`IE9GPR##S3Up#Pnq<N@y556Yjt)UQ`)$__eXVnX{KZ8%7xnw$zNTn93B+; zW8tO?1z%fz4pe(qzH2`1?>Zqc<kjb}fLT8mm;?vRQ%=5S(>6PN_m2P;$<1m4aWkv} zW+*LQ@Iz0a?%S&aKc$UkrS0FIpI0`29}6dteY(1$F3GvBsi$pndgF&XH`<bWdzM8i z*jR5;us+1QbECtKpBvo$#SZee_dBsJd-C9*+KG%4JgnYE&eGrBPrPWtJ#7iQqX&P1 z@2d5RSH*QazsY!fn*bD+G5Kzyx{FU`*9nbTtn0Y8tK16|c>iElM6}}?-H@cFZ|_7L z-5j^50-1|+g*&p9d|4+h3-H|Wu)V-pIECq+zJqz<_iIgarF}n4f8c*#m-DJF$JOp5 e|K6Y7yd&fx@yg*h-%7(8A5T-G@yGywp5$m=Np literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/1rightarrow.png b/src/main/resources/com/unicenta/images/1rightarrow.png new file mode 100644 index 0000000000000000000000000000000000000000..6896b3fe0ee67b01384b148b7b2ce90ffe480e14 GIT binary patch literal 582 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP{O6e zHKN2hzo4=xGd-h(!MP|ku_UuBRlzwwH#a}8Si!NRq$o3~v?Mb>Pr)xgPZuPfT9llb zm;>Z0xTF?kmVq@CSKr;R0BD{R$h_eEw370~qEv=}#LT=BJwMkFg)(D3Q$0figD*u3 zfv)%Sba4#v@Lqd0+K<UlgzZ6n*#V&#rhdJ{swLd(T2#Lr)b8r(DB@J;h>?4KSG!AL zK>(A663_9zkF7?Wf&P=<KV0Jbf8NP6R}QTToXegN8Kl2D@$Rjdt$)fti<)<Itqz!b zd3)DuR>QteI{lw|#HK7$+}Cm`<iV%OH5~gUJaSoJu~1c9zDKcjqeG&Po!Jkoll!^n z?4RiP(&~ixB<a=((ifZF1Sndk@SNmPF=95-h+Y4&bkaNTCBIV&N@O2!dun!0S;TsB zUUN#np~}Ur6JJa^`0VwgFGr8v)RvsV^hma|qMfI2oupjg8dbsUi3bmQ&Q2`ety%cT zhiz$g+jWy$9E!ITnw##X{J5Z0+UPNths)icXSTczhm74M{<itCJJbZ$T@=#)azFXK zU&8-+H3m8F=H`7jTR*Y!<EcA4Ig@@zWqxV?dFlJE8@sqNwtZVZxt_6EH*c0tMA`;m P_%nFA`njxgN@xNA!<Oi? literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/1uparrow.png b/src/main/resources/com/unicenta/images/1uparrow.png new file mode 100644 index 0000000000000000000000000000000000000000..c925aadb7c9de54e2140dc3fc6cdea84102dcafe GIT binary patch literal 564 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP{O6e zHKN2hzo4=xGd-h(!MP|ku_UuBRlzwwH#a}8Si!NRq$o3~v?Mb>Pr)xgPZuPfT9llb zm;>Z0xTF?kmVq@CSKr;R0BD{R$h_eEw370~qEv=}#LT=BJwMkFg)(D3Q$0figD*u3 zfv&glba4#v@P0e_trt_EK-+!q4???I_O|GyzF*-TG2ze#pVK<drxpqPKbx<~b9&#I zSrZm%q*!g<@<OhES(?34d_{s~`m>pLH}5`RQ~#P})g#BBQ$u#yX~q6LH2-bS<8pa* zc_HWPX_F3LSC!e@DSY>L;J5kAGJ8&VY)M-+#fs5OR&p|D+Z#KzfE1$+*5vmmxiyWf zzj5BOHoE<tQ{+~P0Qa$T&hI~8dF?b?wv?sRVsqv0hPBpC`&7kpX0h$BjXk}+VnLkj zt1i{*w~FP5*)}Ew+x$6xX>VffE1u1DFBLDRG)D-Sty^PVXtVoT%B&|Zo?qxKS)3!l zedyLvbNw~>Gp;R@e)3^T<JDsMmAk$;rsdXDnz&a7m3HmCBAfP9=fJ0x5+`E(_4?Z~ x)>~a!dM;wpR#%nm%cqrRT3s<c|KGCF-;=j`+vbmdT!Ep@;OXk;vd$@?2>>wF<_!P< literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/2.00.png b/src/main/resources/com/unicenta/images/2.00.png new file mode 100644 index 0000000000000000000000000000000000000000..0949cd6387be11bba2e8d117049305cd2e8418f6 GIT binary patch literal 866 zcmV-o1D*VdP)<h;3K|Lk000e1NJLTq002M$001xu1^@s6p-X%p00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02y>eSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E-^XO*0N*(00PoUL_t(&L(P`ItJFXcfETRQzrephuof#7 z@dwyzAzD}{Ru&4PHukobB4QytFLyo*3mYp73sKNYu)5@3p@@}=pmA<*FK?6klHBHY zll|Z;ZgyreliY<<d7ejY7pPC27#v!kP=8wt4q+eQbt%}VLr}WD{h@D%M$b?kst==r z1`KI*(2$|@f%m@DFoa#9UTr!-4Sd@L>eIzmsK}?TP!Av0Ldm{#Wz+gO)gHD8CHit* zy40+L-M6+sCB>!>YWvv-eX5e#ag|K3t0a4<#_1jLEarJ;rLTRlK2*=9hh*7TYMkY( zrXSTPJyFUJK&iKVvCuA-H_Im33zh6#RHN*a8c#3C^5f!cG(D#C1Ea5D4;Wfm`sHHD zokw^+POqAq@Iim>gX$2Wl&5{#Eccqum=)B47s2Q;U^EZW>hENu}s~1bs8+5)@ z^5li6^RAf@HIz#_Lrp>`OMQ~1{>YpEFr6<|lkBp-0ps+h8Bs&IZLS3s4yn8+?wN1E zIWwY$a@VyHDi})j{Oex10pH{X{8L+B_L~tkl<#6KlsuI3wST;L`q_OmUIFF1icsPZ z%71}di{F0s-i%g)YPz@rCH1Ym7_XS${dfIm381>JmY{?_m8H*{CqMV3jsexWO)a3q zzLc;1ncd~nOGO;8>wFok@j9wWdZbuB$!?d<0Q=mh7!0l2o*mqM^4WuxbD)~zOALlo zJxvc-%Wq>2KzTmIU?|m-&->)1_g62Uq;Dx_E<t%d#9%08>0j2<Z}PX~zB9XPsGkop z7(!X<M`g)6=iiW@as%F&-8IzHhZqc@+RFDhYe7AIh(TA|pqg03psQ_AO)O&2)g~xE zCNb!06O<p57<9D>%8yA5y4nQg$0P<_ZG!S+5`(U`K{c_6L08+Lnpni3t8GwCEMm~r sHmD{RG1$d6s3rz6*u^%eW_WY;A5QjT74ZEK$^ZZW07*qoM6N<$f@tiM7ytkO literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/20.00.png b/src/main/resources/com/unicenta/images/20.00.png new file mode 100644 index 0000000000000000000000000000000000000000..1b57579d6a2801b2f2f6c748cac4816c6e004b2b GIT binary patch literal 1038 zcmeAS@N?(olHy`uVBq!ia0vp^4nS<c!3HE3de_JUDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5he4R}c>anMprB-lYeY$Kep*R+Vo@qXL1JcJiC$i6iGqoq zfu5n|m1~=TikRy>T^vI)oS)9H&Jb~wImUkU&>?oEvZlE|4qOs<H1P-#Imn*n(4%o= z!l^^zQryy_u7aiuTm^a+V#><&8Fh8G2(Zjval}hR(R%Z04LdE@i=XX{tEZp6BR=Ww z-qp)~sNQ`4``_U|<=>u_9nzZGb=l#f>Vg+S0VSLoyI4eGnY#2CU8grJ@<tJsW_?_! z{rF+vu~hlbM<tV_Pu;xGpLvGcTC;vC>qS$sj=V6bx$T==8<PTWIP7Rr`#<C7rl5X_ z#CbP5UWq)BPl~Bov-<HP@z0CpLV{T|#15Lo&)p)EWMg%}W@qQmhjm%!)>p>uShz0C zH2!Pp-xq1W?mC^FzjR}rRBX(a*If)pl`go*&+K$7U+}(r-I9ahkH0)P9Fz5>{hQ53 z^S7DvkDosId&%FTE$6;{W;(j(Le^^0;Ip=_b)vgC8_%(R{AK7HXSP*%y+QB(==2>G z9e->b4E0TZ&P!=JJ|VufXp7>jnC~;x+Izp{Ia*~q``;*@t6e*{`Og}Vs*UDXuH@hP z8Lqsai~C99-4^}6*RK^V@0;kizg@$ds`oNS;H^_#*n%55D>{ppC2sVO|DDvk@7obw z>ul$nww`ZUpQN*Poo$(Fe}0kl2UqjJs`c{8zjo_pzS=W)d!YaHbH6r;|BP%*GF~XU zCwtb^@GL3*v(Lm%2*1>6ntJq+%I$ujBQ{1}*nMDS%GbEQ>#pq=kN(}#w_yE&rJiOE zAZvLtruM(+EdCg}SEu*;6TZhMCuhnARx|C`(GJpiamCqlYi2E5dv1C7<0UIS&9_~V zD-Z_Rr@ZiZowrfq*BfOIeD++r!*H|xkI9s5^P4Bl&#YuP>gKq7$JVXScG~nBaap}Q z>r<qB!rysjoN?S9QLyHO=8v0}XdYb>AGu}G`4Y1ZamD>ycTZfO^7n9Fc$$K}c7P67 zwSw5PS@JHD(pwo{*@&A@SRc^7B*mxV!YO8v?gPK>pIfH(Pwng;hnbxVW?eAR*!5}; z<1dTCpJ#tu6uNz$Tcq2;SN-`n%>%AESM${WN%|LMO}WRvXzrFz*RxIIZp>V#$tCjH zN%&9P>=z*$@*3ot+t)s^U3q%e<)qzn^?_1{yr#a4bbPE4VHxMDT|dE&@6~=6U5(2e i1d})<<(IG6@c$Bzz|=Rgz2AY^mBG{1&t;ucLK6VMYTobw literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/200.00.png b/src/main/resources/com/unicenta/images/200.00.png new file mode 100644 index 0000000000000000000000000000000000000000..04a64ea69213c77a634b83e51273ceb69ed63551 GIT binary patch literal 1400 zcmaJ>eK->c9G((Vrb{DCI!PBIVlrPhA>?Bi+p6W;62|h?WsOuWTb(2^gkop%)vO4U z$Fa>fiHsvVyBjf|%g5NRThIM_&;9ZK-sgRv_xU})e|~Q!-0QrGvX(Lc08nvrb@G+* zk20KAQjpE(7YMpCl8g5}?+B<J0DqPVc`VEm1_02r_DO>G$n@SgS9Cl80POe%IZiAs zOlE2(IHMB$Vj~iggRh4J;({Y_2`0GkgrgQFr%lYPM?TieLh^HNPB6sPbAROrR)hV( z9My-4nR@9J?##?K)%&R@so8qe^cT6qdZ%h!jbQgkN|g#AAL_w}aL0`S$~YuaSHDI+ z+w})uw;b)%kl7-NdeeL*0yQmuHr~p>wlP{7H&<;5ORcjz(!T|gfj;3lrD|d^X$Wqn zPdj`Nv45{&hCJw8I_Y~D>rrWl>wnljKG2e?gl3n>7JruDWZbb{F^@wxbVnZjN^-A9 z`iBHmx-1-ey53G;Ac|_)%T_*Za+93vWsa<18vV;I4+)(V)1u4pb{1R=K*BAmUt13$ zEBXTs2R_mZfM?&EZj4$Jeepz_Doq8D;vedPUe$|0DkB9ER@dQ=PG_+&rtWp0t4^s; zuTtM7+7SoYGbL;~&}J%nWud$wb(NO0eG21Qn1WtBN;|7$QQzyC-+E5UwM9X`#AFpq z2<BQ6KW5h?dcAW@{L>1MG~HJ_zdqcwlrKQ$z8<K%Il~eBGVD;UrRcpPg~92-%ZoD) zG{`%5#X3W-dQJLmH+>nVxt_yDm(%#BPaZ&QQoeAPOroM<<Aui;FfrR;(L!m6&eb5y zIIpa4ISmYP>aHmm5nic~#@)1BxML&S*KKLw^%x)j)kBjbh;q2(d@IP?c`0@zwL=1> zp%e|aj*y}041%V}hSvEh5F*Wgkn9?dVooh!Z#9>!>$mhj{2<0fPp>fS=NA2}yrE?A zenT$};~DhWeY8HGd)b8F6}`%^?`j@oKuo((*sQl|K~KeK-M$u|dU`A6TUv2c5@Vnx z#%M)K=5T!OKn@+UAZ2>vlXJ;jV}6(IF@ERdpV(V*dDYp`Pp0|_3ZRPJwY(M_Jt-9V zq4M|1gF81Yd*Pn(0hB2NKKGqaeRN(N5frpU#o<H;M4AZOiz~(}cP$QV;+&?~AtItb zmS?n5WM0^Xx@5Z=JlUtdjn)k-$*cAnGcSR$%H(qFc?MQ$tPbBgY%IQ5X9Bee91_@R zCPSQ;$J1_S^_q9HBaX}V78zbm$}U9ZkInMmqnOu2wVlFMZ(!IrY)zsxw$QpG%_{N6 znBTsgy9>9Y-IGB+)Aj_rc41Oa7$88xaP;106}8m5Bu+!Gv^tB4YMOX{qG~tj{2m(- zC_J7uQyfOw#r&)jDA+J-Q#LQ0T3r+4iu&=PqK1-nn82tT!uAfeze6f3ZJ3?y2?L6I zwB!qRJnG$u1|l1t6Y*!E!+gyK-W=DM1;eb~P38^;w6o53tcTcRi8=^y#`dc-lvmHf z39r)LJRXZs6YV4Am9OR7nO;1cst<)Uy}YuAlUzt`P(9NIGz2=vXghpI-Wv0aco#;2 z!gJhpJ{{g+nh}a#OFP8l<95Xj8qldD?V|Qve{V_mm=Hg$E&G<+&Uwp=$4WhyMoj=; ztp~3e9~x8~uX$Tvml*XT!THUvm&lu>9=sK3S$VBZDJBm5{sdyOpyQe%j0HX2{T!!O z#(M^^&PZvT{*ad#OD0PRAOhc*lgV8k1&M^6dz<c$?!QAyq`9Q95y703@P3K!CQq+% zIr?d3*_OlZYsi;fpQvnNQ+~M1z5nTte`^IiF`sH#RzCO0qdHJli~u)hFQ;0^p!9zL DAuq60 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/2downarrow.png b/src/main/resources/com/unicenta/images/2downarrow.png new file mode 100644 index 0000000000000000000000000000000000000000..4d615c20ea00d0a97af916240f4ccba8a4f99868 GIT binary patch literal 595 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEa{HEjtmSN`?>!lvI6-oC9V-A z&iMtEMVaXtB@E6*sfi_-WvL3z`MJ6IdBqBjB_&0fNu?#3`FRR{`FXk^@zkQ^%)}fZ zSHUH<D6<T#p}6|)h6O<Lq(J5c=ckpFCl;kL1SDqWmFW4ohA5O7>zV2q8W?;jTFAh_ zIK|V&F~r0B?Ulf=CI=C=2fJCOJrIiM@=kEqX>32EqphR;bwy^{E$R0&Bg3M?`rLJm zFW*)TkQ5YtbFuQV%(J>Pf1a~D#LvF2#By5l#;%EV^TQ*5HnND{m(<{KO+IsMDnp}? zGJ|4><Bfe^`=0y~np3aH=)utZ$m0UzRE8}K9M<LUCg%7z#mK8W6t)y}uHrjkrV!(L zV{g3N$r_IdZy(Ayn61+c2-+bm!Eor`;-80_0xrc$`rW_CCep^WUpr#jSssC93{6q9 zD=%)+y&0x(*HwCgyhTmK3Z=jkHUcY^Wo&Lvbn$LXk$%olAG20&!&erz27z3ki59^M z7oDUFzU@rOd$?-8QNk3)Ln00qRe=wm__kUcmTU-Qt1JI{vs!>NL8jnO7mEV>6005~ z1MjCU7N(JFJ6Q}qcL}^<Xbx$Yf4A%8#9jRiy+$)wO->y+Uc33Zn!Fu1OU7j3BeSGZ z9riPxj@o(hVw*#QV9}bB{PE_Mcc1+H`un<?wdo!2$#?%wc#&)FTV`9cCvm1)wVd6( f9V<?9xBX}6t$kFSBh--$j70`dS3j3^P6<r_vJvcK literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/2leftarrow.png b/src/main/resources/com/unicenta/images/2leftarrow.png new file mode 100644 index 0000000000000000000000000000000000000000..2ed89685d340c0b1a3eb9cc214a2c7b26b317540 GIT binary patch literal 588 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEa{HEjtmSN`?>!lvI6-oC9V-A z&iMtEMVaXtB@E6*sfi_-WvL3z`MJ6IdBqBjB_&0fNu?#3`FRR{`FXk^@zkQ^%)}fZ zSHUH<D6<T#p}6|)h6O<Lq(J5c=ckpFCl;kL1SDqWmFW4ohA5O7>zV2q8W?;jTFAh_ z*z4)y7~<i*bgHA@AqSDR`Q|SKBX+(E+|l4^8`yuq$wg$V29uCLfWXa-;)1TMt_d6+ z8Xe~kW_&r@bCTQdQ|_tn|LZSZDC69b{`St)RsNf}v`_!FPmbvqVOh<{5%!Ur@wNE2 z!iLuq3syXHTG7U3nG0km?0Dy}qfbhD`Z*^#&fHk*4VA5I8J5?TpH6I(SK_@gWBOma znEsZsyxbf61cgEtJdNp}Qtc~U_P&Kh^jZDI`G>!HXx#ebxJ6aP<HM}RRvV#P^&1l2 z?^AMQjXL+$qjF8I<C@rs3z&4DSKVS3dS4;%Ug6<`i_teOH+8OK@6^+J!5rf+?eR^= z<C|82MnK~|rFH2wo=bm;E%_zNsdYhcUAl}Xf6W9r4k+g&PwojGRvFucOtlww%qvu} z-lS+PB&70W-pkcZuO;0-CEGtap3%@(VEg#Q$8Kiz^$@m4;v<K|CaI&EvJb0{O?-5v z^|E=$1^byX=PiO}u|9YsYp;2><;cJ3={(afwi;Cx9Wna%uQu?b9Ygejd#_f^Hm?Cj OAA_f>pUXO@geCyz9`nus literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/2rightarrow.png b/src/main/resources/com/unicenta/images/2rightarrow.png new file mode 100644 index 0000000000000000000000000000000000000000..8657601f2b09062d870517217dddde06342d2a7c GIT binary patch literal 600 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEa{HEjtmSN`?>!lvI6-oC9V-A z&iMtEMVaXtB@E6*sfi_-WvL3z`MJ6IdBqBjB_&0fNu?#3`FRR{`FXk^@zkQ^%)}fZ zSHUH<D6<T#p}6|)h6O<Lq(J5c=ckpFCl;kL1SDqWmFW4ohA5O7>zV2q8W?;jTFAh_ zIMdU`F~q}r?o?ktCPx9c?7RblHca0A4+Vd5&1+FU!{i#6;xc7ELlei2IksJkIFz`2 z8C+R(q#rfCdgpr7FV1OV_<i=4nS}|Zd38(=EY?+BZOKh9|2yw(f$gT~XtsshrmSMQ zer4KfrOySn$(wg+IF&ZGoU-|ne?DT(8P=Hk#jK7o>(c-JdOEY=6A$mYeHonBH&2_g zjL9o_%LeC~b?LgAbzD3CIPk7~rtop+ysb+NI2{w4TK+^h)%keun738Myhzd92`H=k zsMt2!v+RXaS%=iVS<FYCS6!RbQ=+Imae~~B333;NfF^l<we|QKc-R<dpU%Afl?5OB zq|z9#E3=-Q$9+;R>qpiyd%^3<4?EX!cj{&RDEQ`ec&8lacPqU)`xdl?82_DJWGf_> z->z`ajh8d7JuV}rzvXxoQ<CnL2?d{gKuYbaL<;`2h`l)5_j=-oj9`Z?oouT&oIU*Y z#HE9K8xFH?aX7qlUZJ9^lxv4cz~P#dBHP6Y|MfVkw+A)W-;n<mbG~Xn=XGX*b=6#- hC+F)G?CqT!e^2<X(X#C1I$%^Xc)I$ztaD0e0sy<=_~QTo literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/2uparrow.png b/src/main/resources/com/unicenta/images/2uparrow.png new file mode 100644 index 0000000000000000000000000000000000000000..2690aa2aa37e0ac142dcd689611024d55128f9ba GIT binary patch literal 606 zcmV-k0-^nhP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004XF*Lt006O% z3;baP0000)bVXQnLvL_-a%pF1bO1wgWnpw_c4Z(#Z*6UFZgU_(baZlQVs&(BZ*Cw? zZ*DC^Z*6U5a${*>Y#>f=AVg(yX?9_BX?A6Ed)=_00000QbVXQnQ*UN;cVTj608n9R zZgehAMN}YmGcGkQF)%Rna-jeK0iQ`kK~zXf?UYMW!cY)JuRF-dF-yostYQgqMOi`y zeo-VM3Q{1TATrC`FN!Fl@F);b5Zaf5Xc7V>IE5-^oqKY->tqRTf3dm%B8C5f!C)0D z%MG`W&Yp`m1jOnZqBX+N8zEBFaPT6`e$dTCqUl4tq2ZX32|x%}H0(e7+(b;CNw!2J znv4U;0YDtUpgxK7K~ilI$rj@PngSq%$_#st9wC{IAE`FO$vfEqDh^*&egl0)dIKFm z2$mRjAN=l`oPJ8kbch4U22g$jB2~o(APykx+)L9T*{+1MFLD6<g&PUsiehRo1O$qN z?Yjw(Tu(-}OAdhXa08+~DWesc0ffyP+1e!ES8)DK4glMr!vaEOncu(;Ago`FUaUYe zE(SCPNPk$X>Ly2PDi=*ZvQ@HRNiwZSZ=eGRYnS{53#2*#tl@4<)(<?qff=BJhYQH} znW=#_+>6P9qGSRv-eA-;-xoO`ja<(fK99*;w-R4b8XMO$<Xf2RsPw{Qs|OxUp7xpi sx5;ik^mCi+Cfu0uY_gYdW7cN!55}|Pa4Xt{;Q#;t07*qoM6N<$g8zr{tpET3 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/5.00.png b/src/main/resources/com/unicenta/images/5.00.png new file mode 100644 index 0000000000000000000000000000000000000000..d71e711aa6de04a3aa6fb7e29655312d42adb762 GIT binary patch literal 873 zcmV-v1D5=WP)<h;3K|Lk000e1NJLTq002M$001xu1^@s6p-X%p00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02y>eSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E-^XO*0N*(00P-bL_t(&L*<u0XcR#d#$Tlt7Gfc`qOBHI zX)LtSI)#OTjp;1ZR>4LDwb3GCWi4E8?-WGRDS`+VivJp$$o>nbWyCV)yV==c-TRUo zZr|Hkybpfl_}+W7`%NZ$8yb(t3k@_E31}`7(CjL{LbE#o&8{FNv~~$JL!zyz>(z}= zv@Lht>P>_ql+3m3H`6Aa5W2B8=#0?KY11j88`MNXXx#~O2`!|>yh3aF;3YKpzp<;( zKpW67K2B@NiJd?*O@Ts<+E72fK!a?&D=$We(QH$ugqpOWe)_<KjIs}wj})b!_~&Q# zzwqa8S{qQ}go@g5(6_|~Bul7XN9#V-7M?|U%<Dd)6sk!8O-*P$K3Hr(x`pa>N}-wr z(A0#Y_*`-P(>JJIr7BdH0GgW6Airb({-4kwS*BrjgS}-MjE+wAR#dM^0ZmQ#=)W(Y z0f46zZ60#H6;;=e1e%(-uu*!CPr-Hme3e;ca_j%1-j5?Tw-Z`R0%&T&NB%7Id!zm4 z``>I(x@L1bp&1FF844P19N_Rji<6Kn+3ZHBUjk@`go8gWPC>R}vm2pa37{DgeoI{8 z@Y{S69@^|is8<4LhJ?QoZ<-B=vRgL05$cryni}u}j{nig*XenD4Ao2cH{UZGFw8I7 z>_(_p0%&SrgYm;HyN~J<_#5Js=^12y=+(wPo81WYO8`v`_~CY@2$%kzya7(vvy)tV zXE*7#&Fxh0mjaqvaJb1!Pw^sT-uluj)Q>Oo=SR+u($_ZgKSJwC08LFO$}e%y#07Sw zTg+Y415{r}3TSFWy{~)d+2(0;0;1#^2R~0QzwdQ*pz6FN&<qU{>XQJP^Wq~k7ZPYT zVV2NLNTAt-Swb@*fo2nYgyup4%_jH=&4mJ*P4N+$3js8n;v+N{0%$hHS7^3vpecc` z&}^GPQvzS1**1Zu6uv^UZP3caeT8N<DMa)aKL{2>{2bMW00000NkvXXu0mjfO23EW literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/50.00.png b/src/main/resources/com/unicenta/images/50.00.png new file mode 100644 index 0000000000000000000000000000000000000000..1d53b2518cc6fce2e310ddc95ddcaffdb1b789b1 GIT binary patch literal 1076 zcmeAS@N?(olHy`uVBq!ia0vp^4nS<c!3HE3de_JUDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5he4R}c>anMprB-lYeY$Kep*R+Vo@qXL1JcJiC$i6iGqoq zfu5n|m1~=TikO#px;TbpI6s{c-QgQ3b1eMSS`pt#?u%S1K0LS<pfV+>&24c^(aa;v zaT?RvpRT(wgOh)<(@NvtMlH`c1y3FBFw_rPy!ZO8;|o0&Ydrn&e(SY4-`;#a+f!@l z|N5c%=I`HY|6l&~e(U*L+45m}(|g&v)EHeSH!SjWxTvxqLny$6Q)3p3h%XbG@EPuB zRi7i;?dvrHd^!F~9@W`D)AEl{akKWBr@tc(u6Dk;#=($(#?#!yJ`MiU&6lpMvTA>y zV)j2~>eiq6&sdH>{t1>ps=vCiJMXM?)+61&_3l;tvfq#CH{{d>T)r3eE8hR6aL9M> zmw#fmsA&hBVV3&9eYIu3#LvPRx6M1H{wikc?Av*2dw20kZO{G25pv%zGaa=F*sS_O z;CG=$b>LMV+rwx0%ue>4l~=Oo4LHN~`qQft<G&}|1NKFmelO(u#J<4#_0lt<`+QyM zf)>mW{d<=;{gvdW#~XepZ93JR_r!hS8P=Jl&Ali5xkNTQt^S&Mb;A8~GW#2MKGMkK zJ)?Q{K;=G{XS#K=KLa&xuh4%N`9z(yD{`UZzG=-z?kr`^y^!m7E9>RWKRzMuE#0gB z%`pSZUu5Qyw(@7Tb2-l55vFwES9sVDlf9F+*KXah^HIT<Vu3Z2&tJNE8)9X1H1k)d zOeWL&+R_CT?yluO%GTcPd?xsXW6t8udY>jU9gR|&|DEr@((DV>EKxViRumVi%<B){ z$(&Qi{nN8CY3;&e>sLmKR6p5yH2mc<x0oAB*$&!ZZO+DfqfHM+KiL@^vqG;Sqd)y| zz&g)V_c(+9>>Agks#N4I^Uk00oHc*XE`>$v^Lm|UnuSKkwEtP+V5n=N{biAG$;Rq? zK2P`^jN>Qx?l^d@EA8`hFKxf>w8s}*7mI8CYrm_}?*<CeX<o@&qMhqFY!#=S>~YR7 z_y2V)v?PilRCmABS$EF(NhNQ6pDbtW%3R2rwNy&szvMfH)wLTN_JpqrEL?S}yk-6C z?_rg)HJVpz!s`sI-z^6Q?*hiQ+4BmfIb~cw{@wWWZP(+kc1tIHUcTYlv)7&bwUl$R zrhH@H(z>m}d+D`LvjcOZfYDl&d)KY`>SoE-@4|=wEm-(|(ebNWKjm)Zyqdz;Re6Bx z{qYUw9&uH&-}vX4wP&L3F9Weu!I0e@X?5&ZTlWiHUF;)=KNmnU$JvEv{xKeT%EuLv S!dC^%)C``kelF{r5}E+yVD9z+ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/500.00.png b/src/main/resources/com/unicenta/images/500.00.png new file mode 100644 index 0000000000000000000000000000000000000000..2592e874b5d28cf492f00c2f7a88efdd71cb1a9f GIT binary patch literal 1433 zcmV;K1!nq*P)<h;3K|Lk000e1NJLTq002M$001xu1^@s6p-X%p00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02y>eSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E-^XO*0N*(00jw2L_t(&L*<uQs2oKUhAV<mK~aK=4-pgv zQPc+&jS`KDs1Q_)QAu!#OM>wt(FYY=5HZHMOBRh_5L{5^cK6(fk-WIz3Zge?41tRn zov!NfDnunhT)^?KQ#GBQnt!GT?qfZCGhP4rPuHpH?&@mQ>2zj;S->7ghy96m@D?h@ z1Qla~iZMaOn4n@zP%$Q`7!y>C2`a_}6=Q;mF+s(cpkho=aa2^Zb($K_Pag!!vEb(b zmE<c_rk_*I;sw>zcdABf4)cbnG@q-od=>s*LjGECEAx#C6-PlOt)(h6ouRxteN0~- z3RbE9xzC&Gzf@K{6#A>E)I8Of=lDTo?Q2<19aJ0zmFVZC^VCdwwqp?A;Qw3bJ8--+ zoB$boweYlcIsWIv`!MqMIbE-<=9IbpgGZj^Zz{D^-@<Z-LB&x(L7%x!^LZ>DqMEyp zK!JZqPNJ{xi>K{V5u29yL~%iHEWcRvO#fmZyJ}40nZC})e^-s^L&Nwms5lC)LxV#e z4}te-UnIT47L^u@#gpo-J$h!|_qhXabF3w6TyFjtiw}Z|b*OEvIliF1EY5&`(iQmq z(JbBtch=|PYwS5(+7r7D^L>3CdaI~6&5`i^jr{E_J_st-;h#Nwr9Niy5cQ4}2fvwQ z@hauB-Yl+h?R=qYn-@cGh^@!<lh0*w1{LeTYW=wHXfs|(i%{GH&=#p|`ULLR=ZZhk zn^?RGyzY5U^%K%gi+kJz=w+cd1e5oycr$Yqi!-QL2a5dCcf@!L3tG=@4((EjrFu<O zXJAt2`SWa)cA_7Vc2i#wdP8s_?iO!S+{oe#D%Rl(v;%q)1=}mM3Tyy{*MC)wACE8n zY3>%crn#?r9)_CGCwcGd($35?(oR}EZw3Y~%+0?4F&1Y~u?`e>8P)L$LgzcBh)j={ zdbhAlzftuw@CrP|dz;cu4R(BJPZWzoZwS1r-2~+Kvp9o_GeO?>_I>RNkv#$myV|u) zZDHjdkm}c@-CY!ey#WJ{%QEq1dL@f9s5nzFaCg-*vs~JVzQhko7Pev7N%OfIq>b&d z&%HAAh9K81nB(~kEY6_fOu<#V-3>yolXliV+YQ2O4!t4pE%5`E1rx`1eJLk%81iA| za%(563l(PyuG)jH5c8<C8?8h9Aa;b_5O_Aa-1b7(E*7}9ekJsV!1I-O8&gNIID?9V zKnM8HDYmICtrJ<i3$A=a3Tf_t9U=D<r?ro(dP6X2_@L7Ns+T(lO1smUg*>~%+ZTGP z;5B)yoIlf_viKmVIEZp!SeRJcf;YtZt`L0PeYpGJQpW=5a`pPEzl!}x^0}|}=$Uz2 zbS!dJy^5{Lo!{KW;)9^#Ah5`Ezsml!JHY<9IRmjTd?Bm*;+e^P{vCa>aeW?gesl5S z<er$E*XrgUJHgeM#P@$@Pld5Ms5lIC(p{7+*!Af#Y*KE+v3qtcss4!OVsQfhIgd#( zQ0xz|g--OkGB?Rr(A-SlTRH!F`>lX&@=Z9#c|_l%vep8YI}9q;Asv@jvx?pe27c~Z z{9W`xf3AEjE@3%caMvxz`F90*c0#sdLe6A4bx?5>RO7qZYNCA+Iv>NJum{IS%zIM@ zF)stT=eUiF+`jXfXAoFOFGTK2m6)Y!{HL>+XH=*d6I6@|D#ipAV}gn?LB*J$VoXpm nCa4$_RE!BK#sn4Pp`-o>lBA+#=;rRY00000NkvXXu0mjf%A2lI literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/ark2.png b/src/main/resources/com/unicenta/images/ark2.png new file mode 100644 index 0000000000000000000000000000000000000000..159b05b9666be37a15b3198a0ac61c3d97a22e8c GIT binary patch literal 595 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP{O6e zHKN2hzo4=xGd-h(!MP|ku_UuBRlzwwH#a}8Si!NRq$o3~v?Mb>Pr)xgPZuPfT9llb zm;>Z0xTF?kmVq@CSKr;R0BD{R$h_eEw370~qEv=}#LT=BJwMkFg)(D3Q$0figD*u3 zfv%7Cba4#v@Lqe>-|vuv$nlTYrN3~<B~H_`WpaNZXyatt$?fRUynw~^VEx4xMc<l4 zc)NrOL`<Z5?c%p4FDZ?>#dk8D_4D7QOIVo~#ih?TPLS|Baa=6n+J?nO58uzPQ&_RI zXZL0G_YzKr4}6qvn$_00IGn|lm$_Y^BTI_y+kC+*NjxUU%vh!-yyu)MmHhF%<aT56 zJ*Kaf*<UGNNwKro@cTr<b4LN6%)q}1S6P~839txrb)LTYwwf*4+0kH`=A)t|RtW*J z98JMpg430!+BJK{3-nA-&~rC?FOhSHtBDJw;!bkFJI*FMDIl}taKhgxfiD?7rza*& zcidR*ko3o9NBi}4Ml7~rtLm3u^`2~XC;Q|4u!YIOf0S=}EKCk+_TRFPJ!}q-<NONc zpW8g2?_B>dw$XZ0e)NW#MybNAS(D?-*QGkHYn3X<`thhp>-Ls}momW*CglD*wx8i2 X&(^EA&ZL_IBZI-y)z4*}Q$iB}fNbYB literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/attributes.png b/src/main/resources/com/unicenta/images/attributes.png new file mode 100644 index 0000000000000000000000000000000000000000..09ccae8f7e1bb465cf4bdba4d31ede42b9fd300d GIT binary patch literal 669 zcmV;O0%HA%P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyA9O`nbVF}&d2(rIXmkKlPgy}sR9PTKQbk1|Oi4pUPE$o7-r0+3 z0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK0m?~4K~z{r?bb<B z0znW3(0>GuQb*t@9>JS<1Q)0%f~epC3J$2abMHVqk6@yL0}5#xVc9JpG(D{(;zeW> zS)D&>(bd5JPoF@srBG}c*k!h@*xHjl!`>X?PSe0nlO6intK0?I{$RL6vfo9Bt#^ir zq#hDsk+iH^d%D$xLc?K*LW5<qHu7_vg+|D-Ztdw_Z@v*W-yDS4cx9N(02{9%%eu9v zS52~Kz!2*%3=>H`B*G$TS-1A|tG}KxK!~+xhS&0SLcVS@M83|_?7du#kgM4UvHHaD z56QFpgjjiG_=}Kz=n*3Oz|!EaOqGzS{t+TmW%<*8%S2eFE+Llg_po%&0U?>w7Gkk7 zjKvBEh_Fy@3$ai(WRU}tzB7K`py@k>)GY}POvfFbx>cCJA;E#@`VldAtuS{@f_-LQ zdL2P#uM}plNU%>v`+q?tFBN7kNU+Cj4A=1z=L(5)66}!yhU*aVGllpW33kcBa2;a$ zR3Uakf*o=(T!)CAC`=ub-~o9sT!)x66ebN4Y?Ft>b%<z5AzC8AefTh3hnP507(XPz zfADd*4l#bHFm^zK+XOINhluPeMD`8A-+H`WJKueu)!sO$i+6%R00000NkvXXu0mjf D8G;j7 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/auxiliary.png b/src/main/resources/com/unicenta/images/auxiliary.png new file mode 100644 index 0000000000000000000000000000000000000000..f74409627182552ffc05f4d46e23e6b81e6753df GIT binary patch literal 748 zcmV<I0u%j-P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyA9O`nbVF}&d2(rIXmkKlPgy}sR9PTKQbk1|Oi4pUPE$o7-r0+3 z0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK0vSm}K~z{r#g|!f z(?Af0f8St^kR#{_I)b@@kHQT&!aT5;0Ev<iLn1<`BrK15XR!<<PC^WdfKXY0rpHdX zq8@9ZG!?1ptC=2m|9@MWk;^T-`Rf4)&}z-`czqYqfX!|Ium8l{1T}*3#;f1dD0q26 zje?zXa!kN_YUXCzIoFmKw$I2h`I~wB%(uL-bxID23Xjp&sj|HA;ukqYm!4zkhs_gm zM9ezn?-J>U=Re5-5o;)H{P1}!ZbJHT5!EE%dWC1-JC{0s?qe_wN<S{78cd#fnBJOd zglWWawuvxR<Fzo=mKWBKNicgO8Ikp4J<Sc%4$re|wwBbkW2_}4$iIc=+pZ-M8@G8> z<GEcg^@?LW{YDu|&k-j)`RZ{^WYtQoDlv;uhO!2FBaibFt4``vjnNxXhAIv8Mu}A? zb*jc#J)#U{4VceYk31%^YNb|{7%PV)DBgrChY{zu@%W44(adH2|HW87Ai?ZoxO|{E zPhZLH@Z79LGc=@TevGAks=>|i6I<HXS2Xf}kg|CbUj##{$;2=iY9=Y%Lc!3tys)@O zwOQEJSlCsp(=KdaanIyr{qX2BIU-^mReFe|A0B=phfMZF(Ix%x;3GMtcn_Gyq#x!7 z<QOma2Fwq9%M15oa!R)!q1*SFxoIQazPen~mKW}Qphm&n_tYr3^DbtnA^6Yf?YABi eGjz=uPwyY$A5?RGN9Z2_0000<MNUMnLSTXiD@LXO literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/bank.png b/src/main/resources/com/unicenta/images/bank.png new file mode 100644 index 0000000000000000000000000000000000000000..ad2f26c0fc67129b8b0fa86b0d484b4ea553d4ca GIT binary patch literal 959 zcmV;w13>(VP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy8gxZibW?9;ba!ELWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900S3E zL_t(oN4=C=RunN1hJ!0;cQ8xf)i;*VOJFIz1D4PaFoKE>m+^*N1Oa{H9Y#<=1{gIU z7eT<X{$vs==^4j!q|G@W$)qY(e^n>+DU7$j68^iT`uZ@JKZp+1y*qbpqSfn!$yfya zSA3Z(S6Z!Hkq2VR8i?(3`5eoaq$DuBBPxaE%f#pM0^a;2C9$7{N&&H5E-zr|f|LXX z`AKebjo2=i7qECvN+MOp-LbzlGsLY-nSnN`*|WB=qj7g#E-zr=Osj=6@<^3&ca|=4 zuAuu<h0XeeU6ob4T){=3Kh4zqDH$+c|DXbk=Y#EMTjBeW^OM!$*=n=5dR;L-@a+@> zHkrqZm^(?-+zA;lWJl~eH~UK${ie<F%W=P9gO80-E5yOR%oB8B_LvlqPS#no>Vzw* zFgmy|@%_PX_`nxuaMmSs#mPK@fLGs10SxD4=b^T!JP0NO7uU99v&VT53wtt8AmHU8 zDS$C^M1r)vr=$Hf4wf2bj@G;_2-@L?%oCVjXi@;fIoWx@>^=WR5muPBrQX&{fXoy4 zx&+vCPIk5e>Me@65m0ZX-quTi%oF%N`$`I6xV4>aqRBnYkY}Q~rfR#X0c&ULB|zp0 ze4l<H1u)zibG>CR;giofLw||Ag!NV)#FDWKLS2htm_8tZR#W?l8sDy{N1rr9J<!G% zXQmHy5KDf_f`F-g;zPCrZtdpDJzLS(R=*nE)C_e&8z1}0YK1s5c0qvrh7(QV?;0~` z&Qu!}HL{U2nxQsW=f;LH(H!h>-WJ#OuDFD7s_jxo>^(>d;@t*p@acBminE0khC2kq z;~n|~nr%Z&$_z05?KSpb>wZ=iR}kQCI1J<4R0@bK^B581+qmJGPl&yTAE^{%alQlb z(}Ll_2f76^jsb3BA+~$QUO-$e3}ajL&x~$n{8Y0bj_j@%5LXMs{r6M~vb$bDTrCXM z29<*Bt``tj3&Zd_m4fW97f@~JsM^fiZgWv>B%CMnxq{du8=3gG>i)f!I|l-W*As5J hE~V|AKc{y2e*>2kZ8u%2`xyWL002ovPDHLkV1j!~uIm5* literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/barcode.png b/src/main/resources/com/unicenta/images/barcode.png new file mode 100644 index 0000000000000000000000000000000000000000..8d76ccfd385304a2016f389bfb98ec39e40f9e86 GIT binary patch literal 236 zcmeAS@N?(olHy`uVBq!ia0vp^Vj#@H1|*Mc$*~4fjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgg?ZVmxm?pvYz?*WB!JY5_^EKa|j zdXTTdfWuk-*#G}N^^4_rJT6o|HZT@Cl;J5}_QFR<cH>2n+(T>}4nk?)R-9v8zax3- z{P&vEJ_yAf+Anmk`*LeB?^^@Q8z)!~8|v$voB3tmCoSWBKLv{~&5eApI!q`2UFPM# amFf#Ka?aGQQRN5P%i!ti=d#Wzp$P!(P*Xqv literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/bookmark.png b/src/main/resources/com/unicenta/images/bookmark.png new file mode 100644 index 0000000000000000000000000000000000000000..5e8222e7a2dcd7508412e15a3c1c00e1651bb81e GIT binary patch literal 652 zcmV;70(1R|P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyA9O`nbVF}&d2(rIXmkKlPgy}sR9PTKQbk1|Oi4pUPE$o7-r0+3 z0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK0l7&;K~z{r#g++9 z0znW({}DLC9EGEB1dlK`=|lnJIuMt*paY7_6=ZSW;t~{8P|>o=B@)8Y4Lw68FX?nw z{pu;`N&$n~-lvOwqHkm!s_lL_oKzD3BYUCQPE%p0No}Zb^5@?j<lm_aAyi@ORbl&$ zIwEI*TCU+B*PuQGScPm|AzP<D1XKn8#ex4qnpm#F##00vPaZa(Nel6n7$eKnBFNOD zOpI|EkMUWEhC(!cv_w<1B}dEU)~hkBS1SyKjO2^~YmYQiu=+qF1uGSgp%LNz{7;wf z6+<D@)-RUs6qfENB)T-K#ao5NTMC#yopRwuVc~`XLbFY$uNBhQWEsumf9*4MrI5NJ zOBg1XOL&(qLzWm|W}G`$n7<$^h?cR<p81$PBTM+k`7v`!Rx!H4^ofJ%6S9oKkTP`~ z#ndrbCaPbA$wL>DhopheK7x*~!AnS%6_RD@!4aSFF!5`$PL^e_SB$|+NR)geO4NZP z-uqA7UQ;<sl*Fe~tiel&7Zu_~YN5jGG40<_eB(ulY1J^Oz(gT}@dL&9m?*f6;e^Xq ml^BT?4bd7zL;H(|aQp&fWYhA(RO+7q0000<MNUMnLSTXs!wj_m literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btn0.png b/src/main/resources/com/unicenta/images/btn0.png new file mode 100644 index 0000000000000000000000000000000000000000..05566c6f96b8e8a096f8f5bde9206d00a2e406b5 GIT binary patch literal 523 zcmV+m0`&cfP)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02y>eSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+*LgRNQs00DbRL_t(YOJiUdte~NxK@y1DfcOp&|A*oy zKzacXYg5hLK*LyoxEje4m}ThnQlJ_RiY$g&HV4VF%|Nz3NE~D^kd_7FRwQ|l?}f;= z6sS1^$*>e$1_9L=0`U*1+P!312-K{EWLX^{Lx5@>k<^D1QjZ}I)Z79!;02K8BgO!r zx<ybuk6^)0j6P7@fD#HUh)Rgk1c_5iBwtz*s}H2n6iK5V(HbF^f<gq8f(b?g++3jI zL?jErDUw(K)HfBX_Xx3iK(4HVYPvzRCa6N7K6uI|S}#!31d?5eu+SALbQFlP6sTbz zRMS+VG$1Jg>O;;R%0%f0YB~b7Z~{>pMlB>1Oal>zl%!H$a#AVX^I<pzB@L_qC#j^- zBd06{>On5_Nh(W08exTS9-%}AlLzWSt}Psi)dyAw)J(tn5Ne?`Qm_&X9<(Bj^co*( zDY0!DEue*zwP~Ohg5nan)piufr(LTJ$x`~XOOaC<&}aBs-YUeVNC08>+roaQsyF}u N002ovPDHLkV1iV7!w>)f literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btn00.png b/src/main/resources/com/unicenta/images/btn00.png new file mode 100644 index 0000000000000000000000000000000000000000..aa10ec586146fa78eea48133905cabb1ae79b81a GIT binary patch literal 568 zcmV-80>}M{P)<h;3K|Lk000e1NJLTq001Ze000~a1^@s66BYf|00004XF*Lt006O% z3;baP00009a7bBm000ic000ic0Tn1pfB*mh8gxZibW?9;ba!ELWdKlNX>N2bPDNB8 zb~7$DE-^4L^m3s900Fc~L_t(oN9~v)PXj>^g-;+*2pl0z2%sP-K_DtCkmza>1PX;C zX-*V$O&x-e@C(qO%6~wh2!fx0gSVF%@_M1Yz1t^x371Uva<}{D>+H<!ZnLb-SDxn^ zup8JL?Az=E?Hz2t&Tms{We{6|T@jSSmD>mOSzQFG)GGX#;4Q&D;{G5!xAz^~U(@># z-Sxj9m0G|05Ira7XY-<iK8LU`>-#hZP^RV4+a|bSRgR%=pZX8DKc369IC>*<_=$F{ z3ecwf-p0Ip8rXB07U!N%*<}ozf%GVfJ<4N=7Dw-h9Cc#>4JbrBRCtjVXk}UqcuIgp z#l~J3H?gr(1C(ho;Lx1B#)5f2u6zTOX))lKqfiGD<Blo%Tez2LG2pW~nbd)^i1FuU z2Rbq>2Amq;SO6%~`Ugy%jaKDgO68pht9VAMRo}ru!b;*B246{JS{%V{leIYPU|_y6 z@U>W`#el()FZvg;)rT>>o9WYTMxr&t0cWy3oKlOUxJlETx}%n9m7^GYj@YBzOFffR zYL#=5PjxQ<QJv}<Yn7w8yys#jMdTL!v#=Xm=~mf|w0;1xO1F}i7*1pW0000<MNUMn GLSTZ|G4-ba literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btn1.png b/src/main/resources/com/unicenta/images/btn1.png new file mode 100644 index 0000000000000000000000000000000000000000..80af89b1754d4bc930722b88a6dd37a42c595b4d GIT binary patch literal 235 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s1|*Ak?@s|zjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucLCF%=h?3y^w370~qEv=}#LT=BJwMkFg)(D3 zQ$4c_&1<88ilRMT978<3lM^J?ELgZuk+tLh;^bL7#4|dT%}zTcnQRoe8<29pFUn)8 zfCO*QDi-BUii;hsq?V|(AIMmwXnBGo6DaJY=(6cg#)L^SDJ>>FY?=!Nlp^aqSTz~` YEj+Dz=-!)+Kx-I0UHx3vIVCg!02kRv*8l(j literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btn2.png b/src/main/resources/com/unicenta/images/btn2.png new file mode 100644 index 0000000000000000000000000000000000000000..2f79ea72cf5f7ff18882991e0e58afe0a292738f GIT binary patch literal 509 zcmV<Z0RsMsP)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02y>eSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+*LgRNQs00C`DL_t(YOU;%cZURvdh7kx9f}{%7kgTYw zt4AVM*CG&mfVw7R6#}&fKyd;R3<gI<?|`c65peYX(|OGVnq_7J8%QP(vh&Y3!_2<- zTCIEilx6t<o4`I{2iQ?;k97unyh`o})P}t)Kmz@@(ytu`3v8ocYkYr(br_T@>;?9r zd=_CSgp~@E*JTdBsq&q;tAu!{0u+`2@L!6CJ?>jHe?Ch5ZT*Yj_Y|s9dY6V`>d6#Z zPBFDBvkuM!mFcTl_&Z2D(e6CDuy3P4X+_!;mf@_eLI6jhp|JwApH!Fn$D#4P7G5X- zg{saq*<KbWQ*RPq_}z5}u?i48gQY>?npw4OKLqc=SW(&}hVCF%0U$gnwv9}sOr(a* zt%<t*1g6i(${oZi5Eu{G)U)_uYk>k(DHyAaUnedB5qz#-?B7jcZzr(cr3Ayz0pis# z^^EV_O=06EVY!0U-9_u3*>;|j%{U69?hN<?46diYI?OhP00000NkvXXu0mjfZDY|~ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btn2a.png b/src/main/resources/com/unicenta/images/btn2a.png new file mode 100644 index 0000000000000000000000000000000000000000..f72d6c9931381787d1069383f770c0763e720fc1 GIT binary patch literal 804 zcmV+<1Ka$GP)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00004XF*Lt006O% z3;baP00009a7bBm000iZ000iZ0XPLyBme*a8gxZibW?9;ba!ELWdKlNX>N2bPDNB8 zb~7$DE-^4L^m3s900N*%L_t(YORbi_YZO5g$8Rx(mBN9s5DrAR!X{lvo3m0_ThGoS zf%LHpWDf%tsjdjvSmiH}*w_eH#KQl<%E~{%Zu0%kyf^!Hc5Zj?bm1|(cQfxZ@8?W0 z`cIE@u2)l06!|%e#o`g<2=Wv17ve;IVf+Yrnyw_U0j=C*RN==U4@a-6HVle(AZG@k zpxnrLJE|oEd<)Pg0nS=LfqgTuuXx{s+^15GkbTGxGv~8H8^9~Lw{ka-8RWu)Qwy<h zX%v-R0l~a;Gxvyd8^Fr#iDkPO59IxEgktfbQE<{5{b2F6tYM7rCBS2E)s-uJ{6ZY( z7O0E=*tqmq`P^C=fx(@cEOxxX2K-K$D4G=KL#)#|SjQ~p+AmP%t&A@G;Km*hHlS{u z68Ovj-)soHm9@9g!pfbtlB9O)@h19Pa{+4rTN9X>sccJ>P-s)Qjzu35r5U@*l@a_8 zz?W&#cwKeU(6y{XW-K=_$#$C|8xZT%olKf1#zM`~&|T_;*&U)gI|qQ1G_x~6>(&cz zd9I)K?ILLszw!M*J5A!!nYdS*cwP8?5L0(k05nlJPHppU0cla4M5h~B2<2l4Ez%}& zXg8X1sV2?q*xKmUArBxtDZbmROxJb9kf+9ca113QE$lM4$<=B#8X}zr3e297%XJGH zr+ui!xtxj2*0R?^f$@OVn8m|32Tfec_=O`W6hFTYJapXy(9*zYWxP(T1%^UzmqGYF zf3Kl3D8Do?#;+3=>oB<Tg;*C$rY~;q6WDl2CVQ7Qfs@{K0P$+5F=NdQf+ZGCWBe?U zF0~JozuOiTfuXa|t$IBy8%d+R6rj?;y6&QD|D#KxLxH?F>9JIoh1_ZEjcqF!H!DDY ihmCg`z0>Fj3-16n4PtMM$vS`l0000<MNUMnLSTX+E^77w literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btn3.png b/src/main/resources/com/unicenta/images/btn3.png new file mode 100644 index 0000000000000000000000000000000000000000..537bf6c9f75212f45a34264d02b2b214d67d5b1d GIT binary patch literal 582 zcmV-M0=fN(P)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02y>eSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+*LgRNQs00Fj1L_t(YOU;%cPXj>^Mk^3CB!sk{(4+!U zegPo}0u=}}7EwhI=%xl=gR8*c5Lg5W0t6OSfg*?oRf&W5CA-OF;pon`AvF22cfFZ; zJG*mpTdV!o-(WD<M3?9deFnWVUZZWaw2-+IsEHm8B*N111)Ghzpaf{6R|7ledMyU! zdIcS$X|VZV+$n-;iO`*aRR#*H5GN++svC+^*T8zS0$|%Q_9wIKzdgtKCIpz|76f)r z!Ds9SmN)==h*_5SyM2I-<Eprwy$*nO%^nWD{w{k!TS(QZcT?lKD?pAhK^tff-J8q= zEPD^Dpag6sfY@<V&GU7dpP;`01-?SfoE380ge6r&KSgTdF;jJ%wmYE5L5%_R6X;^T z9=}Zl;Lt$*?ah;=Y(u6h9xd<0>tAFK=*(o<DhlFp0(S7%K-=Q-GGvAqaUZlV&J5#{ zs>S8`VrW0U-CST&G^1R<wA!9?XNq0V>|ZAv7)spk#b_3k=Q>QqZqs+cqH$8<ItCu1 zhIzisz0Rce7^#;(Z|^Fa^*#ZnX7*L*QWeQjQD&(Vf$AZ<TSnWcb*=xDc|8aA1>E(r UZKgN*6951J07*qoM6N<$f`LT!-v9sr literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btn3a.png b/src/main/resources/com/unicenta/images/btn3a.png new file mode 100644 index 0000000000000000000000000000000000000000..c2740eb155a798fc6559e3b2cc25104d4e22342d GIT binary patch literal 804 zcmV+<1Ka$GP)<h;3K|Lk000e1NJLTq001BW000~a1^@s60K&Z@00004XF*Lt006O% z3;baP00009a7bBm000ib000ib0l1NC?EnA(8gxZibW?9;ba!ELWdKlNX>N2bPDNB8 zb~7$DE-^4L^m3s900N*%L_t(YOTAY;NE|^J-6c7&NKoW*We5>0EY8*@h)PH<aD|<a zHiA_U&e}T(=`9p3EYjGe2-k!Z!U<Z~T3ul!7Lv+z={E1V^SR&6&Fq}JToxX)w>$g2 zH{ajP#nHH~cG89ErZRts`%~a&v=jdsiMG?}%md$m8z3?Gjqy9M2t4%~Y9~pQV%cEb z{O)3$jP?@01{i(;oGVfxx5q2YnR8ka0Vz@Ceoi}S8WC$=0WdfVTr2XgxPK)ixSs+( z0e5E3UyMsbA_fKUbqw;F5%9$+fG!126#1}W!(_Z9LMdW;Ktv`WHqW0JFQlPyg#bnx zihLuKD41JU^FMn8$m5FgK+7lKhcS4Yn_!9w^DfLc{eS?5Kysj&n}ng2>-Qi(6E8Rg zxT-+Azt`)<z_Z7YS_1mwHA?`?O-hmD0pQR6A_74CR^`C%kd3`0zIU|?MF_2xzX3V3 zpS^+O>wpK+rc~wvNfmep^wi2Jz~2Yb99S{kuvUm41Tz+)bVOE5xD!g!eP|crk8%W1 z$T6Few-aVnu<(!z#biVj!VqwS+61^Mi6__*XFX+@RYFl>*LNUf+upWBWV@r@3-Wfp zvZ5ehSBc2l@qZLRPcRu7j@yR?4W9>C4YksF;0ec;^1_VS_3Tc_Tv#vbap(6SZ#o3< z0Fq%G-B8qkT({&r54?1)fEyBw>`NS(;g4|@=1U0JlGAV9IWXz9ix2f-q%o=hQ;w2^ zM~);+!w@P(%h2VhUckH!75}<JKnns==sfUbvySCaNCe*Va4Ow!JJ<<XhM`NvlZJWh zUInTu;hy6+{}bqAJDbs9-q?*O6as6ne-DFqYIVN<1x&h+&PA0GK!Y$mVOIYOquzLU i&u8?^gx8}Z3it;)2p42{5*La90000<MNUMnLSTZUL|wlC literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btn4.png b/src/main/resources/com/unicenta/images/btn4.png new file mode 100644 index 0000000000000000000000000000000000000000..710c1622f8e83458a0481c1f7a7d71aa1296e694 GIT binary patch literal 393 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s1|*Ak?@s|zjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucLCF%=h?3y^w370~qEv=}#LT=BJwMkFg)(D3 zQ$4c_&1<88ihg>!IEHw5Cnrd(TCi|oB9nmirK5ipx*LAj$Lg>|DX|>sf06kxWJT(h z?}`_c;#E#(WCQ6;g@2Cz+}{^Px>?IJ>3TVC;<-8f%6Tz|?kf|TK5<N#>$us4*<=Q5 zhvT${CjKYJ6P}*fw{#u<#hS@XTA>+fiWd@Wmn>jbl@Oa1$-(Otk;%m6r5Z8QQ&^sf z_pQ^XSc@V?-%{>IwnJQL0Zx%Eanb=-ofagXVExQ3F#npEkj{*i&zu)H0{JX4qS~Q4 zEK*G|2F*e0@@sYPG)&QQ>}-|c(Uag{TJVrFC92__#v>h-7fL3qA)U@aI<i|QOu3-s e^>zV&5W}gx%MWr)-roTX1O`u6KbLh*2~7ZJ>xbh2 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btn4a.png b/src/main/resources/com/unicenta/images/btn4a.png new file mode 100644 index 0000000000000000000000000000000000000000..b87c53182d84da09563061370a74b3c207a1d267 GIT binary patch literal 595 zcmV-Z0<8UsP)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00004XF*Lt006O% z3;baP00009a7bBm000ic000ic0Tn1pfB*mh8gxZibW?9;ba!ELWdKlNX>N2bPDNB8 zb~7$DE-^4L^m3s900GZQL_t(YOYN31Ps1<}g<aGcBnB3w3=AEavr-07C1yG@6p0-s zkeXI(Oe~0<UjPhjh=pIm#18<8rG)nqyT00?aSYvR=@dt;@5?<uU(!;MV>B9FW9b8~ zFVhsgYz6c0%9KyzND`I-vV+KZ6)>fG8Kb4Lyo<O+<cP=Op1;KmK-Lj&zXFGoGYvXc z=O6p(;&V^K(-<DByU{RPVOg0%;zYyxUh*toYYYVFK)|Yil#((g`T;mMkv5VQpiRVA zLtqMEUqhSiBS6m%%r{Mzcc#gy->l5tU`YWQ2$-zWcWIViPWQ2NtF17E2vA2z`HK08 zXBv~pnuic`EVzfKh>cnv61NeAP(D^hxUAMzSeq^24^A}$E}07~_ly<U{jx_TnTtf? zZ6O^E(_R=*OKG|ZrQ9-4w~z{v^h#8BD5VGl$^&oa)siBiY0NarovV8dkd528va5!Z zU2!aYAd<<({LcG^z-Fcaz;DbBF;LQamm-mD%zU|4j(-6niEPYt=V~<2ebJik<2dhL zxRPdxiJ~zSgP$7Zn}4<m=!1L|32+}u0?ns}4-DvVGk*!{rM8JLf%O6}CDq5me9!#d hH1(nv=g@|;;0F-xv(&!|GK2sC002ovPDHLkV1ls2`Bwk{ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btn5.png b/src/main/resources/com/unicenta/images/btn5.png new file mode 100644 index 0000000000000000000000000000000000000000..7645163ee893c64c73379b31ced0b2a4854dba1e GIT binary patch literal 518 zcmV+h0{Q)kP)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02y>eSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+*LgRNQs00DMML_t(YOXZd!PXj>^g)1s*N=VbDBsfBf z>puX8s2~A_z*eA8XnG1!#ZMq4C=3b*stEo73Wchy#KAXYmrO2jGh{9e375RwCNuB7 zo!PtHZ8ZMsQxwG>c=sY)2S#UJGs&yN@F5vqg~coZjGC&tV=F%#$84w!cfx{}0A`2E zuy5su<Csm8;XEwn5y0%}-+VAPRQe3wQpNI?>c^n%>6V#O`e3Sd8ZkdI1+4@`Cg2k6 zgEi2~9LC*L-9mlEr<P_oj#&rXE7RSus3nk0=lS>H-LyF2xU8Y7augP{1TgC>!>N^D zOB}=8)>$ormI#KkROQkPmscT`t*ABhAJmZa{l)!H!5b;VvDN;sIHV0lyzmm?+$r9= zm-m?m@m7%s7CCKkd9QU(Qdc=phOdl!Kbe-6Kyo|Q1iy`!gyb|h0jsG4a<SS1*J@%5 z#%4DvCxgH?5FzUl{8-h6Usa4y3mgDBZ1dqO6L<mVVACu30Y~qYXw}k(4FCWD07*qo IM6N<$f;W2CH2?qr literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btn5a.png b/src/main/resources/com/unicenta/images/btn5a.png new file mode 100644 index 0000000000000000000000000000000000000000..60c0625bac044e2b982733ca0f1b6073bb916634 GIT binary patch literal 675 zcmV;U0$lxxP)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00004XF*Lt006O% z3;baP00009a7bBm000ic000ic0Tn1pfB*mh8gxZibW?9;ba!ELWdKlNX>N2bPDNB8 zb~7$DE-^4L^m3s900JLLL_t(YOTCuAO9L?!$4_+VqLrdn5FAA6=3ECI3Jw(nofNvZ z;N((QdzFGiCpT9SoLt1An@)A`A8>MV>ex|4IKS_bw6AwbF1=y{U)mw>ee!-KH{<>1 zI`D_yJ6C2>v)Md^0#_M5`N6v92LV*{I6P_qP{S2Q`;>hE-=x7B0!vB2R|&iyC*!Gr z0L`)J&ZYs}X288^08bb&pBhL_;!;Dv+7j3s2S$5GYS{SQ0k9^!v|wx+z~0j|ObqA; zbqT8*4?ao5aG;7b*0q}X;|=qO1AIW=GGh9r=&R7YHQi#^OW__rSdo#|Vm5HZ8^(6i z5WHf!VFXY#&TS~&f)gLQgN~q8D5Lh_|B{TZ&${?R>qtd-`BMSxIgB#x0xSo;Fz9~F zmjJc~_h?!ei<Y20H9pjABR&Q2R7TfAYG)^9dQ?LeWmy9(g|CE4ukE#PISpWW25f7A zqD$30rmrJQtx9Xx0?f+P)~!#JW0YMP<p3BRdgn{P5vY$)q;fd?F3ytnAhHEk!}vpO z0>X%Yzr<(CK!#nJ0jq{t6xSPHFxp^-H%XDPhUqZ7HD@4ggy9o2E+j$a6{qf6{UL2N zgo6SDe&PSJ2^uK@?agWTCN)jO5xoZI(4x!$eOPTl5A0xlI;b%l0!TwoHx4PQtLHA9 zkfWrJ;5S<qLdOEgRn#61jxx|OM31d{eCYt6&^5G~RAbxl{{fy6v@KB4cai`A002ov JPDHLkV1ju`8xQ~h literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btn6.png b/src/main/resources/com/unicenta/images/btn6.png new file mode 100644 index 0000000000000000000000000000000000000000..125d16fc90af32f1554715b221ec1e2aedd71525 GIT binary patch literal 542 zcmV+(0^$9MP)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02y>eSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+*LgRNQs00E9kL_t(YOVw7PZUR9NMIdTGG^xV11W`dX z0vbL5QH7|fK=cD}O~{#=Dnim9AgQk`qE%E>fUK%&5Xj29_6?ay9+zC%Js6UbOl~ji z%$s>L`}PWj|M*Li<N?-$72Wd($QA5I?ba0#AT`*xf-UhpbORLnV9!)t+YL+tYtM|z zp*NUNX<(oGpmMrTD*FU>=S^ijMP=CyP^VJ*WxZ>;f$3BZ2yEaD)=E+7Ct(08!<fo3 z-shCS0_zd1x|6CAh^e&xWj#g24{`&;`IssZkO}Ne21xr_!ulNcO8aKHg#eC23e?Za zTql^B7)MvBy|bG@lx5?fV9z}z*oXp!BTr^0#2G#n0*q53ILZxf!*LP<sC|7?ziFt? zY99l}IKt0_JsPmHWrZ&>iAsfhBrZdoQ$38AKLmKxDuXWB)G;~@Npfuu0`Sc)-!GXe zg8!~_Pbi}zNS6YAV0{5A>0rr+lqe4?%~Qyk{j+)mXu`e-I7>@!wg$6Igifta^wbnc gfZz299fkDl7mUWMXPkJh2mk;807*qoM6N<$g86IN#Q*>R literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btn6a.png b/src/main/resources/com/unicenta/images/btn6a.png new file mode 100644 index 0000000000000000000000000000000000000000..2aafde2a27d6a26c0e09fbe112cf505c7c24ed0a GIT binary patch literal 893 zcmV-@1A_dCP)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00004XF*Lt006O% z3;baP00009a7bBm000ic000ic0Tn1pfB*mh8gxZibW?9;ba!ELWdKlNX>N2bPDNB8 zb~7$DE-^4L^m3s900Q|*L_t(YORbhMh!ar|hBsnyB6=Vwh!Ej~h#+2j79L#e0x1rg zgKMr(u(8U)31T)O2#JJnjf86h*UJ^+6<WnYL`y3xD-lIY5oDcz-^_dSUUrjRG%zH) z*`4prynkk1CHfzqM(lfe(KXllzT7Lz>vTGYWOvC<+IQn5iHzMNNX6cN{QENB$A4>O zSrI{Y$P%_E0dUODmu+-dfH45;rGNyfk^N%W7y3RI0Grk^QVBDl)zUzukL;C-Zo|Ty z<2pIsA{#SojeZ{~aPbIv&m@)mUTS<`Esf^kkChaR1>jRArJPEEefCl*O4JS!Rh;w~ zQY!`IR8BKfDPigeO*BX=_U<Uy<GNQSSqdW1u7W+yRhb`Qm4POmMN>+k8w!S0o}DXe zQD!4v@&qOK=e^9S1Vr|3ePIo`)FPc`@65ecT8j&SZ3SyDf+a~(QSt|H8~|InJ_xiP zq|&vpd1MzMA~K!DMVJlj_xsBP)2W=$^#@r%uh;uJ91bUg!Qko)+pkB|pcFk8kPYm1 zyX4#Mo9tiS_u*(XI^_vOBGc{6?BOhsKq~?4n66hLAULJ(GZf(l**o>zd)o+fgpK$F zi$$71CU9Rl+RfW8R<IV;L<z)A1%EX8K-3tSOagS48KI;~R3CcgnOfk@bPk%7y15r8 zGC};Z2$b1eR0f>lONF{nP7A{X7jaxE0%Yi0es9WYMU?2J*gMltaUC8(=p_p*3S*!& z_9;0%t)>K0Df1EFmIozZ^B*I89XXLSt#eoSfSRKRuT+=Bc9AG)fp!n?JctjX_Mh9F z#;W(ei4?$U80B-0a(2jOtbm@iWpr&j-ih|Ui6RRFaYz#3;QZpoOaP?+?t2Pt#22Hz z@7FmJU*)FLBx!V^c&N2)DMz2^_a-_FryU0=be=crnU}U^&3=hGMKp3mbo&}+iyYh{ z`>CAf_0mUPgD}7g>Fjd{V>EFyHNxnEF0#bYp`S_z0{A1B(D_VZxv6ge+W3XPh8-cE T7$O=?00000NkvXXu0mjfL_vjo literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btn7.png b/src/main/resources/com/unicenta/images/btn7.png new file mode 100644 index 0000000000000000000000000000000000000000..2ccde084dbcab48de59d0ef1addd6c9eba4b0004 GIT binary patch literal 424 zcmV;Z0ayNsP)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02y>eSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+*LgRNQs009_DL_t(YOWl?s4#GeXMJrGU1h%fSqOJmo ztUy;_(F9T5RB(VE0M!%p5Y-5dfZ_-^_>)xpAlS)Hw;_;B8j|_*_O)BsDEgI8(==Pu z%UGG(X98fShWR#Pk!QLiiSHa$4xof!ttw<`0_;M-*fPtR1t=p}?F?8O0P9BJ6W8E& zIoVa##XIwW^<=kl1}qI9@9M!aOO*w180{Xo2DdBd*_Eml`ZfWyK;1^*UB3IyQsn?B z$!@0#`8JJqVkQ41Vj0|SPj-dx!c{rhi745TVmGKlmL@=sWVf-*a%KTqqvW?z?0RRw z+5kvJcDZ%l*E~Qm+0AlvsL3u3Z8!VTp(VTE2cwi=|95m)!tR8+$}2I|MtK9q9xupC SW&6JX0000<MNUMnLSTZT3#_gH literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btn7a.png b/src/main/resources/com/unicenta/images/btn7a.png new file mode 100644 index 0000000000000000000000000000000000000000..062ee2b16206e46a2df731bebd00dd41fb2e4ed5 GIT binary patch literal 790 zcmV+x1L^#UP)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00004XF*Lt006O% z3;baP00009a7bBm000ic000ic0Tn1pfB*mh8gxZibW?9;ba!ELWdKlNX>N2bPDNB8 zb~7$DE-^4L^m3s900NRpL_t(YORbi@OCv!T#uLB5D?G5U5iBeYv@n$rOJk*&+JLRs z%0W_RBf0+UuCcOAqonXJ5bP}c6RfOL*~t1lJM-?mJ3G51*(?l`T_*2up7(2}UR(5Y z7SUqenvIkB=_Z-t*u2&TgTXOITyY#E#t4jH*^P0n|8=rx;C<>S2kZjc!uW0B4Jcfi z+oABrU*(bA0I+4%?pR=}3T#)wZZn3?qIC=CCa#R)p?%+}0=!eeZ7~FwZ9rAsi{XE~ zH><!76s(^!<YG9#3$;<e?k(^WbE;0oP!v`N0&u9*^@46%q(Z<RmAZ|&<1)=3z2<OL zqOOA^8Qa9++)2t~)(606tL_7HMjf)V{_o+19Y#u^ZHu08cAf4_PykL<>@I?vjbbVA zc52+jlO2c9pSk~Wr~XHPRxsWO91e#clgVTc>sGvCr(w1+8qOBD{_eXrXUH`63#G2D zLFopKlDUBEUd>V6y9K_DMx!-AwlP)%3V&IJW>egRcB#C3J6`sHmrC7fVWK(XlAV$? za#Fas78zkCVlX3lPCkd?8&J8Wjw8mCS<6i@aq>yysk>I{j;1OjQL1NxSc^<3{}B}c zZDO!jQr%-g8R%1;zdNd*N)m~SP4O2s06=<5-C+sPKh@1K6vYjjK#U=?m+QjkAx{9M z&RrdRs;N11A~=8mn-<tim6fRLD|P#YvCCeRj7woOxtW=`i92}!H-dHmD!w{|71C8K zfdsg8K5(mCGZ1hqy(Y>k0B@B#cQFcWPh4sYOOwv0zPiO_fB@|)SpMoz6hmXsHEt7A zCJHyfSv-(wi|m=@SBEm7fihNOn?!5?a!TaSM8JMv{K0r-Nz7E_TpTL+&^Ijo1}nSf U_y0=dfdBvi07*qoM6N<$f&~a*b^rhX literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btn8.png b/src/main/resources/com/unicenta/images/btn8.png new file mode 100644 index 0000000000000000000000000000000000000000..0c54cf47feafee23c9dbd52dc7d28276ea0272e5 GIT binary patch literal 633 zcmV-<0*3vGP)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02y>eSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+*LgRNQs00HSqL_t(YOU+iHOT$qRUNBf3GF%ctP!ud; z5lmx2SXnR`Rt$zElTDHR3Huuc2Eia$G}vY^SPWt?nTBc6rr)P`<MZdX-+ONh4nE$G zy}SGF?%mycg~EURwOXw?;1GBQJ`H`Wmq2BzejCw;5ILc)kJw+Dm>5RdLUfMrbzp{u zvCac~03#(iomxvKh4Q|THAfkOObK{1*(Y}>ikM13&x~~Plp(hx&NcGn|LjA#Dh8?{ z1|a`pI#(g`zhtaXyeL*e4Cr}>$WMc?<5@`|tjC;*ow>KpLkeNh%A9Fs1%9`}m`c@( zK8hx^K0A;oFGi8#|E-L3#Uw%_JrmMbd{=;3Y5Wt}XC~4c-@Sy98qgQR!$upYP&qj= zAuGcWjSVBw|L9O{B0?BorF!LYW%`!=EV1$i*#_>#p&NXcqKToTlZIzEHeJ|n2<hFZ z0vqZGJ<L>HkjK#Bed%dF4vsRTSPxc&Aar?K_*FHwcL#Q%Fc?u$sreynN|Zq}m`Yt! z>c&K8y{TypCiDn<34}=zs+Suvq;iJg&O&KXsx<eumm!fpz%!M~d75`y>}FaitU@(? zFwmBYWApQcwjdF4(rg0PA~)Fpw@CBeq~7dP8{q!xzJ&wt5)B>UOZ*gA4JocKz0xa? Tco-nq00000NkvXXu0mjfsP_m& literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btn8a.png b/src/main/resources/com/unicenta/images/btn8a.png new file mode 100644 index 0000000000000000000000000000000000000000..22065f98a55f88080d883267181d2927084d7280 GIT binary patch literal 858 zcmV-g1Eu_lP)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00004XF*Lt006O% z3;baP00009a7bBm000ic000ic0Tn1pfB*mh8gxZibW?9;ba!ELWdKlNX>N2bPDNB8 zb~7$DE-^4L^m3s900P!YL_t(YOTAV-XjDNE&VfZ5bMY{h_ybBro6|0-LJkC@Tp<BH zNn@dqN{iSj**gyOu6vz*4v~O`L<BADf?#1IC>B;$K`gGck@cImvwO4q_Whiq3&VT& zZg#%;`DS)&Gyh^;QBkY<RkxN4*X?!>LvBMpLo~}6&*zYp+>J`_%_yxyneFS78lR(! zfqn`g3n-r-@c;3Q0i~A!)`C1?P<n3xtQG}?kwgGJ#rs*vAu^2TJmeaLA|-HgYB2*! zDOGwa1r#d-h|M<y*k)eZpwobSW8II|A*WvjkTyXM*vL*9m!P*SoZBFML@<}`s|dI% z46K#`a*Dt3o)?~eML=StCB^BAfUe&E3vkCe83DXgNE&QxhczjRl51{T=Y5rocsejJ z$26z35(Cp#C}65&^j)WCn!c41$F9jYf6@TtmWXmU4;0@oO6LZHK^+WTrsj6d9tX_& z4@27m^ef(1AhXQMdAvUm|5GOX#xIW02TVQ0f|1LRu`nDPZ8U`zGA>UENX@?hA!9KR z`EA_m_169ha5x;Ui`ozaDSfAGEt4dvk4B@b`29{e^cwFCk09H>ZaUH^U60lko8+XS z+GW!v!omL=0`#pTm>t?mxB1lQGvEp51bHY~=XuN^w!Sij(38{YzKGH^y%7RjOu;O3 zgN^NJnizZOw6I5&>0N6)d|JcU;6{{7O+{4bZ`#y0)Q?AqX3vXeQo|(~;XZHLuZZK+ zWOmM}PwSjUlR{eN20*E;OF$dp!5;v+2s`T81vcJsQJNa|i)wg&8c<O~<E#NNX${jU zNOMfEwDhzWwRZy?L*O3I(xyvmkj^95A5UTlm`d}s?6kNPw9-W1)U3nNZrOCkE>VeS zW@>)Ap&b<w(OtC(c`5W_1DyKM-cOre{la>2q-A$fJ5%!pxJ|1r1PdaeDe?yLT|`5U k&`tay<V-2KWaG2)Z@>jq=Jd)2C;$Ke07*qoM6N<$g26?49{>OV literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btn9.png b/src/main/resources/com/unicenta/images/btn9.png new file mode 100644 index 0000000000000000000000000000000000000000..c2b7b55cba5eb32b4b5b78463de24bdaf4eff680 GIT binary patch literal 580 zcmV-K0=xZ*P)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02y>eSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+*LgRNQs00Fc~L_t(YOU+gxOG8l@U07H$48$-5VX~mX zG%zU(3kH9IMPb2YvJJ*7F8dQ?U^C1jmVseLi^*UTgP4pqJxA`9!_&9>@of_ahkM!m z&N<)x-u>=-rP6=>Wm&cg^nqvKBj6R|8L&RHydky-T#89F%a7NLoyr&j4d6}8PB34N zqMQR=;621VVXV4LK`a9l;7%yGRwTqVNo?dbJd&NYQX+_LO8ibL{>M7V4?*C{N=E!3 zaE4aSR~$%7lI@|D49<b@7OXrP)`i%y62WN+uWsehaAgKNv>S%9z68^;HB-c&x=I=h zdqUn#nIg6p+J|jqPV!q9q$;3&*q+db?AehdxR*-s*L4W+rir%*Gd~A5fJ&%B1@led zPRtl@KcRVNka>OGieS-Q8vi$+>WNi=;Wlsq@C^~gA2HX9osXdGDyN0S(#dmX5={%w z9g}N=W4Dln2(z}7mM3(srDV&*)6218NzxqygQ4th-z{Vz!l)x=0}IC;le-A~pA(i0 zcqo9e>@N8gV9_m%fstP3y{W`fWSDKq&hG!B1@x^k_ZHx@<2`!A6Pl_<YW)+oMyv_f SsLi1O0000<MNUMnLSTY)YWQye literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btn9a.png b/src/main/resources/com/unicenta/images/btn9a.png new file mode 100644 index 0000000000000000000000000000000000000000..5cbea8386a50ae6f0a7ff89eac1d9a5054d9b6c7 GIT binary patch literal 913 zcmV;C18)3@P)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00004XF*Lt006O% z3;baP00009a7bBm000ic000ic0Tn1pfB*mh8gxZibW?9;ba!ELWdKlNX>N2bPDNB8 zb~7$DE-^4L^m3s900Rw4L_t(YORZMFYg9oHzF>sdoFEtri9}AW(Bi6qHcA316s`~0 z7|4N@jdsGlJ965dU0Mm)S;T`2X#y6Pe?TlOti(dBEG>j}zMYx3^Y*>BcY!Pn`*z>V zd^<mPml_u_o@7DG@vzZ|*Z6DqV$8u{aEItE(N7{L^qc1QME45(nd>z&=e$Byigo5D z`CjI(dY;VPFUXRz>qMUnh=RrQ33$CQl(4e42f)m0(5mcp^0gw8f;Q0~1NMf#*UbMl zTE8axD?C4FzDA1l^j%Tj_139He2AUgVkjiRWg;kmB~W;`F0}Y(4t6S59+1M90=Q4# z0L5NU_VB%vyPOofFqUo3%Om35F#M0j0*<4)SFH*j=vcsSqTqNQm~ru;$Q%)f#t4=n zc5rifPuzLKoc8%S0C$aC(<I7)SgNr_Jol}2EhD&h4!}(#*YYuB>q4wJj@a9>fa@1v zVQbNYdOiaDC7`oK1&RM%!KM9w55yWy4vr(-$(d?94GH#*aCaUk@!mA`ICIV|fdoKf zh}z=>irX3rII6?#L>;1LPt5_J=DZ;@6^xrf)gT4vG}=Yb06q|Ph*reyE7R$8cQhJ( zHDKUxM!i)NCG^s|(~rmF+oa&kD6H$Het$R|_DZ@!TVr>o2F2luSo4S!ek8&Tp`hRC zdt%mTh0Bq3Tc*<hklS6|AiztB*fmX@afpowObeaskXsu-ZzVw!fVK=?Rk*U4m7y%s zR@Nlcws9pgwCG9*X|2UBtlNi-ucc^6$!PXsZWA9|hMOLR&2<LX74JZer(VXG%Sl!N zcx0@5CI_<s+$Xu0`cjYst@<9y#Lp1KH8lum&ww2&uUCknAi=uOq^)Ay7W&3XB#CVV z{G5<s0M(6fZC>d4e?C+wl|<J;`<fZ+3a@}jp}NakcezW?L>+iUu`7K8FUVO-3CK3{ ze(Z%B3(ECoU0DT)EG4jq#<DL}C9n`+a3zvSlc)49jc<*1Rg4z|R9D-wm=yHE8Y1-3 n&&beZ3frIY1sgX4Q~dt{cp!ET&vsZ<00000NkvXXu0mjf07;>Q literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btnback.png b/src/main/resources/com/unicenta/images/btnback.png new file mode 100644 index 0000000000000000000000000000000000000000..601cc3fc448c2b34b43474642d018bcd1bb267c5 GIT binary patch literal 371 zcmeAS@N?(olHy`uVBq!ia0vp^3P3Ew!3HE54((L}l8nVc?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0XB4ude`@%$AjKtah8*NBqf{Irtt#G+J&fW*wa5<NfH5QQ>h zJySii3(aezfQlY_x;Tb-c)y)y%hznc)A~|$f<&a`4GBq0hv(~Tz4UHKm%QSXxEZv6 zmB+n~#n<gZwI*$U@cw9D{j6vI|9Y_md9A&9R!96++Viwif6oM_m+7-OD?AY9zBhZb zyMW!M2hIZfZvAXzl|L&fGwqp7;H$_FFXtZT*pqzlxq?jp=G24J6=YI9o98qC)bl<2 zaA)`vo|?b|2U-5CYI@Jacle8EV@E?wgBj~5_Z{W}-mU9+=5oX;7b#_|wRm2$D(hl| zT9dBi<O#+-F)CTd4AaF6luEceg%?JjoWpT9=#|TrHBY@mMQc7US3kO`p~%C!H5TYy N22WQ%mvv4FO#q{?j?(}D literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btnce.png b/src/main/resources/com/unicenta/images/btnce.png new file mode 100644 index 0000000000000000000000000000000000000000..4331ec10682f0f81a1f7c129700c630292e7723b GIT binary patch literal 514 zcmV+d0{#7oP)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00004XF*Lt006O% z3;baP00009a7bBm000ic000ic0Tn1pfB*mh8gxZibW?9;ba!ELWdKlNX>N2bPDNB8 zb~7$DE-^4L^m3s900DkUL_t(YOVySwPsBhFh7WQiC~_g3;v*2qSrh`rk3eG4`~ggp z7IagAy|b4f_yahQ7&M9?2nvZS&m_Cau-D#pdu@SB-t^;k=Gobqoo=t!;V;kg4r!oT z1LAn8C=}jrbsOTpr?F&fXgN5LD2fiz1bv{~=!NSw+ADI%`&5m!Hu{>**kLe4j~+vD za)tWZK`;=55qhlvv$MWu?7D>p0cE!6S;4-zzd!@!aMwg8{|Qupt0lnwxp~C!RKX<5 z?J@(&AsTy@)C;^*z~j&=lZ~Eb*|c)eFwid3dnl}K4s9Vk%mWh15gMT%6)HBNMN=z6 z-7_6vGdYwlf;Q2LyAq+mGp9<2o+`~2ty0;CdeeXMe2z9OIF4i44wtIHQVk7?&?H?t zjm>3IFLd8MF}_}>u~8&RvV#+8(mvpgXGyCyZxg93?+Lm^`fKsVv*hlev9CqlP5-NQ zvNus_FK%pd22^->vXHXFRb!KI9nAn+J2$o#!e4a!4S{S?cC~MZ^#A|>07*qoM6N<$ Eg0VK%G5`Po literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btndiv.png b/src/main/resources/com/unicenta/images/btndiv.png new file mode 100644 index 0000000000000000000000000000000000000000..a992455856a048f2781edd3747daa4190bce2a7e GIT binary patch literal 474 zcmV<00VV#4P)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00004XF*Lt006O% z3;baP00009a7bBm000ic000ic0Tn1pfB*mh8gxZibW?9;ba!ELWdKlNX>N2bPDNB8 zb~7$DE-^4L^m3s900CA>L_t(YOTCsY4#GeXh4~8!1|$Nw0HO|oB*8$!39x96K-vV+ z15~1rRj5i7C*TewgcIP(Thb=O((cf9mL_YuyYHKs?(0syCh)kfJA=%bNDcAsrc1|h zEI@+<#19y8GNL?H5g;I40#ncxgzH&QDd3s_pDF;Ey5*<<a3R3GZP=KWGYEn?%GR(3 z1#CxvS8E_83{VT>PJmn6z=d`?2eyIKdnenlzLwp>Ht@rHzVG*NI;VMtuN(}ryNY;^ zixBgZD2kR^IVYtvfMAQ;4A@@GdjNJ!z%UHkp65LXaKi;?oCmOJS^&`hyr;e|fJc(u zu~K&2W`G9b-ZPz2!1Q~MJz!iC#`z-N<Lt!-0+^$f(_uGNSy04#Dm#o(X<l;gsa_@R z%GNmzk^*HmPw9GY{=H7pdtbn;2mm~h><*<%^~**p-eZ1c8<L&sUn+a=1={{zwAC1S QjsO4v07*qoM6N<$g5B7`o&W#< literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btndot.png b/src/main/resources/com/unicenta/images/btndot.png new file mode 100644 index 0000000000000000000000000000000000000000..78b00c5169ea8595a3d6be48701d22abc69dc115 GIT binary patch literal 318 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s1|*Ak?@s|zEa{HEjtmSN`?>!lvI6;>1s;*b z3=Dh+L6~vJ#O${~L8%hgh?3y^w370~qEv=}#LT=BJwMkFg)(D3Q$0figD*u3fvR?S zx;Tb-cqb<;Q2z1%zrAcObCjzwccG+@G51U9yf0gLMN$?YbUQB~zqR{^K*Q2=2j@F+ z?ws(-PBBHXN@4OUIps+lk_=PQS(3yQ(v<AlKCVznQ4G~lyf(q{sYH@&uP&eD$!k8^ zy}Z1<>m2@Yb^K@kSflXlz@(~`j|&z&To%ynFzw(6mZ-`;#tctcG48-wNf*{AdyBe1 z*esAGcy9sAO2w0k4%}Zi{MgVP;cTFza*Q=Xh?je#SRYR*!xXz^4_MDR?gRRQ!PC{x JWt~$(69Ai&Z2kZM literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btnequals.png b/src/main/resources/com/unicenta/images/btnequals.png new file mode 100644 index 0000000000000000000000000000000000000000..d528e426d880211e48db958dc1736b56b1f8a316 GIT binary patch literal 285 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s1|*Ak?@s|zEa{HEjtmSN`?>!lvI6;>1s;*b z3=DjSK$uZf!>a)(C{^MbQ4*Y=R#Ki=l*$m0n3-3i=jR%tP-d)Ws%L0m@TF)WP}NLN z7sn6}@3+&u`5Fv3TwbR?J|_I)RQI=M92eL1Gzl&{cB94D`Po5-S<6^#Tv(PEb~XBP zeDs;|e!0Mda@U)iCN8e6Z?{Y@>N<L5t*}qmzsA{*3%q@szj<7`XH{9_UGc$X&3@%2 zqARjC9$=WO$ZV~#A%fw4ki-TZMxGUUQw<+}{3c~tdTEJupXHo=&3g5z1*`cTDp()x cyUws?-XgJ=znl-610BiW>FVdQ&MBb@0G}jkcmMzZ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btnminus.png b/src/main/resources/com/unicenta/images/btnminus.png new file mode 100644 index 0000000000000000000000000000000000000000..9ce3c8380c3ff2f6787d841b9c3bc00748992ce9 GIT binary patch literal 321 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s1|*Ak?@s|zEa{HEjtmSN`?>!lvI6;>1s;*b z3=Dh+L6~vJ#O${~L8%hgh?3y^w370~qEv=}#LT=BJwMkFg)(D3Q$0gN_s>q|KvjD^ zT^vI^yx&gq<!dq!aQm44_?UEsfVk8}3EQy#2medwCo^%1Mcrl+_Ef0ko|Jg+OSWRl z%tx#mw_L8y4v_MnHSN;u0CRKS*)H2emd!eM(Ns-f+JWb;;@8%R+pXyiJ^J&gxcbiR z2FIQRo~;!ws`=C{^6-wSVmrI(xAGMelwvGefAW^q1+^G2FQ{gneU??rg}YYz-b>CN ztH@X}{xZ>KS(}XSUFYv;t=QoksF?MqQtS6B_gLXo{uk6P?XUgDdwT0xH^~KdbATRU N@O1TaS?83{1OOg>b&mi5 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btnmult.png b/src/main/resources/com/unicenta/images/btnmult.png new file mode 100644 index 0000000000000000000000000000000000000000..13816804bfdc860fb46866c9bb988977512d7848 GIT binary patch literal 469 zcmV;`0V@89P)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00004XF*Lt006O% z3;baP00009a7bBm000ic000ic0Tn1pfB*mh8gxZibW?9;ba!ELWdKlNX>N2bPDNB8 zb~7$DE-^4L^m3s900B`+L_t(YOJiW5Bl!RSKOJoYT17Jpfd(^T^9oR$pT1rk^0onk zj1P#JhP+4U>w$)bhHxPMkAx>s-336yeSw$-WH6A{L$lBqW+6~qg<{KrhS)(Z*a4(D zpqBnXvQ!-87$BYo6;mSHQm8?XkPJTyWD5cD2B_FJC?Dh)STJv(#KJnX-~$;7azGzc zyaPzz!J-Bp%y=zFFOq-;@j`=i0g!%$#bD&b^8_eg1H}5UpeN{4poQRsfeQc)QUl_> zXcmKfDM8S19EB?<vN%0_$c$zowm1aE8FCyVr&w4JJCfyNEU6R}oXDwk0yLPBQ!-@* z0nk8LMqdeX09rnL0p*KAQ!B_~A)<YUtKtM2VuDnfpqDgyP)k8RHze9JVif`nMK4QJ z(DmYSII(sNZgn8v0kJI2T?w@aYvT!KIo*RA!$P{dfac*o5EcLc-5zt1Gb1wO00000 LNkvXXu0mjf7WAr= literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/btnplus.png b/src/main/resources/com/unicenta/images/btnplus.png new file mode 100644 index 0000000000000000000000000000000000000000..84f0170254f26ff26b651c570c84c40cb984bb88 GIT binary patch literal 526 zcmV+p0`dKcP)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00004XF*Lt006O% z3;baP00009a7bBm000ib000ib0l1NC?EnA(8gxZibW?9;ba!ELWdKlNX>N2bPDNB8 zb~7$DE-^7j^FlWO00D|gL_t(YOVyUyO2a@DhU;?UjdzNIMWKS?zH8l!qM#@!==0=_ z-0M>J>VvdRx;(}4KiXqQO*4Vc1T1`TCK>*3&ZH9(i$(Y&q6lqJSra0-$*&b_!f5x+ zq|I@h#PNHDj^1kET1p()vUbpH%*n#TY=xMEZ21#aXiOwQEZl!Bldy-{x^VZUOgjqJ zh1<_161JX7_B-5!WaF`h^$t@HMPk;gu#gWrNY*>>+CS48!c<o8izKX|7M4*9OPM06 zEM`3Yi&IwU7s3HT61A{!=aI@h#)7sp2wQnly?{A{3A48zsmx$3OrvJP2-|oP2l)kX z$kdJdgGr2q3Dm;)wHr#<!oqq193qUN7DiDEBWafeZHGY<`1$giW*C9OP`Y6M91dO; zXh5N%bErE<++qJ^ftbX_7Yzw@d(OhX^E?T?sQrYxh3h=u_gNS}%Tten^$xpFb0l=3 z{w=J&=Hj8d2%5+pcAn&@LqUX9k?+To@<kAM-^e1>kU!7X*uyry)c+Lt0hCD*Ah{x+ Q+5i9m07*qoM6N<$g0xfVx&QzG literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/bundle.png b/src/main/resources/com/unicenta/images/bundle.png new file mode 100644 index 0000000000000000000000000000000000000000..5547876c6d4acbac5e9be96e148a941d2d3dc74f GIT binary patch literal 703 zcmV;w0zmzVP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004XF*Lt006O% z3;baP0000VbVXQnLvL_-a%pF1bO2IMSwT!xSs+GIMMWS?Nkc_WQ$--&*^6la000_v zMObuGZ)S9NVRB^vP+@6qbS_RsR3LUUE;TMOF-P-4Hvj+vB}qg<R9Hvtmt9gCK@i9P z%L(QP9AS^JN5C6!6mO6t%tI2<M81-!1W`+kCU5he50)gT7&R-RmfxM8T_0G4-C0sV zCB;;AQMEAJKc;)S|83#<XB(DPWJ|LFsTBOrZZmzBWWQxK*vAYQz{QI%gqL3lbKeN_ zE@7cTc=es|`Uhe0C!w%MDDD$V2ZVBq@aB;4?uf8-Ojtf4to$ZaJi_}^!s;2J)*-B& z6V@*X8<&L5E5g<_Vf%*g;g+y-NBH=l&D8)jF@R4*|0ICq5IE>v70=-i$V4F+>I9y6 z?s<?T2c`hi6Bz0Q$}KT4536l4`dd(L$$<c4xrRY0RzAeivF)2)6;CBD#Y2Wb17x@t zXy+dH0&O-s&x{Koi?_c719)A{Nbv~>RNL86=fEs?L*a+uX*bj%&`BtbyJ5l*1j$!! zsfczQ{HE3^8nt6%fP6D}ap^$D>Vaze83PCgP_cTz5I`Z{6f8)ju^?GJ%QApq05?*Q z!~l4#h-O(4306cI2Jnmlv?8i?90o`;fMi9a`YNKn0J*wiNfzAg-end7<vU+HPlvW| zU8h-+6+@D20Du$O^5ZmNwLN(M_Kh$B2$T2H!~sOo^OxPCwC@STz2N@`$koMP=0NoR z*bwCEqf0{l&kO)0U&Am&VNVw#$FLIWUJ%~Dc_p|GID8FdJis_dGs99my4mm%VB*86 l&BLiX_UU-{-sS1o{sYwqR~tdc_B#Lo002ovPDHLkV1hi_ENK7$ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/calculator.png b/src/main/resources/com/unicenta/images/calculator.png new file mode 100644 index 0000000000000000000000000000000000000000..c5e154a9c4119836ba9159ea29f8ce195564dd66 GIT binary patch literal 705 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvVv45dj$D1FjT2AFf_C<F#G}vHN0S8C^cYUc$L7wU^Rn*LA+qju0R{0giDEQ zM2T~LL1j^9dPWI@b5UwyNoHB9f^&XuZhl^|f@4WZQD#zUNoIbYf?s}~E=WAJC^<7R z2gp@$NiE7O18XR*zPn)o&^#%SdBOQ<CFO}lsSE*$nRz98ey$-3WyX4@dWHrDUy2q2 zU4PQk#W5tpee3j0KPE?!7WsJ#`X89?IT~|R`V6m43wPI%+QYpZO63L87gp?e?;@sK zJ;%hR?di>9@1A(8eO<On`|cTjp)1*<`)zdl1C<Q#6z6F(spd*9ow$(oX4Qw6fgid3 zI5r;*&0q`3I3#%R!Qb!FUEib&P90$Txoc64tYOW^E5G(mSpPe=GAUvm+oO&)M*SyQ ztCY3Rh+e<P-k~hjBEIJHrqBTO`rS=Ap)Y0Zr+w`fzER7*)5YfET=NOuN0@G}SD4<x zx-HH@Pmnuhp2M88&%gB>)R-AZ-~DlfNxENw&pc&bNOs!l**+T&{9^79HlHzb?Y;BY zLo?pWUGXeoU0v?=+HUsESApwxguP#2Ufdp$@Ko%H(8dFoOglE$T>i&(DBXDT)n0#{ z4H1lmI}$f8iUOLP(#0ya&SB1ugJ*KS*6my8^m+OMzeU<Jb_Ya#zj-FCzv!rGIpf}$ z)<>9L7K5C)IbFf;*Pg$kE$7qHR!h&1PzYr!+@Tm6wsz*)Jfovb#;OA9c?QPOd*`oT zeW8Tmk&6FfZI5|cz4vF`e5Dp_)3{O?WXR;>jJ|S*1rNn<-f;KG#O003HXj-4;w0?9 jm^8BecbRdu_;ddKlb=4iCQo}0jCux7S3j3^P6<r_tS2T> literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/camera.png b/src/main/resources/com/unicenta/images/camera.png new file mode 100644 index 0000000000000000000000000000000000000000..dc93e8ed4e7fbb87b7cc6042dc5db79c17c27b0c GIT binary patch literal 609 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP{O6e zHKN2hzo4=xGd-h(!MP|ku_UuBRlzwwH#a}8Si!NRq$o3~v?Mb>Pr)xgPZuPfT9llb zm;>Z0xTF?kmVq@CSKr;R0BD{R$h_eEw370~qEv=}#LT=BJwMkFg)(D3Q$0figD*u3 zfv(T=ba4#v@P0cb--{_x;Mj8xxr53TEd3V*ZJgXcu*oLwcL|H=;7AhG&x?@%&Tug= zQBi4!m|$MS<uiTK`#x)BU#u&Bz;1m0PvwJB!36RD-<Ztji|+W_#d*hp$L8~M2^|{= zoe3SB{e4%1UDA82+4t{%ude!Gvh9w49h@pmt4`au|5-9A>r(gSNbO&r8GaS(bTAy) zvsh`FRm4T5Q<ApZV|l~#SA1BZw>~5E)Xbc70ddh;Yl_d!+NW$9vv1L&d3K4*;`g{5 z@X*~`deHW}nB<qV6%&-#y?a`xxOe9BH;(09T!sZ-gVs5gM-_crVC>i`abwp>+j+bt zYR7K1ev=SQN_c%+ddqPj=Nbo;;|An>P7mp5ymo%xr+Vgj7ppJGEOO$BvHh=|#b=w& z?<XIq$hNMp;FAK-%Dtu51u_d=m3bBjzO$|}yUxM;HQS|>^Lg518=1Sw3lBVubx3f$ gu>YlAQQQOR^B$~TcikI`fl<TY>FVdQ&MBb@0Qf8N1ONa4 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/cancel.png b/src/main/resources/com/unicenta/images/cancel.png new file mode 100644 index 0000000000000000000000000000000000000000..3a282a7df0a7e896cf1d78e74166f16c9ef8a6f7 GIT binary patch literal 837 zcmV-L1G@Z)P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyM07=1bVF}&d2(rIXmkKWa%Ew3X?A5GLvL+uZ*FrSL3DI-X<~JB zX>V>IPH%24LvL+uWpZO_VQe5yZy-cva%py9bZK^Fb9>#epa1{>8gxZibW?9;ba!EL zWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900K=(L_t(YOO2J^R?|Qb#-~2PK7y~|UEjbw zLLQ}Wk_!b}TahXSQ6LmiFXvvtt*r=3K@_M()N!WSO*U!%bkF&nNoKxpCfTG-4a(NL ze;$|bGj*ud?xv(f13uqnx^VB#YH6Rj;+sDny#1>gS`ZE5S!nIw2C#oiIUwgkgB<5+ zg7O)AHvzo<O%9rmeMZe0B^T91lX#>@?&?ni=uatT@1{|C$Ni~dJ*Iq7kIay8;=%4O za_}pghZ6<i1T(&*M>we`J$9}&>|B$f`pUPj6l>A(Sg#v(G+^t}gY7Fam}JTIZ(S<( zpyRP#iIUfGO?tztp8-RL@~wIKL$MAWz4b|yywrWC&d*}=LNhc&8WgR~3&k3Ywbm0w zjJ?t$sqv1y_)Z2aY`$@>VB;Jet@TKheEPzoT%>{ZGcts^1A1e{b#!!AFA;h0{9Uh~ zg|QxbV=~MSSUXj)c8ZS1Y9&fOe@lDgF!sRnZ)8Xhc=lCs9-X??NtAr?^KyOAJ<$vq zB2)K7G3exNT_S=EFIth;>iHqB9tRA~c>2X>6oYZj)}ko+;^s0`dL$lxO;?UQh76h` zI_EYo5og1z*2<Ceus;5w$$IixGgJa{t-5(<)Npz@{|fD)2kjvhfY2FLH*XL9l)p2o zr*F132%t5f3<!@uRX1-98W~@~H=(HmXlioM@aUt@%ny;A)S6mnJQZKH<--7$4=D%a zTxgKvJWWM&yJ<@Y9xNSbh89G$=8dU(&D{FK4<0;tA26Ds43Y~#G$rdlaP>VOd=^8? P00000NkvXXu0mjfkj!P@ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/cash.png b/src/main/resources/com/unicenta/images/cash.png new file mode 100644 index 0000000000000000000000000000000000000000..0136cd53f773aa6549acbf609d64757a8542ca9c GIT binary patch literal 536 zcmV+z0_XjSP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004XF*Lt006O% z3;baP0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK0jWtuK~zXf z?UY?k!axwm|3}~m9DyTn1dh-naD?8VN9Y5BqGAP&@hjGd$RqCv78MaRrhdd25gBJ` zZMzgK#y+~qFP)kF&(3ytTHt^D>ICXzZDD<VoJ4)BFa~1=(AZATUgzwSP#bAXVx~aE zYa@j*AhbVG8=2vCPCp2O>d;~|Chd~tr@`2h`9-M?O?jgy?}WIKDjdHN;zlZP^h$^u z96bA-bNE7t8|*(3_8!&An+Q8@uxk_J+_q!K3w9oeaSAwgykPsD7^i?^#|tV0Vw?h% zf#&)m7KJ_0Z{1}W|H~JCWuSZc*t{ji|KiGhm3`Zdi@9kGl>3>;e^$Al<lF|ZaYGCn zfnoF#FnS831`xjdk1BOjD0R~=sZdd)mju?Y$wi6Wl@P35rC6^sb|CkA4U1z=%X?$> zlHjAG*x{;EL&S=mEbFX*Hkc>dQu>NT2-D!0=_2e|n)xxQK%uRn(53~kS*Kz7BE$Ii zA^bvH_tpp<LB6G8>D*>$4hHhA=+4QvlAJF$j8`nzOd!`(7&U<K<<5!fgj_Rxhfz6y ang0R@JBOV=@Je6+0000<MNUMnLSTaQ-|p1_ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/cashdrawer.png b/src/main/resources/com/unicenta/images/cashdrawer.png new file mode 100644 index 0000000000000000000000000000000000000000..3f1c43e051a0ca6d649712f4c2c8cf70674a463c GIT binary patch literal 716 zcmV;-0yF)IP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyA9O`nbVF}&d2(rIXmkKlPgy}sR9PTKQbk1|Oi4pUPE$o7-r0+3 z0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)>H;LN@>a0r^QpK~z{r?UngT z0#OvkLtkJJH$*{fFO5N>eIX(u+NOwzh_WYaUu<8WLv!sdPUi@7xZW8@XVT`Mgdg5} z?m6H0-4V5`>;EM@fpj{pWj?FW4vs&+!3y%Kd-$rVYKI?H=rl)oK^^ks5C>@P2DJdG zR7%-@uYw!Y0wj}3W$ZonVGE(UM|4zTlD0XN_PTQ6lWV;k$8gad3om%$Di_O}BL zu>MqrcCdlL?7#t5pGqJ?2Z=;Nk?T(Pq(z!*cu^4!u<}>}9q}hJ9*-;HnUghXh?=He z%MT^ciN#`d12in2+gZzhwxli2^ZC+!2}GjNs3C;h(`+xBlcqewJ&X56kcmVhh7e|b zW;NNIv@H7;?uuYWI2=}Gu|~amUG681Ml;+ymo0$Ee6|QWp-{*W0!1@o53Q*to71e^ zC+@j_=C%M<1Ofp=h+r_7nZ@7)tz~nX(a#&b^UTyu0h;0W`wb>oQwiCedZ+PH&EUBS z4A2TbpU)6NHm4q4YZ7&>;MuY3FK87-Q5uGzvsQJ+(USv=UVVXG<eS@_r+(H*<HiZP zfRkC8;Q;Do9^8Nfj9lcw4LHE?c^-)5AHx9#&vIbJ5C-c69H1WqIAH+iegg;adc9ij yX%5;&A8Iv&JnO#79*;-sKFL9+=|K<jBJ&@Pug8BOV05Jb0000<MNUMnLSTZ(k|ZJk literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/category.png b/src/main/resources/com/unicenta/images/category.png new file mode 100644 index 0000000000000000000000000000000000000000..8f6f8a8c29adde3c44e697c0d221fc2f7cca6768 GIT binary patch literal 557 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvVv45dj$D1FjT2AFf_C<F#G}vHN0S8C^cYUc$L7wU^Rn*LA+qju0R{0giDEQ zM2T~LL1j^9dPWI@b5UwyNoHB9f^&XuZhl^|f@4WZQD#zUNoIbYf?s}~E=WAJC^<7R z2gp@$NiE7O18XR*zPn)o&^#%SdBOQ<CFO}lsSE*$nRz98ey$-3WyX4@dWHrDUy2q2 zU2p2?;usR){&vb~KPN+pmgj=MPSlFKT<ka%_CbuXmhEUXL#lQ~cSCaj>QD3a&Z)%i zu<+d%yZ_u0^96F@_Hx%#RJ(STY3w`uGdh3AGMAWy9c7bdpE{J_+PULE!c!IVsjdGe z34P=E<*om7cI873z5SXK|6Yx$5#+kbJ*Qp>MAiy`$bG_G+YX$ZJ^hcx>Vk{W0ZMuo zqAgDPrY^Kz?h>=Wx*TNY$JP8Bl%B4S_?+ukx%W-^nz#-38vpNSo;%Y${aDwO`Mu9> z&)IPABDd-zUE3P4BMwdx+Sc&u_RkD|jYR#>>PM>e#`-b`|IHA(ng8{k@WKgu54=+b zk`AvM15U&xJf9b^fpy#aJx`8Dwst@35GrhZcEU4Hi#vMzlntyQ_s_XMKE@s~@l*Jk dpJvDZGwqr-U1Mow9w<RDc)I$ztaD0e0sxp-=C%L; literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/ccard.png b/src/main/resources/com/unicenta/images/ccard.png new file mode 100644 index 0000000000000000000000000000000000000000..16348e52d6a97d0385037626996b8b056227e64a GIT binary patch literal 867 zcmV-p1DyPcP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004XF*Lt006O% z3;baP0000)bVXQnLvL_-a%pF1bO1wgWnpw_c4Z(#Z*6UFZgU_(baZlQVs&(BZ*Cw? zZ*DC^Z*6U5a${*>Y#>f=AVg(yX?9_BX?A6Ed)=_00000QbVXQnQ*UN;cVTj608n9R zZgehAMN}YmGcGkQF)%Rna-jeK0;EYqK~z{r?U&hZQ!x}p?W9dwDrO301~C*U^CaeZ zc;fT;4Tb_@DzpO18~g)8xi>FW+Alcl?cNhPM<*>Wc}u0GZEx>mJMN8j6T<Lscmg<q zr;BZ|Jb~x&_(xkTkKlPcgzxbHK1qkq!u5h$pn4xQ9{0Yt#p5n~%N=+mXn_}^r$MW? zG3Id#zQ@gPZSe?sxL@c7iaoBwxBPB*YAY)%5va1=)Bja=;?;#xNVtYcEIOF$6@)!5 z!_VPj=!Z*vxVTVqGj*sC2E{`IRxiw#VmS{_;RetS<lKB20ksEa&Z34eC<wS{$m*G| zrFfi%&&i<ybae*(ibzE!oI;i`C<Fs88nk*6c@Iv0;!CMSZBN5fm_b_zgQBQu^*Ayf z$KYEy`O&#DCu;x5Tp0;7P$3M8MF(>|{J9X1L-2DrIr{P7D#3E#Q;{|R6~cgcXu#@z z6nX4}PyQ|~r~h$<eg%8_%<TDC2nj6O+XoF<-Hk$zDfk|{;9GXWBS8zi5IqfAo%~RU z#}4=&+u?hJJlrp|4aFW?;d^X(Ux>$M_?Ga$K^AUu*a**K;$2HTHo(sb8v0pu^nq#M z0h$CeU>Zz;Ca=%xPS>2?@1yX?z(mD(mFGMorjFUTSafQQw=E%I3_EH9KDE#Ys0jpI zM&Uce5%>mrvA#+j)BwK`RH?ne1`rU!opG=VQxgc0Xb2I$M}QAvA2^ma0F{I`cwA_6 zfW;}8;ZHc*YJ}O=7#Ob@fzqSaK&%K*Qm3X3%wln(4VcfW5Iq)Zk+ySB$3l3GoKJ*L z?09;H;7dXqf0mY?n;R^@(ej&&FB*IxmHfqHty{1=hP9gE6&5FH1KJsszQh{+=q|oi tXpm#+)p)%HUf>f9g5i&%;R)ab{sCGSmtjhfPo4k(002ovPDHLkV1j~yc7Xr@ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/chart.png b/src/main/resources/com/unicenta/images/chart.png new file mode 100644 index 0000000000000000000000000000000000000000..7e3ed869bc8e2d302ce59bd031274e072b33cbc5 GIT binary patch literal 950 zcmV;n14;aeP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyM07=1bVF}&d2(rIXmkKWa%Ew3X?A5GLvL+uZ*FrSL3DI-X<~JB zX>V>IPH%24LvL+uWpZO_VQe5yZy-cva%py9bZK^Fb9>#epa1{>8gxZibW?9;ba!EL zWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900O>AL_t(oN9~tMR@*=jhU*AAf{&mh=m<W7 zkH8Uh10TT)NC;pfhB%l}KnP@~JtPRQ8AH;H0Yacst&XZ&wq$EzJDcde@4Z&lUw{3U z^%wyDU-1*zd9`5Y)rZfBLqYD6JNepv@nQP~hm5ZSeEN+rc*?XRNbKPRTh9oC#f^4t zJv)g#9N^<GguzkaJ)2KnVh=Yq9uWpZ0Gm(hW!rdkJ9cn@^#_FhBgnH5?O1;(rTTLK z|0hEKaU%b<dz%oc{v2TK9!ZoJLE5l~ekAf<y|ajHEeBY+MaYLohU&4d-nkhw`lVaB z^}G6VfaM#6?u67YvOYd6-#Ap4y?8z_Jj*>iQTr`jBV<#io_doPuPnkPD$!Y9vbS{Y z5yH@wy7=i`oM7<^$*`S(YBp;c!hwbeS=SJP?$wK?!l|#OA#6gV_;v2!;e{Uv8fiRY z^epOmM&H!Rv)iT>U9`zr9{lhfL8Cu){c?or!swYg^Xx<Y(ji@tL#yXFK>ZTQK=J-t zk#GoUs_XhJs2*hW()8Ii4lsX#kPkt@)DxP&sN|f<_T~U{=Lo$Kv`~LNa(M3C&oP(n z%>ic55PDOL^fRXxq0X~s77^r_mHuIejswh`BAIrh6luK^iwGjEcM=CG(7ni*m-Pyv zo}3JB?%@E_#|YWDhAuF4g3ij=JF)33?_(d21M)B(rjOmk9`4mz2<hmb>$O%TMI)fv zv?8Bc%OOgHx{t4F)23RP5FPV|2+61&{YPW9Sx)K4`T(Yml1rzK3Z!?5u*;nByI}GV zA&EAfJS?^K+O_iDCklkr208S~gRhAL1Wiay^@%19N=Dt(^ykb0-h~Jn^<s_h+f)-q z-PH8w%mK#tkrpc6ezpH1xMueIdFB9bz99SyIKbGR4`X{cWQ>2!Mt3b3-Sr6^5^|UI Y2NT9vNnX8aAOHXW07*qoM6N<$f>8mh%K!iX literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/cheque.png b/src/main/resources/com/unicenta/images/cheque.png new file mode 100644 index 0000000000000000000000000000000000000000..1967a79cd1f2e247849b15e76693e07bc8accdae GIT binary patch literal 715 zcmV;+0yO=JP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004XF*Lt006O% z3;baP0000)bVXQnLvL_-a%pF1bO1wgWnpw_c4Z(#Z*6UFZgU_(baZlQVs&(BZ*Cw? zZ*DC^Z*6U5a${*>Y#>f=AVg(yX?9_BX?A6Ed)=_00000QbVXQnQ*UN;cVTj608n9R zZgehAMN}YmGcGkQF)%Rna-jeK0t`t+K~z{r?U&n66G0Tlr&}%t!W|I-5mIiVAt*>7 z5MmVdzeTx)o1#H^=EVg50ouOF<!wnbeBY!)hQldn&DxhX`OVIL=Q}fJXLq`-G1X6X z1+W4i5As&>0h-49pLr`;f~N5fy2e}R#4UcQ<fQe*A9+j68#I+*em`%CSwI1mU=EYd ze9u`ki;jc=$!lmD)6mQ16$_X`qrsrY%WpX=nS@pj6UZ}6Jidri)>@-LU84Cyjs9BD z1R^Crb#xJ%7kfE74qWH_vcLg+5q~?O&;8>(&i4%Sj($Y}V`w}SG)ACn3`74HGG9=@ z5E=;slEK}q)fj+YF8w=MYo1~N4F)xyK-cJl{_Fh4vlQME|BSfX3|~Zl&o&BRr?&(& zXgr3l!NI!`lRSbJLSGj&a-ASe{@feo@!?k1N;q&Qbd3(^9{PO$MnY%``|U{9XoDVd zdRgGMliT#x?l_GLsg}*GC8iaP#0TZE8D2>fG>yiM6RXhxJ;anU{tvxw{luCFsOT>0 z5l@O}4F%Moib`QvfNLtnDhpr(4$tEIUPftnQbq3&p7ykO(QpSu@I*zA`_kdK;W=~s zIA(<fumQj0!gB;OphbIwaWHtCA4k8n+@!%<kDjRLaTkR1PLWd!E$!z0><eHgNj_ox xQe01bmnq4Z`)PdN1k1RBB&hx=s;&T5;0hAyL~gL`j%xq_002ovPDHLkV1gHpG&ukO literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/coffee.png b/src/main/resources/com/unicenta/images/coffee.png new file mode 100644 index 0000000000000000000000000000000000000000..2951c8b11434ca9fed7a01b247d8eceec432ce44 GIT binary patch literal 659 zcmV;E0&M+>P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy8gxZibW?9;ba!ELWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900HYs zL_t(oN6nU7PQpMGhR+hZ1eVYxbO|hhC9s6<z$NrS@QM@^Z;4U?0pEBRwF)XI>X0Z1 zC>&1}3vDH4?9fQ^1=2b5|NnGu0PuXuBMHhQ4Nfr1(@jimX(&T!$S44c5#&`VzMD{d zN5bIkDyIJU4dDw$NMb~JR0;zP3IiO&=v#$+Kg1*9zc$~O$y6iICfCy;*OUE=^C;wc zAu_EH_{q^LBLbclqpN_?MVr6_WIGYac5sZ!^8)?X9z2KP@TEd%M8Na!KmLDJ*l(+_ z-$uc3tc^W}Fdq!k{U%DkXKdHqCxl>Nu=5!9E`*&&q=q1gI74hd7_j|-b3i3c3(cdQ zX-(ZFnU)Tj77C`~7-goVkUq0Lw(hk_`{tbrn|CM}?|%okkDVahj6k}Hf|(lO*eTtV z93FOnR6~JO0|oQ*Igo0YwvQb^zm-70MZrWp+bwzH^l=m<ZxF<ycmix(YYq=bL85Lz zqK*QY+?0vBM7o+wTXzOruj#N}LxCuy6($x4=F(*pX6hWUqO4u11O|lbB(wsoUPcI< zGmP}TYvXe+R!oJ!IZ+|qC^6$Uv;r(&NU(H{f|xN%&%SUyh@Tk{KSQ6GzuC-gk5y%e tRT+Uk2>(5R)pPMwCQJf3vHEbCe*hBSQwocfjQ#)s002ovPDHLkV1ke=3@HEr literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/configuration.png b/src/main/resources/com/unicenta/images/configuration.png new file mode 100644 index 0000000000000000000000000000000000000000..144fb583db8f83540934b12b8e5279846a3068b1 GIT binary patch literal 1031 zcmV+i1o-=jP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyM07=1bVF}&d2(rIXmkKWa%Ew3X?A5GLvL+uZ*FrSL3DI-X<~JB zX>V>IPH%24LvL+uWpZO_VQe5yZy-cva%py9bZK^Fb9>#epa1{>8gxZibW?9;ba!EL zWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900R$6L_t(oN3E7wQrkcfhWiK{K}XRMd;}e3 zZr~&Ez>+{r3>a((%aDX6Z+>TqASM9}wg`(!!qVxs1=4JiVlq`<)wt*HzgtpEWq`c3 z^W?$KlORI)g4o}?7M~3?VVvXT*=L_`KbFXd4OO-uO=FJPwWZ;k*m@AK^?(+nVY>Ao z9a{Gt%k6CQ-iOV5bdVTt-ir*KpIawW@c9qIYj|CC%Kr3Q5;!F0qx$EDHtw46@fQvS z=N4MBR|44+g!;T>FQ6D|NZ7awh~!P+J;!8ETJ(X^1J@YTir<d)TMyQ6QA5)2rWOn7 zcm6=JX8o46X;1cIPrVLZ#M+G@Fo!0cj}*F_EMo224d>+f(wnq$6~gK@W)RU?@#4>2 za?a{C=eoVQHZ_1bsLzlKeE3-+sxNuG=a{}$u7X^DN))hsi4LekZ7pAxGxTMPK6L82 zc7H8jdax8p0ySbmY`YZs+BxUwdFr4pMZ)4M`!$W#=n80bF@<W@=vGr_$)jm>gH*h# z_%^z}=BZwk(L}w2kf1hD@5uPf{J_*Z&G=0H`qevr$`8$})+37-2nlKfix;wgws3CF z2FC_@Y6FWGe#$SWfm&OTITsjEYpavJa6Xzk8-3}$)=uKANiX(LJuQ!5{>+2<GfAL^ zI@Pr{>mrNpIWMB7)!~{yD_itjE7r}O3Ya@Z2NA_blq;G$4JgKOJ%?k-U~&@Y+O^NQ zbT?*CFbDIN&7OFaBM2G8d-Js#XtMpG`XeMT2Xz?pM;XY^FW^hV{QkQjFq4_%2xg9p zH^ExY$@AsfB=n%tLJdj3o0fQ)V(Lt!?*^Y$TCCCi*o!^YIM?p4N~=T&LcPjLD}Z<3 z&_b1Bg79N_&oNWW9%_?*TuXh$osV_;s0q_YI3xxCl4T9m)S-l_LmZO-@Tc@`i0~SU zyfIGA<be;92WaKZ*W~-adzX$qhF%l<0w(s+f_ZBv_N7B>e#i<pG`?4Y@jbL)e)Y!p zJcqX6w7a?*+x1{<R}dkA{k>buI@Yk3_hzG7?q5m}w?<l8`zZhb002ovPDHLkV1l<s B+c^LL literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/customer.png b/src/main/resources/com/unicenta/images/customer.png new file mode 100644 index 0000000000000000000000000000000000000000..29c318c68aa5efe2a853fdf6ef449c41f004a46f GIT binary patch literal 666 zcmV;L0%iS)P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004XF*Lt006O% z3;baP0000)bVXQnLvL_-a%pF1bO1wgWnpw_c4Z(#Z*6UFZgU_(baZlQVs&(BZ*Cw? zZ*DC^Z*6U5a${*>Y#>f=AVg(yX?9_BX?A6Ed)=_00000QbVXQnQ*UN;cVTj608n9R zZgehAMN}YmGcGkQF)%Rna-jeK0ozGLK~z{r?Uq|g!$1^<53Zmu?juXc60!uB;1Yaw z6?yQ2MQYSiFW9RV_04x1iHKq?YNa)_DtbI8u_aC>nGvLU$-qa`bNT<%$s`mYU-=I3 z4xD{iga_w{Gl9L>Ggzme7J(T-L$p6U0yDw`IC;lRfz}u`aNzjO3}}rVjd~r;um+kV zRN%y()aJ<1=u_#2d8qrSz>E!0_sx`^rNmcD-Cv6JLG2Y&sSb^pVC~gR?5Pgr15}3v z;GF0OM*~z4zXeAFN25=r8|LBg1vPM}#v}}auXTF#YT%%c|H5P_zRyXEbD|&YJz)ZU z*neK6oGr=QKe_%iHyJ>621GxoJfegPiWR0mr1IE^)HEXT0>!yjrlA*uat|f^KKbRI z6{-3CSeAQ6f`&{t9)q1O3fR(HxcguMBU?LNJJ8@CQ}?T>XF&9W?RylEo2315*}k^| z4IV&s21GyDx<i5Zn=j3rb6a<&L`T$>e}~d73jBS5(ybY2Y~H95{UlBDGmy3mn>Y4U zNA(^MhlJuaN@!4QfiQnCBG;1`e{v1ih8ircIs>8~Y<QR{uzuwcm<4m}4QsAN;H;T1 zy6C#(9jw)k1uK^xfwN$_ed%>N<e9I02WSVr0Z_tSyX^_D!vFvP07*qoM6N<$g7;}2 Ao&W#< literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/customer_add_sml.png b/src/main/resources/com/unicenta/images/customer_add_sml.png new file mode 100644 index 0000000000000000000000000000000000000000..5ef52c896eb8c0b925daf6b484d3f48c306ea6c2 GIT binary patch literal 557 zcmV+|0@D47P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004XF*Lt006O% z3;baP0000VbVXQnLvL_-a%pF1bO2IMSwT!xSs+GIMMWS?Nkc_WQ$--&*^6la000_v zMObuGZ)S9NVRB^vP+@6qbS_RsR3LUUE;TMOFfjCTp#T5@lSxEDR7gwBlU+{2Koo^9 zuAobB34QggOK>N$gxLYQ0v;5F5Kxq#2O>fs_{h7WB?J`tYeFOt2wvw3Q^EesguZx^ zuW6Wb&ZV7B2vqd=73Q`R2!#%R?1(LXJ%gizQ<b>Cr@o3neT5!Gf(@uGb*L>-g1-Nd z>ViRaffCsM11fU{l{rcXFrYkRP@bWL00T->9ZFM_5MU4J<=%frIOsvZuSo1(aT12& z#N^-xx~H@8UsV`uP#A|fjC1VyH)(C{A+M(PIJuz#`H{uJEeuCEKO*0@$Aa8Yvf<f* z&Q0hbJ9uympx^#_vjYpL!&SE*8r=0w4tntW6nA~Y$7cd{Ih5%!$n?;M24B-Q(7m76 z<?vm<S#a}?zKG9M=A*71rMm{CyC_A3RJ_z_E7f6;>Yx-6Q1Mcytz?@)vW-$iK*dX) zwh}D{i59vdJ3U@G>a-O%8N^L=Kw+84<CdjPTUW0JT)v<b5m50`=Z<1c2C*jkA_6iW vb-C)|*?{w>D5t?e2O{LQw$4O>I=1u;rNjK3@8tAy00000NkvXXu0mjf_v-C% literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/customer_sml.png b/src/main/resources/com/unicenta/images/customer_sml.png new file mode 100644 index 0000000000000000000000000000000000000000..7dcb34dc367c325125f532cb98c73cd1fce00069 GIT binary patch literal 582 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP(r@M zHKN2hzo4=xGd-h(A;>?{(I+HQ!7a$uRl+0`%DRpH*v?o6OkDUj0O{Irtt#G+J& zfW*wa5<NfH5QQ>hJyShH1A{L`3qcO^ba4#v@IE`)+mFdnpe@_xpv*z#GuQ6Q9GrbZ z@E6+)&Ik=I#RVs_9bGtBroR!L%gN{(H(7v#r72ZBDM#j+;$?2_pK5bo?tlIM)vK@r z{x&r&JKnH}JT1_5H~IOUr;pF?uTJ^(E8&SN)?a8WFlfFN)O<_G_QE&wm3k5(;x8C) z-(O&q9x!t;J0s62W45P~RRRYVm|R_8;>yqTrGf8zp3t)e%#8UL%fEL$77#hk#%_LL z#=T?py@xzn4{01poRfS!_tKr|ZCh6DFDhb|{p8%;%(N@Fu+GCOFxfHh!Nm_b@sE|Z zOniI)HqVRu`MKNj8K2&e-2PrGrHYMR_Qy)4%a>zI*aGyTm+a=b6kD?J;PWfICS{l3 zRn%NxFLr0oLhU6VSKnTxaP^|%RmYPY;>tJECgdzmX-W3lBB2tcA$d?C&!}TIh)y%; zkOa~XUb(iPPM^Z{^iEgCWXCO?lWu(EJMs3BXZz>l9Lo<Lw0Fu@dM)Er!=yILSzhE% SRv0jn7(8A5T-G@yGywp7=I18> literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/customerpay.png b/src/main/resources/com/unicenta/images/customerpay.png new file mode 100644 index 0000000000000000000000000000000000000000..e078303d3caa0e45e1203ffcb3a0e54f4b7035b1 GIT binary patch literal 975 zcmV;=12FuFP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004XF*Lt006O% z3;baP0000VbVXQnLvL_-a%pF1bO2IMSwT!xSs+GIMMWS?Nkc_WQ$--&*^6la000_v zMObuGZ)S9NVRB^vP+@6qbS_RsR3LUUE;TMOFfjCTp#T5_HAzH4R9HvVmd#HSK^Vpd z?}~RM>7T$+Br#mn7%%(*MoEl`7o!(rFc>i=Mq>;nCdOM$Ktw=jp%jph##$hej{*_` zUAEiSw%hN;O0ihl$C*N<OSiDA?ZHWYJG=8f?>o=VepV2zZ91c)DGw+Oq@v<vHXYcY zTLa}GsXgY>T2j4!DqTaS(h`}@KoJ&WnzFRX9UYn6ktjF<reUj8;$}<fi7f?{=u131 zE%*7CM1e}A(i^aDgJ_}T4n8G8v`}&bmMw``wxE(ST!M*&o=ha5k}}+c<C{7%z9~^~ z1WZ$g$B<pqu^%-QiGm`qSeaf#xtnS<t|OyyJw>8m54O+7%5>%>zoY+~g63!=8Hx!M z?9qCp_n}y8o?alV#$PpaR8NzkKts`b=4eBa9F32qDXb@h5h!8`3q=jESn)iSCI&(+ z#1zJ%41{FMn#pAJgpD1@s~nEts{K29{Yk{OcR+OvJEbL^PM<71k^Z2L^ar5=*(#(` zDOf{WKd;P5IBSc7^*!DM*!UsX3k?_peZ&}mO8zWqGMU6dZZ1f;JQGFp@<u@{r<EHp zh&o~rp%H=V?TJJJ`E&{!xVIF;)0G%1O(LcOaala4l^f{u-zI&2XyMf=eM)FfJRX<P zv=BklVg!Tk7%tg@V8;hF>{xD~*JmNUK4?LbB-BlaV0}K1mqMsE`*C+Zgd1OiXm^AQ zG)yly(DMyMBaui1bz?rTJ|A8TXUAVI2NmNvt=vGj2Sg*GPzYx}dNJ+{fbHkw@CDGj zCT7RptcbWX<Htpd7mw!snDy-H<p#RkAQ}-x5w#;8ocQ3ziv=&(agI^WhwGDGR2!A+ zQr&?U(|Z?)M!a4xp3l(<^72j@_Ul|2b!Fqjs~#{d>#te&^aU@0P60$CZnqnZcZ&kf zj|ezz-sS$Z0Na`?8&e`XPeJS8^`wJ`7EE7xIGxU-yq@K8%j(3rAs)?>Jgh6bdOC-~ zccFvVk+<s-1!_6oxsE4O95`+t;{u1q@pV*nE7y58&23WyMgE-Hxf;^W*(uOURhL6e x4y&!=pRvtRPud)<6bl9a2&=(r)hm6*e*@$XSKf>vYa{>w002ovPDHLkV1geErE35H literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/database.png b/src/main/resources/com/unicenta/images/database.png new file mode 100644 index 0000000000000000000000000000000000000000..7996410d3e0b32da1c4abc1e1225100da28fb501 GIT binary patch literal 1042 zcmV+t1nv8YP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyM07=1bVF}&d2(rIXmkKWa%Ew3X?A5GLvL+uZ*FrSL3DI-X<~JB zX>V>IPH%24LvL+uWpZO_VQe5yZy-cva%py9bZK^Fb9>#epa1{>8gxZibW?9;ba!EL zWdKlNX>N2bPDNB8b~7$DE-^7j^FlWO00SCHL_t(oNA1@6P7_fS2JlWt1#E4nH9#pX zMbKJl(>8VA759B#qH&4F_0imLLq!x(MDZb53WdT`9KVxzlk2^ArZmL=B>AN?w=-wH zZ#rr5`TqZT+<{W56o-`$#}??3hsVDb$OPwh^7(b$<YKYtK*PPC^Th6ZcrZ3kZaB0I zGm|{mGfbgSu<!hsCw5nXlbgY+!H4%*izpz!av5Bs-5BE5XqDLQKl1s!1>w4GpW$Gh z!L!ste;u05W}O?~tHg4-oW0bGx}A^NmMEwNxHeKH*3;9|`mX|DwsjLFnRbmU-{wfT zitS7$W5M#JhQSO68m^C2%RquQ_u|(%y5!+9LZ#E`82D<i<RV<gL<?|!c$Q2q49}4X z2X<4d2$#_UocS_K!dYy)IftNb+)D7eT0#qOa%h%Lc{q(wZshRlwp$S`Kq{45ar|?I zR40Zi<c34L@hXFB=?^z<YdM)rI(Rb(k)xj~<mMQHx-pgDHO%aQCccL884$NOkw^r^ z?ZLr*XgD-jA$Ay{+#JDsDxBL4Q85p*mx<>=`v~OZ;+DtbacimH1DH|da_Y08%{4XP zHTh$R#bS-%tHBawyq+B`z=6RT5)NWpB|ZlEwVsbdeV()c`##Q)YCqOYda<sO3oNFH z7GT$hX%co1Op|I4)>L~3W=Lf!!fR>~EkHCHZQTBTnq)h$uiA;ACUSvVMfh4;fKq>X z)Nvdu5{dYram%|h$+lu&wG9DPY6;%w5}4TyVO+z(+)*t+{>>B>AQTEUi8sUHunpG6 z{xS)hu&vsRa3(m{fq<BY*<E6e79jh2idaq(3<m4_kJj*|ff=i~m{5E>MNB(1^J<c0 z8?dhm1OhhrY6yxlY9YCt7GT}WNis=e-DEuiny5v1-&95mu;#@Cv93O|?!HMfS&Mbm zV#;U%I-XCEEQK&8omf|i@an5q8RKtE`?GP9B@oIaiFFgTgxFV$c>ciIw(USD_H>+t zHUu+?W8Fk8!uy!n4f+?5R~o<H-w9pKPsWM0xM)RK6P()ytG%xA8^;^AE=EP|jQ{`u M07*qoM6N<$f<@8LBLDyZ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/date.png b/src/main/resources/com/unicenta/images/date.png new file mode 100644 index 0000000000000000000000000000000000000000..624b3ca237688db1a64688733d4f5105613af487 GIT binary patch literal 718 zcmV;<0x|uGP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyM07=1bVF}&d2(rIXmkKWa%Ew3X?A5GLvL+uZ*FrSL3DI-X<~JB zX>V>IPH%24LvL+uWpZO_VQe5yZy-cva%py9bZK^Fb9>#epa1{>8gxZibW?9;ba!EL zWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900GuXL_t(YOSP3rP6AO7h6_*7N8k!B-SrVX zf=8(vaD-ksL_-vnXe2~YoR+#)iH0~5O%ozfoSrrC<aOIkz_gWo>8g5v{nf*wa}bZ? zuW88TN<VF5PGM?d@|Vsw#?`~oXFwR@ga{=c7USyS;2jAAhaVnY1IdR)R9{Hf*LyQi z?}f1cW`ugrBMLvY?WbMi`g*S>9uj-6K4D^<P#q@p<2qX>>1(=R_XP>_FUW$OE)s^A z9{RpVJ>2Pf<W&<-iS1`3hJVaa&8;rtS?wTHJJ~LXcvjj7m3H!iN;@xS7QVwuJ8*hD zo1}3(w?c%iF#QSm%)$$-UVA8SB~2rTn@>ojFW@tatJj_`NYlvS#v>BheuIc-xrI<} z>4I|0C%9((e$Uo=x1(tWp0IY0gf3XS4<uI*)*tdtJ&tDJ39ENV=&;SX=3IN6E8}Wp zVC4o09WLGa1oqKaG^lmqC>qxjmamb>_9I6;i%o=LQx_DQf#eGJ^G=<tk-=EFp0IR< zgbv%BYtFUDxss-dFK|6!@e&CgwmH|FYmaj!O%q?>dcr~j2}5{EPy46dLZcv_67v^6 zVPNjOMqma6<Pnl*|BuE?=FVqe_ADe!M)1vg-!-NYwp02C1^@s607*qoM6N<$f`vOO A8~^|S literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/discount.png b/src/main/resources/com/unicenta/images/discount.png new file mode 100644 index 0000000000000000000000000000000000000000..00b55c94ccbfba5f2ce34e7eaedc9eec56f52fd7 GIT binary patch literal 1079 zcmV-71jze|P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004XF*Lt006O% z3;baP0000VbVXQnLvL_-a%pF1bO2IMSwT!xSs+GIMMWS?Nkc_WQ$--&*^6la000_v zMObuGZ)S9NVRB^vP+@6qbS_RsR3LUUE;TMOF-P-4Hvj+wok>JNR9HvNSG`LkQ4pX1 zAl;QIueH6}{`!C-$YFa37XAT(rH!J9SXgM|2WlY-R*GPu2r7sl_!XmxCNbG1CYShe zGrK!;voCMgcpP{Sek7asdo#bCnK$nR;C~x$@H2_%LA(X%!_RMs#7DFeACXda$lh3_ zjn~&#uq<E^{5gP}_CRFf4SyB*4oN)C6VF^r&q=+8e9CCSxy|55ertbuc>xoifIzu6 zMkz=<KR?qPy_rtQN1RF;$(9W)Ks)GZG#X&S5V1`8H1mtkR4<fwodV+GO8_)BH=FFT z03xy4M7>@I!QmlB!HW__LTaIozlV6i8svO2gnjj#kB(aTEI`6qtJQ!}pPvt$lK@YI z3O@kNYd(E9-X5djuQhr6Y>hy*T7~NIvFTh#0EPI5iRbYV=={5ml8wV${<PM>)6*0D znwk;;wUrezuImJI><b_s@o^qQ9ol-B3Vd^1OY>2P-32Q5<}PSs0rek0xIT0pVdKIS z_4h-iQi;Xi^nn4_b<Olp^{dY5N5{Rn0pi9%1UQb<N+;|ip3jxSq|V3AF$#h6-Cd9O z9z;O7Tn0kWlqlpnr1adz9OvwecZGG!RVF7rTdhC@lu9MgAS3cNOG}|S7oUUr(9H;U z02W<$cZh4+HJ?R5u~-C+(*AxZ&(7kaH(y>`W9Ry$lU?zM+tRcZ_bdVmg#wsxrl*Z! zlf2_D(0Qls2T)pF^=w$uNa>_BCQTnAAfL~J4aMzkTSIEva_-O&_}r#DfO&YOv>y?0 ze}50Hz-YDjR(@2<<KwM3XE7=EB?5A}9J~i~uD2W(pzpjmH^*UbI?`jBS(5z8$Y!$; zhaj)o0p5N93bV8DI5uXs>K?X5^Qvcrj(y_DxVyW9I2e5aBY~Z+x7S-!>FOc@p(CAb z<qi(C0DYh>6GuiSlYuBi9YnWBN8TFqs5b5Vi9q;BC!UNO?Atb=bGi|$R_otxvKt%1 z4+MlFplzuXgd#v38R>KyOa!+ZZP+^n^CKf6uG`t!R0C`)v$q#n1H_SWb#(<MY_}Vy zqoaxUFgzT&3$imad|aDHdXoIfxV*ds4dZqrTkd*iC&Z&Q>8&kWdycz3r`VSWxVX3g zM%3-*c40v{nor-e6BDh9Na?jA;Qag?7`83<FgPglnybHGudlNR{(HyuBWHoRRs@{k x8Bajx*4quw|Lac?aC&+Qp8*kYa&iKnf!`ywHtUg25SIV|002ovPDHLkV1j5S>b?K~ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/discount_b.png b/src/main/resources/com/unicenta/images/discount_b.png new file mode 100644 index 0000000000000000000000000000000000000000..ae5ad4875cee4801304955c045172df06d5c46a4 GIT binary patch literal 1543 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCf{A_6YK2V5m}KU}$JzVE6?TYIwoGP-?)y@G60U!D<ErgLuK5U4b?X49pAx zJ|V6^1q@UEvrhZZG5x>5tp8$j{>v=*udwjH>f--uOa5yt{jam^zrl+CW~=^Nul;Yc z_P@ir|E?SV`)>Iku=Rh)_W$8K|EKQzpL6hk+0p;y$NpCx`(J<Zf6M9rZD;=Xo&OIq zd=!j^z#t9*$2|8WV4h+q3Gxg6Ke7Qs@OO4qU{rAyctjR6Fz6|RFk{71`!b-QREcXu zNpOBzNqJ&XDnmeGW?qS&pKFLhnX#U!o}r=pXD4%DFdBKfIEGmG_fEbUcG!T&#aiVh zQ=^4%W~1K!|I^<^Y)jc$;P=s4`n36^v^8rUP2T!T-JtyOM%VNNAHkC!_#&GP<E`_o zE0r0O?doGJl^c!y&l&3Rap)g7*uc1BS+CIT<UI_pF9{icIJ;-#_AC!Ci-Z$Tq;{-O zW52V)`4D@8(ODL|u19g+47FcXPNwwQwWv5fn)@xq?#~Jb%|C2&vYOtcED1_b?pJ?s zb*}gU*DFcO4}G3E*X;Lko?z3}1#fL;9DTE8$0a7el^Ty_O&g-lxCuD@%4OU-V_(PA zIg?kOTp)J&%IqyOf_4a{87^1#&R|s25zGJ2lCjapP`rBP<^QIdTZQf=EsOiKrcU}o z#GjSdcN@>#Qt|#>!hFto(|NY+=vf?edKv$xIn^6>=H_o=+W%Or@>l77Mse;lf8vws Qwt@19r>mdKI;Vst0Hb&RzW@LL literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/display.png b/src/main/resources/com/unicenta/images/display.png new file mode 100644 index 0000000000000000000000000000000000000000..4a9ed1e8521126de5b08729358ca7863efb98fef GIT binary patch literal 539 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvVv45dj$D1FjT2AFf_C<F#G}vHN0S8C^cYUc$L7wU^Rn*LA+qju0R{0gnWr> zM2T~LL1j^9dPWIDkbk73Pe`PKTac@(f{&-Ot6#9I!o8c_nLwpdAf>_iX(i=}MX3w{ ziJ5sNdVa1U3T4K6rh0}3249L60v+bz>Eaj?;l6h2OTR+_5-!W_9BXCnuY2Fr)lt~Z z&30u+Yq<mKl^sWyvK-Nna+B(vcF#fYarxxQ|6a_UIr)n_bC31aI*W?C4gxCve<$dk z@$vPKo4^tB+a&SR*ZD_IswXz;6#Q|FP~evN+F`QKHS63<`x^C2Ke$#{F8}|a*W<DF zf@gF7{S8;@UEeUP_}BMcEv)+<o!fg?{18**f=h~jI_k`|=AJltg6XN*L+7dmclhS^ z=xn&GRC9ta#dwp0rrMt$|5%n<$Ou?UMkf58xxqo~MwODz1XeS7PVSV(UUr}<34iAS zg(G$=1BJu#LBdm|LBc<0frNK~RCi5pVcm4#5i8KG0U1Jv|NQ;#K2>a1pqg`~JU1`j z#P$8+C$2lIly9=UnecB8P}dA=kYQ>5Aj4vG-PRqe7wW(DpGp2GxBt>pX(hmrXYh3O Kb6Mw<&;$VgdCs~3 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/edit.png b/src/main/resources/com/unicenta/images/edit.png new file mode 100644 index 0000000000000000000000000000000000000000..90c0bf8055ae6de330a690d51bbcb74cc16c369c GIT binary patch literal 644 zcmV-~0(<?5P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004XF*Lt006O% z3;baP0000)bVXQnLvL_-a%pF1bO1wgWnpw_c4Z(#Z*6UFZgU_(baZlQVs&(BZ*Cw? zZ*DC^Z*6U5a${*>Y#>f=AVg(yX?9_BX?A6Ed)=_00000QbVXQnQ*UN;cVTj608n9R zZgehAMN}YmGcGkQF)%Rna-jeK0mVr~K~zXfrId}0f<O?3w}dOf5-7nEEWr{ifetKz z5-h<IsKA)hgiFK(O}s>N=k0yV&;GHj5J_Hu**EXa%(93dAyXhnVh?XAyo*?7<)_Z_ zNMXBx%ogy(JD%Z8G#De^nQYMh5EBeuiK{Uspt3Z#V+~%3tEv+<y4FOGbc{h>x7uC< zGgpGDa@B#o;Zpqa1x1jvrp0;AUhsXbWz4`4mqM;4i>t1s_>%$T#B}96F9&#`Top5C zg&`5}@tk!tXASWXXDIe`526$g3>@S}{ILkE`+WPocgh*j9fE_kF}QC6>ps7IfAqzh zJ@|&;U||eyRbbuctM{;YV{n7upx#_!NgLmCXCHbzl}7<LU6AvWGgV$7YFP8XtlD_m z7+x`PxQJhqpr{>`qQXGKnt#Ro>o}immA3bei+H8Q?dP7M6lan&tofh!-kRd6SmuhC zjPhI!b|OVdqQ=~eu8tvCB3Lq>QlAaOIU#<cn^Hy$z7W!gZ<wV*&Kw}#<VFk%2pY`0 zsJ|lrB0d9jQqWOBXHH(s;D~_(Ob(pj0~M<KaSe#|curoVg9F6(5i$70;C)04c6{SI eOy0t3$lxDymXj3XYHQ2@0000<MNUMnLSTa6-5Kxz literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/edit_group.png b/src/main/resources/com/unicenta/images/edit_group.png new file mode 100644 index 0000000000000000000000000000000000000000..abd427832b25d0d771ec46446eb00f1e7d129fcd GIT binary patch literal 647 zcmV;20(kw2P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyA9O`nbVF}&d2(rIXmkKlPgy}sR9PTKQbk1|Oi4pUPE$o7-r0+3 z0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK0kla(K~zXfy_8)} z!axwm=LkJQkI*A<1dhNFIKtk5Bk-U^0%9=`kV-58LEd;*LIWZg2$b3g0l{&hK<V1z z@)4W-((LT~XLfgH7vSH&Dhg1=Acd^)oo@}5g#eXB4W7QyL1hs*Pm=PSKzWWX=<xU@ zoSvjKQ=v3N56*B@#c2qNQ}jSQeFue!2!)AGL59%j!8Z}qu>=pFGDTgXj>&m~=S>26 zQ>Dm`fO*ruwdYOgxMYeEhWiiPq8N5tDu%W*XD3$-0Te^s(dcyS($2Y&A95pP(BMuN zs4d9Y?Etxv>Y`i5VY)3ltkGb|iPcHjq2%eG9XgK~G6UphQ-I7s+M`jObxQXU__4R2 z?rR=8rVgnd0v}<=%2GXv>U2iy^jQgR-w6f(z<I98t^~=hk7`89^1ozhv+T((^KMxa zWDmAL?u0?^;2L|ya!1^;>u~dS#GOgB2_)LcV0Bia9cJu09Wy)GcTM9h5w2hH7x7jN z;;oR!oJ&o-lEj)ph&Ay*bpEF$su754cre@<t{Mcc8h9|=2_p3XMCy1T8h8Aa<K;^b hE}k_Cav)QG@dt??&)uh5#XA51002ovPDHLkV1oLH3z+}_ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/edit_group_sm.png b/src/main/resources/com/unicenta/images/edit_group_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..bcf4ada9a1e7519e0d46e816fa393c02f84e7e43 GIT binary patch literal 774 zcmV+h1Nr=kP)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004XF*Lt006O% z3;baP0000VbVXQnLvL_-a%pF1bO2IMSwT!xSs+GIMMWS?Nkc_WQ$--&*^6la000_v zMObuGZ)S9NVRB^vP+@6qbS_RsR3LUUE;TMOFfjCTp#T5^Y)M2xR7gvm(o0BGQ5?td z|EOUY20e(f7A=e@sfeJW2T0K>C<1lSB3hW6T7-}i)S^WTk%)+B8Db*7YDP^RD<7kc z28AKa#zb_+n(@&zGfg^<j;HTjugxTiw|n8kJ?D4M|2G%ZBFRs`itje)EW8&Gm6I0j zz}(}ES)^}qEApgYJ;pN>v(FZ1EY)0TeCor(CJKr$Ntyb~8LQ-Mm-Nn??Czc4$8a0e z3bX9bOHb6~SNBA78192wMLt=YxleY??U3%sBSfK+xL6+%$6Wl6Y2xXcO_i?MW70WO z0T+hQO?DL-CK?%e_iHn*<AJ;n7fHwOv&dzgPgaT&?Ek;=_F#sz2g~Gb$OAvB*=K7d z?ZNx(-I&I6Jxd`!gcoF;u(Q5{o&Wx@J#a<rfe@5#g7+<)ffI{*epef`2X><c5j~He z`*9nYiSkzeM``=1k}R?gBY^p&{Didn)7W2HkuT5oaDE_B-10+-5pSlmxR-{@h^;a+ zKz2A$+&raZeIf2#(1x0)_Tmd-Npmx-A7Xo=xM|WYjT1_mCY3ZI{$93}2T+a-v3f0H z^KD~Y00#!}85MLK=R94zqdhj?HFUtWh9~4pU-J6<DU_m^f?V<(jn!K~b`OQvBd@+u zZuO=h8yDA*rQK;5Kgz%-C<IYPwh;$ex9NF={Zni)_CH_e&XjtOO&UCkA@HvE3`(85 zkaszzw7fpf6CuB0thjdU9G3%7Ng`4^Hp<?&B3I;t#)@l3i=<{W3}sN%SaJ2pO{pFU zLm6hMxoS91s)j>Q26+wjQkE_+zZOg7&^XjO9Nazq2c^xlzI>8Me*gdg07*qoM6N<$ Eg0_HJ{r~^~ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/editdelete.png b/src/main/resources/com/unicenta/images/editdelete.png new file mode 100644 index 0000000000000000000000000000000000000000..a0c6907708158d06d0f21d1ee96b07c7c414d677 GIT binary patch literal 587 zcmV-R0<`^!P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyA9O`nbVF}&d2(rIXmkKlPgy}sR9PTKQbk1|Oi4pUPE$o7-r0+3 z0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK0eDG7K~zXf&D2{? z!ax)T;Ijml&?R&!T|$@8C3FW}LLZcX1VjM|AaWCtx4tW3B;W;*42T2}@pwXGq~%g5 zHF1*fVUjcFpG;;3;9ra?icm#`s5TPKeeU;Inafa_Gr0Z2ttxY!>V(~c$}<6OJ`I9< zDbEz=kkV9y>km%QC4F;9aUwu*!l5+9gA^y)`jEodfWjC(B3VOnBN=id^boTKWQPo{ z-qBOpp=^d^1|nR(q31G#s2Py%D+F!w6s+zn-PdS6xAov=K#HpbZT5emDXy*bSp;0X z>X7WAh4YJ9tw{FN^?edu6%t*va1*exPrRc-yn`08w(TA}B*xkT#M=3lK8t1NFA~8& zV3^xFd-g%}3ID*-ml0{{5NV;OP9KHegAF$Y2shC~Ykt*GLxE5OJ;12PhIbTXIs_RW zfWygyxc$xr>KX*<=mMiP4$Xg}{WS^vHAZkpI@Rs}y}<Fk3`ciS!U@_KG}owR>9$x8 Z=Nq*?*sSP*9{~UW002ovPDHLkV1m(7>UsbG literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/editnew.png b/src/main/resources/com/unicenta/images/editnew.png new file mode 100644 index 0000000000000000000000000000000000000000..7547acf49a2a564d004491009ad9e2a46af8389d GIT binary patch literal 649 zcmV;40(Sk0P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyA9O`nbVF}&d2(rIXmkKlPgy}sR9PTKQbk1|Oi4pUPE$o7-r0+3 z0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK0k%m*K~zXf&6HVE z!axv)`v@E%N5~O8LXN-@I6`iaBjiCX6+slxazPds<Sp+?5m{UStx=HzRBT(KMUo*i z5MNBy_mIio{Y_0~2H;;j6;z>uF+%sD(R(EP9LwV<l*cw)e4>!@*rc2?zv%2;f%6ZG zz=b$_kI5w`BNa~H7=a-%gC(V*0;M5?lM()j($JVKDGn?s4lsZMjZc4Qai9sZ-#s+1 zB;SuhzK;TQZdT&F?ak+UHXOgA0A3)@BjkEfM{@YA!qE##;03ap!{?MEICzQ?=%YYl z-Nh2OMDFhgPX^U9Uk~Qg>@%G}AB&&ReP(cdCW74u6ZRg_gZ#wsiM>aCcAsolhin%; zgb@Vx$#itcbkIY(?c2u^W4f(Cx?SM<Ov-ldH3B8@yGUMRIn&y{i$LlYCGY}yjqA!t zwoFL2PyjCw=MlDUl<C4InhGSE7|3SBdx32>BEo#4IpbE1*JBW`V*rfC4MP9H5@c=q z7I2Q%Z4=gQ`~wU&u2u1#TdNtcR>Kh3R3mBrt6r^Yuv)bVoD-9Bi(fCWautQ;%M`%~ j^kLDvK^fO>@h;96H_3aMe;M!^00000NkvXXu0mjfd-n!G literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/empty.png b/src/main/resources/com/unicenta/images/empty.png new file mode 100644 index 0000000000000000000000000000000000000000..3c076d6db7249909f266ee58242133469d5ad6fe GIT binary patch literal 1229 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU3?z3ec*FxK#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvNA9*GX(gAxB|sT!DtAK*bvxk@TCKoPZ&yq{DS|FY`_rwom~}}5I74wB8wRq z_zr_G<MI3zDL_HV64!{5;QX|b^2DN4hJeJ(yb?V>*ARs=V?9$nvkT2@qkxK3JzX3_ zEc}yy_^Tu+1l|1~*jnM7Wm4hR%&yGhCVVtwk;J`DCI+2pR?;@j&qF|I&ePS;Wt~$( F697UlHQ@jN literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/encrypted.png b/src/main/resources/com/unicenta/images/encrypted.png new file mode 100644 index 0000000000000000000000000000000000000000..4ac01194817a066e87ac50106aadfba475470fdf GIT binary patch literal 577 zcmV-H0>1r;P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy8gxZibW?9;ba!ELWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900Egv zL_t(YORbcDZUIpc$L9!+;0SvJM{op3a0EAS1b;}CQd>nssHIx^pZ}%0N~xlGLWOFX z&eQ1<k*4gM<ddD9_ha79clH4sV%3!&?h&E7a$C!)D=){qhitWfZe{6*$`T3FnowB^ zjwwiR_vL`w&l-V*hmn2_<d_mGFEl7G1l)WWgt_+13#YxkOLHHT<_4h?(ytN7$heHj zG3g&ss^UyQafbiIIQ(l0QwJ2LE<#%`E=&zV5J>18(|C?eE%Fl|T)!jXCjx6fKRKc- z`@S<bc0+EAjFX;{-*?yHrP*DP9qEuAArY{KvLl0IKKltWLW7L(5t}+^gp*@G`W$8H zp$1oP2BE0d+ownk9FQ6aNDpz1a!dC8knAIKM34V<qC`)FL=P=4Uu|9qyUFyf0T(aG zDCm;y1o4gs;vHm6(7QJO(Cy7*Z3o2K0?wb2ajVrf+6q9lg^XfhBTW}XnrLzMq*&On zS%a{NjACI!4KIWm$e3{Ys8Cp`;>m+SAfw=R+-;3uJpjQv5}Vu7X8U{tOXWz{g}bU5 P00000NkvXXu0mjf-S_M_ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/exit.png b/src/main/resources/com/unicenta/images/exit.png new file mode 100644 index 0000000000000000000000000000000000000000..1c7d8fb0ff606f3b5f8e78a7cdcbe530b2b842fe GIT binary patch literal 2360 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/favicon.png b/src/main/resources/com/unicenta/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..c59bdd538352c8f40bd104220a8d79a983388fc1 GIT binary patch literal 1742 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/fileclose.png b/src/main/resources/com/unicenta/images/fileclose.png new file mode 100644 index 0000000000000000000000000000000000000000..65d4e231e3906293ff63d216c3652fcecd2e9e65 GIT binary patch literal 716 zcmV;-0yF)IP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyA9O`nbVF}&d2(rIXmkKlPgy}sR9PTKQbk1|Oi4pUPE$o7-r0+3 z0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK0r^QpK~zXf&68hN z+E5V2X9+BUCETU31eTB`WCtwaKG+_sf)OhPMNq7zzVU8*Ocg{_WE4U151md3RFX`B zVjr4wekYlG=bP`|xi<j+#dAOk4#;3k9|?|Q^RKZwOhR>N!}s45Np+|>FaCO?{U-(A zo@)%fiTx*Iw#nXug0GLr(46RSlgdCrWq`2vK<}b52r=2cufgs;3E&&Yof--6PRjix zl=~#$uBP1AzBz=QJ2j%*M?q(M4YqG>DD}vPcdMnI9?v7c)!zcncd6%$dG*`3NjGQf zMnSPlK2SWYVmHNkFU2QG#jX*kv2|m))0@`@Ljn;uV#>aNinS={$BQhW2?ZpPd?(r@ z-%*h7V5okyjxSdxL!so_DY0F-b{ukTjMR>V8<!?SAs`nC_I%>Faj7G;<fg5kn+ypc ze7*=TJ~3H8*CG0`LAI5EY>Rv#$HC%jXK}Gz*_IY+)ZE;)vlv)S3b1<WHE?39iA?a| zt)?Z^m^!;mLqn!PK9FPA#Cc~LPCUtZF_E<dtEW@DP1oa)u2X=O6NHr$gF#_V^SCAI z(ski_FCQDQd`$lUn`^|xvw}~yX6PLtEd82s^A?X%uy{msV6$fSwH|Hl<Ie<RGxSO{ y=Y_OIZk9Xx;YSh{4lM>5@=@bB#X0i7!SX-SsF-)Uk+%#00000<MNUMnLSTZQKQKA~ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/fileopen.png b/src/main/resources/com/unicenta/images/fileopen.png new file mode 100644 index 0000000000000000000000000000000000000000..e3073608fa8631b3d7a9712e6acd76a540ebf060 GIT binary patch literal 570 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP{O6e zHKN2hzo4=xGd-h(!MP|ku_UuBRlzwwH#a}8Si!NRq$o3~v?Mb>Pr)xgPZuPfT9llb zm;>Z0xTF?kmVq@CSKr;R0BD{R$h_eEw370~qEv=}#LT=BJwMkFg)(D3Q$0figD*u3 zfv$J*ba4#v@LoIB+mFdnpzZ%hmSUE^1J`8l9Z)V{=`%2Yz@f(=D(d>tk;6k}#py!c z7YmXcYI;~qgs$9gYc<F{F~KwRlW$Py-xaG?zB4nJc6$DVU$+c+iWi;ds$6<SR7ZdB z-_N=^7XNP@K5G8l=o|aAR~k*PI=BV6x4EZgEH+xA5T%elzeOiCf7w%hC$Ze-OAQ*l zGIRE|H($MxAGXn7<agoz#DjlZ<pN*0Ht9bwH-3M~SmpgOgKZ}tFsZM<H^1mllD72G z0~a@coqq7)<dr2{i<-`tF26hZ^*XJ&O+L-@Q#Ri3eEeWyQ^wiJxwlVj(`;K_ZKNx_ zn_tAm`l9vsz?3Kvm)&2s<z3%U>+ZN^wffzX33)*rr3cbdAFH+awl`(yC#(`Y`pcB{ z;;Z><qCKu@x~&rYG)*IrTRCuZ3&)SL-*-<H|Ji@M{M;|SUFKJTVb0*`>gTe~DWM4f D1uW;o literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/filesave.png b/src/main/resources/com/unicenta/images/filesave.png new file mode 100644 index 0000000000000000000000000000000000000000..47a4864fffa0012d6b49fa5d6acf0a3c105bf4e6 GIT binary patch literal 546 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP(r@M zHKN2hzo4=xGd-h(A;>?{(I+HQ!7a$uRl+0`%DRpH*v?o6OkDUj0O{Irtt#G+J& zfW*wa5<NfH5QQ>hJyShH1A{L`3xN*v_jGX#@$lX{<)#<2qk!xCAFOp=akZE2U)Kwo zy9By;@^Eq%R$fUjbQW=)(y6F;@U7L^fZVGF3P!fP?dzUiTie*?S@3JFlIJtQ&l3)x z$>ZcMetzJjc(&5fkLk=7zY=<v9C$Fd%S~*zlkfN1Ikll>f7YhgXQywwH(#(x{A;@2 zlU>VAKgAurd8sPjizDvB>|GOH&%4$USh#J=y}1HS;w9=}6-gm;bk~+2Yk9yrcO&=C zcbUBsqUqkR-wG;LI95M#T30P3zwc@PoA-~_=ooyxHbG#|0@D)3>wEVn8J@SDl5VWZ zazAHTx8%F~FIbO#elS&F%L=a?oA2=)3%gd%Go4p`zC|Fr@#CFZrIrZpp6BP36^}$E z*ld^QP`t+UcxS0U$3`)U^JlG{I<_9D$h#xtw1)Lq@!vLqYwJG$_nG?Gc8hx0`Uvfa hohfS*em0eUV&<6`>+Blyz7-e&44$rjF6*2UngA9&+$aD5 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/floors.png b/src/main/resources/com/unicenta/images/floors.png new file mode 100644 index 0000000000000000000000000000000000000000..8ac4e908518f04b013743c486260814d26c13775 GIT binary patch literal 554 zcmV+_0@eMAP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy8gxZibW?9;ba!ELWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900DwY zL_t(YORbY%PQpMC#)lj9I6iU|j^GjY1|Fdg1OpO4W8}Y9kPzSYonSx$(HQx!2of^x z(t_Q(Q!wo$zce#D-}h~rHUjQ?#8c6pDKl?#5{dYpA3SVsOlWS9<e<SZ3yrl2jWudH zM(?{*Ul~wead`MfEtL4E{o2xi+L8;9gbJWE`+aL+fVJRo|AoF#0hDgLfBRv;-6t2I z201tPb1J~CRd%X#1FCZ_LQsR88_p%n?YXS#JSt!cZoLvvndP7|Lk(QaZ1Y`JX7WD) zF=vFv_ED-ljX`OG9ypYzs<~TKnlO##*W=G?ERJJP9HRplPug6Hi(}^6x13(iY_wGv z#UMY-L1E-?F2(sF6QBcOsE^T4Z{87TLI}8iL!b#E;OZ5DCWL^?7la-Ed9~Wz>>vu+ z0rP;Ow+URCK7&jjNdgC?dkoS&Bncdl>M}@m(ZPa?XQmK1AlYG%?4UykUx>WX`4bbM shL8dhZ3c-pY6vMH-eM4Mp@zT#Kk{WgH2}Xw<^TWy07*qoM6N<$f;0Eqj{pDw literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/gohome.png b/src/main/resources/com/unicenta/images/gohome.png new file mode 100644 index 0000000000000000000000000000000000000000..a1797908648d75fa4201924f1a6792083777b8cd GIT binary patch literal 642 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvVv45dj$D1FjT2AFf_C<F#G}vHN0S8C^cYUc$L7wU^Rn*LA+qju0R{0giDEQ zM2T~LL1j^9dPWI@b5UwyNoHB9f^&XuZhl^|f@4WZQD#zUNoIbYf?s}~E=WAJC^<7R z2gp@$NiE7O18XR*zPn)o&^#%SdBOQ<CFO}lsSE*$nRz98ey$-3WyX4@dWHrDUy2q2 zUEk&D;usR){`PXT-ysJPwg>f`v0l?JsP15yc0lNcr@Tqll@7<iCt)sn`@Y65cIlN8 zS$oIjNzt4xM^1xa8_}dkD)&$O{4=hf#rI+Vzc1nz3srZBZR)BOK5AFX#cM6{``7lr zAB)Rw)`UCn%U*b4vEa{jKMi+ZFg|vUYw!A|HB3AE`eKfYWpD+*krqBzqcI^@+M=$Q zC1`{C9Aj>oy=)V5g_##SEK60oth7vC#KYV)LVucr-HeS6s}?F>-7qn4l70}c`<cso zZ5vYVI&6B!@x-`1%^^-HkXs>ealGhyHudQiHD-eAFU9OA=M6t|QK0w`)7hD-?=Ckq zt4A+j-Pri|_#_AJAf`p4%+>r)BDV+$&3u_QJC&!d_3rNp4)a#XZN6^#ZmzO+5T8=e zHP%T%q5)6Y%Y7=l-hG&B4dgv|Cb&;kGn6q;?zXwgQmq4LlV8tT62iKpGAC~0lvNDo z{k`5`RU6}!z^byvA*#O40jpXw2cqg}Fi_PD!~cBqX3l6*efj?{Fzy&UUHx3vIVCg! E06Wn6hX4Qo literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/heart.png b/src/main/resources/com/unicenta/images/heart.png new file mode 100644 index 0000000000000000000000000000000000000000..e9d841d3780dfcf55398f8d1689678aa4d7f1ae3 GIT binary patch literal 1165 zcmV;81akX{P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyM07=1bVF}&d2(rIXmkKWa%Ew3X?A5GLvL+uZ*FrSL3DI-X<~JB zX>V>IPH%24LvL+uWpZO_VQe5yZy-cva%py9bZK^Fb9>#epa1{>8gxZibW?9;ba!EL zWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900WgtL_t(oN43^zY*bYk2H;Br3GhRk0ErM# zkwsLNtD>T^3Ic+%@3IVtf~ZjTMRo<0#UlF-A>lteD7b)vAR>se*s+~y+R|yK)1A<y z%g6hb9CCPjry@d=C-dF+-gD1+|8%B`Lw{vuWl!!-xf#&73g5)_hz2z#$Hc^}_PFI> zZQP#JoAI~TR$M)-e)Wb}8}wRRo|TrC`nCpch_MYb+aA0j3eURcMLO?5X4{Etwkx@O zozL?CB_$=k4M~N<HX>u2kSVNjmCl=SShfWj({j4kU56+xF7CMcpF;WC!y064ZDOIY zb;#IyWXu%QJ?|W1MM8lXD>1WG{sLiNA!G6WLSb6WW|u5KKv7XqpQV2nh_MVa`vMvJ z5*b^L!!x@am(;zTMOX8MEk?#ZyOuBPb7XAEwF0r(<-AHdb1&x$n|CE&*nDJc0W!7_ zhi8?QbY}dOCo?_FLdIqzv(34jC+t%cVwIJ2CSS^vDITW&nI~)-GBzC<(^4#2N$2B> zxuQP#qoRq(Y?E-!;x6S1(^4#2NoU-JTv6jae29!qz+u@($e1Z+e|nX4#+=U)<GtT= z#5NY!?0sbH100l@V)mz3NoT}wIbw{&%tj$&J{+2jM#k)N(Mmc)e$5tRC}uY7T(+=x zk+I?Da)jCCqLp+ak%-&>Y_=E!FtdTk*dSzVFbXicpw4zd-MjqXaj#z@V)Vw$`kaXf z>x+!_JCiNUF2^PBd>MtqVc%P)B4YG79TC<O8G9QUdj|z<b~(GG?s?Z&a+ja8#CQ`k z>xztZJC!A@JBl#7oS7^9C<%o^ZikauVs!i|OIRml><whL&NwKu%jv9pdHyPT?L=6N z*D<rU$XL6RVPWl2gxTey{wCBLFZ~b}<7Le3l^?@mYlCa{Dl%q@Rl2#}OiN3Pb-&LP z^}L4{kg*qWP}Uk5(|7;t0rY{?)KvGm<C&tGlNR4)3TugswL)gociz+H=Ao376u0TO z8S?b8ikcx~&m7AX_ACys^j-gHbMtU=a<co>HyOejA!ChkSk?rYzT>_&H;aP7pxfYR zNZ8}Z*b_%H#HMTi*XCw%AP{gLI~)>QU0kzzM?zxgng_DEc}Y@IQf#e*>0+yWC|y{c zLm|;;AL!=hWr>N2v5y=`7voXPOrLouo7*q-`~7h>_FWfMbN_9cJ@k$34H6O(+^T!8 fOEu8>emB1b_{wYygFc0F00000NkvXXu0mjf&?pu- literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/img.discount.png b/src/main/resources/com/unicenta/images/img.discount.png new file mode 100644 index 0000000000000000000000000000000000000000..00b55c94ccbfba5f2ce34e7eaedc9eec56f52fd7 GIT binary patch literal 1079 zcmV-71jze|P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004XF*Lt006O% z3;baP0000VbVXQnLvL_-a%pF1bO2IMSwT!xSs+GIMMWS?Nkc_WQ$--&*^6la000_v zMObuGZ)S9NVRB^vP+@6qbS_RsR3LUUE;TMOF-P-4Hvj+wok>JNR9HvNSG`LkQ4pX1 zAl;QIueH6}{`!C-$YFa37XAT(rH!J9SXgM|2WlY-R*GPu2r7sl_!XmxCNbG1CYShe zGrK!;voCMgcpP{Sek7asdo#bCnK$nR;C~x$@H2_%LA(X%!_RMs#7DFeACXda$lh3_ zjn~&#uq<E^{5gP}_CRFf4SyB*4oN)C6VF^r&q=+8e9CCSxy|55ertbuc>xoifIzu6 zMkz=<KR?qPy_rtQN1RF;$(9W)Ks)GZG#X&S5V1`8H1mtkR4<fwodV+GO8_)BH=FFT z03xy4M7>@I!QmlB!HW__LTaIozlV6i8svO2gnjj#kB(aTEI`6qtJQ!}pPvt$lK@YI z3O@kNYd(E9-X5djuQhr6Y>hy*T7~NIvFTh#0EPI5iRbYV=={5ml8wV${<PM>)6*0D znwk;;wUrezuImJI><b_s@o^qQ9ol-B3Vd^1OY>2P-32Q5<}PSs0rek0xIT0pVdKIS z_4h-iQi;Xi^nn4_b<Olp^{dY5N5{Rn0pi9%1UQb<N+;|ip3jxSq|V3AF$#h6-Cd9O z9z;O7Tn0kWlqlpnr1adz9OvwecZGG!RVF7rTdhC@lu9MgAS3cNOG}|S7oUUr(9H;U z02W<$cZh4+HJ?R5u~-C+(*AxZ&(7kaH(y>`W9Ry$lU?zM+tRcZ_bdVmg#wsxrl*Z! zlf2_D(0Qls2T)pF^=w$uNa>_BCQTnAAfL~J4aMzkTSIEva_-O&_}r#DfO&YOv>y?0 ze}50Hz-YDjR(@2<<KwM3XE7=EB?5A}9J~i~uD2W(pzpjmH^*UbI?`jBS(5z8$Y!$; zhaj)o0p5N93bV8DI5uXs>K?X5^Qvcrj(y_DxVyW9I2e5aBY~Z+x7S-!>FOc@p(CAb z<qi(C0DYh>6GuiSlYuBi9YnWBN8TFqs5b5Vi9q;BC!UNO?Atb=bGi|$R_otxvKt%1 z4+MlFplzuXgd#v38R>KyOa!+ZZP+^n^CKf6uG`t!R0C`)v$q#n1H_SWb#(<MY_}Vy zqoaxUFgzT&3$imad|aDHdXoIfxV*ds4dZqrTkd*iC&Z&Q>8&kWdycz3r`VSWxVX3g zM%3-*c40v{nor-e6BDh9Na?jA;Qag?7`83<FgPglnybHGudlNR{(HyuBWHoRRs@{k x8Bajx*4quw|Lac?aC&+Qp8*kYa&iKnf!`ywHtUg25SIV|002ovPDHLkV1j5S>b?K~ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/img.discount_b.png b/src/main/resources/com/unicenta/images/img.discount_b.png new file mode 100644 index 0000000000000000000000000000000000000000..ae5ad4875cee4801304955c045172df06d5c46a4 GIT binary patch literal 1543 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCf{A_6YK2V5m}KU}$JzVE6?TYIwoGP-?)y@G60U!D<ErgLuK5U4b?X49pAx zJ|V6^1q@UEvrhZZG5x>5tp8$j{>v=*udwjH>f--uOa5yt{jam^zrl+CW~=^Nul;Yc z_P@ir|E?SV`)>Iku=Rh)_W$8K|EKQzpL6hk+0p;y$NpCx`(J<Zf6M9rZD;=Xo&OIq zd=!j^z#t9*$2|8WV4h+q3Gxg6Ke7Qs@OO4qU{rAyctjR6Fz6|RFk{71`!b-QREcXu zNpOBzNqJ&XDnmeGW?qS&pKFLhnX#U!o}r=pXD4%DFdBKfIEGmG_fEbUcG!T&#aiVh zQ=^4%W~1K!|I^<^Y)jc$;P=s4`n36^v^8rUP2T!T-JtyOM%VNNAHkC!_#&GP<E`_o zE0r0O?doGJl^c!y&l&3Rap)g7*uc1BS+CIT<UI_pF9{icIJ;-#_AC!Ci-Z$Tq;{-O zW52V)`4D@8(ODL|u19g+47FcXPNwwQwWv5fn)@xq?#~Jb%|C2&vYOtcED1_b?pJ?s zb*}gU*DFcO4}G3E*X;Lko?z3}1#fL;9DTE8$0a7el^Ty_O&g-lxCuD@%4OU-V_(PA zIg?kOTp)J&%IqyOf_4a{87^1#&R|s25zGJ2lCjapP`rBP<^QIdTZQf=EsOiKrcU}o z#GjSdcN@>#Qt|#>!hFto(|NY+=vf?edKv$xIn^6>=H_o=+W%Or@>l77Mse;lf8vws Qwt@19r>mdKI;Vst0Hb&RzW@LL literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/img.keyboard_32.png b/src/main/resources/com/unicenta/images/img.keyboard_32.png new file mode 100644 index 0000000000000000000000000000000000000000..6a0ef7bda4e2951d8425737a74777430974fe70e GIT binary patch literal 1354 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCf{A_6YK2V5m}KU}$JzVE6?TYIwoGP-?)y@G60U!D<ErgLuK5U4b?X49pAx zJ|V6^1q@5?NUgbRyyc$B)(58B9t0hD5_I5c=;7x(ckY~V{^8lPXK&xW4N^7=MnhoO zg}@fsKptS8Vkimn3;sW{0YmV2c2!^mOO?1rlmzFem6RtIr7{F0X6BXX`MHKDlo{)p z>KPike|9nls_OD|aSXBWKRel*uR(#w<*5GFJO6iW4P)Wia_ZbohZElIGY>fEOV#mP zD7~Jvd$!Vs9oy3SD*Qeyo*3G2mSvAoe4lN!!2;eBz_3?174*i6!NrNkaaz)Jb%oVV z6TG^Q=`LUoD6-R8H6iB~W6g$+zl|@pWt*&IT)AxX#ygp_HfZf)_|*2sUHj(04`2C? XzsY(M#JEiilsG+I{an^LB{Ts5#4?44 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/img.ticket_print.png b/src/main/resources/com/unicenta/images/img.ticket_print.png new file mode 100644 index 0000000000000000000000000000000000000000..5b28b70b5d31e01cc38d30473fc177b8447edfc4 GIT binary patch literal 639 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvVv45dj$D1FjT2AFf_C<F#G}vHN0S8C^cYUc$L7wU^Rn*LA+qju0R{0giDEQ zM2T~LL1j^9dPWI@b5UwyNoHB9f^&XuZhl^|f@4WZQD#zUNoIbYf?s}~E=WAJC^<7R z2gp@$NiE7O18XR*zPn)o&^#%SdBOQ<CFO}lsSE*$nRz98ey$-3WyX4@dWHrDUy2q2 zUEl8M;usR)espT4-=P2rSN(Mh^p3}tc)npZebB(%Atm@&r0$cv=}|^@0dI$%;2ob7 zw`68=e{rmuEIe!a^kV%+2c9_1vaR<vHb(fwU3E6wxMhRIP7gMb-E%Z2Z|Bd8`zO?t z<y5U#$KhzY(DwQLmIbpe%-gK*6yTe2{-wI&3bifIpEL`E7;jvDp>y$tha9Vz_sqHU z)MMY;hd<`dTfrys+BWOx#Qe+RR~a4iULFhVZUl+h=LiKhF;AY@^w<2{%%Jn@`6r~O z%NOyUlf3&&>Z#N(5Akntmf@R9s~c=~|DLe6cwI`CYD(6xhD#peW$_Z4H!9PXB>e82 z*tFK&jq6e<U%@|T-t(dLU3+a_X5D#p^qB4M9goZH-YV#yf7YD#ecgS*ChNNAmx0#C z?^gX+SjTesb0+uQ?|0{gxV|ore7=%Pu!UoC+qK=vZ1;+-e6o*6)L-iO&h_GSfx{&O z=J%Ge-x?IQm;6rq+9nVpd~0)&FUKm*w~_ml(oSB<R|zzms8Q^8<38v03HIMu*1vDh S(cJ)yI0jEwKbLh*2~7ZFq6TIF literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/import.png b/src/main/resources/com/unicenta/images/import.png new file mode 100644 index 0000000000000000000000000000000000000000..a3ed6dc89e6255189bd86ed5ddaab6642a298cc3 GIT binary patch literal 791 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvVv45dj$D1FjT2AFf_C<F#G}vHN0S8C^cYUc$L7wU^Rn*LA+qju0R{0giDEQ zM2T~LL1j^9dPWI@b5UwyNoHB9f^&XuZhl^|f@4WZQD#zUNoIbYf?s}~E=WAJC^<7R z2gp@$NiE7O18XR*zPn)o&^#%SdBOQ<CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ z7?|WeT^vIq+_z5I?SDH!q}}^U<I>Ows|_V9S|lX$*u~nkgqXd76rT={j%<WPM8M%o zjlK5Gt3m}=XfbWoa@w*ei*;4kgf%uf$NPT>TEF)>saU=vd|K-BUsmQ5?QYsVe_p&# zWz%xGqcv>Jj{h98_I1DB{3^QG|GUvlpLtWe-+cf5_szdrS(gb>5B|>OU*w^>@%w%D zi3Q$o{(W{Zi4n5iF6Yy9MCi7;=?sxhm8!jQe4D>sXT4amJ9gjk&6i&;*j^ta;JGMX zQ6g*m?TpXcnHME+<-}MwWSY(HXo+4cru4P2->30wyqSPhFWb}uP6y*|6)!t5d%hXV z%ImK~n7CVi@44>NxK*3`(2srosv81A)G~WDH&kUhifoPQ^{SZH{-|ipFAv7+rJL95 zuM#-E0jTD}ikz5!t~GxQ6nXm|2XN{fv2NzlsW(^D-Ig27c~3Ir!BunSV~sqUbhM8f zw{z*tl{Vl@3D_ES_T!m_Ox@{LOOBfO{u2LiZUK|Nf2l`vqD0Bgb+0?hkDWMPU}3QP zLuj+b2PY$k%O)mT($|ysbv)ajA;22vk+&{HOGEGYDr45TIUx!>K!K1@QP<Q-*Jd!C z?+@izq`?)dciM>Sd*%9>Oq<=c1U@(wIq!^dgLrrId9H*HPC|N9y*jQOw>4rt)R?rf zBh5}zflIH^X<@^>nkkMdK8&7|E=;)dg<Vq3QK<3H<HJTiO%KIS3pcX6ztqW*`20H> Qn4lOuUHx3vIVCg!0IA|WDF6Tf literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/inbox.png b/src/main/resources/com/unicenta/images/inbox.png new file mode 100644 index 0000000000000000000000000000000000000000..3f882e76dc19219571f1527780d5d0dcc7789dd0 GIT binary patch literal 722 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvVv45dj$D1FjT2AFf_C<F#G}vHN0S8C^cYUc$L7wU^Rn*LA+qju0R{0giDEQ zM2T~LL1j^9dPWI@b5UwyNoHB9f^&XuZhl^|f@4WZQD#zUNoIbYf?s}~E=WAJC^<7R z2gp@$NiE7O18XR*zPn)o&^#%SdBOQ<CFO}lsSE*$nRz98ey$-3WyX4@dWHrDUy2q2 zU4P5d#W5tpeeE^RAf-S7wg>Y52LvscqRT6o`#}uz#D^EQNiA}-Zk+Y@#HJYQ(A5t` z`1lJl+&2kFb#`&_YOUU+WLNQ3>+@B48!`RXCE;sLJ3?07iEOKMw`0F>Kiq#;&X<2t z-2vH!*S}ROR&92DdQCd<buV+5*y+0c$DU=2&0fDR!ST><iS6%ipIZ1l^R|PueoL=- zn8CeCU(*l$GS-&JKY2?y@olGQ*N?yE-w!5OznJLIzvcnc*1Avs55Hng{Mwl8JtyJm zybVR?H?Cw3nQa*|`)1z#PqK+W`;xn57F_aJeCflJr*{G~pIGm`s#f~kZhq!IW%h_w z;u}JqGpIlAS#Y6d!?N!dMGdagk1u*WVbYz;;-4SxdjDRTJwsgY&aWosIX#*t;x+fG z*KirsPd@&KcXkl#jNRuF-p%q|$+V@rK6ayKX~Ru#{>{^K++-7;H5n8iOuNFk>^$e? z=Rko4HEtU7H%gW^tPDPMMRRr_`wSaJpLrXA0-ec+ju-+3B<!^k{&e(Ky!!t5`TU*) zWkdfH$#tB`cIr=-*gsqN<#?jhV)lIxSlGVW*KbJvqR>6DR^6g4Y18!jGXD2V4fnV= zDHjEO|F4l=#ryV|!Io$tzYpRzGqt<sRsZ9U{gd=R>-(yYz_h^N>FVdQ&MBb@0FPNT Aga7~l literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/info.png b/src/main/resources/com/unicenta/images/info.png new file mode 100644 index 0000000000000000000000000000000000000000..2c33db0ffbb9286252b85c556793b4b9986dbecc GIT binary patch literal 679 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z;_sg8IR|$ zNC67El(<HeIOi8s7G<VqlrT6Kr6!hSmZd5<=jZ0;=M^hBmXs7_CY6?C=I1H+<>%>w z#8ZosGZS-wTm_fZqRcX|hT`hG8x{b~lLVO;oS#-wo>-L1P>`6JSE84fTB2a0XP{?j zY{DE}#lXP0!qdeu#KOPzlDFTX1QFH;j}P!FygDGeqA)>bCu4h0Pq6rdBc?l;g^#;* z2GlgIZxH1<m7Opnvxa3Ai>ua(EjBK}>%v#C{at<UiTD36U*>J`{P<dB)?W`Z_QE?d zS(Yl+9lOqa>F*3@7cf^*>B-j9{19rIDq#FfF#pyW_4+fMrOLNvIDH9q{nGnyfkM!H zgY8yoL9?BnEbUs%_E-DUBE$BbCyNiPmtD8gV$DT<?mY%g1%D$>9J(4Tless|(bZ{% z6H{co(+V5DNNd63y9XNW4xg^F|91L%56h;orWm_q(bG0R<}iKhYUZ#JmEdf88p-n2 zjzun9=ktNZj5#Y8-_V^V!CBUId9D8)T}$21{2!jT?{GP~&5NmiVeE#rR;_P@x8=S4 za5w$I>B$Mk_w_#9wbU)Hw`;rhe&@v5$E*5SvUipp{I&M7(ft#?+lneSo2^L`b-RD} zjN>W3&z0^cu5I$vdyy$#(=%me!;*}ieHBxr?$<x~{CfNENkI=k85VC&wvlAN^D;Qi zVAB&%^@rP{{>i*g)t|OL?ZGaugQbZFN<EiJOgpc>vEtgtTL-L_ivP83`hOM_u?(KB KelF{r5}E+EP#mfN literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/keyboard_32.png b/src/main/resources/com/unicenta/images/keyboard_32.png new file mode 100644 index 0000000000000000000000000000000000000000..6a0ef7bda4e2951d8425737a74777430974fe70e GIT binary patch literal 1354 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCf{A_6YK2V5m}KU}$JzVE6?TYIwoGP-?)y@G60U!D<ErgLuK5U4b?X49pAx zJ|V6^1q@5?NUgbRyyc$B)(58B9t0hD5_I5c=;7x(ckY~V{^8lPXK&xW4N^7=MnhoO zg}@fsKptS8Vkimn3;sW{0YmV2c2!^mOO?1rlmzFem6RtIr7{F0X6BXX`MHKDlo{)p z>KPike|9nls_OD|aSXBWKRel*uR(#w<*5GFJO6iW4P)Wia_ZbohZElIGY>fEOV#mP zD7~Jvd$!Vs9oy3SD*Qeyo*3G2mSvAoe4lN!!2;eBz_3?174*i6!NrNkaaz)Jb%oVV z6TG^Q=`LUoD6-R8H6iB~W6g$+zl|@pWt*&IT)AxX#ygp_HfZf)_|*2sUHj(04`2C? XzsY(M#JEiilsG+I{an^LB{Ts5#4?44 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/keyboard_48.png b/src/main/resources/com/unicenta/images/keyboard_48.png new file mode 100644 index 0000000000000000000000000000000000000000..8e32e364ce35729a83907e212d3abdd1a9ad82fc GIT binary patch literal 771 zcmV+e1N{7nP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGl=l}o_=mA=osFDBx02y>eSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E-^XO*0N*(00MJKL_t(&L+zN$ZWA#Wg-3{YK;b6w0<ZwG zEg+VNDiROCLm;*+yP<0qY!FDLTqG_VHZ2RphT8@NDGek|1+*n;JCn=gGBYtg9^3QJ zD5?UeG!FihBRM|yKR%k+Gm0}B*Y?SVp-fHfmn}mvK7hqyu~;USL;1qt-O_>lrDF$A zO&`gfyl`~4<mB=NX0k+p%U5RD-KPsi32W8?W^c|j)4-aC1{e$mT3Lc<pcQga@Rj=1 zMVos3lLED<Pr+B}sbvif;5C};LvdNFzO^m-6=(04*@-(Pq3I`8*&B2HZB2X7r_HW( zm}pZEV=1Vmyz>t$vNvXK$xY2&thPk|9|btW1026y61w<!MfS#EQObj|0jQS^fLh8s z_n<6$W9Eu(YVJa{Df%ZfK(E(lwaqOpzmqHi%=6oM>*Kc2qmn0kW8SR$+JowyP&!Ps zsfV!?)KcEP&#vr^De~}iZq@6H{-FU(Vlo4?`Vsr$_O#q?@-qMxe*2WS+K6wZqV9*O zx!o{14$-C_#!^sAc`NcKqKKl11wo*tj`yJfutDgC!3Lu2#U{o<LJt-kG{6QJ%K$j; zUVd+D{b&WEU-4?q*WSC0^if#$da1chzMm9mQx9V)sHMEu{2G+s3NViRUjf$J0ee<y zYGseK#nqPfUVMvRsuUgm)ONkbNa}RcPk7W)b)WNVQ2yB_UfZapF0_*{mNFKnkPRT~ z{#5`x^05z;+Cg#@f}eikWnTwE{>bn1NBt<mSPE*Xx;1_c3SK4X+-Rp)36n?#xH@x# zy<hrjl(1$Uz+^eO(}jY`l7BE-EEbE!V%Y;6=NCyqGjuQ;nVtXu002ovPDHLkV1nwU BT5kXV literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/kit_print.png b/src/main/resources/com/unicenta/images/kit_print.png new file mode 100644 index 0000000000000000000000000000000000000000..bf41ce5c744ee5acd022b69e1544d5a34d8e6877 GIT binary patch literal 896 zcmV-`1AqL9P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy8gxZibW?9;ba!ELWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900P)a zL_t(oN4?kAPm@s?2JqvBUU;EI6E$iS_f}j{<ElGu+{TG}Ma5k=jtl=B<3w?yD2fwB zEn$TVXrTp)_q;xD!Z9ZgpQUXqB)^=mPv7U9@8SePr(1#FVp@OxKG*=OXXX)#$0U!5 z*Jd|=HH*68;rh>JVb_qc9Axb3k7i+4khw17v(aKa!&=k=yHwIF>>@IDp(HBo{P(CB zEyp{o1(zS6**RqFEHZZHTU3;Zr(lQO^)$-t6f$<QI4bM}GRq`du*K}+CUG7A+9d24 zGIkW1%ebYMmX?Del9OtB&Y{muqRf#mO`;A1e*CFEymf#7zE6#^7t8^?#eNSuz_h^j zAY;2fHVWH?jAbD+i41GOwev%xupP+Qc4TZ@QKKm14kvR5w6nFSLDUxVul+RN{Juey zaZ5?w0skg!wDDbAG4}JX$GkFbaRUNo2i<iY=3HwF8-%SXj0np_#*8h-TUh-zB5V~h zwi20Z#hZw*<;aW{?O?KZU>P=YEiH(MiggE;6of??JFIK6cVO}Buvm-mY{j|*3oxgQ zThQl)9_+BY&VLmaHV+x|A!Bp%!(y5C3huCdo`Vh8?EHFRvtHH<n~BV2+)^@kfPZ!C z9y4Cl%XEl!2d3eBWpvmUlDq@_$ICzEdA+DucVIHUpY*Iw%+%IlTe7PTFfFi&$XEt4 z*Mz5a!p0+0hKKcYtb#4-I?lt`Cw0QcAY-GEDU-;sE$KQcudR`JAz>qsvEh$HVi~v4 z-monV!v<_9GB)H<NZ4RxF6Tdh#2%}wt9_6)2pgt*7?>LpHXt`B=wxd*vD4a_uBxi? z^?w)?s~?_OUu5dP9_(&bSy`FZ=Rr_<d+2pPC|1f|z;0YoQQ_-(uU1?=@YzcF3+Msm z<>hJJ@79XyMmppL>>*`kWtm;?)QGD?UqBBlEiFy!a=S)UXXx-3um=VLfec9J7x)AB WyTqBbh8KbW0000<MNUMnLSTY5yOcu! literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/leaves.png b/src/main/resources/com/unicenta/images/leaves.png new file mode 100644 index 0000000000000000000000000000000000000000..ba3eefae56891885489d29c8637a6c42cc9e1de9 GIT binary patch literal 643 zcmV-}0(||6P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy8gxZibW?9;ba!ELWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900G-c zL_t(oN5z&~PQpMGh7YcQCAb7%eVZk)gzi9>FgqZwfCn#li>UENL??*iqdt29FYy+Y z5|IQ^JpNU*4VfBDdTNs|ZNlkye$FH_P0(Mi{dWiDBa}!C{k+Cp$MYf>qv3(Wzv%j} zEq9Vs?&N6yoqwg=@d655dvAvJ-ndU94zc^{(C#Y-aPgc53Zy`;=XbAmFuF06+EpsG zxr>Xtzy9A{N^K`l<JG342~cbe(#{J92p{jxi}|T5whp2TP;4=M;eznd7F(m;I<GdO z0MY!7J}ui#L)%S`iJqn0dUj~*nPa8UNcy8GG&B_&95c!fu=%8E^NC|75FlSSl&^El zr2GkNxP~@d7Nlx%Yd^qx&Cq&{1+n=90oERwWHA<hV7p#@V3I{!{Kj8`m3t;xw8h^I zuzaUz`HqEgEdK6!v2?3w>6V4D_xN0c#Tx}!7<-S;0J&=oSP%oZvicXUa2_mNX~2RQ zxK)TB+wuIR1}sPhZWZE3fVm3;SP%`j3i0DSm_0Xu1<`P;5I?r#nKJ`e5Cyk~tp@^3 zS6LVZ|B$suwu19u>Xb#vR=&QZvlWd#Zci_4$CD>4jQ;^Tb(%!4bf6ysOdRt+f&k-3 d8NmNU>I0gL1^E>xPyqk{002ovPDHLkV1i@N3w;0p literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/location.png b/src/main/resources/com/unicenta/images/location.png new file mode 100644 index 0000000000000000000000000000000000000000..cf0714a6e37de79d466ddafb602144c27e1bd8b5 GIT binary patch literal 1182 zcmV;P1Y!G$P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyM07=1bVF}&d2(rIXmkKWa%Ew3X?A5GLvL+uZ*FrSL3DI-X<~JB zX>V>IPH%24LvL+uWpZO_VQe5yZy-cva%py9bZK^Fb9>#epa1{>8gxZibW?9;ba!EL zWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900X8;L_t(oN41q(RufAUhBuC&htNaFt52tg z&_n1UWC)o-hL8sp6gfr&Js<}v!P{f|tOr`e3yNCE0RrCk`FHw~N~Nk3T<i2&A6-@Z z-~X<zOPHfspJ%@skjCH-nwyK9Y0N#0_rYDddgb}7*7drlKNEWTGo@$0_)<uY<o@>a z<VQ$Peki~*kV4Zf^qHj>kMMHyc>F!4$KN$z1BG^KjhXSX-GL?nqA$n9OSW%@=h3%> z9(`krd@0ArHTr_BmA)$U;$>>4Y)St-rtJ&1$j}dlhT9k2D%L;GsDGXx#_bEylzGx_ zRG+$i5u%?Od7hQ%4MOS-G)&n*`Xe(bD200iDb9GehlTp*t+Bk`V3d=`1CSOu8hMU0 zq0SVkGqxDbR-Gk?=^~yM?>63zqFu(sqXU{_8{QiPMt;6U)w6Y)(AFtij2mp7c8hrV z7JXV^=Sp9X7eR09G%{)!=V9|CrOgvI7%whPn<o*-hNhb*ElY3amhD{o_rD<sKx5b* z)k^aTZX8R1ErN;J=O!WaLWFka$Q$`=9A`uC{H+bG<mNhw<4+4nr^MPHYbqPZ@lgBl ztG4n?4{1x`=7jgduTrnfZ4s>>DZmDuiLaM|^`i)+me$O(+g)fA(8Xk%MV$uTvEhM_ zUDIrlufUoPtBI`X0DbMy+PRZn>qnE@xu#o{7yb2xEfo5ZG1f*~J9KuQt8biiV_i*u zdhnSoQuJGnaa%V_f3%9`zCQRIRsMAU6Hl;us4yl>#%3QYu9@RR-TxF--n4qiPF6m) zy)j>oIll7IeVAoFtA|nLP4_;q2aWNpChp5C$Nks&-iK!8OUnle@c%#tPyEo}Sw09r z7v%rEmJd2bJxucM`xf9DQp7@#fX)=H?W3V@gRIEQ&&8;ZAENHN2H+YXGM?_cWQxAd zOJYqUKVKob^EL(S!F`qPyzSKF_`Edz`9>9a#w}UePiSeMJw%R+L@;VV-v+8C*Y?Z| zZ9MLK`?aFmui1gdSm2yQIk>bRK;z4Ic{*;$;$BFLdm6BVjBdRu_RBGq#l6^*=kk&o z?rlYp7_bNb56i7rX-%H(XDz+`K{vC6Zf5LYa@iJko3yZ-dh{-jq;@N-;KFW9^E(=_ zMSd3McOuYs#BF`q*O=&(FSn;QzZ24pe-vPY3~j+2o7PsCsAtb-S&!>46T1E~1$;>) w=aOGtH=%1U8g%VN3n;)IBqkdFjj?L{2Pzc^qRQ5DzyJUM07*qoM6N<$f>~)S9smFU literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/logo.png b/src/main/resources/com/unicenta/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..acc2d2ec66d739fe2af35749c77efa344a74d8e8 GIT binary patch literal 8592 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 V<@NoCw4WdVFfDyZwWj@x{|A0hhBW{H literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/logout.png b/src/main/resources/com/unicenta/images/logout.png new file mode 100644 index 0000000000000000000000000000000000000000..ec87d853651faba022f714368327f85cff0a8eda GIT binary patch literal 580 zcmV-K0=xZ*P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004XF*Lt006O% z3;baP0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK0o6%FK~z{r z?U!jz0znjn>j)gtqi_R{(1}Y#gDfh7O8__Y-~4uoXb?d~K?vZ6C7sEH0lH^lCh-sN z0PlTM-CeH+n3ttMY0yMzK%D&$r{BcM7jg7K6#GP>N94Q2VTU+q6Z`MPUW>@S5xcKM zrcnqk<OLZ3VB!A&GK~<1OZ-_B$TdS6J_|so!~Fvo!OwiMga0ECN{Dn_AXOt0Rbumj zh*yY>dt&{Lh?R-8TVnNwSh*&aE~BF!{sH6@R6``H!V|#q6@vkoKA?wiQy?S&V&_E- z5w8fxBM1#3(;&8=)e!cJ5-Uf??tm*mv2S>^VhKRV3+Pm_a>P5p@uz7rg`V)R3rv8m zCwB<@E6^%n4Y$4~-xV&)$PPdxAN5Lj08rcOVMjP@!*Kx92h<Q+fb-wNa345(yM$1$ zV-<ijqQ$8zp#|{jtp{zP$OCGCcqJJ=fb6)}5)*+$1z-%VHxe8`z5-Qc--Im@O#-Ng z%Rau3Kt?k83RER+*o<T&fK*LCd}aVM6Y3!>fOOqJt~o8c9eySSMxj&<vGcMxG@_*I z@PG=KsW@l_RA3Gue@bjI%IA4Fu47#<Z+}KQD|XI=W7}{JpjRO3Gmy|vEdK)yXh*Oj S6LG!(0000<MNUMnLSTYZo9OQV literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/mail24.png b/src/main/resources/com/unicenta/images/mail24.png new file mode 100644 index 0000000000000000000000000000000000000000..8a48306187013f333402ce3a153ac6d47575a00c GIT binary patch literal 1393 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM3?#3wJbMaAF%}28J29*~C-V}>VM%xNb!1@J z*w6hZkrl{SNcITwWnidMV_;}#VPN<L6l!?Ez))(y!0;-8fx&791A}<MoLzx73=GT+ z0X`wFKm`oT?!JBd7Q`3@qaiTDLSUKAPZ40AVkimn3;sW{0YmV2c2!{XyOg*_lsM-X zR2F5XXOu8F7o{eaWR|5WIOpf)=I0eFIF^(YWhRxDWaj57_~qy6g2Ypck~0%?fLsNa z)S}EXu!iF5yBih&&65I|7o49~Ql40p$`Fv4nOCCc=Nh6=W~^tbXK3jD*~uKJD$&!$ zF+?MHYT!j71_c&iT%7M}DS55uzv(28A;&LvDUK?JGon+vN<v)j|GL__=K8FOf~UV1 z%-?Le?v#LfOU%-?16$f>2p{^~)Na8nboJ8qm@NvMSZ3YGf1b{H|MCB4E0P)Hr4JmQ Tb5HX)&@u*3S3j3^P6<r_QFDP3 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/maintain.png b/src/main/resources/com/unicenta/images/maintain.png new file mode 100644 index 0000000000000000000000000000000000000000..71f72b1b641eedfc4e23c5467a6174f279ca5f58 GIT binary patch literal 946 zcmV;j15NyiP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy8gxZibW?9;ba!ELWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900Rn1 zL_t(oN41n$QrkcfhWiK{!AIZ-I)aX%BX9)WAV<gpOR<^31aMddVapruEM*o0CV+<> z!q(~ElB^MuK}wXV`bwJq|L$qej7-#NY`i)2leq=n|NB^fEz$a`)m~@g&6S0*IB?r> zc;GE`ti6<I?L`YLD8V-7h(SXPS~xGTiPdL|R-ZX1(QXy88!JzWR-QN`s*p8fMV23J z`th3$TzM}Ae2HoB7B-e199nvC1x?G391vZ)aG~YLuWcP(Kc|4N!@Fln(w+E$-o2IL z<A2|X#XF`X$p#khtQ21X4J_O`v~cSRTHt`>C0n>vh7K=s3OIsr59e=en!n*TbJvRI zt}Ve9R7`^x!`FRn?%GQn2V%bF*ZOeGUcm(O=fLYX;Kls2SJ95(Jzgu>V7sB2ON(YM zIVZ?b?{c)v?Et)+H9z?8n7J&`cdZ2$P}DZ&i1~$~`5w%X(-X`Q`;6qL9Xpb0vqaTq zbWYW#D{~HrlHq|DquO)~Pw4IR%z0s_FC3b_-~hZ^f+r}!rKxkowBdnwv!(gqJ<P{b z2RYDC1GPT6nC2Euo+&B79oUq3vKV4h=g`vgP&4zGJYz~{Q{r76>p+`4gC{*da|08n z9!;Ebf^Wb4Up{f#C72$(`;EbqmJ5HbQE50-X=s51YVG_=!!zQc9xYI5)C?Upa$d@C zrSTJ+#!omPS|EyrTKM$8nDG<O$g^|(@R(U0+oX;;AZj3rg_{2ihdTC*yuWOqTz9Bk z*EDv-Ez0%i2*!@Qc0AM(3kSSWo|fF4M=*Nm(dZ$k;1?>_yF@cRUMq$%dgye>&2b4w z4w%x>67TMKrqD(X;7QNVd>MxK6%Frm2Q&@sCASo@;eGu<UXDMap*>3$@dPEftp$hn zurM274i8Avkb_**fXB+b0jb8pnnQy%&PdKnm!-9V-5wg)<&3ylO6K$Q?<nfuVFNAA z*e&{Z^gAubd1q~-Z`-53Z8nIuxo_Kfr{(zMvNq7WWl`^z5?DwsfS9krlX~I)07v$? UygHhd&;S4c07*qoM6N<$f=|t}w*UYD literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/menu-left.png b/src/main/resources/com/unicenta/images/menu-left.png new file mode 100644 index 0000000000000000000000000000000000000000..e67e3151f9a91b65d2d6bd5e2f70373081153f03 GIT binary patch literal 824 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvVv45dj$D1FjT2AFf_C<F#G}vHN0S8C^cYUc$L7wU^Rn*LA+qju0R{0gnWr> zM2T~LL1j^9dPWIDkbk73Pe`PKTac@(f{&-Ot6#9I!o8c_nLwpdAf>_iX(i=}MX3w{ ziJ5sNdVa1U3T4K6rh0}3249L6GB7Zudb&7<M7Y15?j3YHK)|({Gp=dcgrymrQC($^ z9GwL1jtSH$Hux4aoU!rOU^!TG$e*QvgYQBmzkBZ9Yqe=DMxNn!JzwAZoaedil-e)* zpVk|`N?f{@>@<I7e8@MR>S@Na`4w~R3QnGydSi!w#^ZV3VVCxEu8nK8`}?e3N%O+1 zjham&rx#~^P3mWV`s$dp)KX_-rvE>>IW_+~M($tj;BR<++Kpea2}Ygf>c_T5tEv2* z_u(ho?`;o5=G?fIE4(S!ZQ0MsoSxzze*XHsZDMuB;^@{pJ<5OFrh~<#?p}Gqe0*P3 zaO)WxXD03IJ|4RmzAfES_4(Asbuq^$EdMMNwJ*u(5^LAID^Knmp1xk`gw(13ADV%B zHL8m8jg#Yc^(Z`#{C7!pc0u5-hS!~QPQSm*VN{c|dwS%a1fV{nep?;;ZgIggzjxe> zli+?1G~eNVaOpMf=Zt55&G@;u;o12a6G|9g&$KS(J~N-y;C1q|?}z5wCIYpx$$b|* zGuO@F{o}Oihx>n@Ygxj*LvH(#H=Zn#cH8crJ|knS_>#%B|F`KJ%RZ1Bz6c6W(pzBr z_3)He?eDrXerYtVS@>rqvzkgQ!|$NUrQSZWM}Yo0w7wK%;r#X2Jbmp7-fZ;~HTulM z>GKX`m|cAR{bil`qUuIF<3WM+?4vDE_kriqZ*I3eo+fcW+iBa`6FqN@KuYKDmj9z7 zeVdoZyfJ6?#LC$QiAVkCU7XvsQ?A-ZBielCg&&s}N@^PHI;<A3Z^?lZWlqYsV>bQ! zXSh-KUJY;Wj+CAGfmMH1O}u)3w5Fb~u=>M)$9cX(4WIrAV6tTJboFyt=akR{08kxl AApigX literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/menu-right.png b/src/main/resources/com/unicenta/images/menu-right.png new file mode 100644 index 0000000000000000000000000000000000000000..b71ad6f1e370bdf0d579b9706a580d1fd3204c47 GIT binary patch literal 795 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvVv45dj$D1FjT2AFf_C<F#G}vHN0S8C^cYUc$L7wU^Rn*LA+qju0R{0gnWr> zM2T~LL1j^9dPWIDkbk73Pe`PKTac@(f{&-Ot6#9I!o8c_nLwpdAf>_iX(i=}MX3w{ ziJ5sNdVa1U3T4K6rh0}3249L6GB7ZCc)B=-M7Y15?i+O5L7??FhgDPmgT-eAYeeoJ z;dZhVIPg$i#bE;{--Nl}S~e*#9`Zl&A)SNo!c0R?@4G?Vv$dx9E_;=`=KbC}Q>oKN z2mVjJ)7V?hEd5=u#;GRkr(~U2^y_lAYwtHCsCuor>$ah+n^n8&MoXD~L;wB{^E<e< zRKMuT*z|5zVb&9aOVLZC@4O2Qm3Ne{Q%ccpx;i_kiCeVq_hj~*uWA9dN7lwDr>s88 z_xe=ngB<~hk9mI9T>R9T9jlm;RhF%@zEsr0ETnS2^7LuGF`K(5EPv`9x9Fy><-JvM zkq)QT-u-1g^tg+Enz>&5w7JLAex)$#&fc-KxaD9-;!W@8sn0iSuGd+RD!jd-&0vL? zUuEY}<H?^+F-4gbaxdpN{9^7?)tZ${;>9j(>a70FoLKQuXy29lJRo!P{;@pF?2-?% z%lWtD+WCpzK%35%w=C}zpJBc3Yw?pyn>uIPI!S~TAO9nEMlMvt8Dzw4OBV^Zx`?8) zGGQ~oX3n;Akcg@I@uktTG8N>m>-PoNgyrwu(05M0ziiK@hH1WcuE-sFylT^(m3udR zzTq<;<W%#W-4pcxC7bMwF4_}n3s!U_oF%sA$7=n?<ij#{e@(A!T6y3HpVPJ<+$Vqd zL4s^2bCg|S@@<ZrU3Z>;Je-ze9b)lrI_s92M{#Z(yL7HtAB)Wg#>4-Dgx7NqRIXap z&vnK6#e+w#tZv(tB<>z+`ue=TGymhG&4q`WQhx+W-ZU}TBx(83`1JV~{Qr544$XJ? Uc=-7<V9I0gboFyt=akR{01~!ckpKVy literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/mime.png b/src/main/resources/com/unicenta/images/mime.png new file mode 100644 index 0000000000000000000000000000000000000000..7101838981798fd010b90920b65be2d121b5bdc0 GIT binary patch literal 1016 zcmV<U0|)$xP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004XF*Lt006JZ zHwB960000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK1BppQK~zXf zrIqVW8c`6(K|}f;P1>hu{KB_Bhe?w*>G!^iTCb={y~VpMc)uVvDkvbL2q@wLyTEc; z4hz$nvo3;{bZJjAnvG_D=RfnGIaUjvlar_ofAv_c)*oG6)}HR}F8Xde02T|-4?K+q zSW2aeMHHp9qLjxpt^O0^691(3_I}p?sr3*5!|wOTgh=F`C6f}QQZkSGdl`~R8E$VS zh{v-Kjf!w}^#Fc<95yz5%Ixf}dvsLzJ}|KIvA=)W*4MXW#dsYM2qXkd&dTK~FsAXS zRyC+pYEUdP$mLWJMFpXGh{ZC1m#Vv5C-U_4j(cp(^#vgxF!?(Iv_T971i)J}N^Be~ z2Wa?Ntu~-ks(~z*A)PKlB9R53F9y52fyV0U@9f0HhI?RO`5PvF{|K=*Wtagl)_`(Z zLlqScxV{!CIjpQ4!Q9+lV|3IdV~N%<`PWBCw`oAV4p^=RmP&(sUWH7i$osIhbp{Iy z9+;Wgg~`c{`pAe=LKVLd@CoC|D1TExfLcul6be<4q%z#y$q)?Q!qHI#l>`BM0aH^u zY;bT@z~pw*0P2O&2UV?uqA=cvhlc`hbSQKOr>9Za-w(n3`~e#tcK#cHR8*^V?j~8T zpoR0i59j9zauaww7qGbK`G0_-=p{-fa}bH7IKbz-0k8KGmX^E>`_P#JqddBcbemFn z5(x<b54=Qyz%3jfM*;1M0Kq(fk{b>pi;{!VX@xg97R&My5hNT=@yT{Nj~Pz2Ie?K| zcaPp&Dh=J90HomNCWEUZjg}R;3PCtQfU7eAHI^orZlBGTIDl3K?I(hel4z9Nlmxf? zl;O%S4`}s1O)vqdL<YoALXdFy9@f`802sC`l^70}%2$LWmG~6X!qXwSX1R2L&%6Rn zYk;b1-1k%-9Z=?g=PGEGUtXrn187AX%Z+?*0LY?xnTlKi4V&>+bOcb<8s1)S?rQ*2 z@dU`>V<dN`fB>}E$eOg=-cq2usY3uhk*rc-d}`_TtpMslHrw6<QzgPZV#BcG(h~5^ zWt7B7B#MP+<&e1l<M9j*TDtj0(@qkEHzs*`*=xhF<1P`lw*2hy@B%0f4nob?-w(px zUXZ_HJ3HsFy-jh3kB%QUH~lolfNwJ!8d`ffXt)7w7<Sqt4u^|POsoUN_;_o$@!Jg! m$IHO!1zZt;$r(PIZGb<JP`==(T=;qb0000<MNUMnLSTX}amlU# literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/mime2.png b/src/main/resources/com/unicenta/images/mime2.png new file mode 100644 index 0000000000000000000000000000000000000000..7f633a557753e383131bd9499350ffd91785c962 GIT binary patch literal 1164 zcmV;71atd|P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004XF*Lt006O% z3;baP00009a7bBm000XS000XS0e@s)kpKVy2XskIMF-Ri5e+mPef`Oq0000QbVXQn zQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK1NBKnK~zXfwUtdw8%Gp?7X>Sq zHoa9Pm$Z>`C^;a}o~pD5P*o|1HaS$P;M9_m0*72$sVcWhIYcB1r$|W?eq<*mjY|V= z!vbrAj4?!R1SVhzCJDhmYlFRO4E`HzzrHv21}oT!@`v=zj`8|^JMX=jt@y<m1ptBn z6)yRC(FZ8{ru;qm7{zgTjJ7Eih*rlgEjZWs3FjK8Cl%0W#<|9iI44focWJ^oA^b3* z!1qW~)6X?XRZGin2Rl1^t4*fS<AZ~?2D91LNZ`Ej=FO4DOP6kad-m)fpPf1L`ysl& z3^fho5g>%`a3Bgd3Qp&8<?QU^T9@l_$Nl?H#DxW~M9j~xNz>Cy(!hY@FM~m9?d}#2 zU%B$n{`2Pz75H1>8LCcN!f*l+zLCQ4HKGYHxDKhK;43Tgw%@O?KtN?)ufmp={LE&X zS8m^SjG&~gt4lm`?b?v;>eV|H2+w~(RQ1*H1`xuR;sy}U2<qK#uM`L<EFMooGPwg= zTMUB17@#<7vCOLd{dVj1>z30b!QlHzKxl$5?ySS-|E_~@3<si=AQ)6xI-P+`1|XHn zLO2`;OcyvDi@D+9dy&4racfuCP#Xq5T##t#s`_*=1cdMj4z&ZJvI55Pf^<5IE7*j) zcOL)-2dqU7SD>O`1cSF0B>S`#9Q`{8)%`&bKE{D4w*nGmvjB|cAQZ|AMDaf`o2S8K zvSqOr3Z}_~f@6qI6MS?_2157{heLnL&lTiy06RN5tV0UC-Uwi^!R1;7yWI^~aMs&9 zB4P0QV!;P}0U(6;jR7E@UxOT9K|H<#iV_D|-h|cFFwD(8!PVSjdcCwq@SedB2N2<1 zy&v8|N(p3HWvNt#2Tvq2u(_Fnjg2kv`&BNWf{%{QFig`Pfv(2~gs=|>qMU$QG?~ou zHdT}a)*;3PYiki$T=WCBED9`p1VT3kC$vfFeW2n#U_3SS^pQxM3n)cCp9;&%GFYuH zhTZh?0y-XiK83|%X&|D}Bo|PMND>G{!Q%<S*x1~w3$SAt1&+m1TtEd5hqqyUeT%PR zWhL}Ff;9>A%v3eW(~}n@o(gEwy#YZO1&OkPhYw$21x}|&ht$u^Jd!*fnaOgL=bWCH z@{V=kn~mDk?e>8rm2T6rT{JZ0)FE|v-iYJlbK7{ZF?<iOsi{Rq^T|m!v)dQg#Kb(K z7R6I_8+WpZyST1+CzloU^oW&u{b()j&JJup(P*?vM&lSlSF3d6#xB(V6dd0P9T>d! z@?~?Sb{3Tq@K<JY^REZn+dHezo$EP%;ew$7X?y_<bZ>k6#cKL(VL#RE5j_2ewgcbP e^{oXiJmCKz_{tF5$YiSk0000<MNUMnLSTZtHw={k literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/mime3.png b/src/main/resources/com/unicenta/images/mime3.png new file mode 100644 index 0000000000000000000000000000000000000000..182fa0122bf3974a4e8165cf680b51299132b1ec GIT binary patch literal 1215 zcmV;w1VH<VP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004XF*Lt006O% z3;baP00009a7bBm000XS000XS0e@s)kpKVy2XskIMF-Ri5e+N?1?g;~0000QbVXQn zQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK1Sm;FK~zXfos>&wpBr$~SV z5-eDt3Z$Y6Bo-iGfdrL6PzfZuV1ZPS>II7|3JDM%-LfcZSEP$>x(IDj5*KQkN0a8^ zBz6+4xT#4XiIX}ZN$WWA`!VCh@9W3UId?p*Ri$}g>6bm@nfu-Uod2E!KmM}`K#?E* zGA^pO<URRc?K9ilGoC^94dXrK)L%)keyHkuR}$a3G^uZ^YP_X^^-Wb@)Av`Cx*Dpg zzo~)sCFzT*PC8X6#zUu1pMS5TW8_$Guj9mx8xGS>qGwDN%dqLfg=@#pp8e%WW8+VU z>grA%tkG+qJ5;cgx(O95UVL`e`}6#~&wBgzhRx%-FTQ3iEUZhp-9Fpo<dUtY=Vqtb zY^!f=wH|J6?t8qc$$Wqy3WGiyOW;$IV)`?I6XOZ+&Ux|G)lfPZR7E(fNrgh12nIFb z_p4%kJt4f_sJL?{BIf7U#rU{ey?)&}Opu0_7VArwE)70fg&h3Y76(iD#2yEWOTxS4 z#k1K0geXZB3MJ%nMWoXL$z&eUXbPdwCVaj)$Z^?jpVhj$CPuGZv7clJJ7EVO4#n_+ zH3sF_a10-j7{F!WUGu`mr&0k*bXh1=kjWIGX<5W#X>4pHK&67y>8T72{hhdab$qm? zWw7Dm#eu`zlXnNAc&9%K<>+7(?~`@|2vI>cTOt=Z3AlSV%8SElod)%yVm8|~D$y_j z>d%~MKJsR71T5w4z9`=6i|hy}mqF#KP^n7T+{_~$PlNgZhhqVKeJ*r&J7KYmm)qM% zRC3YT)YN|b)$TA}At`V4MDRLkCkG5D7InbZRspJ-MIfMIanX<I=~Z&F2<inoJ14~D z%R{zv=gg)TJ3?S7FL#B(dKiFvVe}!NFC&!_vJa8SmTdIWQUG&vUQldlja#CvZA1c| zw*>JVNqON~2#5X%?FwKQg+f`TNz-x&hc{&(D0!SFxLp6Dzu$Ea@XT*Pu#{(i4}!Iu z0|Sss=_LvVlUQ91OMu(GhN-C)3=B*O>VtIfWP1Qlv<09%Z4Tfm(%w>}$CS&nv7r(m zB1`1)_%So%1;v#BHVJs7)en~P*sp%DwgYhOjRbK-IYF^lN;cT%OUM#2WO+FZI@uT* znGtlVB|zcDS;mhC0mkBbdi3UUX?XVxU<Ye!ad^EkifmN6u-Rq_VBa5r8_Oq{cb`aP zB!EW+%_j+ACtfe7DTvY0IYA?1?||Cu^9g1Em&kw^P8hPh9KzVxJ^)5)G8sXKD=$Zc zs%GRV=7Fa}lK0A`1KfLeP%2fB&zEHGxjZ@`D*+F>piz#MmGIsHJfe-^#<@2D98tYY zY3YCu8~0-0fPB74yVsk$9e`cj2P6rg?au)Nc(8GKc(^^xfu5%S0m$V9&3=9NwE*rx dZHe{*_z$BlA@BRK4eI~^002ovPDHLkV1me6CFlSE literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/movetable.png b/src/main/resources/com/unicenta/images/movetable.png new file mode 100644 index 0000000000000000000000000000000000000000..f5341129310035ff2681f69f00521e820031ae5f GIT binary patch literal 662 zcmV;H0%`q;P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy8gxZibW?9;ba!ELWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900Hhv zL_t(YOP!QiPQyS9hFwn3BjgBqgts|LIRPAj8z4@Q2llN&pjM?U0a}(vp4q}yAyBKK zECO1<*j<yEq)D*!sqXmy$1~%qDd@%t8kAbZDIiY4$k27K7AHCWH6WE5BdJM@!f;CQ zAN^Qx^n)JwJ2xF1tO@dJu5wet;WuiOn+}wlB0w)_-3jqXzrNJSK&gQdI6YIT;l$8q z`c3vf9XR;H5L{ZHB=~LH!FhX)Yr#I=vlV+E27w_cR}C1)-iI9Ery1_PPY^hO{>jz- zci+tj?*zd1s|!1C4k0=qefHUY<)3bFaLuc2=iPmr*4|ody|}RTf<B7%w5H=VRma}Q zDAvcJSVte5&*Pep*Hj&QBcmYGP>`sgpR6F=0G)o*z=rvn1^F5(h@LiI69M(`S!qpj zRROswCZvCW$Y)}~#*<56OkxaI?YjP$f%Qj>Nha2zeWJAo3)UXcgH5^Uz`3`U;QhN@ zvK0y03U;uy6J{&6ryl*6;@e>5E)A>q=s_Rg>b>x361@>OSiVIMrsiM16+TU(1}t8> zkp#9_yw;zH*SdAqCXNNyf&~{n*f4)32$R-qrS^{@&tDlZcPR;sKvGj9@da9j*$b19 w1ctyheLji0&72!BeP$7ozz&>Sz_p0@0~FHX_(FlHF#rGn07*qoM6N<$g4_%p^#A|> literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/no_photo.png b/src/main/resources/com/unicenta/images/no_photo.png new file mode 100644 index 0000000000000000000000000000000000000000..7d0748431cff156e2f6d8baca7149f22b75fc817 GIT binary patch literal 1358 zcmV-U1+n^xP)<h;3K|Lk000e1NJLTq002+`002-31ONa4Bp5m-00009c5p#w0000` z0000`0Hf#VssI2507*naRA}Dq+0Ad_MjXcR{cGn|acQ;6rP{74Z6a}~D(zvjhpp68 zRyjpI^srK^O6j597o?=2Y(jW5U>n=u7hVF{etYm>AQ-R>F&yAIfWR~U@SCx*hbQmZ z?L2wUE<g6bJ#Y`)1NXo^a1V_B7}2MXi;GK-9wYwS9bjLw?t=8_;WAhgxe?$1504?E zkaX!X+%C{3j232qLw|cf4{r%>96K>_O<)guY4s*m>?9oMHGvj`2t0o-cG3rW*b#Xn zMpz8e1{!o3Mvjf0E^vq%gEyp$o-VLUYwENdB~9+r1bS#Of%ODO@)|%Fl|ii3xJwt< z+<jm_R;p<O8@mm3sMCv;%B};;X#*9yv64El786)XALzwO%0QcHOyF&T>zPns0fFEQ zfGmOn0OveMkl_to39L{cgFuksM+&$cA;{t4a*E&-7ndrp$sqWSUm0+Qm`Wj}-^joW z-6`N1f&<RTB6uDEa|oVt$`OL6p+KDsg4g^^2EkvPla-(>S*juZMh5yd^npeI_TM=N zY|7*i9O2;b3_(r;9UKXCcrBkD`DMoaXXO>;e7_NaSq{k1mB4cZZ{(-v2wutxehPq3 z5&X*$f@4l)O;6?f6&xHKzD7`;0fzM(8F-G6r7v(6%*jdjJ<5EV8scZz9L>zIQ)~nR zTjqN?T_(V=ej@|nfDA7Y6nGc%O@|cuASoG+DM{cjeB>j?5|}|y!p27Bo4E?UTc?74 zlgz?72sQpha7a7IA%YLIY4aArTiU#m&u#udaIncaIBw(*%Sp)5X7U??L#!Z&2;O61 zNuWiM41!nu#8(JD%?;*B(xW&#bvzg3d^vb<z8dj6f)|)UULg1z6O$7JCzzOA@B;$D zx03g8w$1mu!5jAuH#BLjOpRiqyW$P3%_v+`M_-yMH<;U6JQ`A_KoM<WKJ%HzHkaRQ zZn@%u0%dA5DUs)bJPM<20zEvc<hdkAjvQB9aV1~>Lje_UjU~(tEns#rsgNg6o=Yyd zl&`DUa)EQ0a4C3Apo@VKTroT7D3mBsqJe=Id@{hqOm}r_fQ^ZbjZSCf?UIEhe~*Wc z4;<jg)3PI@<1W1)cF`rz|Gl|;9N++#HU<U;?cfT<PmA6XphjnETN4cpFXEhx1nkqs zKtsdCoY|Q@RhdOAGNzmg_6)K~1s!+gg4{}=i%t_g7^Fop=!7o0xu|pX9!H}_jTZeS z)m#d^qeTNfv}W_saYKMA#)>c2pn|^eRK5h*M@5Z@^M_fZ|6tj-MJrNEg$liRK%ZyF zih(i1v(Og~ub)m3jZ&P;tq~g9RP(6Ou>zihiWQ@+K{@3As0Ba+g?0j9hX#)1H8JFS z?TAsS&CSJ7po@YLx!c(oH0aSorInzyGWS<S2=I<3&DdQ}?n}nkfmWg@c&mUK)r6go zQ%A*2*j7WEIV;WqJrtB+b8`!6&eZS$@SZxisW6O%Y0{jk;R9fY68e(H>7+hY!x`W` z3Y87+sFg7FsbhHt*ya{Jakra`I`xmr6!4xJ<p|C76jGu+4|FJ^rLz0Q8J|PT)aQW> ziXoeBCk=}7cR2v|xJ7xCovDfP8EY13P)OL-<K&v!EU-dxMU!T#sZ!)_0_<{)k}_eE zMriVMCP0Jyl1;ahJn9(ug%Z~r-$8xN+;GDeAK0TndF>82oeFunK5)15KPUS`j;1Q5 QZ~y=R07*qoM6N<$f_tlJF8}}l literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/notes.png b/src/main/resources/com/unicenta/images/notes.png new file mode 100644 index 0000000000000000000000000000000000000000..b1aa35f2fcfe74246d23b509fc1a1366b9b140ef GIT binary patch literal 780 zcmV+n1M~ceP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyM07=1bVF}&d2(rIXmkKWa%Ew3X?A5GLvL+uZ*FrSL3DI-X<~JB zX>V>IPH%24LvL+uWpZO_VQe5yZy-cva%py9bZK^Fb9>#epa1{>8gxZibW?9;ba!EL zWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900I<AL_t(YORbVoQq({YhI>7MN7y6e)weyu z9wA5A8yHW(5ymP?0R<wUARt5*3LfX3QnL!Ih{6EM%1S}olPu}XFq2(Nrs}I?{{H*# zOp+Sx+(b~TJ%&*hVux%`;L(GphJEKoP)3+(h`Jteeft{W-w;Ol_O)>Impofn2%}?$ zZ(WIs-k53+0XF~Oh?wE+zOefAJ|I+~xBCge#wCt`8NP8T96dqy>e~IlsKNW+I0Q*` zI_h90J>m2xJq1ZGAj~?fUtk52Y8<|PA%^(vEc&z7exV0RI)}ge*{blmGV<RRR?pFa zB#pyY&qI&T)vL8ZxE`>4ig#E!s~7Kl`80HTTzy(wIV*+hl(z~kWD&k}(sa~qe|c|( z>!ihFv=}P}EFQ;>y6w;RODB$So%H4hS~QCRufHot-S+FfCtN2j9HB-2aTkt)fu7Jc zbog|iBKU!dCoA8~9U?IN{^t%`13k*@^WVafPxmO&0%xWnzWR#5@cWOuai+&zNkrL| zeTwcmJnmKunms^Z__(tNX-U8JXid;C4xHH!NK^ik%<LmDjl!5~DItiEsNV^h-V0!Q zPi6hy_3{e>GvtGnQeJ#+P@gJ#y#uB?2#lor{4cWCRHsh0kPt*#>dE`PYcfSJkudS8 zNi?$SWI9Gj%VYOc40!$#;Xd%5;MoU+`@lP3d^dveUHng4zWl#<c=TJqJzI<b0000< KMNUMnLSTX&;Z`^R literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/null.png b/src/main/resources/com/unicenta/images/null.png new file mode 100644 index 0000000000000000000000000000000000000000..536141ddfb305b03713d4d10d2111d4fec32a848 GIT binary patch literal 1284 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq8sKd6mGxU^Rn*LA+qju0R_G24;o; zpAc7|f>AIU0wXpAHXD5D0Ol!%k|4j}|05eP1b=5&1ttW}0*}aI1_o{+5N5n|x9$&6 zP^!c=q9iy!t)x7$D3u`~F*C13&(AePq0Cs%RL{`R{j-xfP?f%?i(`m~ck&N^r38h* zzyAYykF?y#(CBRw>JyOgm0IkXY?7(qlwe}t^Q@imG(Uqh|MyCV6<fnV$<Nc(&t;uc GLK6VNwM4c6 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/ok.png b/src/main/resources/com/unicenta/images/ok.png new file mode 100644 index 0000000000000000000000000000000000000000..ee82d90979d2ae9fc8526efbc688e90d7560b550 GIT binary patch literal 624 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP{O6e zHKN2hzo4=xGd-h(!MP|ku_UuBRlzwwH#a}8Si!NRq$o3~v?Mb>Pr)xgPZuPfT9llb zm;>Z0xTF?kmVq@CSKr;R0BD{R$h_eEw370~qEv=}#LT=BJwMkFg)(D3Q$0figD*u3 zfv&Icba4#v@V+`F*6)ymNb7l_G)}#PsykSwT~OV?QuaXT8KX&y0|(<o`JaJ;m9xty z2rwzK9ARV$6kLCqL2#k&ly67X;+M^|{66pG%aVrrpCKI!o$QWw{{F46FL8>y@pyjF z;_I=^m*y-q5wG~MNR;(E&pSJbclNDK{~mNX7alA4ttYajwd9_?eX7PDPS&>pb288I z6bZN8aZ#{WW!_Qw`Avj#SxmqT`OR-;tSoJu9d6_>Km8cn%!zGhI>I=XwC{GR)iV~7 z-nBJOe(9qtJ1V`hJUnkXJ^1zXx=X#kXX1kBYfIbJcB->WO=31mteiKQd6|Hi)#N+E zwfsW0x0u6UA97MI_?k1Rde3v`J??xHR$Wv1{`GoCsbx~E)g<Qg)msh=zMbHE?(JWn ziDvFgeA$)Wn8vR@tlL-6{Y~NOuIAr%SDtW~o@6>-xcmMZE;EZJUZVqP@4}*Yt|^YW zmf5UayxoZNiUpHtkVlM-<%zqej>LaG6mMHRZ}(~0ItKQuB7M%5D}#YC#o+1c=d#Wz Gp$PywyY>qJ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/package.png b/src/main/resources/com/unicenta/images/package.png new file mode 100644 index 0000000000000000000000000000000000000000..aecf41dbb42e7b912a64369815cf3dde6bc205dc GIT binary patch literal 1040 zcmV+r1n>KaP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00004XF*Lt006O% z3;baP0000)bVXQnLvL_-a%pF1bO1wgWnpw_c4Z(#Z*6UFZgU_(baZlQVs&(BZ*Cw? zZ*DC^Z*6U5a${*>Y#>f=AVg(yX?9_BX?A6Ed)=_00000QbVXQnQ*UN;cVTj608n9R zZgehAMN}YmGcGkQF)>H;LN@>a15rstK~!i%-I&c%6G0Hi|5)7g#=*NK4}m93UdDqr z%i=Bc9Rwo;Q4k_uf`EK@&<7BLAfg~35CjQ?Fm~_O>P)g5W_CLpimv+A?9O!myL&1h zy8~QFn=fC(e7PM9=UHOY8~L8+FSX5<S}<FBh`F;op+d;hdIxdya`iD?Y{PUhgPD^e zp)5EhpDe|+MK<z50a1u|KXu%OspAY$B$NfG<dY@tRMoO@4*JO1A>PR3Q41!I9%14z zPpA;`wBA9OAEEg&==+h3*v*U;nlV=Rgwg#6#0^hp{NNhVPGo6q(;NMJ|4Yn%?9Xv? zXAmV;BO`kXJ_QW#J|=F3>hL_TvtJM+-N0-K^dsS8ZMhu<lQP{8U}*cUr@<rN=XQAB z^wkr}UN=z_O?ZE5(Z=AGLO3OwZzgyQ_u&L-FmnR><%?*he?uV(4ym;s2&X+7t@N!c zM8S@=)~Ac0|AWTiHPX9QB2*~;diWa0O&z0Q@Wy%8vw9ERD><S}C<9)vob&y1UR<LZ z2>mu>mRpfoenRXK%7ZPq_UC!M^<VtEKR}vT{3ZciOV^3}=v@5h`SZy4JYQ*(N1%V^ z`eIeIi_^p*=rN=IxYQKO_w8>$nplMdLE{Jf9OUC-dR*M=c=>Ms4;w3h9?q(95oTX* zAWBQ0cikk`zOcU0eSXr6#-*7cnXVVix#&36RLgl}5A+1;lZNT}tT$B;s&zfQ3wo@s zPaA=@Z7oI>L9omC=9f$(tmBe5bQ4)5DK70K%~iE|xgF38iww0Ik;=h3h7E1=+m|eQ z0%>j5Gi-1R^yVdto<Lfg^-^n~9>rHR@cJhpjlM(D+N@{Tz$PG#o<Lfg^$hFZ;1_sV z^aRq{tY_G(AAmG^0%>j5GwkJeKpH)Pv^MJ**0;__D6;4Yq_tV^YBliU8z7CoL(<x; zXISqVA7aU(Cy>@=J;SnJ0crFE(%P(NSkEe-(#fJHkk)3sQ0rdd<3t(s1X7x;V`c34 z{7W+QL`k)*3$N@hNSs;bb5b{SE!SA~4{}@WxQ&x*5lI@bsVBD2vpisfp1{VReNwls zB|gy(M=!?KFZBk3gq@3g6mOyzbJ2Rk3a?E3^fM5kuSLx#DEu$3`7K`X%4Ng=0000< KMNUMnLSTYQM&s-N literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/package_big.png b/src/main/resources/com/unicenta/images/package_big.png new file mode 100644 index 0000000000000000000000000000000000000000..2e9dc0911a10dd148a1c02f424bea63777174645 GIT binary patch literal 1099 zcmV-R1ho5!P)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyM07=1bVF}&d2(rIXmkKWa%Ew3X?A5GLvL+uZ*FrSL3DI-X<~JB zX>V>IPH%24LvL+uWpZO_VQe5yZy-cva%py9bZK^Fb9>#epa1{>8gxZibW?9;ba!EL zWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900UD=L_t(&L+zGnQrkcfh5HCTf{x%L_$WFG zH_#DO1!2wNBrGOo5j*_TZwMgB9u_NR-#f1(+Zh=fw2X|YVyeC>Ydrn>y_u2AL@(oI z2fB0z);LFNY=R<iYRGf0OC8s2t={En_09%9;1<Zde4p>0AS<^yTDdiW3pfU{Uh1Cc zRF-e@w0vU&A8-n!UUWKiDofWUEnPb)47U%vbnQZ0^fjN#;*|kW3;2LLfb_9x@hau1 zEL@rpaR5IdE{TtY%ZR74aA{z%1$@9=g!r+6(fSu`{=%U73kUEsKzud@k%_r;2k<kX zMS%Lb%$-XR3;10YMEuww#*6KondF=~fS(W-y~Rhwm$=m%GJ9&!?5PEOz#TyP*dWGk zNBwg$b7IoWi3>ObL|61v>~_>3)5m$5KDL1mI0aHKIw^O1>d2yiHovoNl1&}uP-6lY za13O<)WzFv@mKfSuvD%ZRIai@5uXcD52LYe>L`yo8~9Cnb#0lqVIcl)i=T2;eEs(s zGWh8a(|tV5nIPUSm8&^4k~*h`G&Vsz9qAkN7a#ZiMF<cSP5M5tK)mY}`v_|V(kJNW zw=`Z46Vjjb#pvUdDmIlW@vm2uFrq8^QGCdn&?r?H#c^<H;?RuZ>(Mo$Q>wTz`!@xc zIAj<~f{(f$5bt`)`k+qglk{y0Fn++49vd1DUoZK7{6N;F?-x4Sv3(|exX=p!RLb+% zzRc_E6ACc8$D|jpN#E0~-*koanh!RkK1TNp?dDbee|<jwX6>j)khMO2_{G{$17xjF z?|-s()BsuQQ}G9DM-7m*KE3<S+ED{!txs>iv3Aq|S?g;zFNQlB;LTSi-KYU{Yl~iJ zy#B(Z8?}LMZP5#jkzJ2Qc3CTG1Krx<H#CNK@-)2T0oI1vK&NitGyG?<(QC*n(2!RI zoEkNN4!ywF!++P6AO;O?TfhgL2sJ=bjiA2;<3{+(M130E&OyMWfh`YkEYu!xYo(v` zmHyhsz*YePijhMk3n2OtuSwEm{hJ2$Z}tEma9dRUht>r;qL=WRBn={UuRfc=1$+-x zx7GJSotdV+zS_Qx0`+a!fE%dl>U^*+<7<*MTJO3+z3V-|3Q5RwFt6>J`~^2S7LOzK Rge3p~002ovPDHLkV1iyZ>OBAe literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/padlock_open_icon&24.pdn b/src/main/resources/com/unicenta/images/padlock_open_icon&24.pdn new file mode 100644 index 0000000000000000000000000000000000000000..1e97af1cbda1296cdcfad4fa2fcd1a1c816ce9c3 GIT binary patch literal 5384 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/paperboard960_600.png b/src/main/resources/com/unicenta/images/paperboard960_600.png new file mode 100644 index 0000000000000000000000000000000000000000..078336ecd3a62babc60ce93740cb8b5c75f318b0 GIT binary patch literal 198168 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 N8bSfY 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�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�Xh`vaorwi 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 P00000NkvXXu0mjfA)Dbe literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/password.png b/src/main/resources/com/unicenta/images/password.png new file mode 100644 index 0000000000000000000000000000000000000000..cb8e31ea68fa0d078644cfaa6624b176188b37a5 GIT binary patch literal 873 zcmV-v1D5=WP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyM07=1bVF}&d2(rIXmkKWa%Ew3X?A5GLvL+uZ*FrSL3DI-X<~JB zX>V>IPH%24LvL+uWpZO_VQe5yZy-cva%py9bZK^Fb9>#epa1{>8gxZibW?9;ba!EL zWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900MDIL_t(oN3E7!P8%^0$0t2Oj=&M}+P54b zH>i)$BlrfZo?ss+lmcnON1-T$B`Ji*yi@4%k(RH5Q3xR^gz1cwt#+*qv4buBH2%+c z?6KutIRh@*-gBO&c}El=lgTEgL_8v0CO*L1H{5sF8iO1(1_A6nqY;gPN8^(PPF&9J zlYrePMW7{38vn{7b{-3`^N6pYNx2giQSWEr`(H(%0X~h9gqM=zO?LXVo)7gt8Xyu2 z)cZNgQHi`-Z_2KS?T0MXdT2m1b>dpjOXO}pSe`=A6%cgMfb@xjuGDfvyA#;D_hIWE z4M?9jE#InwYA1kd2MzHPb5}beHP5Pm&AR|L@6eb^JA_KxBbp;~tO}^KOEeie#j1df zTL~Mt=n!SKK73Po0v(dPCu6Hwzmc$hgAOT-UGx8dwQB)u*XR(7f57UMfUkd0Ly>-; z;@8KG(s{GpuUraPy+RE|TENOBTRmo?4S&JQ7Xp?qP(zVsKU+O!q75(J(z$@8bJS3z z+0Rywjng6J7+$*anSk;cYADj|XPXw2<Y!7m5W}Os;lg|?O1}kx8fxfg8^t1DmV6Vw zZuDzdYzg@C3pEsJ0mT;Ecr5wgFuT$(j9NSuuy~3ZiZuJ#CS%2x<!k1p3KvcUES#W* zBF%ob$ru;qtj!-!!Td35DAIyp8;?oS4tLJG_<SS@jG?G62)1#*;rDBMG;^VZxe$ja zvI0K+WE=S+>v-o;p|gh)W)G22gcw@Z5k3`U@g3Wqz|4V!nFAyOLJj+@8OsNQ?czNC z;}1#T2prz_QN>N~=U{ptV}#U~L~fG(*yj8L>52i4x;dpz00000NkvXXu0mjfUUYLa literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/pay.png b/src/main/resources/com/unicenta/images/pay.png new file mode 100644 index 0000000000000000000000000000000000000000..ac9663bf49acaaf59ca140d10e905520c3de217e GIT binary patch literal 679 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP{O6e zHKN2hzo4=xGd-h(!MP|ku_UuBRlzwwH#a}8Si!NRq$o3~v?Mb>Pr)xgPZuPfT9llb zm;>Z0xTF?kmVq@CSKr;R0BD{R$h_eEw370~qEv=}#LT=BJwMkFg)(D3Q$0figD*u3 zfv#Wg>EamT;eGZ>tluFA5!MI0S*Bf3-2fwGOE_x-l!XL1GyXWT2~0G<cQk@`1&fKY z5~ItWdrKZLG@cW!*>H0DmbsTLgT1&v=x^g<Ti7I+q-*ffV#7bF(~k|N9M_AfUAX?! zjfHa#>TC7#?D(@r=+D$k8jJKb`I-wpDsrwn85tWSArT<qp}|+E+}gNzkIMb^PW$@p zWTdzSCwur_o1=g7>!As+7rMQ8z9_~&W7E4D$8E0<{j~mds!aAone!2qNfY_2RhQ3I zn6vlceCxL=dz&U-=Wt|m?B1x6E`0KY_xcABQ7n>Ij4h@$O>|%X;KR+v#o{RetnT_v z6X%Ph+!9N<bz%XRQSQML{#=)Ixi9Gg<z7xpc%sg_avA4JHKP?xA;AWpLf=cu*sv=6 z?BH3Y@KZzL=S+XMMGqYoHA<~gxF~Sz&%fq{_nuYUZK#kn4RPF~XL3_D{_2fdmZa}5 zoG;99%~7f?((7ft@+$rNqIJxH;^qp8@AY=ne0q8FZnSh+ej%@3?Bba<QJadB51s4v zo^W#Eov!&u-`8!+PQ0<pPsp>tacW=gjdf@LL_bsi%~tzMbxQx*-uu7^X7F_Nb6Mw< G&;$Tf8Wk}B literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/payments.png b/src/main/resources/com/unicenta/images/payments.png new file mode 100644 index 0000000000000000000000000000000000000000..61de8a647e84000d03cd9535f761e33660c534b5 GIT binary patch literal 574 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvVv45dj$D1FjT2AFf_C<F#G}vHN0S8C^cYUc$L7wU^Rn*LA+qju0R{0giDEQ zM2T~LL1j^9dPWI@b5UwyNoHB9f^&XuZhl^|f@4WZQD#zUNoIbYf?s}~E=WAJC^<7R z2gp@$NiE7O18XR*zPn)o&^#%SdBOQ<CFO}lsSE*$nRz98ey$-3WyX4@dWHrDUy2q2 zUGL`U;usR){&w1Fze5fpZU5b0DF4u~xwWU0+vEhF;7&b`zzcWZTvV`jd9q81>)*K+ zm#WQ{zE&#@eLkrcPb#k3=a+tqX}Mx-W4nH<yHW5PQ`h7T-wkeD=2U9@ch0%qUA==P z=h9#Gxe8)Cek;T%h`q=at%^?TDG=_`_3!+j#%eX&xWvq)<YHX)&pYAOzL)1@tlgr> z-g)hmnf-;BEayEg#VhMR{V|=ib8W9|uPb9Ot8<1hyK0WiS?=qq$5))6+4Q-gp!VI; z6}|79Z<jAq&`8L=bk)83s9n>oH4U@P+b*m)yXd#VEb(>Tef73US2YV=q-Xx{jhL$y zKX1RAk^c{|nEgWRTNK-qBW4Or^}Ig8`EyNN?ecZ?wXCO-TR+W^RQ{u?-D?xG_X6jl z*6mD71?MUVZSb6azN9JQ!K2QC#)t(LAsT!$4PQy?2>Z|DJ$&{qFx(kDUHx3vIVCg! E02dhGWdHyG literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/plugin.png b/src/main/resources/com/unicenta/images/plugin.png new file mode 100644 index 0000000000000000000000000000000000000000..7def8ce71e36456576679d8fb1bdd62a9448f2ef GIT binary patch literal 841 zcmV-P1GfB$P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy8gxZibW?9;ba!ELWdKlNX>N2bPDNB8b~7$DE-^7j^FlWO00N;& zL_t(oN4=EGtJ6Rf#uZ$+aFK<epkP5kLBW86f`WpAf}jf*E(9GE6ckikxNu|t9mUtZ zdiDCadKJaDD7b3rBTbs5P2cbL@f>Af8qy?fdK>tWnKR#+?@K!A>Qytm27`fwb~nO* zN_S>x``@bH?@PCT7r@R;g7kVl`PQ#III-dZy4|jP^JgBMz_oDT0PS`=bp1yTh)$<7 zv>~oZRKGR?)YF-m{A#sY?CSR%*ulC)@cI?h*r9NfJ7Z_F*<_c$S>TsTUoGHZI607c zqtRd&zgRF17f?@N@L=YYyk4)f^PjUY4(CvheZgM4_}Xf<8aw+b3w}ZU^vrpXYPHJF ze9V9!DwWFg15gm$n4SKR0Y3yfcw%#@RFY4<H-Xp6<uaqW7bk@tUtx;HA|pgG&gB#D zOyKY}48_FysIf0&5)}#sc6`|cg2q(K=kxNhWdk@^ANr(7C$2k<eFZ=xcJ!?QP8@k- z06}4#HltpyvEOkm<Qc%StkB^l14eOZNrzl6H)M`IGS&I!xXx%ULN!lw5*&Q3gBRjP z*=$xmfIS?(hM^d*(b$(ciT1zJ!HY~L^KV1E%llrYfkR<z;TYEZn^W`N7isWf4{Gd~ zrs;Sld_TD;lo!+B#_mN8L=3~2o;d~4bzR!^Tmv_DKGT3eZFr)mbZgQyP1>=bfg9Tw zRN$a~yx-Z)Tvb(R+fx<1*!n~T5$p>dB9%(Xp?MYjuw_04B7p-WlSz5=Tnffv6Y2>? zQGz{vB9V|bK2E_XFq}l#*Ec*;0PDfb<MFt({-FY+pm5@u!FiZ#aU2T#1;k>pu=GFy zCotS}zi+3s>+UDP2@JOK<`ih{y(HL)Mx#ToJ@9LG+hEPz1aKme$n^i!JktLK32C1+ Tg^<uv00000NkvXXu0mjf{y%%i literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/poweredby_uni.png b/src/main/resources/com/unicenta/images/poweredby_uni.png new file mode 100644 index 0000000000000000000000000000000000000000..843579b66ed90dab10aeec015351192a712e438a GIT binary patch literal 2048 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/printer.png b/src/main/resources/com/unicenta/images/printer.png new file mode 100644 index 0000000000000000000000000000000000000000..5b28b70b5d31e01cc38d30473fc177b8447edfc4 GIT binary patch literal 639 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvVv45dj$D1FjT2AFf_C<F#G}vHN0S8C^cYUc$L7wU^Rn*LA+qju0R{0giDEQ zM2T~LL1j^9dPWI@b5UwyNoHB9f^&XuZhl^|f@4WZQD#zUNoIbYf?s}~E=WAJC^<7R z2gp@$NiE7O18XR*zPn)o&^#%SdBOQ<CFO}lsSE*$nRz98ey$-3WyX4@dWHrDUy2q2 zUEl8M;usR)espT4-=P2rSN(Mh^p3}tc)npZebB(%Atm@&r0$cv=}|^@0dI$%;2ob7 zw`68=e{rmuEIe!a^kV%+2c9_1vaR<vHb(fwU3E6wxMhRIP7gMb-E%Z2Z|Bd8`zO?t z<y5U#$KhzY(DwQLmIbpe%-gK*6yTe2{-wI&3bifIpEL`E7;jvDp>y$tha9Vz_sqHU z)MMY;hd<`dTfrys+BWOx#Qe+RR~a4iULFhVZUl+h=LiKhF;AY@^w<2{%%Jn@`6r~O z%NOyUlf3&&>Z#N(5Akntmf@R9s~c=~|DLe6cwI`CYD(6xhD#peW$_Z4H!9PXB>e82 z*tFK&jq6e<U%@|T-t(dLU3+a_X5D#p^qB4M9goZH-YV#yf7YD#ecgS*ChNNAmx0#C z?^gX+SjTesb0+uQ?|0{gxV|ore7=%Pu!UoC+qK=vZ1;+-e6o*6)L-iO&h_GSfx{&O z=J%Ge-x?IQm;6rq+9nVpd~0)&FUKm*w~_ml(oSB<R|zzms8Q^8<38v03HIMu*1vDh S(cJ)yI0jEwKbLh*2~7ZFq6TIF literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/printer.ticket.logo.jpg b/src/main/resources/com/unicenta/images/printer.ticket.logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a632c345395911db0784cb206da5635700c0c32d GIT binary patch literal 4157 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/printer24.png b/src/main/resources/com/unicenta/images/printer24.png new file mode 100644 index 0000000000000000000000000000000000000000..c1f30d9866708078af706f1bc1f504eb084868cc GIT binary patch literal 634 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP{O6e zHKN2hzo4=xGd-h(!MP|ku_UuBRlzwwH#a}8Si!NRq$o3~v?Mb>Pr)xgPZuPfT9llb zm;>Z0xTF?kmVq@CSKr;R0BD{R$h_eEw370~qEv=}#LT=BJwMkFg)(D3Q$0figD*u3 zfv#`zba4#v@ZLJ*wii>NNZa*2q0{Y}`Y$YgGcQ3dQO_sv2wzB0O5dUzOTRDENMhHT zdBP<yXX~|l&X;9!wkQ92n0&hE|9vTutqQYl`?Kq0+nfEr{ea<{&d1+Z&$&6IH?z!F zThV9sc5A~osjc4^iSIZZn;WIgxOVDKrgsJ5v!4Yy6ld;hu)cG3*+zj25i|53@RbV( z&re@ycU<6>dS^_>x0{;5vr{|u?$ji3TxPvkm;21iJZ68g(lYLCRqO5vlySyX%@C5S zjA=T5fb**6vX);#t1suAU>9FMgX_6|7UO*Txdq>PG#^epuKI&#PQkAhYgRwG!sQ1p z+6u`f9{$+8;PO=Cy4<EuJN6y^HuuZ);F$`E_5ast2`i>A3!L|0{|ckRDa&o#lp+G; zxGjx)Ke2G%(6n7D2-GXwRPeMXSSt08<oWFrKfd48zPsl9$GJ~5`F67$dk|LmLS>)$ zzV-90P9A(0!Nttj+W6D`i0r$p$?v&Od>7<<-y(SD;X1RO^BQ9K|9j>f6t}C+QaSVE S(Me#OF?hQAxvX<aXaWEMW(O(& literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/printer24_off.png b/src/main/resources/com/unicenta/images/printer24_off.png new file mode 100644 index 0000000000000000000000000000000000000000..bb7de6a6dee13f1255a3b039a1eaa03bdd3297e9 GIT binary patch literal 680 zcmV;Z0$2TsP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004XF*Lt006O% z3;baP0000)bVXQnLvL_-a%pF1bO1wgWnpw_c4Z(#Z*6UFZgU_(baZlQVs&(BZ*Cw? zZ*DC^Z*6U5a${*>Y#>f=AVg(yX?9_BX?A6Ed)=_00000QbVXQnQ*UN;cVTj608n9R zZgehAMN}YmGcGkQF)>H;LN@>a0qIFZK~zXfmDSx#6k!y{@iR~t5k$}ny+8#KRA5OK zXi!N7m6eJG5kwbxQ5OY?hE_(8RP-K-(Hn`8DN0Zz(p5xJ^hfkU-A7j<Mj_wM%<h=; z?BJOh`0(tRJ?HuD>@d55cn9qx_~%OMAV_Tq_SSSrW#Fct|1{xfeTC?n2W`WJ8T0t~ z*U|LCz6$@!n_nV2Ywj-}{y0uP&mV9~XLQyMc>mjRd@z5&i6KO1?SOaVj${4#0~!Yq zolOsTJ66w;r%Yvkl4J)*`<O~}&qBwW(RvQ`;>#Uy_z8Hzy@iIyq{$s{pa%|?681eL zvOj~`N03FG_7w@c?vb!tYs;SdkVVY{gzep=+Hn^wJGG}sUjHiGR9)k9;VNwDWLjIh zz_P6i8TnZV&=sv?Lgj5tRd*nZ&D!S?HryamanrU@d$QPc3yOrYt0b(u2A1{OlSTP; zy$7o=lWNTsu&mV{gRruLQ2b!|b=C)tRhI}&?i1H6yGUsA4X@4|uw3_9;r{QVucMkp z=ZP$CPlz@i`cbW%p*n13iO$ECUVtKDUK<JX&w`2q2EX?z3@!>-pmV;3=Td(52fjJx zoXP)xFt-)aS^F#P|LU04j6D0|@?drgqO*2D-)F~+)0CL0=M18=e!xFh1*cz7uglK> O0000<MNUMnLSTXly)z2{ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/printer24_on.png b/src/main/resources/com/unicenta/images/printer24_on.png new file mode 100644 index 0000000000000000000000000000000000000000..5065b90c0b492b7902e32d4e5321e524f0f876ce GIT binary patch literal 692 zcmV;l0!#ggP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004XF*Lt006O% z3;baP0000)bVXQnLvL_-a%pF1bO1wgWnpw_c4Z(#Z*6UFZgU_(baZlQVs&(BZ*Cw? zZ*DC^Z*6U5a${*>Y#>f=AVg(yX?9_BX?A6Ed)=_00000QbVXQnQ*UN;cVTj608n9R zZgehAMN}YmGcGkQF)>H;LN@>a0rg2lK~zXfmD5j1R8bTL@GG{BvS<?%1cHN7Nl+q% zC}N?DAS+sk3V~R-Fj9;_(Fg`9qH-`4GzbYQh@hxk4EARsSc?=Fxfs(lQ%9$na?G>y z>z)@^raN!u%v|_!-+lKx_dFi&WhrZX2~NSewfS#KHL_K9!nW7z%}QDHd3qf2CV~@4 z$7FC4OnN9aIz0v^2Ccxyub;rgy1?vPjLg21gVss!XFh<54PMO+gNZ>a@a9_pOsso0 z{{l=5T7l>DFTq^v9xgnFF|_a$EYk*$zCVG@Iiqj!0o-KTVBp6P+^E~j_i-=OpCHo) zJxl%YFApYAzLmT9PpAhzLHCLul3O7^m}(FEkW9yFHzb|mn@B}niF85I^7A?*t>GKa zhrx3^)$pqgMq{)Ml1tHRNQN8mUQ^`i7FDy>1UI#7&5+dpz6^;v9czH3I@Sou+1N$6 zQRN#oFe*0cAUXM`9+Il{3oz6Xs)ntY&OmaU&OuT_=b`ec63qNq_B!1k?hu^<Gx@Fc zUMdAM8y+eHOZQ-t+fNl>W}QnXz|?jsf^7#Kb%N1=r<bqY<WMnK<n_TjoHgtCc@G`a z=g<MT;wopaP^P2X=rG(Qz6r|J2WpuP%F}fPY1Gj^9h7)<CJFJuXs0eVcIj)$Zk>r^ aHTVl>L%HH>h!i;h0000<MNUMnLSTZ~A}LG& literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/products.png b/src/main/resources/com/unicenta/images/products.png new file mode 100644 index 0000000000000000000000000000000000000000..43e102571b3527457e8cd852068e19fd6770b64d GIT binary patch literal 838 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvVv45dj$D1FjT2AFf_C<F#G}vHN0S8C^cYUc$L7wU^Rn*LA+qju0R{0giDEQ zM2T~LL1j^9dPWI@b5UwyNoHB9f^&XuZhl^|f@4WZQD#zUNoIbYf?s}~E=WAJC^<7R z2gp@$NiE7O18XR*zPn)o&^#%SdBOQ<CFO}lsSE*$nRz98ey$-3WyX4@dWHrDUy2qo zFfjRfx;TbJxWAneS#;S!pzSw@Ra4)C#XmT#ocbO}zu>4k;WVu&z=3h2?3CUX^Zn_L zoJWHkCU(A^&^p27Z}b@tzb6q{2L2^i!&T4z`G0@y#GFO{ms&Q?mF_RgV_N8(KZE^& zRqSVziBD~AUpKwAua8Cf1IGq--?cF>EUsRg>K+}=xcA>p!5vC-8^tB3W`B0~?U|Us z^3QpKprFzFwY}c`W_rvEl|QsNm{r}en)<cdYHhqk<A1>yq38Kh-riZh^>cs$lfT3l z2mSp&dXJ<t9!=kPpk6YC?Wk|K|I9G|WJTdUzuuj$)sSHPE%ktxGjiJn<+n#~8oad& zc2l~}oAq@Q|I)ksDZ1w}KmA&iow2#yQOxLeZAyBTx#Q~Nmp<s7&2u@M_w94$*P4s1 zO_~>yd8=<;KGfY4_%p8|ZMv()tf`Y{g!#4IkKZiak^a;CaP@^l#(LLzKU^}Hsw^1m zyyN%#wyh=nvx+M78pMzLT;(kO7x3_WZOi%nhM60LGxmJgQT1)AXEX1Giid??zi>}x zlV0%g(BoGp)75y*93HnGzxvqUM=Gb`7<d2br~NRNyZj838w|bTa^d{<jWaheO6l9I zn|2RqAebfA&!a0>m<rU?J#U>DUu~2{4~ud^W{!iX|1IXde{vYAP3Kpb%=fw2yuI^4 z^2U8eQ7KB&wq957IL>{>m(=K<)co%963MSYw%o3pf7_jX=iVe(!I8aV@4T#snigqq zHH@p}&c5-z_$5#214HyTx#|lJ))!~pTYH+J_YMQ^&h<5C_A_*|F;8K9vR)9F{un%6 L{an^LB{Ts5H-BTx literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/products24.png b/src/main/resources/com/unicenta/images/products24.png new file mode 100644 index 0000000000000000000000000000000000000000..3d3048ccfe84f20d6bcc2cafbaaab2ade943b891 GIT binary patch literal 718 zcmV;<0x|uGP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyM07=1bVF}&d2(rIXmkKWa%Ew3X?A5GLvL+uZ*FrSL3DI-X<~JB zX>V>IPH%24LvL+uWpZO_VQe5yZy-cva%py9bZK^Fb9>#epa1{>8gxZibW?9;ba!EL zWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900GuXL_t(YOU=_?PTN2b2Jkt8kKiNZ2sr{r z*duU+xj~NL2SOBtDiA^x2w(y<<<0Me$OxfU6{1@Lf$%4te&aQi07=#;53KZ)?456C z;*~=5sn($wIuy=@)A?<!K}fAZ1uT94D??g?82jd9gAN`HeS3^SJXmBZbnr0YtM=|f z+P|-W1^J+u_U>MNRkI&bv#$l2nr7dk=j{LM+r2fkdz*kvfklr9@+;fvm1+ChKtS<L ziFSGsSdfAeoHr1lm-b=z1zT4P0v0ON=!V%a9lCXu<Tb6oN6$oALtTxoo{68c`6i<v zLpCp$X!Ek1*Gs5HU|(dCtXZQQAg378H+`}O8-EyNgp}5;fdF+?2KQ^%Z3)lOn6u)p z=<9C=nZRZ_U27L5JjWhq@&RiXj6>qZ4JekU)pG{%q63QNY2_D#c+mkx^R)bvLA>aI zqIp{S!606AK+!yXIb#qnI-qEt7Ec+(iw-E7r-hRlupkrZfQ1vDm~*{i_eXnL_0&*3 zO+ZG{Y(3>M8H-v3;c)YpZ?#UDYMlt=4b9a${7x;!-Yf*88^5m1ABQx5%v5b#kc_Ts zTld_1wH+ff<KJ{ta_-2`+>yIe_Z-2PYjBPJ0q0aFC}BTV{r~^~07*qoM6N<$f@P8{ AmH+?% literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/receive.png b/src/main/resources/com/unicenta/images/receive.png new file mode 100644 index 0000000000000000000000000000000000000000..ecfe322137ab1fa0dfa519a4634b74aaf83aeecf GIT binary patch literal 873 zcmV-v1D5=WP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy8gxZibW?9;ba!ELWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900O~D zL_t(YORbd6ZxTTm#$Wun7(a+7dn56t9=MojG!eb(0S_h~jNw0!#F%*8t0#^oUhvW; zHEp3Fr3K2;0=Bokd1^zGT9Hb-g%&6jJ3g~)XLtAtMmG6nGds`wyzjiTGY%T`tev_r z^#*vz;c!bb#ttyffO)!q?(;y8z7zSjlk)8#efz^q3V8FeVnY@4`E~(%?`TP~EjQ&( zbija$K+nLyP9cg-9~howwdtnSrVbcoTfWgMf-2i`B1SXfR-3{8ahZmbG7X(pjv0{q z&G%yM)KBY70U_hPcG}yLmE({RpK17elc@C|sdYYSRh~QHEeM#s4#AWg^L^moc;5?X zk5vpWQmt!-k6PzHi1{oZxoG)_0aePJZE0A(CYjg;*_MKN-WF>$>6*v%vb8E%{XnV1 z8h9k)GmQXNqhZO;p?k4%>@!-MX;>Af4wnqSWc6AnHc^=csh$<3Yw})j!8)@oU34IX zs;!C>mFMvL4xV%ri+UWq6$ug*A0|I_wabT|GlSd-|6{C`C9Aig*MxrQ;D+h>s`D+r z{}DVBg82Sx2wq4DQilx7wxdY%i~1L7EP2Mt?<rP(C<L+cQ;Z*o@xq>qzW!!i$O&TQ zcTxh$GrIedqPus5AX0Ksq;yjXnAz57W}69Se|W|G{IB!SKbG{8XQXr&f?GlmE?%T? z@sboUwdthE4aLMV=b~`&0=R4|@GAW7fr-wyaPc~rpwLf;WZFGgXKwsO9$;;7zkqP@ zis8o#H6Cu<p}&8=?Z(N~af+FM->!q6GrytLo=x(5iC=*H#C9|AVjIcX6s2nlrEAQj zfVXNJvwyMbuT50kI7Dm!q5n_79TxTqfc3#Qo&=Fn5WgJjA-d}tPlCA}FU{?+F08v} zELo<vbei5`HvD7p6(*A#0i0rHqSMso$nE(H`%fJ%%@Pkg00000NkvXXu0mjfLobkV literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/refundit.png b/src/main/resources/com/unicenta/images/refundit.png new file mode 100644 index 0000000000000000000000000000000000000000..f94f0dbf007760cda19788c0543bcc4d1067c244 GIT binary patch literal 603 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP{O6e zHKN2hzo4=xGd-h(!MP|ku_UuBRlzwwH#a}8Si!NRq$o3~v?Mb>Pr)xgPZuPfT9llb zm;>Z0xTF?kmVq@CSKr;R0BD{R$h_eEw370~qEv=}#LT=BJwMkFg)(D3Q$0figD*u3 zfv!*Xba4#v@P0Za*6)ymNb7l_T~qW9s+M?eW}beaIq3ttD5qkFg$KvS-twb8_A5L% zTv;Xx6wU3N+UOOXaeA`)&q-<LUfSjsGyaI*wTwkXIxshDp_wYX_P@SYE(@#_*#+|* zQ_loQPUaT#_pD4=V6&<4t1I^k<EO6Io*FRz^Aw6cBy+{ov2tR`$HYY@3hZ{XL#004 z+<B_y+D~iujsASQ7Tmc0Tua!ibzZAe|Fa9tT(<8%Ijzavr#<2QC7E3c_n+$JpWS-4 zRH8_>Xd!oz?7k!Mg}LYN@ub||))MogDQC9+$J`aw%u_Q}CuCj}`jUQPON+Z&Lau+D z&zyae)c5;8pB`vzGc~VB#(uK;%V%aH|0Mgj+SY6-_~Np0LE7Jo|Mng@$ow;4`n-n+ zYBy(HYYJ*oRMlYE+m`)wGB0y=`L-6O70NenOqyX79<P{xdQHsjyU}V3c@^(hJwG;O l1Fzu2`DP!)e+&O$Q}ds;eUJ2wIAEkOc)I$ztaD0e0su%A@Mr)4 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/reload.png b/src/main/resources/com/unicenta/images/reload.png new file mode 100644 index 0000000000000000000000000000000000000000..49e19e1538e04b73f6684335461d4a7decb9f8d3 GIT binary patch literal 763 zcmV<X0tEeuP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyM07=1bVF}&d2(rIXmkKWa%Ew3X?A5GLvL+uZ*FrSL3DI-X<~JB zX>V>IPH%24LvL+uWpZO_VQe5yZy-cva%py9bZK^Fb9>#epa1{>8gxZibW?9;ba!EL zWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900IL^L_t(YORdyvQqxcr2k=u@kR@~p`Rcds zz$_t4a0zz@SwhAE<Y8-IP#yzv0eO6kp9KlnS{PJr2Sh*~$A8)q&F#&dw3?Y;r@1-j zf0{H&g>2jIgM-5!JcBA#DsH!&xr5ISeJ|+glk|Ij+kNm+ADZL0?;P5>7odPkkhFbQ z%ffc<!>ngu!q%-zTek`D2m<tkxxU<h%^R0CZxp@%#s5t<VB^}QjcWy5AU!7gVoP1V zKN}!_#<YIL1`=!OAD!RUuc}xVpbGkWS>0{zQUDtW^IgziUAy!P`u=2fOII%vdiR4h zfi-;fLKu4V44lErxd*ICtl=x?p`l05=<U;TM*wU5!U4-27q!aJqi6K?X-P?7jblB7 z$Ae3%hCUAjgvKmd_%4C}qDqC^iWbitT0E<D(c5nlIP>PK{rV3*eg0I^{3+)Q9b#*k zI|*p+gf)W?*2qI=k3E__=A5W4ht7-IwJam;kJ=&NKZx26z5b$rHP1^AX|&Req&TC| z64Yq%fO@m|d3c;&Z#q<O#)f`{wf^m%7QOncfDJ;LIjS1ZX6DF8eNxb;y~m~xJ(@mb z3yEU^2#7#gYGd=|ol1O~O86he=(oHHCJ%gi`AGqfK+@zviPy};ew8NnC2&a!b>;86 t?D~!Gxit1MfEZY#upiO*o)3k;`Zr}dVgj?muR{O;002ovPDHLkV1nO(O!5E# literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/remote_print.png b/src/main/resources/com/unicenta/images/remote_print.png new file mode 100644 index 0000000000000000000000000000000000000000..a3612a4532802a290e35a6440554ce620ae84363 GIT binary patch literal 835 zcmV-J1HAl+P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy32;bRa{vGi!vFvd!vV){sAK>D07P^}Sad^gaCvfRXJ~W)Lvm$d zbZK^FAVY6$ZEtRKAVG9=a%p09bZKvHAWm;?Ekkc@ZDn#}X<=+2PH!MYWpZhDVRUJB zWpjJou%G|{02*{fSaefwW^{L9a%BKeVQFr3E>1;MAa*k@H7+qRNAp5A0006uNkl<Z zSVzs3zfQtH9LIaqN+2XO;g1XuA%TI!!SDn;ijUyx#^z>Bj1yu-&^K^&F}i9<R4fiA zy14ZL44l8;wTGn~JxB|9$v1bs{_gJc`_n6-loCZzC}<sRQvrarYORN(^Zy@!7e=jC zD@M*=sd71BB2Lerd9OAfC+bO-Vrc{>Dzjrsi<NW$@an6=*R39){kBX1@J`YqtsbQ4 zb0@S2l*?s3eqj7)C-*ece3ApOIx*?S@!b$10;fPdeHh|~3gk9=crzQo_|TQ^%Qo8C z_9oSiZij&Z*oK{V27sHg%|+q|xBFD-g1uuC0stQP=hgJ#&O5XLz<fU6K!pe3@|M7O zmiU3WT&{t#p9c^C|EpeJBrNnY**SOT-+nfO1CUmq64=Pkd-kpa-@mH>@o;k13jqK& z(sg|oKPd!}-2=>XXvt)<j`ks>z@+hboB{C7eIYOk&|pnHoD^L2N8?WrJc`9)MG*E= zVo@?)oO*y182wT32yl0=zqjU#z+{@j13>Ru&rYE^zho>lf!rwy6~Mi5wOVDl#-5Kw zwXrmSN~OX8u;=5I0+dQ627o;uuN0tAC@=u*`FJG&*=$yayWRp(kE~??kW?yVrPFEZ zRVI_MFDGd5t}e2{wSkKeu3@~2_uSs$oY!0L99+fwI2RZokw{RHya2Q80s};&Q42)9 z(ll+H0vOjtHn=u0fT*xkRkc9Wqoov~==_D|=7|9DF^Vj7n!s2F@C)Sp4!`IB5bOW| N002ovPDHLkV1lhLVGRHP literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/reports.png b/src/main/resources/com/unicenta/images/reports.png new file mode 100644 index 0000000000000000000000000000000000000000..d6be2e826267afea8eca232b2ef4d53ce36c2f1b GIT binary patch literal 971 zcmV;+12p`JP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyM07=1bVF}&d2(rIXmkKWa%Ew3X?A5GLvL+uZ*FrSL3DI-X<~JB zX>V>IPH%24LvL+uWpZO_VQe5yZy-cva%py9bZK^Fb9>#epa1{>8gxZibW?9;ba!EL zWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900PrVL_t(oN9~kpQrkcfh5HCPf{x-Na0DHJ zBj_foN+9eIAcn96v6FxKoj@4Y1c+f+0%q^LXF0Y|ELqs_FH`lEM>DTq_jneO|E<-3 zVC}IWYmcFPR;|E3$6mdyK6J?HLkKhl&UL(e9V_>qtlS%*G5GCQX*B1xSIE+>BTKiP zvV3QN#`uE%zvdiUzT;e6YbqY}%H0-k99g{afkmLk2+?o8&(tj4Qd^IuSLB&d$ilTN z3)ca#Kw|_5Y@Rr|LdHaXaW8sv%zY}KFMBdy)&wEG6T;m8V_is(`7*td{;_QguUrYQ z0-!bKF0IU62B7sK7#n%mC*D!62EGjV^g95WfMfX!p*GDY*Mep*9GSiFfdv{Pl$rDN z^T4^;i!c#G4|+Z0Cj8yOnR5pTePDpb2xa=L{@}1bbI#)88pbfTg~W}{+Vq)+qy}h> zsZ%2)J{D=(e1x(N`_!o?A8iOUL5O17NIY@u%H&A^EKp!%;yB%K@}yAJGba69(1Tu) zC%pssCJuD5<Y7=7QY;xMmO4THy`(mZ;Udy}V~Z=6T>0=T0GfftoDb3q;asGlHp?qO zaSg8Z_>n8)M*+|bY(+D6ST|rlisM{XEHydald(ew34CCIrZRdkA|y)_dC)8W7S=Ao z=z)U-J}^L^31b-BLgGf(@cmCuMt&HeO)x_3tF_^MPloqHpb0qEM&iL;R|a<jU}b1e z@oPZ3;m}?Ix}Zw>J3tS5MV_{rBXJN1c03u_(G(2EJ3;=vq&A9SY?^OuasAt_^lt}1 zGq9NRrEe>}5YAE4zfEnH7jreZj(uA$5(GdquoX?OsT;5##c?hxmYN*zK(BF-zy}s+ zDm|McLb5cG2fgxdVeJO>Y&uBb%e(Ie=rb{uSbDrj>)!CBd&2;20yS-1$7a=bt$Wh7 t9s*6ku~$r-EbQ&Kg1q?}RA9e__6PnVSzA}_ecAv3002ovPDHLkV1jr8qq_hA literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/reprint24.png b/src/main/resources/com/unicenta/images/reprint24.png new file mode 100644 index 0000000000000000000000000000000000000000..866c68c98631fd24df2e85e3a28b5d75c52d1c13 GIT binary patch literal 813 zcmV+|1JeA7P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyM07=1bVF}&d2(rIXmkKWa%Ew3X?A5GLvL+uZ*FrSL3DI-X<~JB zX>V>IPH%24LvL+uWpZO_VQe5yZy-cva%py9bZK^Fb9>#epa1{>8gxZibW?9;ba!EL zWdKlNX>N2bPDNB8b~7$DE-^7j^FlWO00K2hL_t(YOO?}2PZLoT24G29_!sz4i^G^w zS``thgcb!A0zpw!YV5+F;NH!cVAO?)niw~lG&L$H2#6N3Xa~BeOIHSC><5*)A@K*e zIKESRb(qeX-cItQXYM)ozL{yJZinf*tQS&s_4U2xHLfN!e*fCK_hQt4Rc5|4b1C(c zDiyKD3$GQE(g71|MKWA;rdj(JRwYBuuNKK{9QRf}Tq7|(I<BK<a!%i@{v>DhO|mnF zb;0ZPx>0LmNvv6%NmdCtjSWsl(f4>f?tupjVWTejxZTj~=ez8GGJ@g%exR<Ts%o=w zz;Gg$8b<%052(x7fFTTQvx0jIMNwMC0ipYI;lZWMWZ%R1RR6P2*+I-2*nm@Lp0ty| zdRg$%O4MC>9SPiwT{(dn0~;`qD3H*Py25*`IXI4<feko@rVv{EmPV~{`j!it5X3BM zGK7E)2rh4s(0S)&SoRC;xb-yB`)-2-c3%&MdX}6WMZX$0Ab`z6_x#s%AfDG`bYZqT zo+p6~IE*2o{r0r<D{7mJMLOT+NnisGVaU*7=MB~!97IoG0}d?aNbt|Br%`Km_G8`5 zhgsZ{zl;s=z0Q%K+;}eiidwX2q#b(&HlS@GOHMrK%U}cc;ee9)EUD99()iV6v|?5@ z_LQ*!%3PL&rt43nUs1!g$C16*`&Wkll3QM7$X%m7n73k|VE1f>gk7j>(TsV)<#O$` r4QZTOPc_YaC$mP}*P;Pum=FI0;M&7^!PTor00000NkvXXu0mjf0$F3r literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/resources.png b/src/main/resources/com/unicenta/images/resources.png new file mode 100644 index 0000000000000000000000000000000000000000..af85da3eb85b44a60cfbde390ddf5717838370f8 GIT binary patch literal 439 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvVv45dj$D1FjT2AFf_C<F#G}vHN0S8C^cYUc$L7wU^Rn*LA+qju0R{0giDEQ zM2T~LL1j^9dPWI@b5UwyNoHB9f^&XuZhl^|f@4WZQD#zUNoIbYf?s}~E=WAJC^<7R z2gp@$NiE7O18XR*zPn)o&^#%SdBOQ<CFO}lsSE*$nRz98ey$-3WyX4@dWHrDUy2q2 zRqgk5aSVxYe|y!E?~s82>xFt2`J3gO8cTSSw3V+Jvxr<`+c;J5_VJB}I)p2v`oCn= z|Lu`gIJds>?eQdcwySerrhhi$3;n_HdV1jsr?P^tDkdHcPn$0&Fm_#Alpz_hzvZKD z2k#NKU2M<HyN}LwEKUD4Gq%@R)b7BSB$-tc{?4Am$t#plqXg8oXX6QJHnIP#A31w? z|Cmm=Di(S6z_08XVQh<)Lx1q?V#stA{Uq4N?$pd8@dl_#K~s0qq{f^2Zwva3E<X9c Q9q1JXPgg&ebxsLQ0HF|`Q2+n{ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/restaurant_floor.png b/src/main/resources/com/unicenta/images/restaurant_floor.png new file mode 100644 index 0000000000000000000000000000000000000000..03e3cda06babbfabe5dc9c34ecd87c1fb218c83a GIT binary patch literal 231460 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ÐG4;8<rJQMCxxt;K+MXKX-oek~CC6G&e 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%0A`P5$0wtm>}<}y7yjTsKA*9ffWJEc&$PAB zO{o&t#F6NLR!6iXRcMu#(WtgUljY-%4owAG?O}WVi-WDb5#DxX-W~wc3oVt|2EdMB zcwzuQSm+ERy0{*QzMAZ-YsUDJkl+{Quf%`h$ig%t!EXa{o-6Wma!PAjd;5n`aUunv z(1<+<HG)&jVXylt;uY>Ujz#SCYI(F~6Gt*;uzvO!!oky+a68moo|9AA{#Xe~+wO=1 zsL7V<7W+|1^KC58FRrDkCCzR`g=Wg7D}3>_`A`?f8}DM1*VR#`Lf8|RSnR2(uJ4z7 zAd+L=JCJ+vlMg<=nwDRH5iC{yU_E9snpwga%qR%1D8nq$)SF-5Eau}*4i8O5_Du6W zg%flk3)vunDT4Ipk1K(-sT~Bch+tIpk2Mx1B^NXdp&%UqmU<%yV8r`SIyM@vD6H^T zrd&LF;__Y07K1a+UyWgAz%9^Q9|CkSCK;t}t)ME5qs<G9u8k%hdg+gT^M&+>0C@A% z>nEi4$+i|%v}|J=24p24UD|chu+Y{<IN)uwu^bPkCe=~`b9+5`VrwH|vFqJSWwQfd z#(|}*M21n*Q)&SGgbVV#d@A?+*_d*FFvRSu)-EPbB7KASg#ipT&R<!CNszUzy@SIj zE}2GfUd`Phxl9&Tgzf7=uJ=n1=sgy($F1cAn<%H9qGI)G!AUZ=IMH2Gl$BG_`NRmO zL^8{E06g1X)8ZruEseC47nIiZDS#QIx0`Pb+Hbha5vuA!cTH8OAF&iGwP#z>&g^+- z*WtTG#jqHCRe}13rshV>qTtmS76ezplU0y?_tfDlerTGLt<6Y6-?BW|S*Dun3RI5@ z%?v)1o${mrMkII!Z8_HF+KN+>vjYQjk`8S&XbJW$ETi7Pq_{FvnSB1p>5F$0GxAF@ z(XG0!raBM|)rLSz;72X(t!<d}+|n4T_xp=Wd=>Xkz4!L_|I^Qt9-=~jTL5F?Yn%0) z&>ty|EO7^m_|=g*Y^$RlkFCPMJbCNwP}hh9;0X0=thF`LN5jK+0n8yca7GZoqJn>G z056tb`|3_nWw0Lgzu^vw-!?{n;lF|b9D)Lb$;c)CV0-W2=%`F)9~&LEsC6N1+*ejE zdpucQD_C&9G4XO^h<LLdtcf55@XTPi8pX*z84>w}m*-sUmn(yz`aY}itWEbc)`dEx zVugmQ1{L_tH?5v<p3n>7h3?ww`aUNma-=fq@cXa5^U=A~GMUB+0gNhaB*HO**BTBZ zE+4{FKVNxiLBhGuKD$-X?vJ^a=<h@$?uW&Lt+}oMW-6sLzb37k6rv{qFzSKf#e$K$ zw7j<1TbY)SUWuJrS(w%7z;HpMP0R|Sz(plBO*P49j|0HTY5B#N4qR1JOOqY|mJShE z8I-&(WZO3eYx3_Mef@iX@bWv){->WtZ9Y*amC^z5le@2Y1S<pKZturyPaOkbB)CW- zhfz#8Abm?C*mx|tp>!=67)Sb$$J@e@jXBgzF?iQv2FYpt?g0FtBlAX7US(Yam_FpM zsL!qK2p^#yxUoJM#2|HFd6BQSxwCgb@QZ}{(c$4?3SI@R5yKY2Uca-)f8{la-O#aX z5qnAvt&7Xa$}&MEG~QaA8R`m_q`@H@aUf3!W!Gk%>8Ncq^9Ny-&WsHXO&HbG!dH|k zbDj<d@S2W}F1^(=SbEdkFZ+sx-r9<~E>l=ET6*E**Is&c*XLJrDk~8{@&`iDG9`OP zE<hMxghBy7W-66sUO(``$EQzy^s^UF<f7K3%M?#-xq1b#uy@h)w0Awo=1Bo;+sZ0{ zC6KhTzB(GnN=hwh8pW(k0$31?M!?G}Gi?=l#lfy%+PUMWF5OGc$S$s^3IytEYiodC zsL(R!xuqR$mhR5hW_%sWKlP`7bH^|L;PY4i@W<CSH>5Ewbtw2e3Y1yz6M%WHFWehp za!7}D>d<VnF7W`i-x9M)Q#rQ#aJrkdoI#umvb~Wnoo;X5un>KAzF0z7EbL?mf=at7 zDSv{+Y&!1QV0vO!X-$1|3#*S1OagpcjQgrKP+3ueDVuHG{gA)oz^}kpE(%|Z+K6ww zn(`x+>Ft6`ww)FsuI4a$mM+bV0>G(p$;C}NckG*84w}}6TWZxS%nRcuEOnT0kxMtm z_57GOBo)Y;Ejid!T6zCMPoON&O)Frn@%HYQe)hu7eTVNAV+b{TKCopF2|%(Nb7=5S za~O?J{M8ssS{Qfi{kL9!_IH2d$LA_LI$I)Yq`l8Yca0Ij6u?eFzjowM39Q#<U_`7C z05%;t5Cjl6*8KAN`cwl_IdbcU=9f{=VDdO-(7+5Pa7kWSV^@9Bxx=Rwz~uyR000gK zA%TJ4mi9JLp=H)&Yh(Vwe~BEx*G_->!)LB+ZaZsxV(AlY3#vyS$xK(<fToa}lV4{j zNxfKtCYe#G?FCJngRKEYS&9$Q?mL>CvEh}ooz0PMXr6@ZH_L$;&tod30WcZCL)7+1 zFAnVz>hdy+s)Fdff#w@Dew&ccQ4jZXZEc{UxUAA&-`U$gFvRv{4uB1gZRpn#!2H5> zJ5PANjIf8d@=SZfOExE(E-WT>Orc}i^k8eCAT1^5TS;J#TWM*qCD?2lf_nCf(o1b- z<Ck;@{mJM^Eg%g|cw}&Q0LHdxz>EH`-u%f=UweQ5>G-lrpAYm-02}-Qy~sp|2(E=E z8bfZA&g^~lx$pn(pYF{WU7i~mmS#0uU8?Nayb`Hyrn}X&l~qc0O#FvahygH+-I?hr z8N)umu(l2(I5jcT-#fi5Ba&pi8BAaZ;Q7H&L0(1MP)qVxUjo3G$yi#BkQe}rglK5c z0B}P~OIsTZwXPO0srI(w1OH^lj=%Zgov&Vg<?7~+9iFCk5!?4TL>=*(>CQH789Ck4 z)-@{ozHR_aBN$#R0GKTz$+x$)m<&s1B*_ApH(DC*=op|aHs8@a5NXYC1hC14mJDoh zC)zZFZzF@pY6|koYFj!0U@%BHui%lc4=R2!TMljO0AES168x$JwsM%?M1t3R=enak ziIt;};7*o@Cl_SPTrC4(o0TPz;CVEeEzQd=uIqcU4sVf1ZV6m|x;PXLHE#Sg!LF5` zDnp-`X1s6MjQPc$KzXgu)Jov&8$W&K_4hydDhU&WeHH#dU5H{=#4klKQsJ6WOX7zp zt4u%l$(t`d^`}4oy5*tI6A56n<Cp0%0$`4%Wt$5{u)~$M{Wye?D1iZB5x_F^W@UZ8 zw<0|;wJeN4()=s|JSiIVBAU+T7gTjkx2K&wa{O{sN=7c6>VZHF2nkMTF@Z$_w~42v zv%MLna7V=<q~rhf&+=}4^wym%C9v%a{W$je_Ionb-Zm(UovKNTP4f=|!6@j&matQp z0$7HO8m}<f-`1Rw+BG9{#st<>*v0nzn5gU);S39%Ek@YePY?n!CbKrRQwfX<?HnkZ z)mv(8>~BPA!?lG)H4UxpsN`>HX=;G^3+p$8JRl^~`x_Db#dr@9gvR<c!WUY!M;?1n z>}b|oCuMm9P~LEq>zTHl06aCt2suqmPfZLo`0@*U&8Dj78!eW~n5MPLwJ_LJ+cXgA z4{`zg4e#*Cw=MPt%Id{f3g6!M(sQrAzwdk!@CyJ}hrm58cnM&{=MgsbS77ja`uWe_ zedR}g`uv5?N8P|G(9G)wfF<#Z00sfE*|PHfEsaa>XBz;oNkPAuz?hhUzB)sp?8L-^ zW(+x4mQ;?(2}#mgS)S~u%+0GAm><YIefaq0`vkB*;3t69hXnvjy?F-;Wni&&cT^n( zfd8jMmC5^d-`~mxwvF9g3V+nXxBUH7M;lurbf%m>@KtgXj2F?Nwb7qx^~Y2W^w^h# z=!YSg_|=krTD5%fXvw8d_Mgp@ApPt{0F%&c@q<%N=uBp?%8;?RzR~jVrhYVp3O2*R zk3!&ZBQA84ts{N|VOYOFD(ZVFb=76%n86}WtupP=racgjNVzo9*CU4`jbu;ZLqt0d zHmaPM8XfEmlob2FWmTccjI>O4exRwQaYHK<`@3%^c^`Hf%ZLX{kFklO^B=wT#=D=K zO;7*_>Kd#BRwLK|81CFab?W)gcfRzaKYH$b_)!P#SisW9MXHgQNl5^!yT<C!y25SO zX;f&=VUR#D0E|fRcymE=Qf^(pM1p4|%ZA-L7Dt-Ove9;FeIVoXmm+~Pb4#$G8p$Su z5sZ)q0E{+k)S=tkS|EX|P6&XH)D)aNl)MFiIkiZ8_CD+(AGH||1i%8L=IGD&d>I`= zpcVi&ojL(vZFj$n2$?5%xXp($AmkMFn>wWa>|^h~eK<q9e$98cY*3*IV0Bt+^oj$% z?PwL(n)z0=w$@yfTV4nA1Q(p2*l0w5t1HSYgUy0psqJ+^Yh%B}vjHI0YBw3$t5kb) zI~?Rfpt{iY+R2VG9odm*0xiPFhx*!@kQdPTEt8>5ij>vL*5>*eYg^ooTaP4%Z{tpJ zKYX#fwx$z?z(C=}J#W3U_gGAc0@&EV)`=x5v`AnHsFtUm-S^gWfAPn!UTu5SLwW&h zx)F=6sFaFXF3xC`M|_YoUQ_@K1Y=&tBAUy#`BIZIt2(Bny}J}55x{eU!IJDEaHY}g z(_fyr7=_&1vWl8o0Wc=C!->@>(}KfD;{bp=km=Xi9XR`McI^1?J}xi2cp`IR)1%no zW=7Zl<`h2F9v+f+ccq;@b~&dVyY2xnM@EVKMIabGx+!8GVly!_$3)Tv@$%HerI!yJ zxLh)B0K7q+1NWi33r=XTQkg}KJ36zGoHQZ3{BO3*@#>t6B7Xxiu@FOo7A@Hu<>l4E zrmnu>fl*{WtMnb9yIC(+kv1q+<JgtM<1UQ7r4L()WT{?qY-4KcdW~2)3;>VzcQ-XQ z)VKCOc?dX?G}Nlq{(|zGwW;m~Aox+3_}0JQa55`>^$bFfmRv+0$7eSR%FBEeCJf9d z5+g})Vl_6wi3I=$isDYb|LU_pc;?e|Z<p*%&t+XL){UjT5OqAT_&&w*GVYp3n)iwO zj;R+~@CyNqQAZ0%<>;==Oo9<SzJ&S@Y3~jb7*!5EwS}2w?W+$)^UfSTaU~X`*~@$$ z00#xX=oJ9~cXxKQNzqK`@^9?e@mF^hmEQO&XLCir0kH85Ka8*+LG*B9vC40%J}0dx zEc_q6p~WpAnH-8H?u$y`hp5m1wkF708LR+a>?lo5E$fi4A%QnE<seUB-ZZBZN<UJ^ z3$3%;v=rjWyrY{=y*)oEHQxtsA;NRw!t(n{3QB95d-?{3;7pQGpErEu!7+iX-@6vE zt3rE&O|D72jdAQr0}-KbFHGz}@4WsF<kPnGjXkO%#kN3m^kO5P)PaDPuTFK<2U?%J zXVbTY^ip3_vvkWJFTSwv{k>nMl>)$(HMPh#lsJ+N1c%$2o9d*Pr=mLN_Mx|4dH$8X z_nIFggr=ETa!C!FOi<-mX&L9@sBKPIW!se`?mJq{Vg^;AC7%`IYH=`xbm-jB5Gs<` z9U207d3hQpaCRw1u#ab-{qi^foSj!zSpyZizP3&z@J0Y5Yq$R9?*hO(bBm*{lx#j% zbftt|OD7O>%D?e7(`~{?)BQa|GTjUv6`05&G1)m8_PK;T()bz^cph>uLd|VXsbQq0 zk)ED0`m^S{!yBp@G-4-qGXN}|Kx`OE+WMPv6BE??#tW232xY{^XBAfjYGJWdSC<tP z<P_J2d*FSRC_UZJ5fNZ7gjE<vLU`C?273a=UJSebXpd{!29YVfZ4empcciZ^R9oNi z4JHI_QcWBOkK@S!g6nF&O^L)e+j%4ig~hotS$tvto@4j(3yP7*Q7f5P2qZC>Cju+n z5~{7PK^)kZc7E@xZ|*)4=Zs0-^0tlu)?UQo#3F!A3cYlK@RH5Lfswe!0$7sK1;8`2 z&;!Stix5Z(^v+3VI|3M}9%(Jl&aQ+ZIGOv^!Q+<%z$Hjbsj026@c_6L5*S`+NMPi1 zG~N9}G?REUBmdq_-<ANDB3(6rzXg6DEcCbanU+cVIg-f1Of1Z7o5f^nPD-K?Z0)P9 zm1xb#p&Oc6(9-!Z@(^Y^TW#+}d1^`FkT+>dEUH3U%pfI<8&2X|EfL<7iiG>|S%qa4 zRmk}%%FWC!s%h&%@)a6iO%lGNqgHJez(xSr`303}t6L9m?bULf(5^D=?Tg2rmNwr~ zzMhyuDR5sn=&x;MG0wNV>=CS^`IV%l%f2m7b=KClKlu##Z}}*z!(k@gO&6X2?7;Q3 z+`?jXtbiK}I*^ohN_8io+z`T)$m)vHlKV&Aee2VUxxJ6PtI`=mm9)I11r$B5;>6;B zZ;$Wfp>&hDR{^|$D3T1Y1BhqE2=4HuCT93Lr$CTW<6unSqO9xyj%YIL%)yhFVv|Gy zV>z`df$LQQ8vxUZ1puR)@n3l(E$?oufAgxSLW`ZFMJ111_O>rr9&C%Kv)A#!*b)r2 z27<-62h9ZgLUMT6ou~~Ey9!{pBE{T%s>72?N&Hgn=4;s!3oSsz2Ifg{%$!E_tViaX zFY-ZmUQAS6MnPFgVL@(2T6#es+&eIWE{N!MWZTpM!xp<+Bbbq;tv%BoG<*8(c)s)o zh#C9U9{|44pL@dfwZSdMu0HvCb*Bs)l_Upl-r{&?u&(plHT!t-XL+zb5++lcD7<*$ zQd}Ck$@={MAP|gd2If+Rn+3lCzpu2UFzw1GyAIv)O+4~GH1cie(KJI8x`CWz3Lnc@ zZ4$i`Puuci6Zao2r3x*=m-v;4@7jECATu$os2SOmGN3`C!)TV}&(AIjVGqYL1i(=# z>01Ig+#wQ}0PbwMO#o-)-HQrs1z@PqD?BOz%_ddqksIN>W2DV{wqgJq0lWbCnl|fb zcyEp1?RkasF!ViX2jPgvKrXcBfHYpoum^2mQv(Ht$9}dFcs2%&2AIG35=E_O$%(#~ zn30p0m64j7UQ*kJ;)QY8J?ajo|5$P-sV}QE-XMjI9Ck{Sj8kjtTrF>%zYAUcsdauy z&n*uB9v$dtYH02IHr^|b0Zb-qtV3y~0ti1?U!Lp=)p!3_NAQEOcJ^bOD!O^;UP5Yi zZV3<!EgI2a`mvCbjzp#^mJ{ASec*UX^Y$(Po2zZIK$Y#Uq79?;aS{AtwgQMonyHcT zYlkOGHe09g3xG9|L*OeQ7Ihhou^O_I5J(zA{v>iaL@F;&x0dH*mr3uvv5XT3PhJFo zvqgp8D1pNrOynSd>lMH`h4*3_wg520z;rB$3jO#9-lT3%w6&Yig?x_WhI3FaL@*^V zGC5@KDiF*H-|Z}J{aBM>ZUBt*51WJ`zg!z_@m3?LzHNM1l9SGMq&x{m^z?Q{1ba>I zCovct+%JUE@1d(pMp|lWc3DFwY6qugFt=MGJ_MG?M5aG0GQ|<S3BtxV?Nljk^h`_f zgM&|x%#CnCJI#5dtL!u?)&{!T+Iz-5-uWk4pYFQD+pGp{7^t*>rj-RJYEwh^){XTa zo7I1V7mkM81i>?viLr_CNm==VU^pTq`#%JiVyFg5Smh;oS?LLv&t5Bh=zJ2hNCQlv zd-jYll{X-p8B@G2KeS|H(}TA*`jYk@6BU}187P9)54}3sT#%BKS=l|!zB<#40yh?C zWmk0IA%;><93X&mOW?%X62OQ9H@gxzr!Zz~05d;I&C-W!3Xj-$q+(6blBUoU50?A~ z@hkAfAEQI7ADYI;Lt^75@S_Bz6WYmR<U&Dzr=cN!1fQG#(O|}%p$g5;A|utXQn8{H zz|1fD1_b1pTQN}`d-G;gd?N5$-;2_HoVenb*cEvw*i!*1rY<q;IIuQGn2cxIv539- zS#BAGi(HTNrTWaCmlMd}8}ILGjS#;N^%6c}3silk5T<>I`UTq*bbhcU+`oOD{5RR# z$9T{BXls`U{;7t7^!T{stU{E?0>WsCRfDF=k_25<UYwhml5p=vbooO)<*t&UiO|xO zKx8ckdI;S>P-@`~RcO+cR|IcGJ&Ajd7yuh5))ZpCXeELH45{&HWtc{TKoSNyBMRJK zTacCSmyG6t<YNbpI{>y$EMo(QDS<KZLwdg$6*{Lh=5Ec#+pj-BTUq8e$~=>AGB?QG z{h9XgC?|{BWD1$nIFC;CB7p&8*%nSZ;f9&=f~^iuxq#8>31B*>994R@udUzHd0*`{ zfv1k?k-APC1llA^N*qW}FKR(HFYYmDCh{d72mL_N{cG3nC*_nk^p2o>U~YO=M~4Eq z6v6mMgS!Ny8$a5{r^O$8yjq?Zu_x0bG61aKY5p_hFPO;qP;YBP3v*e`_2{0An>N8A zZj(o;`X#ep-A`K^Y403*<luuR-rz^El;O56VcL@o1=;ZlDcQxP=qc;3LhmT)ALXy| zl@#TsCnluCXVg9<gT>t*6ICQ%SJx-oLNCtF0cgVawTz8)V}!)^j6Z(gG3kkgV39hZ zr_jq?>K5ku{aJ}g`Dz5u&cd3T>G0=f<=2Wu-<x>sz!3l#sgx2%GG6FN0Cxhw9RTnj z!wdaJUU|%o@-6y8BkNNo6ou2b@X{hWJIq!|rmd__H6wb7V9jt5+k#5%!-b)^)Vv-B z-A&r)YvbJ=W8U2~x&!rc2?I+UX?_kYPe!UqJ8Bip#+3d>T81!dhs3(`?xJ<OPZ~a; zd>&oov_6OemsLjNf@F)~K{tN1QI~e)uFci52Ju!FvFmhpJkSDP!SD3+_-J28U74@d z1=hFlM^Z^KHsZQC9XYwjxz;DTI?1X3t6r-^okZ|dxFj<nF)g>Cq_m;}U7=B2SXo_J zj;^w)iE$~}zVKuD0I)=!r?7QxVQf@rIBQ_O0>CoVR9(~}fld9~HY-ltbF4&$o1yB+ zII#r4K<!W{FEKG2Mlg5-Y{=#1v6j;8?2=~TG41h30AS`qS8oSkNMIynHAVeC0Q_2B zW$cyW&E+YOz(fWmp0~5u6Cck?zm8Uy(n`%|R3|hoU=EG4ZFN+K-d=&09kT#7qSuZ% z!sjmzwP~5CTm-Tlf<?RZl$VYia!*mA<sfYGCU5C=h&_Qe?Rncub4FZJaj0uxbP`Q| zXDJ3bIdaSq!KVBmLJn_X3wu(voP0|OFhzK&JXu@D?QABqhztgRC3}8!u)D4#CAHKo zR)IqG#3yLC)KnR%s-#E7YaX+0<?FHT4P6Dl;hmo7Z7W0VocpoZQ~(60=N6Y%_<U6o z&#Qp>TbP}m7@wB!-*WuBhg8g$RE>=jS{OUie}r5~HbOueN1}IEf#Gp~ZhY>9J?u(J z8yMVFk~UxjFRsjwhcPlb!;eVtG8{5u0@uR?E^QN-JRX3X+dBH{3E(&Ks^hNaZ;^>5 zDzp=5QEkD6h8JX8uRwmPZ&)2R#nWprTA?ko5*QjZ{)j$1H>cxO*j7iYgC25#@~Nud zh{R?;X=Z>38TGc9fHR*~TarSelit`(4`E>5QQT%`o{RBO3ukbeJvj`(GJ|aniM+-; zC1)y-UsBgKI57j>Bs`au^lVOL>gokqqT{NfOJi6KVtS^x^lN#;#%_?<+YG=_s3R&2 zC&dCE9qeuKW!}4$Smo%CI&f&y7OQtkug%*}<3+0kwU|N9z<vn&yO$J}w@AYKbZ@68 z5dTCte9{-YPq{GE(JPccS)Ugbo1C5pJJ{zJ{8m&z{$?a5q~_H=tbo#}!p5LwKOj-e z(8in^v}7qDe-A1&`p(hTQ^yHiFQixNwArMmChR+0JV6QUcG;hX#<?_!Ic)K1<sDO~ zm6%5!<y>!VVMcysw<t<oiAP}r-;Q@Aa6}x~+Q2S=-^}wTUCYL8EVY_{cPyK^pBh9m zSriV0xqq?<{_Wj;O9GB4U7zUao{*OSO)}n_LsiJsFfahyA`)1->bQfuw>wPS)HtoI zfx>C<vfKFd>CP4=T{|n$ye>SRyhajga93zTl)(57EpF{WkSl1`$0qr|VR_Cr(Ul`2 z-o4{udtF`I0GiiGC+{g8;46QdoMcKyN$y~TR=!dU8xU)#X^Z%hSJ!qh?9I3I*u=&N zMuz<K<oMWdcT+`9{Jk4DQ-h9&n3=qh-cvot?Qm;~dks_Ml5HNkyk)hg@W$z*XYUmB zV(%9Ex|~5tPYTH=dcF6c=Z88K!GY+T*KeohmH5yN9bJ?weI>amvA3hL0&d%ojW;p; ziX4hEM-v}xfKh@bwgyJh_NAS?20RU~GYB@aZ3FL%hXfWC8tzPO9gF{^c5r#Rw<aqw zrJ#8d6IMie&2&}fX5`nAe0!5mesTQ#?L-0?g$!;Y2itsU7^xKi?y0{c68IMd{<!Oz zoAbLl8%ekf{l10)Z^4}%uI=GJ#w}!7^b|BJ8e!tm<4gtvV9}pNAWDl29oWnIr-$j# zDt?XeDr2-LgPD`NVKx$<)%YSLoF|PH#APr89w<6At!|nKbbN~h-o~PF#gb<NsywAe znq8V0?{04C9+`xD4sHwff}{)<g;smpFivY?O2&h1<?slhNkQ!Tx3(^QuqLvDTU*uS zc(5i!T^k)7>;!&O<6`dKxSQT=&0txyYEvFT>=nRUDL_ixWOMZ2xT{|8%K3WF8*jX| z`|BL>q0aaH*RX>((Bb?*2WMiB7hFAY`0~xTv_i}V#$2TA*jty*T}%jgeRvxX?CgQ+ z6-IAU9YgeI2|j8)|1@)sB!y4-mmwYMZK8D>msZ55uZs#z8(7MIg{87ZH$G+_MsP}e zX5A2`6hhBk8gD7j&L|Fz%iH_Y6u@b@r2uf<MgTLFQUKi58N4R|ex;}?@kYj002Ugz zSx?51wT&+M2;RAbe$6z3Md#JQqLPLM^x_Y7X!T-gmZ?tD**d5r>`_5SFR1=8PN;=} z_8w0vfd)LFKO0{J<MD_-^R~i4IFiYzLUKp?!CcYwc=Euja4wB^x3+W-BiUwd)*Vqq z2n%?%K*$PQ1+x05BQ0X;(i?-sZa7K7s^2?~X`8~OqJ2UJS5A%$4t9h}vyzijk`wOT zx}SqQdA+2BgI_$tG3jAVif_|^h&<GO*lK&)S0B9e+%wO;^wHPFLV)u<U7DEwU+|)< z*vn_;`rCTN4?A9T;gh`wkDa@9KRO}q&W*1RfART=n7W4*P?}F6e=-u-ng}fBSIdi@ z6OaujGFhulB?(zSiD#1rEdVZ3FEjy++I<3eZg~#<uhJ6J{C)FC6_Jr=p~AF`Qdasr z=*c*x5;$J~3<(_EB9)Q=Zi@XQ0QklHnv~0ln=?eALQArephMWMS>U5gRHX|_CwGI_ zN8385C=XR1K^`=%V0B?p0y}Ny#1FlNiDsyQK;yothhJ1<Q557fr%^QFi9>2xlS&Lm zj5&`<BF|`XF8)MK6;($ad4?VY_2NeoA73Bwvh~Rx^!n@^68(8f`nS^qO))IOml#$M zJ91cUVF$yE5gR%DkX$WO_u%N#Du;=B4F-=-z~mYk9_($ywAs}3w4AJ*<mlV6W!8~p zTn3L^qkVxTZbH~Pq0KKBn-WjH_sR>ne*W4=7g^J}JkZ1Dvj3$n?D}TU(M(@kpWJl1 z`24<i-`o4ykt4?r9r$?9hx<+>G;DqtdvLCmr~HXOSCx|nuo=f=`My}Ml8eRZ$Erm; z2=>yuvvCRg1;Fd9ITGy3g$7u2i%U~5f)i6p+NUIuZFR0Uke{CI(<FwjGzD;K4%*5_ zsL-aI(2>AR3Eu;NpUn)VUX0t=Wn_JQ$I>#|&S)|gl}w{BZb9G1fbg8y1_f=VyMx13 zPzX$hCLQf0kpt!^Cr)T8hg!3e;jH)Cf&v8E4uBQEVmu3!R!7_0O{CtcGt`6B6(OdK z*uX~cbHKYE5d}CFMYf@BZ8zx|?z4EfQlyr!Fcc2f)wd5$K%oGBU;yK=1hWcXeyRN- zMVt0?k0s<Hyvq;G)pG1%M+|FMEypE23iWw%d}L^#yRo`B69ew@@(KztB=>$2Mq%+1 zH>)1dRy(}$r@9?RftDTBz`0%{zPktCfBp40-`V-rFJ66n&xKskq8A2xzj@W-W5AxY z!9{qUb*{IKTJ&tm<^Auy{o#lE_I|YM?RP%@Dx+ibCwfj!MU8<krK!;~)N_J1F^pYE zy2316lak6o^pb2;6Xd(-+cS4^zYrUkUT7M>6vHxy5L3?P`s#8J32q!+!o628B|R%W z9}~~y6ME84eSZA>O#yI4Rdp@WQDmx$jRR{vu-d?Fi9Z2=pUSFDJb9-*Vwti<JK!+) zB3Ln{SrlFpcc?v*?j!KGI?~=f&Q+=a762=hWc)NGF#UUr+!xuBZDb&K+Dc$LzT|%f zMi%<odfXtAIb_xm!c`?_A^BgtCv+H5+Ubd=nWJW~3VtJF^jMYNBbck}?1^~9xt_+_ zn)=RRj3AQA69`~~VUfH>8mm*w_@q&0=t7s8uT`cAMaMC{UFlL}mWR`5dURAK?Tn4| z4|F$I7i4GV<YU^kuc9PBEiO7UWP*j7Lga0n;91MYvz5J3=|nEaEF?=T{YBRfy#Mab zk9P0>WdDcny|Z)wxl9rB3j_Zp5Nvkdcz$^(-XoalZs`?SJ6U>h-&?Q0`S#8?(Q4=G zyuPi)fGUahbS;yzPEVU3Aksw05@aJ8Q_@0JyfqXE4ubg*W(E|W$%(YD$L~2R5_nOX zPl^T&@r(aNheqmTQA%PKn#<zNE2GUtY3U^m94z&qFa6ACUtYYKAhVIGFqjZi7Nsk6 zQ2GPeg8oiv&C%1A_8b8Gz0Ahgqt}}v0gM&x5E+F~5&<Bm=!Eb|(Geitj%_*{Jk!(O zFX&=7EcU}<4wkr}0boI}&Sy}8uYG*B62ZK)=6eY86u$)U>R4yH+pNuURe71zDbkmy z0G5IElKdrjwldgJG3-Im0#L@h_1ZQ(+)QsHYRS8ZUjUfC3gNYaSyi5m_>F+DsWUX* zERQZtrP%RlZBCkYGB8~+Z2VZ@3y|=m!vkH-{-WHxydq5d!dSb?io%TexB_biD<Z8Y zbsI^nCt#U2aU6-?_1=POhd)1f?DU0eH*a3Mbo$7F-JhM$mwe;-!GXz#4L*1bF}v|4 z3Jr1*O-*3D)_YBLw$KoqE;{$&t3QA4xfkBpcd7Vc+0WMMwMWfd0E1!GpS1~ur2Ud^ zK&Y_wv^TV50UB?N&?Je4hOkGsF#v`QOvy|9$|P^(ax6}^muDnpRP{)D$<k0=ZgOUM zSS^o%-1DD(dG>ZfdR}RHbpU2C0UWHC8cEEWkd`_apGN?vzYGBXX=>HgPcLk$W&nU0 zomCZDx6CS-R_(CzNyVaNV}`LsZ0_n{Yu7kj8!&>|j*>wnYXigSBQ~(O2gK$U5p41> zHXXE8p*6Qz0L<tUK6tiw!~6$6j^UM>hGj!n$S3DXz?$&{l63)=Oq@eCYqfqG`|}7L z0W*g%R;0N{@GAnCnv(Q^mS%F4yDo-}DeShrv1YLA-g2GGPTj*M3_B2}D@!w~rG#H7 zMDZIaFDxpr#9*w(=EnNEn#z)_q_isA`9?i_hD#b=>7Jj3u0gQAREe9`ja~~Kg;D3f zzIZDpIVZ0uKRY8K=K5DhPT%AZ&!yp^$#2~I<00@?GBg<8*n4TJtEEpcG?shj{g<A7 z;jK?^R!C}Mq-gSfr-$kOu}gH4DD5<B@j?rL1-@bgJ0jRH6ElP{62AB@e&5le3C4jj zK1GfO?nPniPylDU{aHyVC9UEcn(y^zr{+|3PSN={oPYic0Wc(Rd380Cv4RR<%nq<U zu{t|D0OYQ4>dyh-KTa;Zy!XtedP0@JLimCzW!Q{AFqrR1Nd3n3<r<pUWWi3MySpfG zqC*42OoWCzNs1vM4}m9*kUN@5gcHo&bd|t10g_%U3gGqS(bmYRD)OB2V02ZhDkQ!L z6~SZ}#z&_XjWG-~6I)$y&QgT0dL6H%Z;uCSwl7>?SKrz@rudbhz4BYiV0`7M&PEP< zB(jsHWyP=^3GB4QGVbOrvOFlF-K<M|f~e29+3;|8V{KJAdPD_+L9_#Jz_5tMP+4wz zUcJZ2aI`+fq;rbqc<uV_QS)Ed&_gGqvcx;LW0JFqk$zk*NfX7nDL1d&h^-R@FAfh( z{ul6MsTWPXOq3ZB=$!6q>Jh;|Qh52m-j7el)NQJ7bY5@H*8#5(EHw;DE46V+jnv#g ztYYiI*o#Qzpo3Sn0VS3V3fp?zz9RrIoLDlGQhm@ikTf??m!FhU*f@blnuat^%dP2~ zU6JP-D!zE&z!?EB=L0K%1;J?Rj?qZc7`n5otr=wv^@*ZF|M88a<L{gbZe&yfU_mg1 zobkAsee(cV9laL7W(k&UM}FYSP;1wuAOna3j$}(vS`YjR(G$O%8)XU@)r++SC#EED z0IVWdY_ipvo^ba@mamqK1OwzW=>O(Pz?xAf7K8F8HQk!_hA^xz%ldn)l(H*!%PY~Z zz5(iU`@lFp89`==7a07C9juy@1+l<Or7^xT*;yK1ash0kOKx_?7J*^gM#~8)jp9Qv zY!;gO=-5bibD*pk=}0x`N6Ic;7)lv#sw&C#InGMMrmO^Vn6mqGmndEJ%4J)NJyoem zvGJ*y`2cV!IzpBs?Kn3hDdv7bgQWE>4h~LjV}3kD!am|xM)Q|wBLkcpiDas+kq92I z%}huxY2B0`?3&FMa}LpJq{Yg2M}t<M4Lmkr{IFfw3WClpjd+^0A~i=W-**<V9>4cU zA(Vhc09dp!hpmGX%#St~CM9JDC2?)4r6?_}pnhP603I#9bl||L+eyh;1spG06ND2B zjiG~$L@)p>Ep>39;b8Rhe`Uvx-#&Wt;F~8lsL*&K0+=$`IF=m7X9X}5Jd7}Q|8Woy zc^GrO9fQLD(bOHgA@Wxmyt2<1JOp$q0Z$S;r-iGE&8Ew83pqaN*vq}dYZr#wJ2pl8 zD1eDiTgf0%B*Cv3GrXbkP^%2a83+q@4n=RKR^W!q6~Jrb9l`3Frk)Yzl(GB%%nVee zY4Kaon?(#8*6YY((X187l+T*y!7NKB)lx%3RuV^~d2CfkEPk*t!SCo`f7oACgv!_& ze;x3Plb3m$7%E#+URdL_kF*|~O>5im10(B5-R_ahb_H_dqvJAi^GoF_2Yky*i;HuS zxR_qjA<me^p&?ZXH;RVMKT+|u{R<Uk>UJ?=(kViTeB*e#%HZ|sq0ud7sPaZ8{Nu_S zBhGD&pp_3=fGU=k@O_G4&@CCi372RrQy)v!Q)`0hTGnIt9xcR%FM=S<C7}t}RY<Fz zXfI8TPp_05labool#CM8CM^kqN6W8%ap2UA_|)_QUo|9fO)U^CqZu&Wi~w#^05>*Q z$G!G<cI^1~pI_Mh>d{CQS{`VJ(zu$5vM94oH9>gE^KUwTCq-q$flPLFk6~}uS2@=k z0+<T4T;jwM-vDlAjqYvz(9ULQ%Wcu`MS-5`?QmwryZ2?iK2;$(3JJ%HDT5&w^e3{b zjv5Ji34jf6ch<PY0)?6!<qfk%>MAQ6ddFr^rzo8VQ9;jiIY#aox2H#%niK!B(P1Y` z%j9b*hKX7?UE0C0x~4hXfoUEaozpOcF%cNSq*3&bZLGjVQ(v_-L#sza@CNaIU@T?0 zDNtV4Xp3SUtB7%-tuFV#={NL-k0x4u*>TbF=~)GEas$1*%F2oha#G^sbE=q<zA)53 z;b_rYI?BvRS*MAWVJgWC2dCRgnTOIHS*$rQ<9P8<8W7yQMNzWlR_;d`EPJTgN?@as zQGeD_BqZR909Ip<e1A#pE>*N8D?#C40BjA&mAHLJ3!x(~h$05u(g&@xR2G(IdMYv! z)5?U|4fr$R!)l*E+(+gYSKs`6zXG@n?f9guIT)%FBUq-3!uD<NZ0|tJpm2Rf{J#J9 zAOC|t-h1e+7Y_Noa3e?AA#E#E1QWp;yEgpT3t;a#JFs>?Ze`gV-f(B{ER-tgOa&l8 z7NTC3MUt8sMFbl&*s4dHj~&{wvO8=Y3zk`|JU7_cr`&$sxt)BY0$B6ml#xpMHBW*@ zFhkGQ@MeZ9J$BYfVtLfY70UkbZWxMNU*)TA=$XI=O3wz-pbcA63{z_&bO~SmF48G& zqQy4NV?(zblYZ&w(?G6iFYPU2f-#JI>(P;+!T$aZ!EYJ7A9W3(M)Y@s5v*fn+nYnx zCB8<-FtmP+jmtA<Y&?_p#Jxgtur4<>Dmp$jyQmnzt(42>LjhlDabb3Hd_qQfi>O1$ zi{5Go;?`J>RJrVHT;r0qld(C4B-zVBQxqcH(c|Izwhg8)nZ6U?cSL|;($@Ajf|O)# zm_B8#rvIQeMd*}nECDceH`0fs^U_Jg&r>I;dHl7weTSh!BaB1|tl*U%OOtS8%@5RO zCZ`lOPhucYX-0Ckzi&o#UUV0!yK`Xw(QENZnUuhYBL!>gWI&-vU@&5o@?!=j+FjTA zvTmQ-`}RBgKY8ofkBcng9L)j%)+#@Ge3_&yT-ctj6~UhUu!P|0RJAq~@|F04%mG>% z=o*#L>dSzR`mhLKv4YjMaI9d~7^wQXQL)nB(7mh?BnhK0O!P8H^<X+&RZvpd;#7W` z9oAR?eP`^$3$0xvS2SoGZmvUb)a$O!5=F56(qUiL_F5h9tn-ytHg-=*lBNLIWUF%$ z4ka-Ku_J!fg&{wrE^RZVRgc!xEl>4fq#!1QDTu9G%Oiz{A%7>4yfM(<-5jheD)j-s za^&^Rjc5!-`P+rrr_F)V>@pci;#?}!tV-oTSp~BGhK?O?_p!xreqzjh^q@i?$WmWr z70T!3Li#ag^cH3%$Hrw9ghbHK_w{%Y{4go(kRPQNZ!8>GFZD1PFSw>ix#1BiYaT^< zw7Hh-!@Ed>VB>FfXjoG*tYp{9QwBkV-syps|D}8CER*Y?D~hBM#af5b3kP9wp`{sX z3hT|+;`bZ?c0h^0E*gW*i7BFVX=-sP&V33Vpy8&XwB+p2=;8!w3(+Qe7_Hjo7S|ul zG(;Wz^vi3pDe3uT0C0dhG=?+46lxSNR=5oSZV82Is|vGAn!-6(4<C5#M<3>y-Bl%C zwoU*{-x5_&U6-QRV2CFip<?p<y=T4LmUZRWp<@?Q+hjdU{e9z$c+)b%v1rIa3s_ri zs!1w;Y;rS45N>5cam(=(5&|X{ez3MU(bq?!94)zd{ELGpZdN#IB1(`o;Zl7Ol1GUu z0|BtyQZA#ktDR3CWtM1|zd>+>ipi;&xE6auzM`_a&e4UnWi$w74;`_BT^X!3piUn9 zW<jhNX1Lgq%N}J~Gb3%TmbUhg)_9ta<!ICx{vhKY1_yfqUyL*b=LUXZG&MH}e$mCh zy|YV(uho|2r{y(AglOH<+@MBVVAHtpWN*v|Q*K;~j!sO^E)@7ySEGLo`i^4?CNS(P zE69Qjj!Uba5E<Oxqg5<=Sp+L8BRva*tMfB?DE)~QD3o!89xWnk^$6q$arZ7G%{38I zq7DBgQoRPSWl(AgI)me_elAR3k~lQt$>f}Ae8J$V`cKq3WC4sPp(mfW(WhB~4O}pW zrk!Z*pxEWniWd{(eJ0w=(i1bPdZ$L}^O94FTE^fUnw?*LFxMJ?Xy4K6vB??vsH!pm zHb!t$Gn8mFyKb(ptt>4{Pp+6+>xn(}=_@~YFVh+hx`}v(9b&2)PmiF$w2f3X+BJwb z8c=jKnB81yNjSC>iL!4UOlX%MP4^5;$Z$e*+GTdQw)w*U%GuQI%?-3R=w{c3G2QS) zl4y?h9q39t&@0sPU@Y(KdoTU$nU_Ai;&Tv8bx1g-84;<CO^^&t5v<uGBnWU)<E^vC zg0sfRB??^`XY9g2Q)OvIuxDaneFd#PbOfDF(Xb#^h1&6AISRE2DQKdHP4jTFr%lc@ zkn0`yjgCB~;#W!uo#8BiH1G>#5B7F9*ZN8@q5y_dsG$+gD`_PRuHD|=4f%_s4_4*H z-plK8sa*qP8=&iIRmS;&199FmRek^Lxf=;7899aJ$Pz*ODR|1*LJkce{r(Cd7<Tae zgbF#6`R)!)FER)=HzJLAZptT6j9am9psPU+9SLo%U!J{nU6|Ahj|g5HX|4`B0~1|k z%5!i1lH7nC!H8ato;DOH5CwHe@~w1nfw>2=QBgzHjXqa(x{{kvc~eR6Ab2@;&zA*b ztE&rA*-6}v;RyM~^xXVJPqj=~X&>pS$xcZt>6nndTk}f~mfDk!e0ub1Oln4cc~!OK zV!;p1WUP7|Y9oSzEe%0`X>oSy-8&_tYu)ij_rCc3chXD@#@Sdnu@qBkCfWy8|Glb~ z%DT+u@<bQE&2fj`c=jhh{?X6gIGoJ*#YFGG^fG8>d5M(_1n?w9utt(Z1WSsGrke^+ z+e(R+Gcl;cZmrG@_tCXFU2yi@XMc$6*$=Lkk6V(Fhm?a51)6D;Y>+SAK%^pxs*uS6 z<4LeaSW?fd_Uu`r<F_Em3$@MmH~K5<!h^HumAe2xrTQwxF5n+((b|eZm1$L>?HB5u zjx>lhU7FX1=n{l4JMt)oS-BvBcvRe1<6}~L)Z5<RFDk^4FR0HrZOC6l{#(WT)mFkX zrNCbjed&H}MB^}B>E_E?c}nG$mG+h1Jbds%Tv~2^L8-5*2JmfYXq18GFttN<wFp0# z6y~O<-1z#YbVPnI)43IbEz59thXZi4v*s7najmUtd{>N%(EVXViek}2C~LzFm393_ z%`ld{Rh!kkwU_ptBo1{K454%4yapac084c@6gSinG2}_cudlEk6h*x&*mOP1aeKea zhXkGz{4#uK1n?L-md?-g*XF0B6xVl!eVHklRXtO1>rTxqt}k_`9sBsp3wM(;1;GB= z0HR2!ND2k(*r%_iIuNL;EY8o(N{mgZoLcUT`TXsl{@I(!>U4LFp;eK<s@O^pmHluv zZ^E+yX4&-e^5<%l>NVdKe`M!N&p-dli!Z&p>vU>ZY@5;k!I|ZCn8A!8Q5>T6_$);* zlhpJ!${dV#<PjHwXGu4=eg^r-<?(?LtwTBc!Hds6``mMo!Fw(j+4@MVNMZp}(h1Ku z0L+7M5ey!y*7uSmu5%d<bJugG%E8~c>tqK3TyulX0e`S#6a=*-B3SVYAPZ&%#zuX1 z<ggo3;#UraH8`xebs=r*51HLT1zHP^v_-8z7zpMhZ|KjxEj49@c?D?7C<c?@SCnUQ zdZ39v0uSMEYq+7VJn`x+pCsT~nJQM0S)j8}bH)bPvL)tF7h7{Kef-hED;c>3h2@wf z7N`e&o8c*wp^VK)83|Tbm6aCerQbby^rlbZ!IPbxt_+Tl^uiQ2{6JL!YIsboQ6tqx zJq*?~171dLiwT8`Jv3A+H^AwyhYVJcq;?)p&SAhFD%K?$!d9jrbAH4(qOIFtmjYNq ztCCfRCdddR=`W0ttZ!b%(~wrw+%zUu%$`H}V-Hprrlg`pAgp<KBLd*LnbC&A)a1OX zkiRHBHMgdB2EHz|LR?wy&OE;F(=#{Y((?*rURyOrE(&gunNwC)T2@k4?!)9fWX_aV zhY)%R-`V%tkN@nA#0djnyO@<7!fV(&L)yPVG)mS31eD=krXi$Kw{8M|<80$hFy`1t zJKuWmgWVr}xa)&Y&nCCPq+J>A8=ApPqE!*WBC3F209XdB*xU+p19hK7xF_^<3`eG^ ziX&T|9%IYn$&w3u-+1+nw|DM*<Mmg5vFB2OEszwrvke#9=s^>bX6I0bphQcA9=z1+ zmoV$&LvV>W9E)F<b#c*rnuUHraQ8IYqRdkO&xsbzyjdf6={2)jwIha!UKh=ZT_<I0 zW2%-wmy&lw6%)RPSv5I6Df)9uO<{IsA*7<HT=00vaG>UJTRSe|x3wh<hy`-u(i@i_ ztadh;E>V<1%Ak}5yKLG3L|&lan5s$qYR}v6pN=gmE-pisL2Z4gDU29%7;}*^MobWl zIVK{5Q!an;<&8@5CQfv=4|*~xHbPbj$VghE7k?3zD$k7NN{_S98I@;tX0l#P;>Env zB6uL^51B4HWCRALYWi(jqKI@==|rlk>x!39CAhxG8j2cG7RC5d(~?09vVPq*s*dUb z)9qRk6?$YH09M6W<?jfxc5v2nvlDHl>B-qezM|~pw8Hw~nRyJ+nwVKy=*>C3`=f(j zUx`W0DJm^TgRg3TWkp#@Q9(goeqLd5SygSQxwE@}XkuD!(;4;oJ3s%~?lc2n3&fR` z9h&Z-R8DuTE{)4{&)F4BhQpaXoT!ODv3K{r&yJipapLHqFFrYVJ}nFcFAnzzg3$?x zl<vSuyh_I6)_iEzE_v)}%Uw;zo7hD1qt)s031PJ(C6_<mxogiShYlY;_~}RQzPs=1 z+%Bs`K?I8;!O*iz8iCB0>=F3U$W7TFM2#BtO+;K?nl?19`6I@|HV-X25FVVt2ha=_ z5v+1p?O|1;O-r)~dsxNq1`xYdhpuHz#?4t}TChYJY|t!4iy)8Dq3+hIqKu5J;#$nJ zt3$*=@Qc*hHc_A9!D?-5h6&u-7OW{ML?CH47=I@tOc@0>xp~Rvd{uBciyiUZ{_?$F zy#DFsjA8(o!#o=>eW(?~0NL#YQaBWpK_=xTxp$82J9wi)WH6>D7-{IH?HLQyK`+7S zeCK{?XXvPwi^pNBW5xt^RxioV7<GbqLncduwN=4hBZEyMfLV&=RE|1jG%IuZj1p1t zL=lo?U<rPWyA{ME!Ui2R)B{S@O|>^B^(k)=I2#EZy$4RL)s^`vs#0Sk!}uei1RUQ4 ztm@vX?9|lU{M@wUw36`1%q+6l$EN0IyYkL|^xj7YPF}bhmysa_DMi^C8JW;|1kN=L zZ9PL%^R7=~u;A8LM~+^vrW;q)4L#2tjP9_~&t^JGH8W$|f(RA5`dVdhbmW>Hob*Q> z|LpUl=dRwod-v|GYv)fMIesZU41dPlV9(GrMwvn5oSTup$uhl1R9cH7Zh#KWqBqSV z*FmtbW&J(yJ3BHe?0um4>KC6LI&tCl{ivw>H!q(){Kc^wdF=5gB&tnO<S3vBVb(Qg z)UX_Cjsh6#V_X<olTe3t&g2qxc~1LjSKp$t!7ZEVYp4me4NomDW8ACBnKd$)7BMH{ zxH34>sihLxMY3CQ=+UDYT#7V{*(P2b)NqYXO+laTX{j#2DHr(AL8$@iGlq<__)Iz| zK?Jw8wYIf)bhHOcQtoGWtjvV&AKZUDsfG2Y;?mdtg$Bs%Gsa^jKciz&UN{%Hy7!Hj zUwij>bYYpVyh7%Fz^MW&TjucM4-njlS)M3;^7%?)PwjpG^XrvB@Y+C2v+Gkb?kg{J zRf(e%HX5`W!m~bMvBUM5MEV*tlp;_dL#d~*H)OKdQ{$`a<NAyMwsdMB?^&XkbDN<9 z1Sj3kj;+Trape3mi-3(8K|4Y?LNo>$)C(Nin2+9#IPmJ~`~>VA1_0g4?FkeC4A$hP zCZ%Vjq$X!ncTUXAOrW%TY-YN*{LZ0|_a8WN=Hl(B<mB|s%+#nGx0B0io5CHv!;=de zQp{I+>;1mUAj__t>K&n609a(OG>?=<1RBAn=3u3jTFBZ^QkkK%e`CRfOQ%m?i%QFa z%r7p?NsqsA@$B`q2Iy2kaNh)a(JyhbqV$VWx3H+RdIS0c=)TfAtq2G+7utF(mZrx> z@sVh&7Ipsgr91H%1(Mg7mz8w)%Gt~J3Ytwe-J04m;={tEFA1f?O)RSuXS8+~a5<`7 zBDoaf2##>JCvCkLis0$4hERRm5IXKld~6QkV5rZcL^G?>!EmH^+T)qlJ}WF?vQ916 zlf`^XQ%~$*SQ_(i@)5k5*ujy3-p<C#+|+b5VS!MDt5TxB2>L62k+;**)*9~Y>FI9H zJN?#kdt>~?Q77Ji?Ty3fJ+jT(G)9ikqlG9$tb<QY;DMCSU;NpNuYGtf9-cDfZ}@9N z^)ibW@RbV)##Av8!H5U@Qoi25>)ns9mcpC3(9_VwN){CnHntpzVXNm_Sz!Di_FKmT zV`<RF9Vv%3)<6QZ9DlB>rXtu&1RKs2aga1|RS^aoFv3(h19dXSC?xEN|70|`W?-o5 zCO;I#REfrrj-Z1e(Nt+}*nHIP!}()qS%(xGgI=e5%IL(*>_~HQYEnvSN^)vWO*hg5 z#s&w6M<%95nu_CZUcPeeW>i#ST2^*JVdkyVR|*CI+)dKV2q^Fmer0SvJ<1($_;B)x z17X#tHT*&cuCCvFNzP_YX|yKe_SIXl8M)B3cohLuF?XUe8sM3n>2L2D!*B#au+0AA zwg{RuokQYl-X4h_=L9LhlO(+~IW&SJTI?)MxN{qh(LyHWBBQS;FFWz>o!BByzLJH> zjCD0-BoT%~gH#A}eR5}xOEQ&?9yFT+wWRGFJI`I$yE4%oZfI!hpMqroy@I2lO-?kC ztPU-?A)`ySKd|*oYh=m6uj83^JzAb_9_EMef&jfTxEtP)!Oqqu^xjCz$jB)v4KUOI z{7UdhDn}7N>SzUi+dKQZ>N7w6&0pH_cmDj-lgB=N^O>i2-fj?BsY2>5RKK!fj;g9E z8(sHyJ^iznb{@DGUyQ`7iV84`rpB<vuOJxnJVT*CO@*(zD&x|@4_<%sqbsHGv&>@h zS)XC1rqV~`rCO$xoK~L|BBCXZpHZ=sUun^({BLbjQK&SRj{ag*t<6VSB1fmz%AmG* zU?mHqlrGJB@T<ONwH5in^OCJ^=Z4VN$|$ZRx8oZ&RnrUExqP3#Ta)`tMj-(V37kK& zvNSUR3rKq&$-jgBgM&ku8#yD9;G~rF<mA+%&=8ss4-XDtqV&YXP#5xZ%Zp185v&XZ zn_B#_r*E_<B|r2MRnwjx0E_^SK$toMq_C`u|DzMN%xN=6Ootr#(9)9Oerscm*$MYz zk~8xmeVOZyH21uW)VSEB!k~E7`#VwkJ}<+K3E*)7lO|V)N}}{)&S6tggX`A9P|JZ4 z9MEi!FC`&1E-5>|xKwW^GCw0JE-9_tjGacFg(P9Y4WX${X#57^=UuTrsX~BKG>g@7 ziPEr3mdLc%2(E0BKX~Ab22xX4m>6iSZ-5MzS+X1?3luZ=of<VgTaNtoDANoUYpxbc z5FLw{KXY_wPdTCy$C4F5%>}J#hx$4js|(W;6Em_9*r}>TNJsQ%N!fw<OZ;{~e{OB> z>#0xr;9sKrY{x(N{;vJ+zxdM^4yJcYa=HnZ7zESulhakQ)alKtLU-SL_ovVOV%L|K z<5B74D@Uy&cm)A0PG|*iV?!u_hOYjatZRq&zy89jyKe-*VkcW`L%k+H&IGL#zD@*- zrYwJ={$hh)1-A4(Gx#NjIjG&R8RN8o7uX5N8X}+Tt|_nWVZ(Wcu&vm1-mGhsS@TGx zlV)ugl)yYa1_gyMBwLV85=JpC76=wIm}M)J#h@B9I@sV?k+7sTNA&I^`9n*K(^8Q_ z01xsK01u6h&rEe!W+o;iCL$%eX#^gu!GXTs!I5z(Kph(%=<Dw8?fw7r_McI9U0He{ zh^1bmrCu|$X1aTROi#~R({dxJq*iHl%e2&`YDv|VDwnEcW->GBnV<m)kOU1#cn~Dv zy&*gTK){6e-h1=H$BP&Kh4<bY1b)r8zkSYq_XQq+0Kl3{5H{kSd(PS4_NH%Od~U8c z{nFiaJ+JK0Yqw0sVYyiG;wGUdKp442(oF=DVdRmwg)d#E?3zCd!7BSPex1c(bPI`z zj7!VO0ix*dMxjc6ZbnjEe0p&MrmQRubawWQ$%jHUK@koHkq9Z%Ylf3#8$D<R$`3-T z4dQ+t8W@HIndz#@PKb_6PRl6}0W5{7vRY<RTx>#SMTh3{!Rsx70PzM&FLhdv5MRvX zWOHiMBGbJ^UW`17Z~NGN^DwYyadOTK_!=8KMrTAwfV?<z!c>qN8LTR`$?%{cRwN65 zr_kjuPKa3ZEnWRQY{rMgBcM?Wgr#x(U=K>WYqBG6-;GSmMnm%|B)m7bO7b(auP_G7 zkMfm{j?V6$p4x~{{(HgirhmP8$Br$(-*zIcUE~w0JIx-0_NjkK$`=2hsAxU+zkK7Z z_rE%PHKC*oZF;H*V8N{eV6Pa#3gE0;#}9n={yW=FWWzdJ8}e1xcg^U1>VOVwk~(e$ zBaMwg2CJM8<1_e07^yfZXrroMhDt6AyUAwNh;tiUvwlxmP0ut8E^sA>TqPe*?~|7; zbS$8it;&{#o3jCy2K2?t3iyI#q;UdiRdbJkY=dE;9eyt<MZutk>db>(N3sVN7N<vt z1{J%2F8;^Q{X>{uIo)5K5g!vBgXHnHktvu$eZAd%5YCYGj7h*wnx0!&do-SZ`A(}_ z_C8!(k`cK)5+gOyt%`Cdu+dE-0wm-jJ)VeQ%;m)Uu`@d6#E`D#fxwaC-i0Mqpy&D; zic{mFk!e?0h?tciN+1j^Iz2f)KDDG~a0R|-NQZ$j*cQkSg;-%uG~9AL2}G?PuFj5+ zjL(pdNgiwn#bIHrzjp`%WU8YwFDW`UDHGz}tcJ?AlA^qf)cELxobt9YIm<Ql6%#uK zwg?p&N&RPeCX+c?pk(+|V2jQMmErPH_1NxQ`b$fXvqul7dYT%%ox|c^N0ynKh@6jT zS;h|5->4vVfJ_jZ)GZreT9>QE-gqK|EpoNP7O*Y;^gd)q`a8XOk=JfUBxmFmK`0`0 z1WDM|A^7dae{G$T2i@E2uf6le|3%>Y-~8#;ou6;{V8@k08Kr;@3+{b7TXU{g5_G3V zhv4d8^<8@RmEUas{QJu>1p?smAPGz(SO823T;s{Qb9~=to8S8Aa4P%U!P8RTO=$?9 z;$u$`c!^kaV>3Sqd^PY&ok#3UYPrOT=Ia~33?;Xl-%tBJrFA`X@OdIaU~Uk<ICRV3 zIe!H4iKx;)n^I6|j3iF}5vd#*h71O#q&!r#Q{ntdHTcgmK^!LE3OUV4O?a^LNTvXI z3~4qFfKhKUIMhEhG(I~$RG%9k9T63qUe%3K?xBI+?j9g`U>M<j2|A2`Pfstbt&Zki z2x|&p;NglShe0P+?n+;UC{7L^)~#-m{93*zekgz`ckzWPf*p~h28oIF&-ZxHN<20( zH7l<O;FTd$@^eLbDUwH065~^ID$&7rWz65w)&nLa#@_^_pvYiRT10V$M{#Zhls7OX z#}E?0YqKMLy`zHP`n-&I)SzbMNMTHcl*E+F&$5~zIJ>|*LdGHp29rbn15Oh9i*&DG zo0A{_D~}?RmTl@5T>{F;WTS!5at6Oa#1Bn%8hsr@vuM=4gb<my#{|Q)l&nL`y0#2z zO_Yghw4+SZAm&eWZ820F=#U3qCuo*`5cRpg-REuXA02KhhzY+JpORZ#S=|6vFz}1U z4IPla68`OIZR_mqZ}(jO6^g$%ZTjE7I&)&@hac>_TTA}{Ue^kvAUVt(3O^NB&RAb} z-}wAk-rk@6@h>)icHmr8Ua0^WPAsEBs}l=}BhAg;22Z7@tiqFi>+s%BH^1}QnF3a_ z%=9%v1~YJJol1}6SiPZ)6v<BlVye!Xq^AfLKao(bK1LABUmI0lrhk|yj<mX{Dy{9E zgBdN~<fv1^vQz+z{K3bF0VQ(S0Wbk7DL)b?5f_wB%;4-PdKH5J40&w`181fNrjfwA z9RMrc;V0U_L#QZ21DBDO;^e5P=)}B+KCt9L0JyumufMmqzrSywZvYSE^z_ndf9APs zbw+)GmkxRNLSZ5_ZLXEEXN_8+8{35ZJX*n4Q=pDvOkfATVhoG%Z~PpO=KKZmago4p zUOwhLvP=c3UnniFEGt9Lm6Z6nl(Z5*G~dbI)|U3Z5e%^h8<UW!=q*|!w1Ro%UEbRI z_F;y*LiFZXoE+#LkW9S^PfBbeDksxrwF;zuV>T=@k!p0cwD_2W<ZMsB`kH`XCKrnc z2ESv&8`+?6E2Bd58fX#maLkokYH>7a`6BDf!wbvDuTJ)~2!a<d@z69Pl?a5KvN3~= z45n#JyvolSDRz|U;CxGMi>GuXKN%q{Tve32k)DpG#+Du^rptrX>5=#2P(NDT&;bov z{8wmv=7;(W^A`<Rx>|D1V3_-+O@I51%L(BJw{ANe->&+S^eA(4<AAB4rkz9v7A64T zv6;Ta?LYgA_jY`__vF1C)JwoqRoei4-Fl(L3KlOk5~77+Ctv>In@>Lc<cEkx1}Gm+ z_j#=h79H9s$o4k|v<hAm(r^Gy?O8QwmAinOSSixjh2AH}{R<EG$}BE<#^zs7`zuQu zVYErEy0f)_Ma1j2_bnGs=_~A8G%}qBs&<z&B}3OScu$zR09%+koA!IBIVs<5%}J=x zg14E-T}NO8BUYjv7%YPEn}LC0l=V;et1@GwVv-75#-=gHN>u2czP`TRo*sd6FOWPq zG%>$0kaqS;jkdqR4&f1?*)9^;I+cy2QU8V6C~RQXKvIe@RZ2?cL_Z|!vtOn)2sZvZ z<IRY;8y%Ab{7R;~Byysu9-eA}aEWBe#>Ylyb>M(8jk~G2t$!2<5~(L~Bva(Ky0$#o zSzlG#HiYWK5JvFYOuxT#fJ0%+uv%O~YBp9A>}nHEnd@9tSy57$n~v4)#}@S|<Hs;` zw44zHixZc1P{t!cZ-jAT39FV}26pIp2AJ1Emz^?yljcGwtWEW{G&XlnEUk%KSBkC3 zBQ1oDhGF%%fG$n1v^&{DVCr<#(lih1`c}sl?hk8Ye5kv%v9YyRdMbfbnscKbM5h*1 zd0SdrS`hdZ_f;pPF+9=T{;s-&UH@9}`#*e=RGf6?%g@hb4X8#2W}}iU@L1U<$W@2T z;_SrG@Z{`J!RfERzk1{3fn#B*xdnyA6_EEn<X}l0m|iT212=i=Yrsb<%Hq%O|LU_Z z58bauOBt>-*WXm#z$T13p~GU;W$n6UvdNZFrvmXS`4u)0!kHeRN!ooTjb5Ce$c!K9 z@U`_hy+EcrD#|;ssP;29-bd>=wtJV$mLGEQB8ut65@?E9CuZ;j`}~Rk7P4UkLx2Iv zEpQkAm+%L})k!3j!1GbYi6v1a<HB-aJPHePx({PUqhgaQ{L{0@W*-=U*Qy`?^>*Ru z>FMg}L%!AQTz|&dt7d|?RL`z1TL5xH+?j|Q-lF~_&nCiGd$7XfAWlv2iyj4a%bN)Y zdP$Gw>tZfnzZaL7k%dY#07_D@y?D@301&PzFUikMPmQ~MC%X*@UK{H|!Hj=!e0COk z+%hhMtB5ZCaBiU8*W5c1a^U;oC|dGylJt1#ol9X{4ctPiCJ_VWY7hf8Rpn)caAhTg z-@2c#2wqv3qxV)^Ky+Ri?!=BDJbe>LQeDkN33=^~JDOx*EDxn8a4+tCZEmomrF~#Z z!gZ@uaYT()AZtGsHG}CLQ5Ojwy6@DHWkGF_Y8v8ce@pFDYxHX|YQ_h<d<_jPy%Q#K zH`kIKb3Zz*xK@B9=C9xv`g41GcXwO${g3}Yg5Q6zH`|wYW$&&Fr6#<_X>-m7gZ8Nr za2i;v%kz*#bJPBcqWbolxO2yDB&4GhSTeE1Wd;Q6gT`CUzJ^-l{gs#H+&lX9SG!Ng z*W0=<L<<JJHI1fqH>17*ysGork;+B}OA(4IHm%G=J;mxKq=wJ?;B`s*&+=${Rhb82 zXX`f^uP<#J!}TMQXg@1>!{)LT+d}x_BNK|yAs(6qZF1lk@&qbGU1ao8!boK1@_jrl zT}J)6NTocMJF<i@lBBL%M>O48{e#0}DC!^c6(q&RXI2l)AzKTMXHlDh;C{$pfpAw( z|KRw{LT|>ID>X`F_@6;D$pp8hIGO;e6svpWi)@0HAb}8N&-DN4KhkEl6+Cn%TF=2k z{ryu%evC`W%+3?}D|kXfHOX`L0af+2Rb{1xIT@*UFWu5KzL{=cZC!Ks@FeE7p$E0} z*pM_dyye5$k)hG4Q21S$=xOnFk}O6`ZXG=xk&>A!t9j6O1pV763s4usls>K&arJyy zz6{R8r%EoRU>M##;#YENcvp@Ha<<6dki>M`K@WFr47SBZCx36OtD|RlPF`QLuLZ*@ zh>2&L*AZ~1Xn09}UYDw+8JI@;Qh~PkrNeD{ysyJo-_Y70=sGpmRu~@<pIz1jlNWa{ z$&<*O6!%qY#r3!UZ-U={c`&!JJmTng*GkQ#LX+I&Y>lkSwPTVZTgJe#4k0rIQMTxf zy>dA+IUPR#iYl;7xnGE3z!#a6g5MgPdvQV1rTx3UyPVNs8x6|&&kr`&G-_^zO^;$W zp9)(?bvA~tc%B_{RA#FDm5QUBC!s?bOxc2H*V@|Bkguem7%?kbOFrLHRxk4s87*@j zyGiGEZKRmsmMltsI;+;1eJgP!Fn(dV3|Lq_#T9pDvatzEYv6n-N;0t|4lE)Zg(xz@ z%IeZ16Elko<G#Y=*!b+4fw=_(U=hQR!9C^yfad|=(^mssClPu>CL=33B<+i|X!2Y% z&(x6aCJz2IB3a<ed@*JkYPy&bFuvJ3{${Ju3*_V-q;Cp)t`R`VrD~~)RH_K33i7jK zuAI4+Ow(v(xCOlieExxnsRi_3*Z$Zl%xyxr{>eVe6Wz^?t^GvyP~o+MKU_`1YDJ}} zi)kP&nFkP-)ygs7IpzAP<JU4ed7%&IC3}<Un~Gm!4cJslrV3zN%&4^4t;VflB!s31 zJ9)2SuLYds<Njv<sL(6|&v*!2lkw%aq+KG|k;5v3`LiR9X&Q@Q)|v-X`5;rfXQ#$` zQCH+`9~5R`pT%Ae#%1MJHnoZV)zuDN8d&b>ZO=a=Gwe2P`q_ot+T!TTS7K`Hq)}6f zqwyN|BVJ)mjS#WM@&Xi_)3f?$u0HAReWV{`7nYSvp$y{Afjh>jSC$pyj>AvxKNfDM zF-fyP`QAk$*w(!TNXWsjy0178L}i50pEZ0WdM<^X<_9Xq6miOVz-pF8TdT@F%|rUG zcxJpM4I+VUqNtNS64)Yn7Vcb9vW&w_65C}Vtwa(fTG&2(!h&DXs?byh3cQG2=`XJT z*#>g59WK8}0Ix31Xd#NL%_#jaGmG;h-h8w_Ksz01;^U(bzL3Fya9@89AdDZq1H+T^ z3;kJVuekxtp=(;UXW*-uE^=xna*p3^V)s?yadJp}KkWi%^0jOdjg!1KUUqB$XS>eE z=H(X_l$HTe)USj&3oRkUk4hB`eJn1>xOw`-kFg#W@y_;m>!69Xbq`I>$(Wd6yaxRV zjSYson;V+C#`)JB85j2KJaRuz>SD?eKM{wDSY#-=K@kq5Fk}Io(RsOd&+I>NE=hZg zE-%c8|5l9{gI|q)quNS-sLbI^96cMirl(TEX3%Tp3H~DR(i2S;HJ#G4K)kyYz|y!t z%E9H<Rc$s&T5MnGGyt%*hZep9S+vA+aLutCRHcF6Y2dfM*6UwCfM}#4CpE38rn#*P zf!|gXFChD>za@DO&ENm}wL68Cxk-1zbNyC01xUc`)c`3Fr`5mL(Nie4Qe9)ZAuBF6 z9^OIJ#h@F9)v|EG^<LBi!%oUhPq=pGbY#_pxj(7i=C?vV)-+fI^JLwe!~S0JD^-2c zhe2+{D$mSX*F+18V->)fk_Az+Iy2bS);Tz1_qftqRnj5`gEV2Hj^~iP^Bc2YBc5q& zTfLf!lg-6~-X?iiVi~FJq{=(rP<qMO{W#@>E0Md8=8Q-&0}7FJ+6DqrqDqfIp`M&s zob9j6Nkk4#xqotgc5+l&A{hktQ3fNXG(5hrG?;njYM|>R3qL4-P33|~h|!ureF@>d zoAB<`CTNq}HbAU+c1T;3-t?MA3a{?@=%ant5&kWNNQ6ZSM710H2$e9czJ_|V_$e<h z%8R~m_{f?2CA3Tt5^nawR`$UqJ&mz#%a4~Y$frxXQ)eqw<PJ`gd9>ObcXH>KyU#@< z_e$$xkd_-*tsUf42Wzafw5&At(!m|O&m=eT8j;XJ02}<8BmiR<s8T}a#&d9?*TJzS z-kN+rAqwk%m$&LEOwO(E*I)?{%nB&+@jAM+%3S-C)-E{)v6ekJGFW?RDWoSS*{fDM zBhF5Z^r0h?ulw;Ko>Q%*nYl>jknZ2YH9LBGn&Q9sdxGEp*Vc$qPexp1Qnl^gDLIXf zE@60;(Jr*)PMMce-nzO7vx5`rCR$1|<D)VDvZ$o83hi{*j{^_<93J2|FC#56;@Z`O z2HTm6*^^p*vNY0C*VM~+FpDRG1;7216~JoDQ8C4Djo+U`0obOB&L-u)H2Ro|zl!cv zGmZtkI8<L+#U7c`xXLINOu}}ESngZ0MOY?5{gbjvOj;3N^kRtS3<(UqjrgU(YmlqC zoGz}wbrciJQG1W%4X>`u0l=(7l8PkzjDp&y{GQAtBu5mtj3M+qHZ&|Yu$agezXJm! zlZz|E8RxGz8fGXLfZR}0C^JyymJCG(Zc#LA6f@Aj$6^b%9uToa*lXFcsUR^QJXmn) zs}J7&<nY~GWZ8*_((6TuDD!lf=Ps2h4Yj~;SxIU9)#C>b91qLw6i?Lh<Zz!~lHk3~ zojnpABaD~D@{*}WV8Sy~qXRwdtx(lEdWWagJy0KcX#2<8_uWV<LHd=}#Rz_7HHl}4 zKeVB~2CJ2orr$ZdWBcwiN>D3v(@bcUdk83Ba%*e@qE{j3VQW%@3*AgFA<Of$NrZE> zgQfRxL>9CR&GG&O!Ay;2A+kZSVA*kFxqiovc=81L@~}ItCT;0&A$+0LO^+a81v6qM zM0(3YPi+at(>MB%j0J6^qpdppz5iD5`_K2r7w4x&rxdgWdQ$S`P3Mt7DW5GdFwH8o z%8$VSKx2Fgc|nkJ{_@<o$oPz0^yHxLA1$$@DHZ|&NZ83tO^l0($kb9NexvglIFymr zI&Uv?vgnI;KTZIc;>7|t;Cc!~0O0(kf5xQG(@iZ`C~qocX;ywX-CbW%-Dy4Fx;0a) zXcS2D7B!2Mofr}@jv#2CieS;ArIU-4C#mNb%aL!GUgpXk^s$=cO4OdC(i00Ub({fN z7Qf>Y(~D?lSCW~GROrISA-JJ25(mMmfuVsxBt;{b)C+}rcyxMkWib1k8^EyVwf&RR z<4cSjEtj^1UHC0q>R4Zufx1aR*Hhs4SmK?nxbnqYZ~p$v;}Q9iyCIb-(tykOCk0qA zhZ!S88hrY#(?|C1{qAZuN5`!!z=huDZ)rpm<0e$V`QbqCfg#`DFB(N(kG}&wyc+6# z?Y+Yj^ICPW;=Om^qYpm*=HTsoN!^guFnz$an$)JUE(WXRMx5TW{nKwwC$+O%u_#20 zIZKajQ*tDiPqC}W6ux0^n>QRd9OuwX!8u}@&KV38-~aLAjrh_wgW!j&5}aW0&GAW_ z1TDf*Gd!$QTFRIVhWU&55Q%7;uZ3h*kj~s#PkW=Ub0|dHaskCib6IgwaV1I$Q4ri% zboJH$O7Q!ij%1eQ$3~>q1e#~F3x_F^SNIz0bBcr<7Hz8Z)>daH#*nFkWflh-Ak86z zG5iD3cLA|P?r_{iIS?rc@o6QJX07<uPqxipmxo*Gyb`>A9Kkk$L(vrEf!40TCLfDa zo>hes=}SM7QDe<;cwKpQ93JU9zvf^oxvqPda%}{%IRL60>W!lE4lPQe!;(J9pep%3 z?Oo%^RjQ#JG|WLNu9Qrp_a4hbM-J#Nwi}0b)ftv9{xE^Zym_g~DM`t>wf$4`Gh=4p z6@I~VXA#E3gQH_JORJ+<7j6bmUNCI~6oA^tQyx=htvi*LI($zRPEO}9(zf<Oah3Y@ zB^`M4H}8D7_k27nRiIh{QYwFq3<jjUb?7aC3(pC^c;ed~Uws=^D_k0q7S+MiBLm$q z+|XPJ<*ewa=!MPfMPp+L4B?YHx`!qf9Cz7Z>i3&}_tq!-j@|>i;A*0;yH{(GwEEf_ z`PYJ&3kSd4wsp^qO8U(fB{o3T%`7~eJjE}0uQYMdq<Z-!&^$s8$?jM>jq|Xykzt@I z@j&r|D;F-`e1NXVL-a0TV+<||fUPD?yI7M?HMC?KX}KV68}lfB<!45b;Z<2)o|{0h zs-ss1#krq=_h7oSsyHvdqypUxE0T`>OyK*s{`x|GWp2!a)Y?EyNBXyE!;2?8{1?Tz z<EBKC1XBBihtBskWS}-BGrO?3T=L&4D=YCc-2Qp#2#cf_)D2j+<}_`!rQJ&-t@Ta4 zru;le1_$fYf*@;OiXLcV@Z!hP{0ZKnhCvm=TF7Qy63gQ)m1Xt4wi^il+HTg8y9G4` zlH4boJX>taC(3G4Q3xR_NdxTTqW&ths8Ria4S?jRY+De=5gWbtXu$-U+D##QPP?qI zH5NNGpf&WuU~P6H0GyiT@sG{UOdwx`LnierU?~qHD;l{F6M2_zH3!`{?`3_R9{+4` ziC@?giw1#;CV4^qHtnBjzSewhZ`3!xd-d&)4_r(t0f41ar9lf+oJ4npRFyF7oQNx@ zzuU3x>$3&okCNF%w96M~B^|V<vqPo`AcqL;oRCW7_xBErVj`oPWLs`;f9;oVfBx;s z2LLegy%0k}Fk{_ns4YiGva+%;21!95f3V|n$%I_tlBhwZFN)SO8y2c!i0qUAwZt8u za?{|&NEYok;LyupS=5yuuiv?IH#)7PWz>|CBkPTdpOiRR;A(b<1VZpP2EW9t))E^p zwMLIs;THJL%_GpZvN${3)7~XD96|6EntNz+S!a8z^3yW13ySknj{OCbpEutxsm_VJ zpU@C!2yI%unJqqHHiOg7#)%WI%uY|vQVUw@tIxt@q>TJRm_$f**NT<G+_Z$)xSaA< zO)nu6Q)rO3^siP%+v=ONN@$%H?T#lI7nTWr&<kxm&J5AAQpjY}I7YAudg(gzLq3nE zX~^les<ZAK<T`vy#TFG`Yaq$c4+dK_N{(ofwkec$?2K8_!4?p_NWQb}f8@-Zt9cl^ z4*-S-UsPzq*S5w&mhv>{K&BF=q^G22l(mk{3xK6XlK3j&?2zCg+CfMz(`@n8@Xp{X z59ujV#zD@DA4US}G*k{aV;3r;ce^Wg<-0~x_PzDHcegzoz#io3<N?4x?AZ3j={$I% z#a}B0NL(8zmTC!cw%S5FgtAPkL|_ZeH@3a{t2aOWP63R%n8yJOHx>b0UReMD@BDPj zuCN+jrgX$4faxINJ;+bwy)0tG4G_OZ2B}SByBY?!AQoO`p23pXTVeO&qNAhGMxnIT z$Y3VTu)t8zN^^?9WhMfRI4wN1zAOnAOQgv5w=};6jOWF@w=y^8Z)+P|Z~dw>+#cd0 z$RZ{tDI+K5>wg0L{@riV>#I|5-Arh-Mk(7Z>lTe-X{gzyVCt4#ByYfnS@ST;@Q20T zN|eGSW#<(LfF<F*7){+%k-VBy<qzoh&cr_wmVU_Ucx$~^JMjl2*rY+zjY<_(Ww6Pp zQMlU4@H%hX<kT2j$Ru-ck=cH4Wlh_JqX;~vK<l3E5Dwj}w)S_w6qIOAHj}b7n83{5 zRPA0#hfQh0JgJJ=9#9VV(($4IFuO=d9V<}G7PI3M(iyt5G(9CPJuNl8plKKh#S$$Z zn*^^$%pF<P;%OzfT&}zoZBplgVI2BTl*3e^O{SGG^u^<$_v-5MZ9ihA=-7L2ytDPd z#dwjxGS|{dU^<m394UbXz&YWUPJZ{*=igkE{>=|n{RvfZ^u)LAi2UY_U%kF<?{Nd* zfCP3{YZspx750LdO9#K%wq^eVR%A&7XUzuH*d6g}YRZjYjuu6Le1pd$k^0Sxxon7$ zis)P6QAug(=?RhdqtiXD!>07c`l9KOrY)=m;hIdOcy`QSidqN1TKq6aZw>MLaDJ@U z=c$wO9`~~*v;=Kk{IK%(ivzVO5mCv7+2{Y$f3@ikzDX>}kGyz3rryb^kn%2zRi*3D z(~%r}<IC-)SLY`ogJqd{e?BVVQjoJF@)rfd#d#P`7#){d<BW+EV!@f}<OH|EH_=}2 z)jnB42-e&LtspdZC~aH@cx;xSIYB7{GJVv<IHnC8=soagx~rz5#+biYhANdldU6iS zGW|hRwKO&ZowWJ@z_>MOiX|#E-DXS`zz<>eRM`MutI^1(1d{h3#_v5|C|xO?(JBIC z;uoD!7Z-<pMX3Vd^wgZ%e%!T0i_w=-6L(Nf2nBiyo!%eKmE4ZCT~?okV0T|=<7`v$ z<fuXpo3Z?KNd((c$+0(o`{su`PDKO2C8k@0%Zb%2IUQ=1mX~MVIe&EDj<1hKw%}V= z;U)lvmmLH5S+9tHA1^rd(HpOSxbtYZv4I)0Y9p&qKeRZpu$nrt&g}bY%X?qnZN^#5 zqo9+C-EtAy@5xxa#tbr?)OF+5TA=pfCIZ)sPSzxZhsUPp<mKdKCPzlb<kWT!i^EoQ z3d!jJGc@%orub5Gvj|OQ6%n;E=Z&5%Q^92ME47-)4S2XX-rH1^p4kvISwY;cBzy75 zX$s%UNJD;hMMr<`u0Q#sZQ&`gmye%~Y7FE=$rc>|KTg!n7F9$UtyAVj%4a{sq^=nv zc&afi^2V*Gw7il^DA4G-l93Q`Cp@vj^pYcN$nCW`Qc!QC8GmETKnNLZU=s{r&4e~i zEQuXSv4QyHtrMCtS@l}02m0ZZzq+z6@FHsMxVEaMqQY2J5rc5*nGS%L7EvS5Sdw-l zX8c)a@QL$_RrN+OHQ(>%?;P-52noC}Yg!kwFAv9P$aJLHf!gepl=Pge)YQz%Zqx*z z0(fF_W^%C8*W8HM96O7)_l{0<XI;A6u>n{Z&Lr{|``V;IIN^%wbXHr&Fl#4gYISO4 zU~+lMAF=(fU)}uCmp_DO%ecCV8U*+em{oyjB0JU#U7UFJ)OY*7Jsn*mP8AM2gJU2N zQ4am8hPCKF_GX^?V)KXF58g;qpLcbgc4yM|YK&UJaV=ixlH$}`Cw6}M!EfI|NN#a% zY@mM_)(0!7B)V<!EBBzoJM4wZ4I4Ep*w+){^`;wBBO>E6bI}APKR+iqCMq$vx?@y5 zStw;=Pd$)<Ri#;`MCofwMH~nRv}qe7h6J9+J>az#M|-@*iFd*?f-h6&QA?{;5k%yJ zYjeZB6AQE6+k1DNy?XwKZ_g&TIW7bhG}eJ-X&Ch9czBf1ou8GudGCr~*um7IryG*5 zpZzgBDj^w$Tte*qo7b;gi!BSdubeePG-X)oY4TYuT9lyRIwU6(ON6WJi*70=70JUC zeJv*l^ggCKrCwRYs%kvGVTaEtPJ{Qy%~*ykrjR9X`jX{9#RN7foLG@l_)G-Yh-Zm4 z8fTIYH&aE!MIUkdj^$4{!_5S}lG+XgBc!~rIMr2=nUt1~_Ax1G#V~^Br=@^@cAzmI zeeTlI(lawrBU@fk=dHYd_;}`k`-1~(OroJuqc3<gr?M-|2bP8t5-+Ap)?A}G2Qv&6 z`uTW|zkjs9_{3Yk{&?q(?cZKWE+{HSnk?e`C>BLzM=Mn%GK=IW#(@i?&mR8%hs&ux zajHC&p`Q%t2!zQ)l#!TsB=<I^w@VEh&bz$((@%DuOF<l1=1<gl;l*-Rlc=-k>sYP0 zF#6IDd-m=9@U5M(?bEZP{e7cIP7_l`L)<EVHL9lYHM}&~L94n^(Cq{cbfGCdDk>$v z)KgViSL3ND&Pl~+$lA`aS@sfGg^q#kX=<$$ya<q4h2~(`=+f(DuSS~iwjzF4=EuA0 z3X<+#L$^ML-|Qo=Obk#=A%t%JVYV~>=7n=7_wCqq-WDIpdFu=>yB|x!&bIj%K^}Mt zDdUtUg6Gi+lQMX^F8=JXLuW2rymIBr`7=j;IDRpzjMcxqK@vA_GuUxp{=MJVGRTBS z;XgK+Qxl~$TT0AKQ35T1rHG$aFk5P9>kJIac4|vRDDv~>2bwCYI-CJ#jyEF+!SZfK zRPkbswm?d!2&QGlXcEW51Hp1VY(hyHtidrde$JKVxba{bS&IjNbvhxZi<<eOfUs!L z^Al|)=;&Tn<;hJ;$!i#Zs*XNci!=WG2RE+W4v&gWNCb#;^UEvpuI=7+DN{;=d>yFk zbe9P9XIwpYVE6G1rZu{7BNAB1Tsn-Bz^O}-rJ8M9n{{<=6vfG%1()~#a4+V^ef!Ve z&(4!fEOtCY$0Ql9B@IsDBt|AyCCW$(Gw+-{a_nZV)D%MZ*3Js#7S@NL@fl+}DUdAx zbjWt3B<$c9JB~-^6&9CzWHoRK*J{l^Bo;6&H|zH4W2eGnt{=aY(=)d?If4>t(V*#! z;NUjB3E7(5ox10hhq)eZoaC$gC4e9Np(8gjCEFt#maOlFhKl06jLcFD9cAtzWiY+b zPJN*&&<=(J2C*rS!Y`UDMim?Mj1EI{qg{1*Ne}MczJ4RB)Wvaa0GEza<`}53ovcl| zcJ|Z{-+Z?7viJ&JuyVE-yg`=?4&J*t4xs^l3hdyCX~u)6JmCj+e6#O|9}XVeyL<Qk zvytV_iwS<kHEA^O5aMH?wQYn57N@V)?i(B%Z?qf0re;C)Sw@i*z{t=xjx50&@jKny z2>d!8cXh@&G-NbL<JfTPRtjM=5kf<|Vu&+iQdD-yVl{N*j$Cl^n|vHyM8XvUhaJE7 z1Z?0ngpow<>Udzb#~VjB_55gKesWS?ZF^IBW^zVlpNv+)Y^0gCw3|O(4to%V@l&~Z zn7>?An}2K9_R~@6d07bCm3ZoX{{BIXfu59DME#Y|-}tNl^x9S1GRw*syo5Nh)X^r% zf;<4epz<r1EP|7Ke6Xn?tFnKj<i@enVJt?%vb9=@Bz^m(<#&tZLZj(-L2km8<LAQ* zdYF^(5QoFMED;|n8%!>R%LA(CuN=lXoyqD4M|SSHjLPF8<U%8(PpoXzr|NP(FM2b9 zS>$9SUO#gsxwf~Z%F{8uvWzZVG=ae}7<AAyG{rBs$X^VvHaeCYtbB)c)YxB@n_E)f zjK*;tGX0>bxv{>yBqz5DjVc*51zRxrev*j6XcFs<31X{9TX9U(vauSAm|*=bi}+of z8fdG_i;Ikij=CRyC*G+?kiP7~St&7?wvK4A;B2BQ^7MiIUv1sGFO2bT3t+oN1KuDl z()CpV7G{)e4mCGidj+1XX|mt8hyx$LzjfPZpKjaw>CUrpbq=Sn_zj^wubCdGkA^!s zS-WKstnIICR=)a>7|4{4#wO>P6$Tc-GosQO+t`}Fs}o%f)m~GzsJG=jL5|Y(JCtj; zY}~|kg}sYb12=_qB-YdsQQR!Njgepnb{c)d4Pfy?Ka%;tY-5IgW)#Gz<%gfSuR0Sg zrrHMlwYka3#r`R@G=&tK_N9kixp6NxB{K(tuo%5Ry`^^!d~-3iu(TvUKQ{*oF1n%M zDXQz5p7#8><K6%A?|*&K&LMH`835J-52_ME)%w5D^VKb3iDGefa=2e2ZgZs%E?-BF zF7#KEo@Y*;JBV6xlSL#J=A?$7KmVXq-Qo|Iq_%TmUUE-mg3F5OI!bckG~ysU1wm=v z8++>8lMxuxQz%pNbaWdlpTI5Z>yUU|R*;LP*f;N_i?eKL24iQWojhDZ%C)TlOos$l zvO{(P2wo4~bzDUL*k4~%T;*+U??mvr75!XMcU4zYfp&g1?ZXpuRA`Z^!i&dGBstBm zv{{x;sx*~qC*&l*5tSGRy*xkO-|Wdrh(h;<l(@*d_tKhedvEIfRC2|QC93-3Jl0(4 z$-cDbvk%|dyyu=T&<UJTYol8jBRAv*^)Hoe8tzG1YSj>t!Bf)FviZiRzx~a-@4x@v z=8t!tjhCju=37;kty5Ka6y4=H*`?aCd#tmgpJ}H8cWVYa2xdi+3&6$>wg49WMRTE< zp=CVqs0XgCZbc6c=S^Jf_AxcU2nM@N6-_FMg(3vM;u_<U(p5@apOV_7nHwe(hQ^g4 z)Zo*E3Vj@@4v@eQ!J<U7BcUkL0PxaOcX?V|3dV~LH{~TH7PgEd(y+L)Hs73n`{te4 zw5&WdghUjjwyC8m>bnCs^XnUHJsz2gR00s?W~U{^=6O3R!Vm9w`_JFF=~ym-H`v74 z6*?-=s#Ih#>je<LWfhTbCKpUr#NCaIMXg!B<hi2;*xMvVun&5r;1`7qnQ8IYFGYHc zR~%td6Oo5PYowveW5xnQwJbt}nU<Rq&z=fPNR{pZKyYmhRx?>9?J)oV|MW>jK~$xS zaA0}LOAFA;HvU0$rr?(_5@#?6M#{B|25rn8gI_x%%O&wc(04EyJRGPkDypiN&X0hv zq>{n<Zm6p&D=H{&?i`#}En0>j&{e9UL_N~XvSet<bkAa|PyUg72Ka>&5#PQ%gWd;a zImxjJ$!Qr`*~!u2QF&bf3MJH7Xrp5$7SP{!WuWxt{`X&d^XvO<fh`CC6_M+;C<E9~ zXf~!Dbz#Sl5Cj8y6ZwbV{_W;ZKl<SPk9VF=at5oLj0h^U>&=bU_%q)fIC=xV9YL_j zVDbuj(gPZ_sR=fD(DXtxa8G+n(L@EB&J68qM*>+IX{)VkchX2g(duJ+H0R;=+9`sC z^tGZ9M9QvkvL1ci#IAMHkxH#s*G(M);6eegv`SJV7?Z4|-wG<b7AM+DljG9shL@*W zic*sEnnnR&#A0TfQ}5iqmyng4UsCF+sHkpi@z=#3{x-a<y%S*^xTYKH>MDxzvNIAA zQtP`aBF-Jy^7D7@j6Z&Lkic4BXx~#kY^2A>zIu6XYKF3Aq9H3LHZ~DGUV>ey*#N zS`}{{CT^gXum}bA@e#KoD-3?uAb{l_G!)FqY1ROXKy<&uqPS&oKYxTUq8>eLPriKR zzI3ES20xnVK;&y(4D4SiB}7}hxRlfaX{kc|E@Au$`Ke~ms)7;NpmK}#o`_IH?fSd^ zYIq9kP{P;Mi58JQpBD&5DrlXjyrjU>+&wa-)rOL;Vq`ESiQ*SM{PcH$giDiZNeC}4 z(W?slb~l%0C&k0kMkkDd+|;Ohab+&MR*g3)0ARm2cIjH^&N=txM|<x(?MT(XVoV?v zug}<;^UwA!#8qp&*{HCYLZNEzsV{aOIdkmb-XmAi+nnkJHMT<Hw=L$-*0<mK{TJu* z$?(VhT{daWhF-O(z#v$I!1M*1JPy^N**ua4hz_;HP0At95BO^8I!(KgASLk`n{^ye zW=xvWp^%2wK|#uB*ouT|9G}+g68;ki{<=<;5_kemED1u1=oK4S+QGn#Tbdtk%1unl zZk$|Q@Rz10WY_o2N*VFmY-7sp+p)-yfmA|uSB<yT-w=EB`+J`Dt`4|_WsID!p+*`; zWmUI!*M*-wwC$D6;ejMs=hiksprh+7y==U1gQ4}Va{Y!C^!efi&bJn&#zn;>=M<rH za7{H*EYPD$0EOz@q8v1-ii=FF<RBNJYW6LW^ir$PI&gB#P_hm8skrH`HTCxG$e6?o zv_!^OO(~0!#jqL*kI{fDHYz2rM#F(<pE?iQg)T)?&k3E~UKHs~IH@LwuOscJQ2Ib+ zW@bT!SGr(`1q=lmCa@s5wxYDC$kW`3p-KF9$Y7Bm42Liz!UkxjTZjDC;+RG<D<D*T zezZJ0(%n>=otBc3TToC`QdWfCfYDJYbpbbxys|jsSO+HxhJ4>*d*+SHN$vJNtpXgd zNnG#^=_U^PcOH<s==JXr+=NfRJ}oA_q9P|bF0+P3dptdLdKz6V=<HT}QQvR<-LHT3 zo3}o{RK>3z!}L)?Igrs|5KJ7~EDjrqV>!Rrz!C<QWJ+}l8+CoIx4x>b+erfpTKZZ1 zO69QT?{J?)Dc?XOFbEYkurNm!9&6Ns56?wObRDHWT1#Xm7H&{fXdsw=ESc~yvmjC6 z%=pBD*11Q^y%lK*8CAVAv~?yVr64W?ek7zrVYqj5b4Pvrk?-$S1HkPqZT|N5jy7Kt zwCS>nYF}0Sy~E#a|JCMj$9M_c+NK4S!1R*nyDAfZOfBN~EKUrM%*y4i^m=lmBV&@$ zsH&nuno`!(pwV|#74kcB(i3B25;N<K@Ia>)xc8_sYBO2&%hUQ*%kEi(1sR+Z9f`i2 z8M$^f4;EutOddp5WMZjzRPGTyVUP!hPX~&m6iL-C*`01t!+7*DKkKGlbd7OAB}uVa z#WmiR_RcOp5ey4hrd^}(3M{0cys2|=N>eDL{gmc!%1?}Eij>vuThQun`BxAu%t}D) zx~sW7FDt9C2$MtW8tSS&rG+UmF?sDynxJYetl*)`1<?cf#sRO-$=^{*lMTv$inO4e zJbmBl0trI!Lt(ySeZ3RQYYSt8qjqu%iC=%xlXNY!SbP7wZJXbC^R2hveD9ku?ea9% z-l6k@%}53+eUQIa1P3y))bOzYRxO$U#yRosrh02C>-%iNO7QMN?bz*!CF4;$-+D83 zwu>|afq+q#0h>mBpG++_E-z*Lyo~inny~+P0id-!%LybRe(A)5KWt%f1}1QPYFRg0 zW)4+lB&3yhOw!{yQk4*X4*+JvlbWi!miF$Zq~nM0dOCXi=vN`rVmn)qQc+)BmK%QN zi>=21;P>x^0<Z{R;iU|Waeo%RkH4zW%Q$Kmxs7pePE2G>Qg$vH>qv)DJTOSnsW}yy zb{PfU2|ZisQX~f>38rdUm=SYwhNQHOsChk=*-6pS7~>*!F=a3suvi(?=lrbX*qEg9 zPO1fHDLXT>h-5@aV1{OdW6)`)w9f_Q60DjL;`T%R)pX(A+fjKHwe=X|+2sd<al+K1 z8!?l)y1XzSvEk;PNsY{cUy+@w9A;{fhL%)=4k*+7E3t><n-*q9x|%BT@=D4*wO|ab ztxd3ms>?FslS-VFO3DD1oRHd}(wG&Uch;lSl*q^P;5VR48(yjjzxuK0+$XFs=v<VO zF#YQBvm7hE`Rykke6aPSt=qP|_tCB}?GiKE-p&E-K(M1l+lJ7bL`Vx)6j{?KRPv&1 zJ9g!W3?D6xwby!@h65hE4c?*qjMQwSJ|n$vu@T7*q2Ge88nRUcON8$`LQPK9ItPMJ zat#2^69B_&ukL61qNSJd!s2LiaY|ff^&oC}%$t*vQq(+701sEhg-0Z0=M*A9Tw?&7 zaQtvYRaZ|33VfvFXlGlq4>F=Se9IsHkN^8uS3dvMd-q&{2D_n60I&?5Bs-;3IM|=} z7`hfG5n?6f%(fIHM8#uN07_Mm7hPG2><vi7wAkqQT#sX-Nar{BpjqbXQcN5;g%F0J zESb@!!qn)<gml!<$;2)23`{aF%FRrUjZ3RxOX#&Fs4%nQO~R7&N0@upk(w^zcE%ps zLwE*h_at1nno#J$Jd@T=8H51s2I-?fa1+|S)mK*(78DeFyxp8&tah;GbZA<U3KSDq zGQ|$YyETv0QgWV!>5<N+ilTzTGU>Y6=xs(!y`!zwTV0fvRqd({RHaV>&KMf!AlPif z@Lu7HkHgBi2iIS(yssMqE(F_KSX)G%i8?RsLaIWk_+9UI?9Kjh@26Wo{rsC<yLNs3 z>6Wc~Z)%&E(e}<UMwJ5@$SQxOR|YL$wqI1!Lp*yLMq(<AoFbEO*XD=Xs;gQjLZUXL z#-Udd^z{b5WK!y97QX_ShbE7R!%X^0sfJBEf!KJGvn+A{u{^xeBI*=O{74XtVk2x~ zpfM*YDc3uOSD2QJj@$<Jnpqnvjt-AVLN%E*Y9xUBnvzZ(eo)ih<42UT69XqZ0AO!h zOYy1yZPTWIvg_u-S3}#tl8|bQM2+$5W>tp{rE#rHkB!d~!E-G|iIG~Wf<dy#l$AE? zs8mVH^z>Mkjo>IIpmR`(wD)C#DUQX2t5gE7JKhkUXne&~OJQ<MOnhc876Y%qY8Z}` zm7I`}?O}9m4ef@eXQkLqtVAg7=tinE5s<+0kLsXvKkG}bT>m!QEDaY&vcvD^RMnz( z8EIgg<cYJD+?8fD%!LfDC@;v*FRAyBDV0k!$r`}~uYs_bbsW;89%%8DYf=JquOWY9 zc|iff`872S$i$(ay&dgI>WXsmjdxx4$Q+bq$s9s=UXU7<X!{V|>O)?y<UM7JcwhH{ zSbIj5X(a_@ruL56%rBvNYEjI)Tz8a@mfKS=9Qb<op>tPm-o&Wc?{|Os#kaR=`Ih2~ z4o0xko5Kui<}c2136$7Wg-&7iU|O9X^m%I9&HS`rveER)_3vW|cwKCm0@!2?X%2*G z=Od{#F1~N9N&)X<ry5ub0HzHr01hBn(y*3hyP-EH6}5@(JKs~4o}B4n!_L*-!pPhA zlEnnBs;H@}uJyI|0Ki8Sz-<P==(y6>R(2BAW`Fl$%!N1JyA#TZ1shljb&Y;t-|A^H zX=MtH>uJ!;qQQG~Tv{$tEGnx6RTz_y@ZfGzc>ups=mFhPas?$TDp;SD6St<?GZnn4 z=DgUuk<g;qOCI@?5^PS0Nh;|QX0e7&l#}y9AmS&%l3*E92X4!djB4S+uS<43VeJK9 za@hS!P@g|HsmRj^$CcDlV3;S==vHKOdQo}>9j8tbS29uF-YHXHh+tI*nSLMuw!Z;K zrZA?7C-sx0Y?SX0bvKsg!6E6Xs;jG$7(x?9r(mW<TT^XuUWInc<tI}pu#3dvf_P{H z^<5^}k6PZdOoSldt>3)$(FmK>e_NUu=<Ww<(7FKmCNvH;mFY3=JLOHie)jaa+i}U6 z*}1t{8PT^cqeJ}N8fv_w9sV(62OBk71hDOxB^j?S0E<0}(mS0F3mTP^TAl3mR@VpI zS9&ItGr_=JZ<X`tTwh}LMVc_R;f&2Ks>l}!ESqG;o(MN({9GiIc9^jLSkZ(4n6V=h zM}h>NTV9;(C`rLkvu@!zOGCBUNg1W>0_N4;{D|98$>?=b?y0D$A%GhbPaTP@^P@M7 z%-H~$fdYIT-BsuQ(WXs*c-?#Tt1ThD(Arm2^`Uj@RPd<;{sdq2xcY1+t7C75-NK7N zuf@Ffyp+gWH?Bn#5mMYPT`uAs5EYt=2{jX%AEL7d&ee$gC#{LUpKi*yb@}q$m{hEW z`40sdNiku!qI1}l>ESHqh?;~bF+w5p!Aa?hFup{Sa^NEFXR(aAs%zhD*?9{Q*2%Ky z<e~-{C<X*`9D-jA6?mg9g5jb~%&G32P}@vB#kReKW_8F<)T-4u7OPH0-y+(_b~Kjd z!xHh-ARGtuHljHRCa1Kup}}8OaZ&A%Lw(vzgj`Y2R0=hO`>N;3_#%Vc`A<2~C;XH7 zG?F*BGdD6YI{y#>b`7v-VWtfrxjtmpn|m)TJTe(GSt{UWgiE9_J?7fQn=uXioRN-h z&Y)vFm^~E?d|5U?f1@xa`CqoD-I}E>0>}oJwKVQW_SMteR~y`_lA4J`uq&E0Q6R@< z{RE@H)SfjXlU`4Q-%v{=>_18XV^*4pBhi@!4SIg0sURUCtEN{9_LoMR^Hb6aed7Y) z?t;khs8k$OxyMsy0ek`gh6DzHF><BT-v$8tduuNI<4v3Xaa2Rf*W2!5mG#disL-(0 zHM4z#2OvEG5g(MV9xZur@$~6ScOo$UG$!Kag_Fn6-pcg{=uPuX(PUqJ1L~XC_+coA z-qT-Tt|{^2kwd4h+<Fj;$t`!ouADu0C!68l75M)&^B%+jVt~x&BuS}UF`et|MLh1@ zdD5aicR%<KfAqTpDP4oLH}{;pUjlUo$zK-1;^&79Zj$ambv3ocY4LH{Rh^T%b;?PE zys1kwbBa!B$FC*7UFLZ|T%7K2Z>lXT%qy%Qe(`zI=t^v08J*HvS6NWhU;=WoJpffD zu#W69lhUcrKK~Y<gkVZFieS>j3YyJ=QNXiL{|<9;$nS$mW~wbuCOD^Mp@(Q$nG}$r zeMeSm#DjZzKAy{{ziZ5?Y*1Z-P0OXo%5>IY9vgE-C5|K#cpjM#kiTnaY}!!kDn8mM zv4;LSAwOdRv(AfwB%Ra1AQBnBsR+?nnM(Rl7!d%|3oTA86~QtYXLfOUZlFFVAt|R} zcpl%lG}%^~k(OW2m_dJ0^aBfENZ|UGj;_YU6UQQ<LU${GF>;asuDeVCw-oI@5D^l< zhMxv(o{%pYd<+lgQHe}3J63w{*#12~96NXM{OQB{zS;fVh0HFu#>WtwOoS4buw=qX zKDa6-Pc_U!9{XZb?6Ge?`)2>KbLTIfKX&Ngp)2WZVTUeG<5P-Xm3}Nn)7jn3ezy@1 z<)xu)r4Z|N-Ff|={k?y``AqcP@BZu`{qZLcDn#Z|i>3@Ff+2$eVC0lkWW`3sWmI=F zNFda&0W3}HFxU<JPLh$7_!q`{d^PBzEi$VHpM&a9ua|=dF*_7#BW=E#qRgCH*Ui~T zu#CtP79|i?*(+!2+TDiv@nd@zXsU}!d#KP?3umN^=TqVi<-QtkE=h}wj7!PR#Q<k^ z?<ht84$QrYiAyQcH2l%7u2E{y8fzBkB1N$b2)6lH>j8|Qj)X_%hMH??J4V-a3437_ z(+@2>b5hKuD~BYfqi(`DTX~=+!^x&cgj&!AU^8YzU0BOYGu>6`aY+Sj<M3u<zI2x- zHzT*2>BR#8aEy__;<#+?=xItkag+e=lu0>wI?!O*0Qet8bQE4Z82>~7t4AXAh~AKA zv^s|gZba~0)$N1Zw{8F8^Ut<@^ue~>7c;t@Z=kebTvRISq(~Y@u<`6U>3Yv~1#{l$ zLtEc}|C7(Z`s%CCKiz#HlZz3*EUZ@xm@5j$z(q)m%yvOCF4&C{_I$~=fBN_T!T<5m zx7+{Y{|OU^K8vbDFLgBVLOwK26zS&$Uo<3U1AZz^kGL0|UE8fOHdO?4{)1Z*Q;U|7 z8HNz&huiAPi*k{<?x~Tf6X@94gwZkZa!Viq_-${gDM^V<YjT-zY{Dy^K|HL(Lli-h zw2V9qVG};r8T0KabBJNh0Tvl$nIbbP9^=0c2kQ$`BJamw;A}xjksTOa0@VUV#4+h* zI=E^STD021HjR-MHAjcoIFd={kX%akw~<7bRSZq5YUrHY=-oYW$Ib`vm`pB*hPFh| zNcAUGChpO?+T}~lCx&`~B-p?j2R4&(D1t>3rwN==>YtT%JS%g9n39`YftavLU;!|l z(6#mGrQG9<cL3ZeV+&!XK?3(TT>ht!z~QZxSAWO|6$hp-Kadi)(Ys!q866s<7QI+> zYU`WtzPI_Ew_bnm>x&90edLms;f3a`VSz7AQWJr2yaLZYYu8t-)ZIVu(c5po``-KS zZ~kCUcsr?W7A=Mhex<69LHT(R7RpJLiy9N*c_?76=)0f&-GBIJAH4S;{x-T!{k<=e z8j*<A*6M48bTpo<7Sv)jqUU+Dw<<3_B0MIm+9DX!3snYld>E8z<BVp+#P*L{8fmV| z&B!V&1AZZYp*&;yuD2QZ1%SJ;8cMDjD>K5wv)yUzoNTI7=c!~!7kV}_Gud<-y~C$` zoiYQdPt&A-DpF>Wu$A~hn%Z(#c}9E$XfhL_dNaWp*#VHjaBL>V#HZx@41#;D6g8=e zM6mp){nqU{F&P?7<`8N_^n0eap{jwdpr-)o`Swi%#wY^nh9;eg=4J_%0OqHLa*H|3 zDS+4D#F7T1c0vv^5*A0A^Ah6Hss`p6E}I`~D$dR<r5BwNI3=eTV=ro}>T5Cavd5bw z0QQRn?(7AE{hcVBH30sD@TRgW*V00Szc;azL4EK~B<@iEusV(Im`u#6IP%6Tum1Ko zul)M8PtLk(%EfG8^_wIxaKbVx8Eg!Zu7T%)lb+Xd&5a%J{Q8%_`R(h!d3D>J9(nC) zjBpHi&1CYkxD#atvmn?s^0hf}`Y9V+cg=I?PyX&d`ty&zVBglizcaN3^TgVkfMCRf zA%dYp6Txs$H&qv=#)RLA&aCzu8LU*#3;}r~5xZ&&!$D%!UmR*GOo>m<K`fyP*;kO| zkiPI<wPIchCU*;dk+fM|aQAXVVCDwiUJW)8z@kFSYzaqwW(LOwxAzQ!Cr6MU(qNow zjgA5j1>m`+%%~`|E5STNnF@}KTJ(@cs;e|h$rl92B<A?I-e^aUarH5$Baqf1cBts* z#>FT2MNDT7Sqf`Q6PQEW=yG4Z#0Jf`8hy>k;D^j5k@^!vOUU@e24=pXnwC!!z>g3{ zDijGU0G_k}h7)xKCU90lTvo#fJ5R4HO?H-NXBM)WtFI_h0bCBxM<W32@A4*{v???t za4#e<I<WeCDS`jsc4Nuyn^__DZ2&Cl^Lj7zGkD#@nbH1XFq6T^5C8N(zw*0Z{`IR{ z&lQZhc%=B6(M(oNU}KTmJW7+vrnL54*RfoEbJsh+0=IbOKmPfytO>YCC&s1&Rd+@g z0)CCiw~1dGUwPJ2>;Jv>@PGOT|Mc}^r{4VUf#83*C)Ec8`-tFfi3cN=<P!w@khWT! zl@xLF_Jb5p`>1&x?P^FlY<@!svyfM|JwM<rh>M6#DXOilLG%bgWl7)we%nQV?(Raz z5lO~rEQz_H0OlZNJTS1K&{BnFF`0N47)Nk3r)O>TDe&b<i4U5Ju2`wUhD1Km2G%|m zZg1dNdDPXb_oFbvSq2JMA+E_W4vkD#FDl5(NRECG7Nt#(hdR1l2v&bIU7PH+&c+;q zC9UY6n}>^aZW!4cUP)$hJuk66b4q55#<4H?MhakRHLT7v!5L$EJ(2S#?o$AZ3M~V< zSkHhcrkcPBd99O6=tzTD*j!I_er9g1xFq}Xq9bC`EP(3;z%7pf7{hmA17A`A7u~v1 z5h6tb0H&MA$)S7(TXrAe+}O~_<gn-B2XB7%?RR_k9J*cZ3N<pLk3)rC$KWtP19B z+Pv$HujYK^vM=uR-kp2D+x`1rfA*jaeS9aKA(N)_8(D@H?5M|7<J@$cKJS7JC;s#w z{P8z;Z}0wp6TulkFp|tEgCQf~DQ<(x+tk+DRE<J}`0(pj!(xhkgC?Ux%{miO(%+zy zs_E;uGTu{{9ewXU($<iYsrZ%P5vKi0CM>c=P`KFK*51@uo|#fHfmD|2VxOtF!Y8Q> ztX6_<(RRprK86_jKve9gqe=8AmiSSRlG%RrE4TpMpLgZxsT&yKoCEw;$vDym{NNxZ zbSy*2FE1-G`p&fomBB;p-KGyLAtGE}=LuNnJ%u6N&?4@arU#lmH7znc)I82DKKE?~ zvjB%jF*QYEkMfA^3Vq2O>P84P$qitU!UEt~_^^x#+&P0rNRVI;=ZBh#GqNkh9ng~p ze?gjrk&wsHSYO}f@AIXdJQ|@+ERn#yogMAIRsi@40Q^6NHx}Fo^M(Sj786qOdV&ak zGR-eej1Kix$6N}}t*I)=tLSp8=q5<c>Qzb$W;DQCVYBcyAP=9g@@QjWUU@@R?1d{? z?HGXWOzvg2DwTFN+@*p^abcV>E>5~}95)~T*&n`gG{v+3e-H%kO7nGf!WWI1o{R^Z zXfR+`Uy5mc_pV+zbulKdX;59_CLXM6H2dd^y`pO`jdpl4B5sGrW|YBqCHixdM2{eT z;Uj|qgdhSmY4p5r^b}-xfZws4E9W9=m<=mNFo}%-HeKpXe*P1cz2~BK(t^rh0hn~G zV49&iB5{lEG?=!Ov%B`5LC=NU0t~Riz**NQLoen<SD`^#cJjS5$L=YD2cbpl+o+c) zkTN3vZZbV4p&|ghvNS)|?X9j2w0@Rv3sQqOewFLKQtevRGGvseG)b_bIkmiuoOu@C zPuh2a5*XdIfnBkJ*^C1wa8pivTn5Ghqsy_x>=(z|%CoY|I^o6Y%a6Jr=K#3&aR7G< zfZJOA{dHIVkO0oRe&03v%-IWap%DmX?TTC1-{7gN%!~|mH#MwpVXWUx6<UVDnbLM; zY{qXu<@vd2%Kb`&$9NN(GEC08=6+%q!p?=4N{B^cERrc|>c^g60ArbkAO7l(-hJRJ z*zx}ag8$h8K`_$HTM$K}BTF(?VX8LQ6lZ26+`n}4@bNq8l`Va$B?4)p;b<_4Z(~Pt z%?&h{Cf~mihAw#?ADRQ0=x<wx;8y@Fle=+${+6<c^Ji0sA5Ils-1+IZ_v*E510fG} zD@fLTz_0K^EGooZD|#I#t@ssa0y908PP4$(EjBzjy8ZKS!!q(QFj@w_dogg<JTm_k zjrWnMmX{NMZto8fEnIA<qgQ7;+GtYX(@=<_+>ZT_mX~KoJ5YSoWs84Z#cR(;Jdb@f z^To{;$wSonZD;)%L1Sxso{ER0{SJVokdQ-Sr-0Y_{+f)qgsjF9xU-NUGQYe$(^;95 zT_P<J1_~{Jt7~c-Q76-}P6BuLO0rOEHvs(40pQ#9dDreYhO~h-wDV*e_^I!{Haj*n zAZd2%9|j*p`GWc-9q8F?(6pC(83o$4&hk(n<{}4@M&v&5(MT0`<#9-WQ7yz5(x7Fz z@`Jzn^$)4FDO>-qK=A(z1S8WNE$k6Rf}z?CZ5QGg6U+;<Qlf5NICc73ayc>~yT-N4 zj^m^e`D+@YBB(jiQJa@|_vXz9N!i7<C>xUo0b>3_ZI)C`iRGi@skOViwdC5?|M)N8 z4$H~9aqzQuKRl97ceL;*!ii2S(-HVNLfp^h&q}#QJZT9sRcO&^X>;3;nDpG*zirD` z=aULBZ?>`m!7$(#<y0IPjV6a|TUJqCQkZk+yRVK!62WVOK(L0aIlIYCmun`24PC;( z`)7ta>fG*Uck#sYAvhG93IJF$ITXOAk($YCBO`nId8K@NT%A}mY)HvDlNe>cGUKmI zi%BYI9f$0lot%LydZxEFFSE!8b~IcV9hCqHTvYWG0E2^f_cs~<=U%)2L={@&56?`Y z4Ydtqy7%{vJibG+H%&;AyeR3KO5dL3!5iP+Q(g1VCb35|0|R5MO}395wE#xWi~bg- zDcPb<-J$(y1E24FNy&*%KRJ_A5&wZAIJ2>{6Rof@VX=di4V}<*I~&V$(i6fiUA_@h z;vXCF!~3A|P9{z<1zg%wE2%C__B9kG-o1AH=3O)vD{qu$M9`l_ftHU1eqjZP_T1gu zT6E#(|7Q#?``L~&$98Of{rzLvOv=*WIt~@Rq~V1&X34WjZG*e!QCSTd*QEvT#s+5C z%5f--mR$bk{dYe2_GSipI2B2sVGf|PBP4-fDfg)IRFoH|pZol)BlqczTkCD_HiJ{8 z1vy`9d45iN1F8y*^ylTJ>AvQgYG0o%-q(8Wmj<pS0@?{`B&hogL~7^;s*>#(^z2g= z08bFW3?UJ~2qLXawIYu)z1%;8W}}!R1S1$qbx~$sJ@7JI6pNfSbawSr<IF??_xMu8 z1~y@&Zjr!20M5I9@5ul*trec7?1x0~bZ<xZx&X5hfRu1ZVF8^3Qsbd%6`HVX8QY8B z#@dL#SJQgTLqD9T&{$D47DfX&soU{Hyx3~1o~vK)#Ejyo5B_T)_+KB*Y;5mrN4y6Z z>-0;L9Smx#ElZ8Rb@f_!HYbcvv^6yNwSdQF49b{0P5zk~@z)nbUp{^6(yhp(^xR5s zD;(KgxUcBIB1?dDZ|&&n>Gb6s`#&Utwdw!+&VhZOyz~CS*fz}{0*$K;Oo3?Zk_`xp z4I-HL$CsytXk0wf?@cEbIJ0@DE3SV2+8ghDhT$0)c2|mONOU@oLJ!rUb=)kJXc@JW zbz|=*pMQ6^PCj_KyRBPiKpUFFl!Zob*Ob^*M6hJ40l!UEo)%Z{x+jzzZG2bGS2~Pe z0n9Cm;zlPHek)BvwZv9l@##z><$wYhLl+=^Ii3OG>xWCDFoBT>-8Tn;B7IU9R+ec5 zSM@Eg4V7ZP)bj!O+C5Dv4}LbG&#<brdYaFF7E42&UBP8e=A+aG7C12#nnMztb8(36 z1y<B|To~vcbnEWCdkbI<u?WXd6WH_(c)`WiYHt2;_<DLt_?v$VVEVU5(|z6Tl))l| z<?**vWW?URc`LT8TW#NAUrj^jxXNI5{FJZ+&v<#dAL)?=(U*=MzYvBy%=a`PJrn*b z44QyN%^X<R*8p-~e`Dr>e@*=UcYnHd=NBJ+b}X%1bqE9CfJPgn)ja<lhPZpTjjCPW zq%DJR3~t4&(VMjQ&0oFs!B=M@?erTAj28Ub;WsU)iNx?5Po>9GeE<7TKK^KTSd9R8 zp{v>YqPe39Z~Fa+oHmiQj9ZB<gx1d$o))K&@g*-Y)TuazzEu?sfT`7N*wS+VEXmM} z0|UUwCmO0jOS-(qq50(n2<Hjv&|Q^z*`*zGt3#y;P@z#x_%sPj8`z~nhXk;cS_T08 zB6mMOKC%u-awALwz*Q{6?IFbs3SbJ00AqWR<?Qz?PmGw93HvwH*^LuRd{{Q6Rr3*^ ztqMK)ZPuD2j-R-ao*(`jBKZ5vmhLV=Fk0FJ!H}4BIWhO{L}t|59(0QXzS{Z@wSzSg z(WLY&j`_Wf9X*|%_$#MQU%4BfnNw2JgmF(&d?dkNaX+`Wc64_24)ip|@A!uT-@pAw z?|ru8^KE;tl$tQR^g&fuyG>Pj`7N&ByzyfhH!%Us{Bl~{&KGw@e)ZemY~H%-Tnq+A z%K%B4cBdnpo$*!Fp{qRAC6ULz`uN@VcHX2jb*kO#p9;vq-rP&yAHH2WOg2pHEKPJb zlvlSq_|>Gam$}8q?l<76)8Z3$5`_d7*QWw_LuBKYzzSfDc}CQ?yD}v~5}_BD*>QFX zG41*O+QRI@risO&iUdmF0D${~Rp{PsdZERMMK5%{c%ef&u`~$x+#w{_X+Zx7aW<-( zAd$oRl++}(rHe1Kpsu!RGa{VDnROseEat@7>L*t`{>2$abJB(5S5gb_y(NhHx5x5Z zU<M-|ER$Xk5w0&v3Xe$fxCU;{_4&~Gbj)apR03pi<RsM9wn1T8>B_xz{_M5;N!dj; zJ|w+L00{u@>FR2S1E@prTN|<Uzm?Vg`IeI>cYgZm!3SP*%#5|LeFU`(kyj>>@-ctQ z3#uH#b^^H^$i>oVAOS30dYy9|j{f?!-@U(W-^I9MnX-=QRWhgDnZYhS_%Xzyz8W3V zs!O6z?%ev;t8aWA#SRQ3%}oIWFLkD$-nr*m;UKLqsT5im@z+(>bWE8Ow4)Y(G5|Yv zK3#R1GAQv*t>?#vZSue~eOQmy0T?>;^bF?YOtlsv5xU$ziLQoIQ)rYWfus>%S#Eyq z@a#ZE($fLVTxi6B0bq>-=iLZv3I$+o3bY!k_r{BpJ4LXXPwK>C-mV=&Y)#S^r>@7u zg(`gXngswX)57SCVAjD)Uj1m=<wIA~%OZX&nEIoWIlgwxVQgw>Y(|k`T}ei4Qh{&6 z{aOoyP1SWBro7Pn!`fVbb9Gg-is{j^2Ny0}k4(<5^+}&R_A!&}4Y1ud<ifUA+<rq$ z?oI#4+1Pu>Kl|cDvXf<Q0IYcx8r2Ep#=O*}xxZP}OPYu5Ca;-T5=n4bq9gG;fAiXV zTlZd!m5OixSO(7o0~jiF9RXYxeQM{{H-GV8HlJgoyR`vdQ@54DYr|!C&s~gbu+Ee< zRC!ca*7vBV%l0GW%Fpr%Z}0#Djyh6}=KPv4l6J6FMPLJD^EiMZfLFu>PDqd_@RD?l zmgFokf;%em@~eBN`pS}HlOTahgH>oJ7g~!MoJ5X4xK&pWcGDXYz}nK?RkXap6L`{> zi4x?%NnA<*u%srd7uv~+dNyNwzV~31NE81wX$bKEo9J(JcD?!+WgA0D=a1aTt%`b0 zQ1$N)r+HBNSC8?G&<~4qGBEmeU8BT>eqU8x$GF??Fx}f!Ro!aU>{(Crm5X7~*_B>F zEz5tQHNpAp@91jxWu5%bG=E<WE6u#JYsdMZ$wy4A;2xPtX#o6u2llM5RsdV^v<|>) zi_=rmqoei42Y>bI??2jeIvNET!2nhjni9BH09;!ZduGSh*M9MrZ=LjT?NuV!T*p$6 zC%>@Cp4RH@U`us1#)H#k$9{{ZCgnx4=|b)_2*ARlShvnI)mjF1Vr_(41i<6Qi6vev zjDJQDX%SIiF@Z-GS1>hc5^b{JnO;U9sVLv$AL*@3#dLNV%iytIXm85#pmIXyLU#vp zp>N$N2(gn*DuETiKM8ZQTc!h3YJ*$=hD*s<IAm-aIh|+GneqyL6-B<d&8Q0DHdN-T z8D|*AbCgW3U%5Z-@QK@n^%1`oT>Y=##+Fu9SD`azaZzD@MXldbV&J<L2AZmB+XHsq z>Qr|l{sLERp81BP8`ti{7uL0RLJvp3OL(6leY>DYHzw_Z<+Ewi|NY&_s{C8u@3~a& zum_+@Yl8v+mN-5graXrbuF8!Z;<~TVj!`=0&=`p7#FAjx8k%(U4NlDUr|tQxKY8u_ z55GJTo-3UVVFSzjNHcEMjA2(BxT>}+`uLYyU;FD<KDnt$(T~958oO<Z28v@$PciAQ zBCXrohLQWtFq}5WkYxk)FE2|w0RStZ%9K$^8nJ;TU@rwe?)5~gf6^(Y>~{fJYWmSv zOQOIsQ>CP19Cg%F(yCItSP$oh8cXskTKoK!83N#909a-fG`9MC8~}r#v!I{VNCv>D zM!Iw>D<pua?f-NDwqP=RlTlfze8ahD6v@TdEXln9eFeTnZ&EhE)(YAYi)jv$I$~CI zIlW(;zFY4f*nQJe8$$&D=OamIJdvN9m6KQM^_$c{l^6EifM8E;=Y;v=>ZHG+s?P5W z6cDJjXWqYcKeMWZZGgoY28F!6yRV}<;*-BGi~NJH<H{=|PaVEi?H&W9wKHOuNYgKR zh1D^rOzOo?)eQ;*U=_g}$OMKV8Tty~`H{Z9(UHcx+g^ER_x>+F`~GHzR3TwTSA(y$ z-A0i(hOVipuD(XPc$Yjl_{ICLzxMHoY<naNy<Ttc<E>I3&h|A_*Zaq%4+mR%GZe@f zT28p+rP!1xi3(uV+6;h2(kP*_$%Re-AzOR~fb%JVC5cjW<!MY-UYTsoO^C^?>Ve#y z<){Xva;OnpSmEpJK$rLUECXOPL2H$2q~nLRBZmR7xJI0E!sd!Ar!(EXK@C}<r4BW) zpG<`|ha(O=sV~v$T>1tGVBW#TG?R_N+7O-4t~RBRfS%lhI$YcUercv%f9b0o$CC<f z|2eSrFTYF9&reTDPRaFjIbm=X?*x`v>TmGWb!*n(G8!7!c-fNB_4E`bL?#y0HA8#u z?8KyWDRb)WC=Gk#zZ3laFW;q9mL*=h5>xNW<i{EUV8nsl0Jiqp#t!WXUuEB1DV7qL zw}lq$Mm#w-@apW?$k<3r>iJU-vg1zgK5#K1zo-Q524Mtq04xK+sLg1Xd3Q+U0D{vl zee=nOAAET(GcaRsp|9z21g}nYd275~JT}UHX)9`)sssT1G8+{dCD$i_O~R3Q_BCUH zMK{(g*??9G2`odP(3O$^MmdA{n+NJLqvNvchcMD_b{zB0(4+&d>7}vG>cW!RR$qB~ ze4+s`Y_Z06e;=xmf&h$;9NJPx3i|JL<X<_E<L3T<Qvfyxqe%b`fSCr*a(=_uUgrGQ zf3G#CsX{ZQ#?+oW0N$80;+gNXT7L0^cXr;5{N|r-`a7@QEiX(6znfUlV2xi*=t00J zaOaDCjg^qWhz&0c`>JYM9&boKQk#*KSzPOFMLt)vBxrVaw-=uJ3yD^3`q`=MvaH0r zk@<Ekth}JwB_@$0Ac21p0NVo)0$&GUvSG<?6Fl*bmmqM4TdJGJmj^R196A$~fq_n# zlm!ti!)7@#x&`=c_MsvPo&U=UBaUqU<g<f!+*6N5i}t$f^aZmM{<^x>L1tf>axMZ` zwTz$Cbz;nXda+nCsbQo5fH&g8dh|$CXaIOoB`|%^sNV0ZNQp@(XdZ`iduDu8CKgJ8 zgBZcZB~|s+d1;ABnJR%XDM$e9a{vr2jOp+Oz-TM`kE8qrhrf*tk+ZxB)bNu^U|z0L z+W)@*tg0jPzF1YN01h+|*l0ZOnE-yYSp5Afue^WgyEp&CFK_qHwWi*S%x!gyI5C~p z0r=5kPhDkg`^YrL*_IX8_lHp57dnb_a*Jyknp)6y8u;yO%sl+B82$a#kNH(uF%gN? zAdbLe(*7WUrCx&-PA)V5Wt9wFCnSKSrH%oxaXBDCaAH!zJUvO5F5FGX$jU{Va!hdc zHH#sv6P(dH8xvqF%FBu~uJ7Hx<5+Y<uo}3~Q{UL*R!f#g+v@7t*q~R2@<?s41Z6o4 z{%;t-HV*tE0JinOf?omf>TG*a5*o^OOrkE502Vhi>KWz-n@US6s!Fplkxu|zX#w0L z0A^q4;I5Q)7unR#oB!p$h)|Om=)|H5{o=OMdde3%)gY2pp;ZD?g;vwz*<g8&uP`|} z3<m@QSZ!bp*#8u3&S&ra`M>}9$J@XD5!nc<zS1hcB|c2|#{Ptr2W@V_UtQ)wokC4n znRg)MK%cd~`l9^e3J-E1U@^AW#P9rPg5UqghvB6anXxfBK4*-V(6oqo&KDwpHPlUy zsR?;J$EiK}OM?I`SH`ZZ8V42$Y|WNsa1ee<YjXJAXq5BIxY_D@=}XTEu+6AOYN$th zSqywHOgR7bH|Ns)>u+JMqoKJ!0P3Z&*7}A{trtdJgT%=so6hX-Cz8Mc6`FoJjXpXx z&sJ45CFGW+J^8pq0y{mi1i(m|T%Gb|C&Xpf_M%7L^wjw1=%^UMu#K0-TPsRR%kz`s z642LOI&#!O0<#(^>9jU>M?iv2*F*w$bl02%fd9!&@0~BVM22eY9`Hi{WB?9yDQ0+0 za}NGy0Zf33aIyd<u}On&?OOlSz!!J8n7j99|N3X|?z>ehG&Udb4YT{RcA*Yp6*C>^ z>|9h_>}h#oN5!e;^8DO_qVk&hruu?=A4%(gP5<z#1f>7R#FqpOW!Fuvu`)t?Vrj@y zEkwJ^m*!N#0JbvU02t+qR*}F&%{gLksWm$~IyycrTa@TpY14`743ua1WCm<iRY^f% zc6!*+{a12y;Cs+B)9G#Qw@hkosHNW9qk;xQJ+MQTTiIkI_AGdL9u*8=?LBD#%+Q=R zl~n-i^VCJ%0EPsf5fgX?wozO{4)Q3M7N#f11i;XtF@1hz%3oblTACFfiC#+i0C0tt z6N(LN0Bj~R0Kh(PM@Quu_%r|ErQC~eeh_j#FjC=v>Nv16HOfQgLI(pl*opPxKH;Ey zq&vcKCsKu0FSHC(CT*JuA}`IQma=#L?BD#^wzEl%E`tQd0w;yalnaGZ;O(Y5Do`ow z>2Rw*Wc-0IS?=>>rzB++l$B;(d-uN){QmK=oVsF6Ew3=ila`K@Pcb(+kQ^ggh8w^y zP2p|;JGDBR(ysN#mY^TbfnH^=D}8XvM8&4$6d;y_VY6mnG)FjB70U?r2N#duE(_6B z@zJB1t_E+f%HY}lrn+X+&jjfzoXyG(0;Vg&-wc3h>p6t#0N4<Yj=O)_nXU&gG-&v+ z!~`yC9bG~q^!V5)AS`YyeE3{%ZAocyR%}F6YDO*rTn7m(9XXOtA9{dlBr_Wc**!8^ zrKSATzu2_te>{2Z%qzbS3pt%IG=N`>&&gH;Ie3h}2LTv0VpOdI)caEbShdSQKu^^@ zHejQ8T6IPMy{!7akiGlQ|IN=nI(j=l&?$0F(#<$lmc{PDCc<<Fa*Db_)l3JdVz4~< z{)71R+^C)KSZvz#yPGARyn9z8Dkp*o$7p=)p%?^Ushx4@89%|PS|=8*PbyLZ;2G0E zz>>$x%!C<MIZ~S&A03kd8C)hoUpB?6mA-c6#d+BnID7YcMBNi+f=+eRdHYZpx;)YC zZD<=YGZ$sT6<kVcBuHCU6PJB4$_!@rZhmMw#Mrh$juXq(`RN%P(KxY87ztB^#02gv zN{UG<^-s|RrUa%Ey|6Mr<f|wu%!s)kosyN066$IJaHEtHCZ0NczY?uTr4-FhCv5SR zT>gu{v*~}{cJtF$Ucdbu0Ddtp?gFqTvar*EmB3Qn7nI2HEZt-SFJa9w0$4Z$cm^A? z1ORNrlLShsnQcfdddkuZIeY%||MDkq?YdlI{8#v7c5_ewLjt=K4)8%UgWW@qNAQAm z!Tz$CTX*7elK1{yaX<f<o_X)b^LH!9*S&@S7@SA}tetZ;zkD5lH*j#z`jP;E83?vT zWm=KqloLK$ni?6=o`R#zc`=Z|*@dVo#H1`ljyS@(1oPfg;^ShXQtO^L6Lhk}+te{I z)Z5a~*kzKjaG7kZ0uz!&Y*GzkTpjx6FT<l;6ky`O%>M~?Vm%jt8AcK>v}n*UftSX8 z@KT|aa0VSxk%a{SLx&z8!@Q*V(YDHx{ER3}7tJZeIJ@d9$>eB;3Y~cBhr6E69+_TC z0Jlg-!^X0hZ~y#1{Mp|9pZ>}3ZigH%`ctaVZU9>~S^;be`c*Fpq?o=eKXn6`qE7*= zO+YkoWvE-0eHPVj?B8e8KL6u?^|LLf^G#BuEXks08o^X(gO^%adiKhrm8q#kUH<r2 z|IXj~S9`;6pZosktx}tG>3S`EG+kH*z^o3!f<G;Q<xusC^s*$GLY-KmLNm+3VLwY# z!=u_&aJ(4<qvKO^3W_k6p@K7<D=;rQFEuGHCJ{ruo-&hr((gsKWlc>}uT@lZA^@WK z(vFBN1QfteZ}7UY`*ZLw`;@M^nyeB8;6NtUv#o9$2gW2A$>Lxl^hiT`Eb=Iakq8YF z*Z_EJ97VzN6Mke<W<+8fQ6@&vR908Ri$xna;rMs=D%v4|QCNzK(vFs<`l_1B%F?vh z!`~g)_wN7x+dIz$@Wu}y^jE62VA`>$9qd$TX{VC)0DjpO`Tg2pi}V)AiL(H9iKmz4 z7WQQ)V?X+{zup<))AT52!lNOY2t-?1@a$WEY~!;%ozRf_&i(w)wjDb5#r6YX<)JJ_ zrpF)-%#n}Mk%K)6oe<0V9lrREg8-~E>Lhv7j(84ms3i=Hp5aMMHl#-bs`*IpMQx!B zj4r_l=M2oTO3JJ4dnyl`>1p(MYFmd~Q}GnQbhImgg_FGae%9+Uq#F{edTiVP#+g1R zfVH4sY6%fU0)XfGs?s=91t#zmHE1J)F==9^udWOL4hxUZ%r7cKJz-rfRA_%+Q{2%5 z;T`}Osi-JPLlSv)RcT2<fydwG2|KdmwLkvtoltS$ASYI+T|N)Q^nA7Pgt(1D0GJU0 zoy7HQv9y7;4bQLucH+R=)Xuntf9e2YPt@TfkzQ4cP4{|sxKW3xNlf0r%Rl}lEjK>< z_>1kE-~IYV2#XPWr9F=p@w5-wQpXURSO_n`HXeHe2O@3>EYz(4hIXi#je*Ns8n*+Z z2aA)UV`15qDSj&<e{<6l<6=^Z>em|s>(^Zv@9!NB<dZ|qFj@`yKAl+B%zqrj&k1V^ zUISp8Y=#Ayv~N0csI6xskk7bDYXeIr7K2F3E0Z0iFoDavXO>V(C_yC2<bVzh5j;OT z*i>Ga@!-bIsEi!Upz&a+PIY}V<^#taK5)AX>F~Zr8IR>{tSZUN&P+)!X&SGOI<oyY zfBc(gtI#UWUi`5Vn1YG1JI#gGN;F3TLr&7!_2LT!zS9k0;iaazkr`WH<G?>r0MS`? zu(qz(kT9-ZBqHXS(%~X1G>x?v+1^;ygQK5*^v0`i?TW-y(@>A;^r--5<VwS&LfuxT z{1nHk4AJC233Z#s&;YPxHo5_f0jZ;7Gju(57ezdXh|ef0!=$z<_^%4{v*RNpVhdaq z98Z2ZH#x9kQo9jrM*C9%{G1zJ&!Y%pn}N$N3D2i0rl2e3gh{1DUw6rP9&O6SNQT<J z*`;OVQ5pb`<C(;a=+Ty{qO^NIUb>f(RZv)3QGqEIwM}hZ^)ZJJ+${CBcx!5_J(z!8 z3izfcCd8z+bl2S3_t7u^=+`$x&PLK0n@R6}Ndz0-#uFk{N!FjqOb%3O39esqAs2v& zU_)(GqCsq80$T}8>HAXy*uB1v6EG}F9Hs`p&(EKFQcmyu`0Zc){H-6-IfHWjLkY}0 z4g+AZx(Q%nP0#fCmwghe;D>5>T>z}*Pco30Jj(T5i<6^cQ-a{t&h)Sg7jHyBjV>-M zEXYZZy?yEG-Td}-8Q{+Z9Oy>6@S5h{1h8|9FBu39ViV+1szJ;2MX(EZQ@eE;Ku<i_ zU;x7hjj^IN8PTzMO{0hcD}Yu0iUeMqpXjbDObR=9HasCCr$8o2p_NI!ue~nv+g+D) zs;V(gDnB<bJ0~Y6zo@V{H@Cijxa`uG@BI9K{p+hEkDr`OW)Mkfj^!t~eT^g05XRLb zKCb7YjSg(mkRi5b-sH2tfOZTYmLs8ggwUD=u+0GY8w0TR%aM81)G>7K2ub4EufF~( zrV3Ae{Msvj@n^3e$_rua$X63j;>41mj^?Vk0Q?hNp6ivACmQNjqg%5ajFRCl%v_il z9ajW5#h?A|yHi*0-hU7gaqs$tW8WXXp3(6X_f@D<BIB3x3AR!TBt|J4en|k^1u1K+ zmf`M7X{%7xg%eot$)_uQp&@~h3ysl8$fI0boashG*@S|&DQM6PB2j@Rf~OajW_s%j z6R)C2Q$%8Vc1~Ua5`D_5YJKJ5`*xg7$}cI%&B;cO{F2JXw(fzxehdL!s`_#Jn}7Ll zfAM382J8mF=2(83!!b@~R`+Rfp8>EsFiq*(Pg8wt>cXVjiyy4D47T5lQ^3eq`pJZo zo6G|}KqPI50H!=tiTGTY8p}KR-Y@>-&)z&$=5Ds>EM|OzoFcFezzo#}Jj2h=J3>l( zqeC;5k^mO91^{MX=wKu*j*pMdP_1f;KJv{M`wksDcKq;nyLWuC_greva~*=PDLU$G zMmuD_Nv2#|lMvlcL!*unOhZotWv;%^K?&y1I?fafH!}d1iR4U|lqhgz&nyJ+l!Dhn zcxrAD>CpL!H&33rbT2k3IU_4OFAr&WwY5bzcYS$2u>|tiQ`g+tH#`;KdrdcYef;{* z-@6?ez~bT~dA~G;o13zf#(F~MT*R26xDOhQ^t_iF;xI)7(*)3*I0D$wg*bX~qpb8< zHx+7evJ9GQGD{xAW3Zs4JCe}!$3~xrZBe^^_lplMK0ZOixLnjd#tu~|Ezq7=CamM$ z;&Uwd<X59&qetgV4$_I@wqH~b2VNK-9@VgT>-~M(KHReHlWki*c<-a#R|`WL15Y~= zVf?0-nhtZ3CbJqwBBA~y+mjbCy~}lz+CCMB3JGkOl+IQ$ulf{?$^cl}%F+Zz`{#z7 z*tjf|60R}|>;~`z4sootIOXn@OLvmev$JyY^9wK@8f`gB?jHO$qPBlzXmoPD$}*I7 z=i;fuKNdV`KCqfJ&wDgaJV-VrQ-K%|7G~5K`$AJ?56&jsD3P!GI^L$X5~0DS0OlxL zr?b0~VL${w_TEpSh-VQC_sIEeff44K5N6z1&-#F%{VX@!`~JH--q2^Ebqq>tY&2%( z_!zZjgX-Q!&e^aFxgoJiTz#Q!W+TOYFug2{4Gq)Ook`yN!8@BVFZ%6wKH7V|BsdrJ zNz2<~;+kqDh+|L!&!+7c!DKC==VOeanZC<ShtC#Cqh<*UHaG)F36%u))F%bQ%^-mR zV5rd0pgB_|AwH*B@+esgY~`;g(MV01>MTo(z8{lQ+1Q8>Qhg&@X?OGv_>#_E_Jq{E z9zE=9s;jPOa1V*LZ?wtG9<kGKHgduGHBZ`=3UXDyw3xxnwUZ{~EH*F~@w^P<N%!E& z-Zb_69Q~!WZ=B3v0Icu)T#$NvO^4LvpGa)zqNg3I#9p&-Lax#a>~EpDu*6;b>nu-- zRi>zob4|LpsVDqN8gB;e)zR0rt(_E4NRtHEz)Vl2oe+GK^J9Y}g5b_uTi<y5-8Wx* z^|klExwb+42KGs_n`PAmFq31nuZr4UPocZ#CS79z%aN`Hv>KUCsBL9QH%72M&7~pJ z2?=1C?~NeR(iBbL668^$n-0NioLB_#!pdw<WoBYxZfy^8vxW!yhK5GQXI9oGi^C#i z;Pn&u_Y+J`0kFFGgtm=9+xSt00+p*FDTRehs#0ywRC$=3xF;LI8^)Mbrx;QWR`+DU zs2#2HQv%rTm}f;ZUuXBx%qM`g35fC2J}1jqn-9%`xvB$Tu@9NZA>(?%paP>+UYb7z zwx^zLA!EkLSXn?DSO-2nCIr{!$A?Ge7X~tacxUq`pKX5gtu4E66oamx>#^x00RYR2 zT87G7e43)TVX`r=qyW}Unm!P+MLJt$0s$orMbXpu008G<qbo?I6b*WLak8}_B_XY< z8z%5{zyt<(0od{Bxy9MRx~!zsVxRQ9M#&@=B$?FSi+gT+<B>SA0;+<(>hm7N`t7Ot zXFR5M=o{uHvn!>Ijz7Q3{*+Tx8(4!#+QQg`kxU`W`W%3l*`fJf-m3<6r1dqsvDkU0 z>ZjX?_O%h}c3zf8Dk{4)c{M$;$S}<KCq09WeB`sgM(@yAA7oJsCQ!Z9K1GkKv5VtF zqr={)?{=QNb^ZAF-=B-B3(*25<kI@m0h?5A5y_%<hB*LiCtUqhWaF3#YF{~KK9;oQ z6BKLYD9=EI17N0Mp=N)`i-xjd0-HQa>wzYKr)HPtN4@#UiAc1Rw-DZ;`>zX+4pDCT zjJpDWMO)CUsGsQe^~0D|A*qy-$bo)_EDqvmGaC(f)^g87i|lUXuu_u(U?zVB+MYk- zCN{F5`!-Faj6PbKDZYSq-tGyiFV6syKyAMZ1N@ZYf?fL<MKYOKY`|tcgFgj;9SgxQ zVTxb@utrIBe7y~otv}9%$&sO!{Fvn0?#|lMlDbe0NJ5jN5gb+`YSSS2>2$2LndtF1 z(EFNlh6)pyBCDT7sgYZ><3)p=L!k*IX}?I|HLB1Y$<SAom4I$Kql=4k(@qdc1h9mX zrZDz+s<R|9A;Z&+GH97yf<_QHmz9be_dB1>TGxGrNML#-G<f^m-~aeGkaH8j+9JwG zCj~HR&1R^*T-@XFcLlp-Ub54GO^J=VkclJx1RFFazES3knGa(}jc$%WR%bC0_Y)kb z6;9%37nZ0qu<0;`aY6)JhYPl87JR{lU7}Dm8r~MGpVUfl=8G~ldHwE|rbl|)yxmVR z10K`X^e?DF8nCFDFR5SJ8d$f8jjLAoBEALpssV+@>`=C-T8(=4xkWqR+gzi=*FxQA z^8RB56U>E1EfVr5r#eg1Vp2-{lW4{<i9AZT8yZ&d?A+o^mnS7QrLcKy0qG+s(wteq z0`tX}Z?`@-z0d}xf8Zw*z}A%3D3azyk+IocL#{Yd2oyf|7MyRO$Y-Sv-5+ea%F%6V zJgN+P@sGFcO%Tiv((#K>_5`;ar)FF{CQSNMu|y?qGwzZ~4F_;8$hn#=vSpM(!Aop0 zn7EBw-|Fn5M@dx2%r^_kpdQYS^$&z-{PLtzH}|3HIPXV3mH^fskqAD@7U@-RjNq54 zX>e^(e2_*@6vj`c$eCJZ5<Nw;n{1vS;UIwv#<i)P_^=j7F;>(>fu#~D_(3YiER5jl zw7B@}ntllsPft!w&7#zDrr^gg(=q!wh!hf7#}%mo@*Lm!1YYVGDORB+W0RYZR4g-1 zUb`p%B!MK?Wm+3pq=m78v7)_sO|J-r;Ehqd>pP9Y!o(3;PfBdyQPMI>Jf>`{<Mx@p zoOYus4dtN-L>-`O^-F5BZen|?xY*DQ+n5A5sBSvABIhx)Rrs)J?;WV^a~<H)WPhJ& zsj-ojoMX|`B8D}bFXP*&(ORx(404|R%OKdQD9SGQ&=aYyeRu{b^Eq(J09X|5r=6() zc<K@Q3r$Pgy2bf{hMa_$3^tUV3QFTpTX<@E9!78uYCOt1Cg$hRF$;zMi2P3HU9>Il zH*$35YiI+nsBn5d0Iwta#VKc2pk6=8TZ>8<U6YP83<$7uhKb7tQ1ODYaejg+e0+Ep z#)-u|L#8>99OU0fAJ295?k&3UtJ;bRC<b)|z@%=I2d~XRC=&yp@q#;aoIBzawZyHo z24b@&sWJ@8;OE-nQ<O`kZbs$|oMxCO$i58frwhRk=ZF1W&?h(c1is&BM}l51XqY0m zsJAFPWTz_9*2X^n$zR3NV(T_pWvhI04D{2`!O|vjWks;As2K<ApQQaq1;Anh<9yIK zwk9(^E~jN;X+=z6^Nfs`Tr7-UnVX+L&&uey+?LT9e98C(rmg_Mx#w>-xjuVidxQ$j z3A(B(ym+63#gX2j;FNXI`BdN2K?$I7iLWtB$po$_5}jAx*bA>ay~&;)>EN#qb2l|A zE7UC_Uq^~N+LyT2UT#6M0i#8$vS*yov(pkP(+(Nx8ll+amp*4oR$!0H0^ANIwes1m z0t<q=p==V`s$r-e`a<L#P%hQppw7x{SOu`~C`|Y!k1`40p&Tbu{e2tPq3x?$0pbWm zmXT|&3RC#x7L}tI_2=cbXpYIUC?!)?&A|<&1yC$X;eyZNiUMHpEQFDuK`$;&wwI>F zClqvPDWS!$fv-e@0pO{giqvS7D-8g^6XWQ$0{~CvT)63b?rm*?2`nPm+?nAs&;2p0 zlfC}I-~=!l7$%WJtS8gNm;zBA6Y_Hr+l$cMR9Dx~oc%@-z*1Ery4MWsHJzTTcv2DU zYUx0R`XZ0fy=;e933!NuXBt~1ZL5@&M;gDFl;|K?yx~>#1vOTwia7x#&5~i}Bk1TV z5h1yey}0Gmi)@jqg`r-uKl%k1FlJu2XxwIjSW=LEusSs!Vgg9$Ejt%y6hJ*XiImwb zDu7KD40+09w%3NY=q5Gwh7q6wRox@-JA<B*>Nc}7pX)u<bC$ICXdaRrX=31BMw<(g zW0J}T;6|UCGyonMQ5W?1i0IHL>L0Aliit|8@K4OmPT-3SfWur8c!O*hqg6nGrXcBs zP2h)fWBt8gLhgsEj<#};t%>rbtd#Vjob83Bg|pDgaR2bM<Mm`3Jl%;#qt%X4<}u84 z!x#QI(NUNNlrPP4;MEItBR*gnRv6ogDWxyUCjyE>fY!vc799if5C9fDF>Ofx7J2^E zq@HBxZ<uKqXA%t($wyI<FDqg})h|u13dNza7&k9mdt&daC%gme$jEuPBIg0HB1N`H z6<WLaXmyMlCNHN%Q(3{X)C83&s?P3g(GV(~3kJeZJi)}hOypReof4rj*ISbn7nfE$ zytFiD0c>Cl=?fsk2%eiA_T?r-B^9;}&+v=H4uk}D19*dUvuRPi(0cJND3ey_CWZ%w z-3`b^*eQ2Y^C_TwS>elRbI)s(hB(9Nk%{R=#|&osCgB*k3h|qX3eA2|Rs_GW+*LZ| z%phX`t7@+18hQ^xqqX`a6l*$DRbH?!>GM88(t`8KbQ6Zyq;O`=r20$GH^*MprhPB4 zVBiIHe_(~eUUfZgaej_?0)Qo7RNjSL_~oFaDuXIUj1mdSXdV_zG^MK@4Iw*z!fG@x zvqfugQ)Ll|(kc;-A!n+d4BLi_hO)|<C((`q7)~sjZR4HLj$?DYn5i;5sj**Mi6nml zfG4Kr<|f*T5~E|Y>IWugpk}icb3EsKSda?6p)EoJTgGipaYNr0M2}0eQ^S65^ZIII zBY+vuqw=K+rb>HbTaZ?sm$-wze$3yC{BY)?$pPE?C)L?OY4i%yauU(6Ulel1jl70@ zr}hbU3ky}Du|;X2NMaMLDepFy{}NkNhrNXp9fMFYD1p&d9m~=2jb`s!siQ@V8`;dd zcd{oaI)<K-%3#r3)$1+O3F#BYg31!LPxA{bruSfOLt>aJRgJBqX1>$|>lU5tFFLY< zRksZ<?q-RG?090%7U^xBn=@0qc#GDtptE-kXMAkK0RYd=Lbf*L#YZI;woWcd6gYrh z#|Xxdm6^GTuF|Ba$mB9V+PymfUS|Uvj`7qTu5Cgya&r^P2OX_;!zZ(dH|VKIh{|s1 z^|!W4c8LKKB{1tOshOCpgFtYN&RiaiLrWW8^wBcLL$`MKdb5)YJEsv6RZo^sfXO)! zILYN3jzKq%XtW{Ymu~qJ8f-jG5;tYAump#9Ywh{$%v>O`LRp4szxw=+rGOMAx$x68 zGe)#YS_vX7MCRKqGF!z+#K3|ZI#9AD1(aS0ena(H*n+iznQ$=Y@F){XU?Hmc<_)c7 zXoIV9K`LS<6_x^6wg^ryTFsnzGDL;e358Br$Ex{H;){>JiDggRA~g&d{a|e?O^(r9 zR5q-7fVy@`IBGlTE3ac&MulDkk<ZRe4>rKMO)c-5LWBq+cLa}kt}K4#SLo1Fz13+k zkx8ZP0$`ZMqC)3g2=+qDa?V-?%|Sbsm*aR*iYVbX##|4vfAT8%ZkrKdKk4D@#Q5Yy zcjl4L_g%RicKLc#>9DhiX`m?D9`;7xfZ|E6ot_f1_yB?fZ%KBi?-5c*TWE~GcK*`M zn`d|LzF9pj(m@Sje74cq!Mo)q%!FWtts+<*?h5z->o8wn{(_<<2-f=VlopP)Mp`os z1mMKdrv47gpt&Y?u=2(A)Mh?VUnj7-xi)huq#7~Q<O>X(1iqqQVnM1kR5A>)$yd8S zEohrT3x#+i!q;fCx?7q-^y|}4M|nuIn>q$>PwgOn+Ee{5t}XK5)w`?TiWAbPqu^8> zC$c8tglMX)XIB$Vim+eDh^^YNj?kS`w@fCmB9Sa(YIKYALW59^A!O7jL!rX=xnzK9 z0{003Ya#~{GG?a+ytxU9Id%Or^FW46gQgRUFa};{rU!h5DM^{0jxof6C&wj>G?{lk z$O~--L@I<Wy&BS`0O6U71h$RX^iXtPPvULs|9)k9WMpD-ZL0W(S6|t@{nM@6cAd|5 zbZPKY2?JC4nwcZ5X`4u0-r)BcA~EEfEY+dS7s|%br{K-A4NH$!<|d~XRP)m?lJag` ziV4Y^>_#CRqh^HMVgN_(Wl5X7c~xii_(*V^^hxR#6<V@Y6i=$P%hxOK)}wv)<G@$Y zKz)H6$0&OORGot<7O9vC*rAFi^H8$r!s`}%_UgKM!!g(^NIbM6os30l<RN9g3C&r0 zA>lk_d%>HRUGlOl4Dl<A^^MY|EJMjgI`>(=Z;T-aP8&N@HzPJ|M0HI~RNy^Yj-j_0 zV8hNW62Sp>=-TU=6f*$83sZPzXGhyS`3042Bh#}YfE^WDj9(GRWB4&TF*7sXU0+sI z*)ljeJ%y1g0^q6q3pd=ESZY!{@mS5?H!TZ-)uN$bG(MUQQ5!q}Q^UjK;zH^U`|#(l zy#Cs2zj^c1lbN>j2iDhko_KhqlvIh$r0$YW7?m~zdD|lj^(Kq;cMrV(yWhR>=5PM` z7oSE;4c7A1#PqzV(cq~L?>1g6#|kz^f)e-Rm;VF;R7qhTibD-aiU&)WA4M>1C(&pn z`e9iHF${4*50v76BOo&D*672+Z<Je57E<eDOh;m*FuAOfL1j=~ks2&}ezs_^$k3NI zzp!wkn_YtW@YAVRm>w)**s{Zrn|tDZ4SemP3Vyj9<46*iV;4QUMI=+2V1iI8wIBnh zryOahe^T9<{~0|+tvs8D#aj%7y2-<wTMXbgcw1|U`%j1jUYJ2D^z7`!KxdP$b7T^~ zqXr%1!y<miMy4Qw#|QlFy(92v%}zt529eAb{TQ5y#UWeIq8Ul#P(-Ot`=tADbDY5M zS7$~?rl`A)#D4Sk8*jh;=4)@f{n^RXF3a?wp@?e$d`%2Qt!7Ze!-yy$7iY~NRvGxi zW6`ad>U-aP^wt}1zVqHY?`%1eL#umfdSZH(by+g!gc4YFXibE-W&&;45K89L^*@(h zqK8Ua(?@BI>fYQOM6v37MnDN+62V4(yRSaz_v_ge&1{CCEPjb$wyFSv5v`yEmdF(z zkt6aiM7lw6faN%s5kz?FD8s74qNAwT;T8o_4xEg5QYFLOqDfUz%^~;+!6Sq88aGc= z{4#7oJ6{SWVFC-D=oOa9tppq8v}}=Q6N(Rq-mVIK{dyj%QKFP<m|LVLgKXHnMQT9W zbB$^ZIeK6xYl(Y~7K}+-SxooF8&9K0CunhY3K<$=02{Sgq%rY33<-=-u=EI&*&)~` zR1AFFV(GQ;j-V6dZ9aqPZxXR+;(FYb?s8)~-wGxdPcwuwQF7&*4?p~9+tw}by}S8~ zQ*li;u(N`>x$x~7hl|>z%1w=ysr=B<rJk*1!dR%feQ?|6cR%=O+qSJAZ$A|2<6;<L zF)_0wLLIj+3nDJdVJ8-9ya94=yQ2Ct_&nv9_%&9aVUZR8pqr2o3yzSidyeX!b`j7Z zi|$cA-U!ElSa_N^Rxt5xNp||?7Bh;cIeM`yS9I_c*rKD{Zs15Q*p=ZM=Y$E6YM@*9 z2n}(L)XfBXvPO9~bBFS#&SHTB4Ry56f(8yu4xk%G17)&B*&y(sN`}N`@#w$=i(t26 z^sHSHd4{f4fGfukUlsFVsYZznEQhMCRm3_rTT}$obYF+xM{7xYju(z0j5IYV^9KQ4 zXwTEojExJ+0kMD?_|;qvkck|Egb%PcdHdDMn~@>gu{>#OB%w`mH4G)m(KxPwzyYu0 z+HS78GB+`<NfblHH@^R7-+_Zij~qI%`>QYaoQXAK3q&3=NJ`T}&P6NGox4{6S%oH; zp$5<uMD3HFTi<T~bjQwvKO8!A@W9>!XJYE53+vj#v`l{!Qh<aq5||pT<N|VovOjYH zPgqg;w2Qkc$0koBngqY}_gct^eTb40y6J#m7SAAIl#iKnM)vU7f==Vv5K!iFTu`A* zO5-OoL@Hq`@F+D&RizDZMcrb65eNG;lq0xrQU73es5T9q6Dop5K@*p-a14nhfJX_M zm-sqJ0+L@e?xa#t^HyA2;)e&5VBk!RhR6sX{x^qaw<vIuEef8PQfD<Ai(qawa6xtz zGTfk3CFb=O`Ms)e0-kJ-fD6@I6u!?}RL8ev89WVfo$*2}ew}TtCG0<uKf1QMFf)PC zNHBv1!UA6rz{A7C;)mA9;CBqE3zDEBE>BKSU1T4Y<;vTUeb3@U?tkZoAc2vf%(1pA zB=q{Z{lL#5Xbc<!IV2p4vo=t2_w?aY=WpD;7ao4=#>Eqd4qwS=HsK`5LxW$$dK6De zY))@1hqwa_RpjWCIxCNsKREvF_ealP2@Ah{`{wnF$4>m1P(2~Xx`2XAgoMRNq|g_Q z*72JO?c4nsyE15_f)j@V9ACSob>6?CiJZ;=R1!BuJRsm9)J<Ze_GK&u6)RSP)BbW! z)^(;r`0L1={6eYI_$Pz|sc@20q+=h%raocfNtHpeVXkPGb1>^<x{Gs+U!bp}n=}u_ z6hFnn$>2%0h*Tq$z%H(+eBXH6HEG2qeXW9{NuGf<9Q9W{1TOrte~)zun=LXNNFMBj zOsFcD6LKA@$z4@8;;iV}qFPWYf63S-3d2ys(!B5}*`m2cCgzgy8&090_!vJD0FOOd zU7VSmKtyH|7?vr8C?o`aMQ?UJkiYO@jl+pGH9p+i-RbY{?dj_q7#f{eSRKv3y0L<O zmxOr;32X-XP}vh5$U-=X*39X<@xL-VH95;>-u;!a*Dqa@F4aXv1vy#q5jQSe49{sZ z{Z!V#*^Ggxc;cA|b2oZA7gcgo0qCf;&V{?y9j%J_@$7}L=)|0Y0!)5NkH35E>Ya>6 zsc2YR0_T(AtSB#lO=>mT0I_Knr?P!Ry6zR-WNiOlso&n491uUlh(lH)Des1r?^xZY zYLfdjyg$GW9ZC+S>2<8vSrZ>X`DB=$;TU2B1HeWga$16M^Qh)ccI1F0aHbYPK{^H@ zr${#UY*h?hR;&3%sWIY-&PbQgr?1?#QHz(L9U5IrnNrZ1>Km(g)q~Zb4sBqRPcS1# zD*VX6T!+dnTA^q@cs-@+j#Vj8zNWI+(V{dI$XK8(DB%*8zUqOhBf#q3{18&B>sd=U za7-jHJIG@80{#Px9sOBMU`GTG599YRfoG<MS}P0kb1|5q+*4ayC({XA6Hi?z4LJfG z4zAIme*b_SPUt37gpt_7%SNr$%jza^JplW&^WsZrL$3pIMrtx5B4o64sXWES`8jEE z;o%sFW5?%eCWjb^>W4N5V}ymWd;{UY@vlddS$MoY>2}!t__SQRT46?FRAfSa6Dwer z=b^sLEee3=2w>W4s<10BRSQbC7`);-S_^2JmbC4~J2$ViMgUU+BNG;T<V1P1Mct=E zE{<-gTXX7P9m;!5eUdfhKfJ2qmm0LVbdch2@gyABG~ZP6RwRizX}1_m+v`r&jVI;d zmPJ{!Tk{&}HPbC}hbAhmrWg6XY7rJLlyR=L)&tn`3&T>4$4ouKrZz}e6zvkdMm3QQ zf_00A=UAo~xJBnIEr6Y`wD+%ZGINVeE*F|{^eDYVS<E6>_;!F9xGpPx-|_r002ql^ z=x@*Y3lcyAYKKQgMT@owRv<$Fqne?sG%-9pB04TLBL|J4OUmn-O7HCd_Fh$YU;n_+ z_|#$$j~FdWxO?qlc$urr%bu(NSgv0OR+$)}`d$LSwTHmF(PwdLVv6$j(P(3KLTpS@ zW^Q4zKKc2XDRHqeDWz>ji(ZAan3};waA2=Sf|+?hYSXkt6&o&jXkRdxs;9h}QTL+~ zQ?v89S|OhNjO3Wul+sqRr-wL2RM~;TMTHhts)Z%=G|K-00P7w@tf-eHA7%(&{%kZ; z1wS`n;Kcq^szQtVLu=pYO0_&g?Jm1Thc(bfcx;ys(UFOZb5Wzs5(`{V97^=Jh>Mow zZCXa@X~N0FGc^EqwrCL?geTpmLy|PKgY{=wkp*Rv4l71C^-K8^#38em^(qZZ)B|;h z#5qUzCS7N0bv`Pn=7Lm{FaS0jLySe8D$Z(Q9W}~F{e)al|H1)qfNJc5{1T&O>icRY zox;={DeV%qfld0gMX;VsK(x6faNPdm1*5BQVlmg5ZfDKFf&nZRFhFdcVL(~{JhM2_ znih8PQrP{tluQ7)ps2F0vGn$yug)bEm6f8+dp$-ojEYNpfj%bR?L8m8_R5F1I?b|r zpZu8sRt-#3)r`qSdUJD7-nH}Ec-g5r9n9WT5QnL-nKGt{fWpt&*(q_+ap|58BlDN$ zt!Y7%RPSAhoUty8;J|wJMuOq{Xu?;Ta6d9GEi136NLMQ?&d<$A5_Zwec|s4D(Bc3Y zL-X@+DT=R06pSU(zuuQoqRsvSBErzJC3OeCDo8A)D9Kp-Dxh?bi#oC7_d?xdiI%*D zazqP$>`Waa&DrMK?AVBDj6jjk<#;FZ=5%?B=L6e<k&kF1iA_8%E}?G_C0xtCwvxAH z48aN@2|ut!?v<-)%*s?EF-r*xGFgS;Ky}fY2%X)aL5Ophf%|hUuPbs<8$Gh}SIB}2 zwCs_Yl-42@#;>&%`gZaey2T(#?>50)cNn~)zO9Q3YlSA`ow!AAQTL7x*hWh8i1a`M zJW5YAasSc0vDMWDRPSrlNW`xocX$|M%>=>xnUI#>%ZS41#>6Y<uiTAI%PA}>D=Vw0 zY4lY`?)&<DVo`BkZf<UVacOyVo!47m+t@kzXs+_Y_Ba3h-~HmO0yw~T@g|#WyJqWH z(svBpsQshcr?fUd0U=MH&p<<VTx4`oMs9v#35K1@Q&duvmz5qL8JAwxHo+AiLLf@2 zzv+%*&c+b97{dx<L$5kO#LyLgHDvH`s5U?0enfm)c40n7N0*DjUQ|?4kdv7d8=F+@ zALq`N=cWK*;8#)(bazJR8-~j(=Qa&Klw95F9_i$<hs{JBwM#Bn0fl8mI!&q7t<)XB zuTq->C&K}p52wCsceu7N+TS-}oN08KNzsp`TU}0_(84mNkiDtt*EYjVSrloGICO2% ztgAzf@T}XRITA$_RTYb0-6D2|1;HA%`*i@pd_!GHUX>j{-Jk8K1g;g$xvK`Ix4~oO zp^;~3VZn^>V$ErHwx}(lb&ElFWdC3`r}#7%>)f`iNDs6FU&EwC$B<iu6Gb!3smJR* zay>J3k_XG1;jhF~0_uUsR@V@d(NM27dWT1b(6ikEFV$xtd31DoercjU@!I8Ek!iWb zWilbSs;Q;3A@<Pzt65bw9?0O5V$4>~FUTv%OwFqB`%A9u{^Zwx{K_SF-*;Ud05;A2 z_2_hGuDe%0r;NuwYYUU38a`U;u1blFj89I_DZq*qo(g%&%1a9|*f~BjCN-~qh|4@& zGCm~<%G2{BB3O=w|3jVTy{jz1KN;z7&fl!N*j=6xe?KBFH7BpAw7gu`s;H1D(wRwd zu?a;@!)z(=Z~<UK*8>5tG@~{RQb;7Cx$7oXC)S;r6)j=AD8qh*g`E<sO9IpVK?g0o zk0LE>@`#nc+yhyZrUI-3Fpt|g*`=xBfqr*0WuwwEp^?2mmc-%0X>sr&imG8f?b-uI zR^=A$iUF+fccw3mX^O&kF}A9{m;+yVFT-f5UP@3_9IVDlpkAX)N<P)jY9N5Qj>Dh~ zkjRA`CTUJW;be}~VHgI#lK6!!GTlsr35=F;n{tP`MPr-r)g3*_1PKfimW8c2P>-^{ z6W+**68f-2;>#^Utzq{k?aQHfpd@DdWrxq>_j+$@@dpm)jsU<?m7wq)6L0hA$Pf`L z(}9fyR&hLzMhs(h@z-wNOUlA<(V8lZS7~nR@+Kbn_ExE{#amljTaA$`Rb@qa*=g}H zDOJsdH&5)_^5?H#3-o<ATGQ(4CP@boN2=j{q)(?bT(49O$3RWN!juXB&if0JA|hf_ zvh$0JF_XOtL!ITREUN&h(&D3|V^Yd{iS(7FxmkGWS=6t54QefAn6VVOrnv(LPeKNc zzBkvH6BQK^iGfh?Uts{eu2zH9O5iuc9QgR`a=+^A%X1T;?M1PHnFPSQH>S6Rpql)8 z>AX(;qg(P?<<fkO(ha}gx|AGusn8nm1hw7tEpQ~TlCqTBD_1fIb_pS8j}PZ(CPp<g z)!~%{gD5FHG&ws#li*jV+pNefQf+5+&b*?msD__GuEQ2x64L0;DmIxuDbA4KEgJkv za0JJSYh=N!RWjrtg}!BSY=GY>KemUfC~!0ldk)kVEJxJr0NDmRiAyPioT=zF^qy!Y zz2iWUffPbC&Y_b1>Ln_G4G$3>=-}7tPljh(7RBULCN<)bTNF8CQ=G^cxj}xSaqb7U zvlh4KNcQlmWJRdAit!@?cu0OIdW|YAfJOoP!a!Bbwd+yo1*PSlnwrL1c%gfIiN}Aq zTh`v$*3#7EYi;rQsy(HJ81kK8*I5>E_TXo~dM9ku(uLu**v2My7dFgPg4#kb8til_ zD8~Dy3<oZ$c`~2Ty6pG|5pl_IUzL?t$(-@}`r7*1>e{NxiZY1BgxJ`qn7j_Q%6bSN zh@oztj8*y+Sjw|4vv$!}Kse3S#@!5$j!sU;>}Y{6*i>V^@T#gxKsYZaH9k5ay{Lr& zVZ0+$A<AIhyWaiMva(TLu5QlWvQE8ou~(~TD){(rMmbT2gM%{m=!)d;%pvhct{!)< zA{fgV{;l<RT+)1uAuRnRpg*sP^*-9)JM6Uh;<<^PNXw9#B|S=X2y;OZ!LUrE3fbzI zLTTnCjjCvN>L|}a#sbw)<L2Z0=?FEw3bRFxbK3=J=^Hf3d8#+hK*p^;2RL%@PUW19 z!A4z}N26gd@d&C;gB9mwe}X4fY;=pJ>8CZnly1z4T0ZPPU|y?rRVu9cWr|A466Gd& zsLV>1ALPRfx8u0^j%JJUJ*vB@<*k5--Fq}=L;yT$^yg8+R}^UTSRqW2j8X;wxI8lK zR$O*rS*540zOlYh0Gtc}SG0HgTU%P%+gsaPeGOGmFpFy%JXv8EfB5p(zrQ`909L|L zHV743NKVyS<9g8>w+CZ5vlE<!M@s8{21^p|M@J^63VthVfZV!<`UbE3s0XSb7PFHR zBEs%uwooiCBR|=R%o-wR8k@$j<S<pUH82i%5BbhBH4o1IcrQLRBe%F1N=J2lT?3x_ zhK9P@YEM;ZQBhV}d~9M&M)ioEs<a3c1XJWIer=JbRm1Eybw$E?9Sc!S#IP3yJb@&X zt?nfD5>@~Uh9!t4^BK%~njxi<(Htm=P1mzbLSGnZG3c$*UYhM0go$N_Z3uaoRlzZg z0u6gq08E~NHfmT9$rZ||tRPn1R^Q#VV(<>_Kd?wbAH$v02`5_eV_U?6^H#IrKkF8q z1ub}t0v?1Vr9Rn{)p6C9RSqXV^rpZQ)kfeZai$V9GuKGbZ*IZ7wW-9?zYOAz$~ZJy ztl<ta92NTf6v@$)CFKqU!1B;AvA3v_#%$6s02(3z8~9<&zN2|V&@qvG<@lUM{0<6y z31fFI$H?g9-27}$N#u?2q@2>S%IZ4IDD-v$z-cEA->+!z>S%9i^LMm&bhI=#)YMg# z6(n8VyYJAM&wu;gZDd^Q`B_y%04({!gs>2$-iF|br0X)-%-OFl%_B=&gz8|yy{mWP z65vLILR(YY*ii5FHR193yk3!uWef<1oxhgiWpo;|Zg}^kZ*>kEvqo2RYN8B*%i7MB zk9+PPKl~%yR|p?ffLSy&czs;02^^yyBEP6GJ3TSs-krD#Q;xi{AagD_!d~@gvQu@| zN*6Fga@HtxtIk$rSy;;pDQ@+<dGpG-*$oT#0f&;HNv@v0I@u!oNTIzG{}U1rS*NVg z(E=Rz)hcRNW~Td!uO2#=TwYaH)-Yf#EFn8xT?DYEC^;fnI0jTGK`^&y*f4KVb}9F1 zRmvxBQAt{@Y<XXKxIGfL_=B-Umy)4EUvoH3)XXq{6{D7HXdBzdMCO24Awa`4iC-Qp zzEOE1SuXG^O*i2+Q>JK)FRmwqWB8(Rdr9S#VZYWg3E)_O`v?-04o<5`;a9m5B}CDd z#APO30u58-q0+gJL}jdLWt$QFCgf_Pjj?-=<czGKnnqnzsyy=naP>EWW&J(c+fB?Y zO#5>qZbl}H23=j#*x2B0_YbtCoH+ELva<&gxUHk3!{6D`>}zbSDUJB%FaFJ69{F+K ztM7%GLS46KMpbA=FO?*Xwq`6UD-K0o-~d*U>ohakURB#S+gEVw%#TqB{}z;1RMpfr zH29jDo0|DF`2@k`rNsrgY4^?^znWA-#a8Cq(LJE|&YVO3CyJpExgi`genqIt8o;9^ zHxKVQc`rRDzX+>U*L%IbR$Z&P+2?J5!Czidn3ItlarsJgMfYg8e_;O6!+9yw!h9*c zBn`F*%P=fT*@l8t#iG>&`6BXH`WH<2bu3Kfb4L8qoup_I0E@>(EPeXEjmWTapJK}N z4|MctyTdiyK8m_mMzX(u^UYnS&z(FMmepYp%s12Cc`Pb`{6!(lG}x$68w(n!w&Mm> zJh5U^rJ}=h%qGos>Pd6gX3yNB*`;MoW(z_d!lD#SlIe>WySSCCc0+Ea-;Mo=J{91K z#^EPdDR+rGnU&~8Ac=zCDXXjOl~W^&Vkse(n*dY9EjpHoIe5DumSY;Q-j}mI!=L3Z zxh$CZqF5&8meq+tF3uDYgJ0bu@*A*4?I$nSXkJX&jIKu`MO<1GFe^}@vqzRzkR3Tr zmld7Q2Cpi76}d(dk4?<XPqt*<za5<}-kd4`xUN9}oN@BVgUYTRe|uY--wyz{wfY)c zd}ZhV^WWO^Z}&$Ye(l|xDxAn{^$x`bX7EyUFkZh(VN#k3DWe{daV}1dj!aB-=Ug}u zk)3e)$l*%~nFwQ*S9+j5`<k0tTcN$<CrDvns<Hy0%1^j@<j95Sib2GT*Epe4RCb{^ zPyn;=EwPFEV+DcHF$4H5yt@C(oj)e!<jZO`(9*#y>}t)eL~t3{MNaayQ)lm{rbdQm zbgn#tO)`#N9rQ&na7;0o6t7KhPaZLEtcZ2~QunS$;Ceyn^a7Tw(pPSl#0?t_q^3qN zemh5%Mov^Du^1=zBprY_T*EM^)rCp0Wt{MG-I=$3{@O>|KK^LOnbc0Je~7+EjIbz3 z<*!N$P&WXq1HhEnsQ3nNQ3bdue0BB}*qj4)z9(OqAHYX0i!6#dh6L!8Nr@&UTNGwY zs&VLs2(~tAfIo7p3*$p0vQHL;IF>IEVPiJbX_yy-lT@qQMD>j=q~0?wskG_vjCJ;b zLfXjv$>E_189zkg7oo2@lpY#-AaX?--M}wzk)uSEP=mH8z7H}+`5*(}xV=YnA%Wq6 zv|u%&cVIx}@36IniDm)txHscoczjl2NqI$Gb$vr!Lu;o1`0#@&KLFg(=0}!v2LSAC zYb!bRFE(xZ7Z+16ZT|gro$xJchC&6;Cg$>pCa5l3L&L_&=(=ubDT`ABT|L7S?f16+ za?8Q*_v}4>D<ik4q|{SYUE9#q48h+bPg@%h3{2IC3@%O$JMsOuC+-&Y1Hq^gq7F@g zZ#|ioytVg(X=K8;ShfHj$o+BGw$Jz9$|@)-E-kA<fIDb4A{dJmAt~$5=^u_A-LviE z)8(_PvqQZD(nMRr!E}PqQq=gKGJ8=<9cIkqKv{>WBr?D7pQ(Hsm0xA65ftiBQrpRK zDhYzQJzY@EZ(}n{>5JhAyabZK3c~6W>KE*a`1;K^HoyDso14EplW9v+P!D3&SqaFh zuBQw`Qlk{XRt(#P$YpF-KUE=gcY!S$rH31rEgCb5FYDT(;8(I^96SkvjVeV0g_gIT zDO0B8?o>bsvCCs_a&=~?XV6B;tR79_E8omdl6@eAPyDJvJ0m)@<mDKm(FOS(W{W!T zlw8Vg4u5t9FxIAeyM|`z98?Fb(Zz%v$_50yqSHtX-~<8~<ijSO;E<}WNH1FOww3_k z>;VC=gI`*|u4iCClCpr~!677fOwLY^G-QO|OUZ&f^3=iltn;>a545Ej00Tjtot=Jv z3jo~VuRQYyn>PLPd*%1Hy?;eJWl(=Hs=&%7(*y_|7lh=LiR)v?FHpR_INsOQJ2o?r zwDsTr>04Vq+jBmu5NRah5w1gnxz@IpX5hEExuvbOxv8PfQ&~}2UYs9s_Pf1%4&5p0 zU4#q}M;4?o(_3X6+%g=)IBUt*H&#p_rw%Wv<lUKh_N(_k{_^Pkg3^+*^75)$NPCES zXSMcbA6(y6@YfX=ME`hr@Ah|IdGkcc)Z%!5ci+gAjMot*lLXE@DczUdCAVtWR`4%+ z3KT_wFBU#0EJ)l2>c0YU!`epq7_Xk(n_f(t@W8})v81d}3n(>=t4I<&3cMLSnrpbb zZ_E21e)#^ozyE0W<t*FT1O%tAEg#A{VBl#2{YkMR!Yo9v5E>G(sY@|C+Nyu%HbZXF zNZR#V#3#rP*A``uLfpDViR>_?l84HrT_;4lSRrf{H8=TiZfaz3B+&KUM1B>&JXn4p zNW>~NJXA@?5)AVe)njA)8tVzwF2`SiV5`DBTEMzfRHB8<^j^6n9qi^74Svz}bq0QD zxkV)#wNEH;j8(y0JJ})^Sd7|pG`oL!VOo@Df$o4v-hux9{sH}of94~<8y+2>nH{Q2 zyBC#`Ra}C6tJ+2{Y~b#}b~v#hfxDnWD}dV&OX}#ZIron@ZTiEg&iH-XZfGJ0tv%I| zmsd7TBW{f?h%BMcRu55rqe6r+bm4jUF7&ybUU{_SIr#HG`|bOm9=w_Y%#?T}4&Bsb z<gWq?W^hBTrvlj)CGl5}?A`I@_jk$%1q(vkvJO6Sc@_9w7Jg{*%;|s-_M%=J@Hzsx zH}lNrn>TOWbs?b~0EW1)hX8i326o}CtF5XiFD)xcym4&Lr|-W0$qnxux^)eWOo)V% zGBLRfgcF&YC0RFmB~N?oSJ2p#{{@jod!WdZ>QQ6=&P=0_3^S^LWbtD`g6MkW8AjpY z=TOU0e}l*-+7$@s&d$@xGFBgdcJG%vzS;TBSKGI4-+MXRAXtjNm5fw8NyZQs97SO` zv$5#r;fma#u4t~&P+#c%>fJhiKG_xVkH6F{a*z0Q#jkGBL9qO@Fn)qqIF@{xF^)BN z%JN3=XE;!hP&+m0?j8=GifTpj-Ks`tX9VsL>a46NhJu*-^hL`%@dkMrdW*8WQHvbE zgIFByjL}6gYZukoWxS8(rPU`WwJ6vaI22a|f|W^ei)3W5`E-klW%&V#F9bRtz57UZ z-@?N57(}dsRe&qlb$%v_2k@`>$5C{p9H>i+Mn-UPQ7HgiZvdQm>QE#A+|l0F?w6;n zy~XG6t-A;S|Kpg!(jRtQ@1_8T5~cShTiB$25HeMPu(=HUlMW-ZBn|+J!-;R~J@eKt z-}-3Bk(*hPISHpyowphC*FFF+FjZe$Qw{)^CEqx4aOcO{kH-6^RvrSt(x}@oGr2o7 z6VNWh6v0~WC29OryeO2au55qn%@4mkcrm%MytKTcvepX#>uMtL<(JkbunS%7_UVJ4 zf4F5|bSoO&fe7?&$Tmdz6bP#dPZF0wbmmGdy#;<XtXFX$Mb|2NImw%F(a6IrGB<^| z$1n$W94?m`OW#~l7v!2M&$xH|B>JATW5@g}6fw`UrAkjl<b@;0kDtBp<Au{FzWw^^ z1DCVAm~SqP`sCZO5Ah(eUVL(5Yz#&|{B(+7db7AoOdZt)`7LI_$M=W7;fv|79OTJi zo|N*UwK!W;6M<Vq#X3VR(x6f)Ja~(S1qiFreG<ZSgfAhp8ES(qiBn~ez635P|EnzI z1Jwf6wPR>bgIo@tDeqE+qB0kIi`=IwjJlxw9E@KC>Eu<B4k9xw1i{XwNC~0wDd-l* zpbt@R7iCIagg8?<RKunWTjnB^z|nh-=JYPiPmYO_O!z|d4)oz6Y>gCFQ9RH;G>mY= zKto1cTxxb9oX`L;Vk&Krz?r9xL{@e8H~{W|1O|XF3xFefs?YAfr42ibt531HiFStM z;?vX-WlZ!jJtfJ6AY0|ZNVx+)pz`>eufDx?&xw1vNJlP5R0mF_c0vkHVfk5H#0?Tk zs_>Mh-#+!j*IT#lzf(016J=gBXc^lK3SssV63;*slH!94!gTXxLfCY$k;TUHj(zaE zH$MLQhie&?rKOdS_u|5Guh!x-t0Av4E8_h3Uw!)N{)px!_}ms|glLo^n58bFSSEt$ zE}j3Wajbt7c<OaCUn~Q8<+H?dub(QR4iYz0=CBp8Z|R4`yO&ISewBiPpQaLnBWA=6 zAzd6MXBR~N&iYGYu3fks77-I0A0PYR_JzZTPT$Jw)4VLCI0&fJ;3mhIl)_Tv#fx9b z@(c=MF;d7cczg2x#Pbt(sPARBDa%k}MIePOspR)q0Xt(hf@_OBRXGg&kUNzhvLexC z)DGIml8mwpAwEAl(B$!UPfi1uW)Pkj2eP<~^43n*JXEpni6&VPfYOM!c^g?zxUwNs zeRowARX7N-TKPLOG&DB5Fxg$#Gzb}qtV2=k4SCB4NWp|LgY1gnQW_F;mXt_?__cK2 zIQ4k-8ma`2+IuvkZ*G2kSj8-5FThIxD~1Cw#=pahH9g?XOG--3E|Dmb0=SC+j;MhX ztF5(_5*Ptt0J!1uKLvpAb=2JY?mhvm29<p_0X$%G@P?q4nOA}f<gH83Egj9R51_24 zvXFQ1^<Td8(Jlcn5G(+01b{_zmd65EvN@0)4FDhddfV20cRb@zl|X~YkP=Qj+~3#T z<?n#OE>An+)*b%d{vm04ZPrm6W-RZ}`@ee=0KQHDR{+3`0I+K{2f)aT&Wbqq{myOM z_ui?Q#yz1;AT9$kgC5iwF&7nCvPE=DleBf|nx-_1hqUB8=C27>L!&q&Jtrw!k!)n@ zc@uD7h_g}1Z5)3=86{L_5P%QXA3R&3a^Z(C#^xrGS2xE3LS%X;hTnP+pHWa)f~PPy z=JxeVS0c;%R0f0S1XSqcz%@~J%CH2qXe>C+91<xnlnQvhpROdgh;0&~fqgypJG*K9 z27Hp;;tbgX5Hvm^>46dqK`|WmE5<jz&e*4Vs$7Hv1r3=iR}evkLAjF?v&$1T;U~`C zjZcn?N%g2hm5xpOeOf*!mnE$&#>bchp>5H@u;fsogF|5il!Y6EQaM3KFH_l&Ay^ox zB-PcP;>75Lw9NQRN3K^)tSo?=FD#3T4qqoXB1ErC$`++|*F<XN7MW`<D_Ta3*#x?n zEJ~hC!)GpP_mPa=x!K7PqdE8Y1G>HPh!pPY<FELW(W{5YCZ_tm1*u7?nebs%*VH#6 z25SK<UT9##0=UKBPXPZxct_=(lQF%rDQWXcfbvo|NxNE6Q$$md6J%X0ufZV$2f~Yd z;rW6?Z~yv@557Jc?gFr?(28Fxfh$D<C*MBt-LCDQ{}An+g2Nskig@>6Pe-%2vA({( z(c9S2SYKCHhcqtv8Mz>>?VWvN)AP$VadxKS;%9HZzGcVv*HT4=h6ENTbdbCk2~2iT zR*`o9%(q`{`}DxQ`Y9Rii0o8Q8@rr<^yMnZr!Xdh+jAZVXk=mPH8EeIUnkcM4D0C- zz;rs}gQbWY;Xid!5Kz*OL0F=kDJJR~IN0-KIS<HMqC&G1u!rW!$CtWG)8k`eld|&) zN>E+~2p41}$A;ZatL@VY4Vfn@h{1;fLdIV*IE4Nz41JJ6$u7+n4Z~2T?AlZ)7&}K{ zwy1B+6T|-06lG@MAY3$NixB<7N$@o?mJzo~vN1Fxyu%1}Dw@j+lVj5TaH{0k+rQnq zd+*M#_g~I2K6Z*=`A%YqA38~<I69)fT<KsTECUNl17-P77UNH3iM$_qMB9~Lv8I{R z(V2YVz}LGE?EmbyzuJ{KzP2_mbBP#%5UBH5u$*L-gI|n0=@&RuUL)T|c!s$}vqd2u z!7?;P3*fBYS&_i~{luvVUjo=Z&L8pbeS;$t6W!jt<d|dtxIzK!?dTb7Plp5+03&`x z0SpP;VkGb%+-|MBb2)*D9HNX_!Kwfj`X+#dtqDhy7gQEbHm($>il2Ny{k1RNcw_Tt z-`~zepa{v>qSP86w6RRZ4P9GJt2FWIv2VY@)P{ooh1G`(AlZSg7Ad%>0a)AH{n%o6 z7kqBuI?dh&V7LZJUA~T<(OEhT@pL5}`uO*ow|{#fSrm2;QqRPRW$j=26(MMeBb9q9 z%F@D4?)u^r1X0^j%YYt53SiK<5*yJcyjztEks4M48<u7Tu<FQmLanHHJhcGi^>PKk zfRjzQk!o$>hf-!hh%0!k__ahWb|EU$XD3ERr<9A&cUPvyM#m**<mID4vZSO8)y}yY z$?>ttc~z=KKU~&MvQknYD~<|r1Hf2b69A_uOq4?zfp2b*vXQT@27vC7w<^DwW1yTC z9%Ube6IhW0U?YNMiw=P0t3|PwRYly(XIQI)7Vs+iIZUF2PKsK*mp1?9D{pOn_wDz- zJeS?07Yy-C$&CSc6nN8amZ1QK)RzT$uGk;b&)7jhq3>`Dn>wqu>7z$|X=ir4_x8J+ zH~;3(UpZ8U7eE`;u_>wb6(gMx7NU@g5&-i^Wkt$-0WfY+**O=Lb2Y0ORHy`w*?j~6 zo&^K2PAeL~szS@pM)VqUcz9%Dth+8RF(x@z0gRO3bpUSf?iK*IwlsJ5He8|vZZ5rb zJ(0x>Xfh{UN{!KlO=#gGbSB!6*aF6wp;ctTD^47v4pE;QE4Z*@%jS>wUP&pIB0`mk z@C&O?i9)!ksZPDnh0zxe?cKTm#|+dopzYUapWlb{<;E6poUy4{(R8GBwDf_UnH(ML z>-D!cql&qvwyC3ka$dtoEpbP-zQ5(`lhMV-3tf*e@VeEE&$}%C>fzmA?mQ7)Gq#Aj zU~0ESn!%C7t))M?*`vdqjGb!vmH8uguBTxk4D-;)X*y@+@<C<rU?7<t0udTC7o^oq z)X=YFPEcYz^y(~wtcPbPe%CPXIVBoy$xKvg$S%uJ5()%orpCvo=K2Oyi(XbAt*DsN z@^F+%K4Z`;rEEhiU+YzK5M(5wVZrL!Fb-;C6bB4oM=P_2gEbTA4Th>PIx6@b#&5*V z$C(OAn=P6hsuFA5XR17l*BA14OuL77M|}PIZ{K<cExq60eI?5v7|}(sD!Hz-8Ns0f zta7M=DDe$ag%+jVu}Nr=k}avrPL+0jV4Ns^2XfAT_5SYx;NQRg>POc(_-}by+F_VT zFb6J5vnTj5WJOVHut$s<5ktt_A~`;plrE@r!vK`FbAB`*v-fCLA5>`Cz#2UQaC>_l z<5&DwMuo;-4uk1-*A*B5R|$Z<0^rtw1Qq~y`#V~Ft#D#p5dhzADZX{9h%I$i)zM&F z4zPj6ePn!Ca{N4hBXMnv!CK6y0p!W#U){HT>y9%~g-EO@udJ%Kky&E|iw~;~saU0@ zW!d4U5AHv5HM0}pzq!f2HYmH^)^3dSbvya>yd}Veik!*ez77O->%Hwg<Jw)upLFu` zZJ!^$msf;1Frv<~8ng?|q!gDoWOr?qr?j*rFXH^Sd-k7>t{Fk-6$YF*6ltvqZxa6w z{SU^2skE%FQpYEt{z>b%lh}=Vq4i7xUT710VE=Bh5LxpnerUQ|)JMx4UbNyApPinl z*0u5w(LxEd#0@SEx0NME$0VfZ<VdOt^bGhGfa9XP%;ebE)Vx~Bf{|}w8i#~*2x0Z` zz%RoI&+z6Wvd$Ided#W@Zf|Z;AM55Z8>V+#w`lgKAb>~7ume$#RYD1ZrKzz<NcK)O zes=3<H=cHSpy~8fMuq$z_}O{ii}knnZ9zNltslO>`Qts8v;9WX)gUllK;8N_XoZ|& zJyZDFafb-)XuQncq5-V&Je$Ck6yED;4dh+kx#j)$Kiu-smJhakeZ7{Z$dWkyAvdHU zkny-_CXVb;ZV^2*#1AcOgk?#NYv1_iEemuM(npK2@Iv>&3q3mIK-h$TZ7j)pvKUB$ z6KkTkp&&jcRV1(g*yn}LX#p&bApjT<h6>&4@2|V^hnqJ2Pj{ON!){b++bB)pHa7?_ zG=t=<GT`6QKX1}%v{b_e>E%WgX``jL4uA2*_cu@oTvom=H%btNxDJd`P+?KZ^<#%l zg%@@&KU$p~>}>HiHv31lm)4V>wdKXxv4Kus18S@WG-^1IeqzU$d#|MxBJT@6GZFah zlFGpc>bhC2uqfm9$^GA5NU9%0uVR^W!Mp>#2cd0=21yi=Ar4K&VhX|&lN^}ME-@di z*Ai%pU=e&6TAPyu9`RoyrbFVUQ&{6GY|6zGRf3j9ZF~~NgL7sc+iXvDeo}07LTYw? zA)NZ)QFzKxQ(at`pP3L7n_f_B>_v|G1bqvnXcxlat@)v>x`9?Mw`f=plRg!+L0h!Z zSreqy-I+uzb{C<Cm4H?_F-M7`s)c26iz0p*^dVD|FJ`9(yBM?EO(G-4=1xv(n#xjB z;_1CRcYb^D+XH*P{_?B+*CgSUk2F@-CC#cplt_K{r;$r^0>PU2Z5CumUn5nTIU<1) zBN^6ubFc0HZ0nA_2e96ruXmqKLSRDl7$R5_gGtwNU~-l8bJFpRTO@wTg*8~lSe%}W z-J%8pxz=K=#(@z=5(Qj-5*cj5Motn3{zaoq!XV(p3INzE0PY2VPl^rf25?(zHvs(4 z4S;WY2nWe^Vmc>ZMl!M3mxbp-XzLBz-)c6E$&EIlYYZc<x_@lf!K<;E`6Z}`f(Qnt znwcNf3V|p!Le(`$Zp_b){qe-P$dbO*N2}9)ZC<qM8e2C9JS2|M!DCb$T`m4Go>70s z#eKWZMxy^$aYdD^*4zqDnO)5%N_T~<7JvD~(d((rQagbLm6+7P2#YC#3TPEf6%0Hf z@k_C0V*YZ`R)DD(R%MhDfj(|n!V~a76TcF%Bw5heEExbnDB^|?7M<6k%tsR~Md_IJ zoFs+LWyotostTT}8eq7j7)8}F2?-gM#%KFT5iFU|m}xf+@w>RZz}6h|5OI<$p+c4^ zqne@^pzw9ul&nMjD{~S8bIrC^=FTljdtNaI#9?RQL>5Jt5wk`$^;>Zy|4X{Cph=Mg zPdofZveo&f<R1?mJ$d2Ml}i^doH_RW!DC@2&W(R0J(@*zgA%zy2uZlq^pr_dVBHmS zvB0-9-Ha0ygfD6>hE?p=`txod`gYIZvllL2x^(HnnM22~W;96_Cz__A%?B6?bF#>$ zlo^X9EUSStYRWe`u+`VdpCoxh)AF<kR>j#;%$}o}{Y&%HVq=J(Pam6o#ouTqCH_&` zWI<gY0DxnYb3_6oG095ckN|E}05=xiyiu*#(G+l_cWokkt&kummMi6n1QPmPS*-?e zGv1_&N6+0)$&~s&DbMx7m1K&MBr^)~7vz_f8h-goeAV#UqxlhkTSxbh4q{pVEYEQ+ znfqB=o}U`*Zg1^CT@jwK;@iiM-bz936I%9pxSDxT)&O<As=TZ)J1h0xl?(UsMO#M! z3KA4eHL1y>)d-;`-kXenlbLSsU+VPP=iAgVXwsuO1`BvLh17|JqHCJOWL~{;Zp}@0 zG8vr2T}lXzrHdb8mMYz&@$%#dn7^sOZ&{h?iXi@Y?Nm^dpP3Y&7!g}+dNHgK!Sf8M zKnUXIW=DFO8yj0Yho(fDK{GVD-n>F5<&HpQTC#Zznw=fWmutP2vKy<H5~bi$Krnq- zCdolmOVum%XNq~nuC8PY309y7%>aQwe!sGgV74Xw+Jy@@BI1(L(^He<@7=t3?&947 zzs;;P2sSd2EJ~FOaABDMCPs`Zj<OaD3^bvQ{6Z5q1NqO3Jw@T?Po2O1ASO9IJv}+@ z!L3U_-p+0rmm|VF`pE^V^blpbS29I9CEe+wR;V$L)l_U~_PjYw<-kiZdyi!IFD=fD z+1f$L$O>Q>kS412*Ae7G&rA(^3*%#x0swC6>=|}TV85!+ZEfBC3gGa@!s|B`!0eIZ zq||Q`?NZo_U|8Rhso`3q<)pMSF-q$@4a}DOnb*%>6Tu<vI0RGPCL$OLErU9x1^Jn& zap8AUy)eCJ`a3#$M${{{{#l(F?Cu>?ayCte_?~DHJJ#RP-plOw*_wzSuf;;mEG$7b zM}3{-Q<~Kve^Gs0keittck^0QDWtvaiv>X;<^feR3PWX2*rjbFV5No4+I6IqQxi-; zBND<NMwTieY2z1*U~!b%lnO;J6?IBMHt--bFx71cf=rM0fv-Ip%)fK_ModCl29L2C ziS6)cprjg|3gi&WO7gQ)<HIk7mzYw}hnO|R{6_J;K((70ZYeJ;KrEo%&t5#zy+elW zm<zN8J5E}%EwVC|x<oa8(xwVVEn^!orV6TYD(*2NSkeqNS(Ir>+@IK6$`UQTXiBU; zD>L{Gsv7fcxe?cI$EM{W%nc`9QC>zucvx6OVTaYo$a+}OV5$klG=aIupt@xk$}Oa3 zid1S!7+3})on$O&&2<z--MSHu)uiPkRx8LzxEmgu-z1gkMDQ#lKsYTTm=&6o`fx^r z3yapKbvMG+nCwaG$Emet9*$FuwEuYS(9#kH{fP@(|5wNgV68;9E^dqyo0%T+7RI>% z+_)aV#s+o)xT)}Fn40m-g*LB(Y9yw5QhlKU#D53~To=nW2zEr}!=AkRVUbk*1i{b* zq{<#`GV0JIL-3oImYf_NpWQOOwmRM4)ipe`Udo!|o*!y&YU!Od2WskbB@DdwaCvsL zzpIbkCTHto?ncC;BNmi)2r3jXHYlApG}_e?Vj_~NhPcYIBnxX@SfDeO+6K;}Duz?B z8u$k*t8Cr9p%bNWN8^+a(*!`(_%vcD`ZJ5cjS!=5r-DLjazQjRqu|0rjTxym16|oy zj-0-YRD--?xaX<`zU)&VHPvK;Wrg`UsfpLlhgXX9klQm#G)NAb>tuhkr=+af>#MD- z>6{{L%#eG&tY)N|UxnIrOV02n-MrTI83ZeX3p~oCU?fVt2CYNQ5)Lv#bdRz{Qi)Zc zfnTVrir=2nl&GkL47lkeOolLbPIg*C^!=3bZl}6I$_#{ukZI6)1{o|q1+FOl37w)Y zSrA&Jv!L=Li(e$gq(nr<CZ^?~WxB4Gjn1X<X~lj{(Q+Y}5T*zgZwA$9&1<6;<!D`| z_DMIXIvIQG@J7&;66J&|bJCB40Y%g_80b0`{kAEGbd^QiV5q4uAwDTbYUw5U!3|)E z16wDS*uX{tHx=HvX#vcBK2V|M^0Xs|z?W_oa}iQNt_^|%Wzr<SKno|ld0%-_WOQ^q zy4=8a1Evt$#Zz1BfdN-qkd>O8n3_@AKE1R!*4I5a{RH^JIXwvDxOav+jWQRx7t;=X zd2V#Le@yOp)|-)#h)aMBE~~1+YPFEV+7zoC<N&QKAvU9SR6|da?4@>$>U!dgQoF#^ zkL&(a)eBUDbB|`*LWlaVrZElcxmkjzg=N&}SkTYlj`(IZiBgSiQ^#Z!S0aVUDG%p{ zd-_JkyK_$OJRKEze&6@!qq6hZ76Dwz=NKZ=si3afQ(007;=6g`^!@UQ0D{3aq*KBC zSdZ6J<?R|pa&1#pZKs*bA?dz`F>y1x5%S_d#|q6q*MBhOrP5o6wj}YW0+^Y~tPc_v zB{~LE%Z)!l{a@s4{CJky2AbE2{5Afo-s;rosDw0xxfM~EiUS6ZK4w|f1Ql72@&TIE zKrlme+BJx3qOxDjLN#Qf+=8WS?xyAb+N`*!=;XBA{QMHhi9ruy^d3g5^31AkvB(6$ zQ$_|;jTRZqOJpuA@hb&B)U$Mpx}xD2JWn0zCd3xM?-+VwNj)$-*Ac@4U=_aFO_u*8 zznApanVG?+{De3H7}iq569L@fII+S3;9FH{fU-@W{w#f=88xx+Wy>I{*ukx!oW6ce zXF>U-vD(ap$jC$>xU@nV%|Q-VqeE3yRYgfrR%%iL8tU~-ug;J54vfr&)Smf1%j3PB zU8+Judf=d7(MY19x)kAbm>3!sJ!`4GG+o$eHmq*AvOG27?7?c#GYj(4lj7nt3w6MX zd=IoFbMvA>tKfAItXnkrHIOxZ?VLtcl7DZ}Ov;oWMn91Pdx{D=LB!huf<VBT{xX@u zC~gi_o-IStCg>t0R;N*?JTX0(d*HP<zS#TCj-z1^6vZgZtf{Y)t_U!E@Q5!^sw6AR z&=w&t;?%+8cgq|E(<obpqpzc`qON^Hu622^*;Cu2P{50809Jck5vc^KdvoUZ0e<E5 z`LjBM6+hywV?Bcj{tAl{qPFf%(ZC&1j+G1?nKm(@PLKJ%>eSfC*i>{6FE)@WL+jy; z)VRp_?CK7SV0lTws5VLvtwypLC2K=$5-pKb^V77>ls)P0oJEo9+g_a;8yS@VWlh|I zg5NSKGD$J98CA+IB)3z805B-!V?~t`mcgV5jUEYq)?!l8Vgf8m+aD{6NNt$RkUg{l zZYB9Oru~(JU2R8c`%*Hk3>o@^&4uv*F#5}c0B{>6aHqdh;=neH)R-S;0Za%}oZ^2B zHxpHXcA>ffq$tQ~g6g_*GS(mo3=e8kUP@$iBF3temIK28ab-EuC(#%>Cp951t=Ky_ zzcfEOFg(Gt;(3_?tF8low1hw^&0~2X;dAtk%Bk^U9xl#|F!_C@w>mp91_;hCmbTE) zIjitXnKXt@ONvd%D>IWIqzg6MRnQx3f+?yOYfnKV;++QauJ&@yZ;iU4%_>z$nQo;< z>6TX%-9@DZ7i8f%!!T4tsX7}GPLoMBu0@O@Uw*V$bLRD5yuRhrUFRM^&nuHg1#qrQ zMw@1tAycIpHJR8Vk~-qfeYf{mc!fo<ROPR%%#XHJSJZYHvAZ<b<f+x^6mr4JfOR+G zS_q9@_inYv1n=IooG}O%_lT6(BfkP;YixU9=`R*!Yw(a<@O`w3v?rZ1G2^d<{KXic zyaEKdOVK_YwPU4)kc!Fikuny?8R->3FazEUAc+p8W}fgxeT?d_LMTZ5KALVWN{WMN zmzGn2Q3D96OPv}bn)zs&h6x_!$}Xhg(wrg~pQbXHbA65fnO+Qb8L^{)1nJ7i=|&3d z6vNGq<c*-9p9!a<oXHU4k!lygGML)j>_~HAY+O=SQE8dfGOUxpCKp;Vu>y%4O@+5_ zRXZ+VWgW72BZ29IAbdr86~3k;i_Fd2-<V$m=$mTFPeBM1@tra$w%11jIw=VW7|bxX zvbr!fFp9a`3SK#GglN|fXryG~3n{wTj!i+#xWFm|91%QJmm41)pPH2q$Anp|vJ?gm zI#MQNdb*82WO)&Y5`$C=-5vYINF&qK)NIjo4OX1G$vm)qqesiBs8CkxnJ-BMvqy#$ zRB1;n#x~^L*{4tS8KpFH?%Zrg__p7?^}(kHucROYrNpMgm<%&*i-4>bPn8GG=#<Mx zcI`fNyVx}LmKR!?8)~a6ukUfn^A-mhD(k2rnyY0ic{5tv@a$k1J3BPp(dD!i_{LH; z#xOFa#6&dlUwQ?heHa%4J#&ULy2bA!G&-NuM3wR8(iG^=A`wd~qydDq^sX!`D=sa@ z%|$~J)sI<{G6=@KL9dY&g$+}MQVY+v&?I$QA?Q+{A5GV%$HYX&B_TY5EJ2udTufS( z7w2Xq#zuo(=mZaN`30JFIuf3i0&7rA-%Szt8lzGV8M|L=lS^4Vpi#<n!d&!)o<}B# zbaY2Di2USW*#6dxZ2*Ah=f|3niItRrFcJWa2`VlpR!}j6lS+BJG5=0jt~#;gmF=%o zp-t9|wmGBuX{XH@<x7$5khgm_%v4K0ic2tU4DEdke31m0l^maxTGTeR_Gob&;@22k z1_(h~cz_pJ1dAV48y(TNseapKXf*N#qbP)qltRjq((+33R-`+?Pa7AP=IPb#p>z#} zaN6)q9au(t7E&|HGk(!2jEYC1SDi1yVU*1E-^kz1*YP(-d81Ke5DWl=yxG{DUC%{O z5a2qFfDK0kz-~S7(W9oYt#7>h@mGg#WFYIxCZr<4%+xqHONNSwV5l{otXrq|?D+EA z8%3t&CQf8#(C4Y}YLHEz#eN`I`{>ItkZ0)otLntv2y@nly0!kDYlnu1TL`NuKpurH zibl&W%_ez*hoIw6NiuHE41mmN8>+sl%;Xp}?aoF+U}?uMb{1?O52{a4bd{DE8ylHY zYMktJgTTqmAf0ew8C53$<}K=cLJ}!sDY6Y0Ig>yt;=><AV%8qCG-+1usg=bLrjVFi zL0WQLY+80zFZl{eYqTB^FU|@>09ca0xka@PjEbQK7p~q|pTQ!3EeT#|k-$^Z(Ost^ z1tu}bcr*N+ie>5hJ~lNqH$T=|kQkQ|0>G8h6RTAU`a2~P%PD3EZz>KC%XV(tAQ(3X z0Mo^zeh9J}XI!A(u6fK|8_EvwpQ)Cdh_HJJX`<GadjKhz8`&u_5wW?=5Dtr&)wLvt zP3~#jB~M1MnXE$zEC{Ckq5TY(=V(R`d17zhjY)yk4VmS^gXZ<=v5|KZ%exGF!tEos zff}vp_a%!vleoyC!~x;>rvj3fdCB_7Z&XKd04$)Okxn+CN`ed%ry0yC0?eIctQkYo z6(DwWpO|TGLGfs%^6ci{y}Nbi@mpEoLI~*B!vAdABCx1haz&*`0~zI>g6IoB?EYly zzMCGaBhU9YmX`aFaprpFd+ICdOaZZ|%?_hAwvV<(wi|R^uD+;YX6$`$w#Z&t%tixw zBQXYUI`z>Rim~FChZMBEM@#eUQh-F*`~<i<VP+MVz;hw4M?@;nLIvJO=^mb)nG%2Z z`rTris=^?N=5)~TmWpHINlx54W@NNC0UQuUdJZEccdp!sic3ONPO=oM>+Nd7FyQON z9K6`Lg!~RYHwl?4f+>O**#<-=GpON3?OC>H{D96~l0X~?tR){fnm2;R?vTJn?3%HJ zGMrFnHR#YYnR+%hGJ$r-Q|%=wVgtJ+aHnQsnSy@w)Imp%KsjM^>CMyW&eR>%Xoa6_ zq7zy|4HPNHy=Fv?@;3*;=C{gjooCvccJs=WFvQ%7#RM)z`d{R&>-W-{L2Jun=msbn z7Nb<^#!-n7>X9LyJS<v}5+=}>(&z|0De~)J9%Axgk!d+4;IEaH#kr|bx3ArZD(E!! z0qhx>G6&U5r&Ou)Qi+pZD6#VtzyY3Qcjm&cGXu`BESV9g9r+C-qFYQnn05{qhXvBx zq6)NeeL3Pu_;+C2b7jZhdG+m&zCLj~*JG-xr7w}T71L@fA7V-MP@w_fxJ!q3eX{xE zL#dinxi-_^SW(_WUC{N+0l^J}E<=eFPMuG0Ta04|!1iLfd2{2`MvNCz{no0x3V_Y{ zC;Alx*BVX{ty@itplgL2ah3q?&bWQ!0R#AGAC3l$8Yn~Wa0I#`7)$a|vT^U?sT=tY zg7Imxs5Jj#Es&&NDS)XX%6jC!dW}IxFp_um=()RzsaZJ?CrB?sOx?9wWu;`7$3@?{ zpRKJe*3g<p5iCXWGBX`)Sb9upy}sQd)l%UXW(FTky}-f`6D@!(L=~<IW&&60G0e~; z{0=Jgbaz=&d{R~+0gO=yP@xAq(@!6gR7&J;XiqHd$YBfmD{mZ4od~{fxj2!)BIi^- zs>?-bom|HCNcw0%9=pzMsww%>k?)UPycHFfkPshx@8<c_r>~_5lLLOo=W)Y0C-ub> z!s7K0fnU89U7YxpI3L|vs<B|C3pI$5g0K@m9KCQeA|@dzE-vEMkEf2Exm(a}UI;fK z$`?!-9mJ*KO3lnQ`m?zQW0&ft%+GSEdZF%}D}B>NV<4=m1R*RwQwR$wq5*&zvNBl> zjwheiw(^XC#8|Gm^wF>0+49w~+qvS06A2s);AR0ZntOUGJ)VM?ONaJ+{LbcmF-m#U z-3^sa)X0tCzWVZp!9b{9-3~^VHrll1$3ghDeoY0i_FcEURKSXTp+5)xbgWrW9;Ix` zxb)pB1}X?A`nyG)?@hUS`g&|~W?sJHSHs*A>DGSU@IdBerrkV#@W;#nvk^AE5w^&I z#B7u=3#tfKorZHsl{LAA!9eE4o%=2&!^<h{!)sCI3b(#K5>~H8ys;3`=i3)=WOm}7 zXHZ&*!XoCsFlS{!wx}YXeE}VcRsWo}UR1lpC4wKiBruVx$feS(;8hT-0LC8?!J6$Y zPmWE@QVDDUoT&hof_`mkr#-Q>rH;S&*umI!02VsMd|+Xx>L@q#=@Lz3&U)4B={i6+ z3+<Ud?%%Ov-;vX2&z?DX<lw#|*V5&Hmd6HxUkN!gchww+Fwn<TA7zMgD#nK*fqH@P z3cBpbz$W?kr5R>>OqJa{`1Kci4xKo4`qYW<_wM-mhg*f#He~lGak(II2ykLDoI0G8 zB-IQQe-*hxfFYUbPwE>9`H*(Z3?)O}R1}1B%V1e{r%;c=qBHG7*rM<Q!EPXO$ldlP z9eDfA&7U0(%OQYKRqd+Dbg9sAVtH~OTsZX2NAJA<eG=Q;O?TE+)%Q9E5l-0V0MGT- zmNg7o{%AI6EP3*wAlULO+&tR&1IVw4Ox1-DPmzRSQnx1F8Xl$Eh#Jwx*v9LvqWR%y zk0&XnpuHvW%(tiRrDsT-8~Bxe{ODiG?&0EON2*F0T%P%nXLjy7o5q%Ha#~Vv13*cm zW@))7T8#wm2whe7jd>F+f4fsoeX;e2d(u4|PJO{I1`KJ&ysjqQ!}D@8V=f%MkWk%L zTL|~JbpKxz9}TJ=CBscR6i{ckjv=E*@!(7(jvID)l9CP_m-)al+zfLU90XfAETA?P zFpXr%4WI2VONvcoDka{tp~=_LH`oaPOH;cb0C$_Fc2PYgKkSQee0_=*c@Y6H4Nmcy zs;JRhcFWrUfZfFHQX+aXFYNr}lkL0q?%nmxj;{~=n9(U0F)=tkw+!lHKHdUJ!RXK~ zN#v3r42@e2KvQir;odr<7pCcRoh`q<Z`%hSZ2j!B&pzJr;kJD@i|xiF6_^f1!7q!| zjp|N!i{lJ-_81^uYcB?2S9eQ|iI31XDV~8SF*`&COR=HUv5K}QZ2_s!IJUD|D|BAE zw+aKycX!Vx?`=JBHMO*ioyCxg3Tk6lF<VvbtE+|tuB^(wd*<L5AAb17<uXC-Ojm7{ zZ_x2pp)tVd*qj0FY*%f$*EJt)-J$_`6|_;q$u!8P)}`GdxgWcTv1nXfSOBmMS{Oyf z5R7bbWpb!*XrLwe$o2!*Z=Tq__s2Lws?vivnRMf4oLd9k4UI_oL6|J%!tPJMIhopS zijyRxLlhe}N0FE?MGUq=F=%ylc~jSsuC>J<`|SPC&m<I}*)h@sq`-zzb+#(!YSQ%q z5<lhoq5a3MUq5m1O3Co-)X?w*5G)PtwP6AhuQdcLmZjszAmcaCSm(`v6YE6&=$hET z04gP})tou0&`MtvSD~1C3;@QMfx*h8m;{LfI{@x)R{+xsZQIJWboAC-U{}hvm_1+K z8xKMYuMhw>_@$H0GHH4g9c~>=dG=34xp{iB&wah+y$?SA_@j@v?mC;w-aV6pBhwI` z%h~}D0G5<sQa(}f_=n2psXe8tnI<3`gHpbJWqy(fp05nsyXDO{-gxt^*MI-Po*Tt> zUqB7jJ!y|7w8p|A2DtSzt#nmA$m}toJwNtFdH~KrkiO+xjg28pfdw%vymO|>GZk4Z zH1Y{@YUPOQp5?~7-+jLIo3rsHDB@>tPi<7-s&htn?HX~{rlL>5r`vX(N*6VAzN?|3 zZPZ%2YfIz3t&MF%>hXQFHr-WM(=_s=w719JB4~>Y@Tov0g6R<^fK93rv<%j1z%a3Q zWchu7LoJMUbq$XBGrxQFH(S2`V*8<68K`oG1G>6VI27=tW!x?82$MBbqkDK|X~wPZ zwr=_Ic)ZtW6`TPjIjSo0*|+ow1Y-|%*&F#CI=Ae+k%n#vrDzj_<8-ao)-EMB5|l$Y z>F%kW-|X1-#=FOh#ulggdWL6(8#8^Aj9>V^NlO%xq54ea)F|ydXY)UPfeL*h9};+B zTA)jfS+!>o#?qR{s?SnWjk428c;{CJDw3m<vI$`L1)6;R9s-z?8Nl8QfYI2!yXxHE zM_=f$lG~qd3l9b`2^av@x)s&(1NyQOt~s8^4{!b745EAU@85j=^|v;Eb~=st9qSvI z1P?=%xn#MJi|RV$?;!!Kwx{Al5zKg!W_`+v$m(Luf2lTX&*tC!@|9PA``+#wWdYxu zaBg(Y6E`%Zg=rsXr)?^JO(0K!scQR^_>+rM85j%dH6KxTA|jY>ENN~iX_Qs~8?sh& zLD|6L&vIkL@$H`;iO4II3Jnx?H?ktr=~K{(wkFlcj43Nmytx0HFTcH-D+=^dcSD1J z()qlHX!Tf8T-l+C&^W>Au7(<)nbG)!tvP?~d`f^*(N|}tbemfsPo!tiNMKPi)Fr6u ztZvdmY#E(`X4d8#u5JFS*S2i?>SUC3`I5RhX~Yn+Z;K}{;^dAkA8tP!<y9FhJ|!_t zz=P+ddAOK6Pk+{$@9+QMwKqTf?p`5MeBi-qlwl#l4y`_ec_HW$1D9Y~Vf^KNUwr(= zFW<Y?vifKNewqdBS2iiZ1b9wZo2PuAyx#=i_^YF-xn3t_|B1X&0kHH(1A?vJDq#Ow zD;Q<t(kFNM(b{lTYJ8G7_5fh`1pwe-0+?YW%tjI)mX1~_JO0lgflnu0e)ogBPQr__ z4>^=g$jPH~0Q1|deyjnA;4=$(fbPHS&pNgJ?blv=_tWDk^psBb^o_v)7W`^E87&|o zU*~;<`b4fO|86p(A%V>#K^10?R;Grvtw`<dU2p&DmEUaM9p=&WNx624M2+aF@?|`9 zD%2_Ym5(Z;dJ1~iy`HKJ=0CbJG@v1_1CvRs>37T<5of8fE%n8owB42Z=%ZhKcQrK! z04}SkuB%6pBoOTL`CzxTw?aTk6bThc_m1w`efVyf>~z83;OjNPB%ahvZ(U(dN$Z4k ziI*dKIPGt!ZkY%{?@wk{`i@k<xJhR&C4F_q3oVBJjCh1aJXsA}Xqx7|OP^gO3J0Qh z{Q7qvY~6b?LF$2Ieg`Mwm|ouUD<H+@!w5bmUf8wm-FLSgNmEZ2$C=afxnvz6&j9dn z+V`7({p+{39f>SPZ$o;Z8)Y@yI-HFk;1ZNn!LsC=hjx7U`ft9763;ivyChOCDbG}- zOdU5S(5usg{tOa;@_y2-n|Rk!_8+$ZHjXOwJ5%5i&r+m_pXFElBIzv?^{EI}I{<ES z0a&UC?Qk=1TT9`&e+LP?>;B>2y%+9~x^o(9o20cmMWfX(t;V?i#Gb_i`!X-@|MK(Q z=QHSMnd$8wodaB@M}+n!1{rAmght>)T?pxqwg$5nCG{oX=u`=_I69!iN^9?azx~rM z(MUHSfAPU`?MU(m>y~y+qWLkKMw2d#^TC8vo*)*VL@26j@)|YqgF9hHGy_R+mvV3b zqyLX>(U=VDcfHaSb>xS05t*2pT2fU<A1xrvKD*MgK!!Y)m6qhkUfRF!ctpKey|ey? z)&U#w=0VL3HkB89{E)z+=*bCA`Rl7&Ln7E<JoFxQbK)$w2zIteH<oG{9ETv<6y%~( zxUge~vI8GI6#eC^ufPB4fon;UkIac0j(zX+F7-Ab8jNUu>XifAKX~n}uWmQ-h>Q+~ zE<qARkU0c`<EK$z%dM@i{MD~Ee|{<ft&F8Gv#!Ae<ID&i_A0NhMyJ$@vh?s{ySBge z`j-(@6$Ou+mLz^}QKMvwnmBKC3}f>dv&*eM^P5uv;4z7Fq7R;xwMK6?f7I3l@<SxB zjKP}nX2m6D1Oqtz)S(CET{2ol$BVXMyl7KR;q5Jd`1k+)?u$Eq`Hmg%?Y_TFI3w6> z#=quJ>9f!piUg1)6&00Q#nSVIzV2b-S8N$==LUwVgX?(b?m$}5htZ=c$RL6(Zy~Ah zv}OiP_EBd(GF}TiY<3y=4uL8fE&51^LQ8jxZSP`S(BeL$t)M*QIreGJhTm)`7yF}& zR=cCg)w6y@<bAN#r(8S4V$0sx^QUi1A{!bNAjg4Y7foLTpSQ8P5+mDkvJf{rpVT6s zG1Jl5Hfqv`7`9(qTbdeZ_jQa&eXBJzru?-vEM5=wJVg#05v=h%aw#e`vPC&l?MX%T z(gf%Yeg*W8=~V4upZxl_?|*jSS}Fi6BXMM+hH=m-fZ-kXHoz=Jl10XiZ@+r?cfb4e zYMt?8$u*%v8qzUQCO?RtQj*XlvP^7L=WCq(t<|0X{a^m&uRr|atO2m6uAxc#rUkb; z2D<>asK^XIw)d0Y|L&6;?e+s`=R*RsYblisW&2jDsh3@N8!s~W4Ab`?&mWVPjpGop zY^*gZz*XZ{J3a7`o+gmM(*oex=Iprm48+!~3f(u1wz5B9J}?1{mXywb@9f*hKHUD@ z(e1x@^HvD1yb1W#_C9K;t2y(8yMNYSFHTLEdYGZEfoTyBqR^TaoSGr58R4puKK=+V zcZ3^_Ody1@3Y*XIXmz63IA9;50LXQf3<a>}esM{fj!Gh>-UJ<~;$o+Gp`6jxpKqTk zfE^Eyc-tIJkF8o~B*MaxIZi?Bvrg>MLR);;?a25PlsT7IR*ORe29Z3dbQS{`h3{#x z*UwzZW}d@zM`Nc=erD02;AV9J2Z5wO_DbSBnuk-J)gE7n+g|rNkL}-5CZnx#p4=jf z)sSBfwFX>~Wt1kqq=<K`&w&-ZS3ms4Z#I9j&jGNsT?zs)6b%6|S_l~l{Mz;#O#w`z zZRcRGA9L#2JlxyZC@mvUZ`sn`GcYz|8WPzr_g($qzx>6o-ghK$XaJ*8jK@<g0N(Y{ zYroxgz1e)b7WT^?4dW-@M=HC>5$;dZcmglyI!Teh3Sa@Kn7QuQFA<FHY>H%YM9&C- z=iBm=64UaLoF+DKqtD+bP3;uGsA1@U4%X^JqbTI~R5p~S+&FvaqrZG3qy%1GW`U)N z9|=)Eeyz_W!}VV<hWbEcKqG==`sHg?5CM!cv4TFdfFLDmGM_0M5Pe#de7@PjP|r|^ zL=ZV-hMs5zvwy6q%N6Y7pRlNShM$W=trOA?f&<ypMgq&#Bks)n9T*BurkXgTpZ+Yj z<wi!LBnJqVjyixadYhn8K|RW<D@&2*otzkc<xUyp=|sD)&qjYWWt^Nsj1K-R{Dg<J zHr-L>X?2W?4d0&uu(ERMLJZ!EdWjv1V}V(X;uaSFofW{e4%c(Uj>xZm^Xqp$+If{K zv<#J`3hmgyXljPuX;3m?1DC=E#!R~R4<_4uER2#L?QKP`Bn-|IhX4Y)&`jVSXllen z06@9LKZrql&NGy-`?bG*<*n_<VvG$86<Q^*88{G7p*<C;VTX5YdE>2}F=lw2c-xu1 z$wtv?<(o<OMprZV4Q=?Pix-*zW^Y4u{tG;WFCi>bLijL6ZK<;`5e)|vz+UNuj+Q#7 zez;fJ(b?M4gr0A3h18ap<mF}NmbVPm$DZBu-k-i67DB5M32f|Nav8<1>qY6Dcmk%M zB*tdD(aH*+Mh}+upEe~E#&xN}EHqu2NR36XhyZKDDsj#X^cXEN=mQvlq6nr&D^oO> zhNbae*F}WZFdl!K5W7<Z(?k>k=X7vNBt)LYYo?XQM%%~RtxS#CTGuCnXt|>-BR)C? z2rh>61)2V6Qh-EZ4~DarqMuG;Y+_tSt>&P$w+=ZpD@)V%u{UP3F32(-PIlJTc03Eg zy62!^DwRVOIF1OGVI-QMDvm*Im?wTZRcchTF$Rh26laRhZ+q+A_rJVACl;o_qYIME zunfexTbXGl04|I^`SpkIee&G{BNCS;NBd9>+gK0E9vGXF;bQDPhDa-#hoevy4rR>L z?HQbOEU4zYdw>7C*S8#sfEQY9;Ck4=t!>r`&F;hEGLzNH5-;!G_WtHCFIQ?a5Y|sZ zys#xE_Q(nt5{(hSlDlc#d-@GQ#4;QI?a4y1fdOEZzv`?~_1OZK2<BhTN=v=f-jbxa z)V#v-D%effXGa$#@bQCpN_}m<2Fy#Ut*@#;OT)~RgxJjXzPgAbU%l}ke|s%7fMw>i zT8J7OU60q$?r7e0XiapbzoQ3@ytUR&+i%kdmQzu`fZlp&nwEdj_yh$nL1JRTN+zqL zo&Jf(zn4K^&8*N!Fl}IX&ZPR=1_VR`hj4~GNlX$8?xhTZ@fnORP_#?Z5Sr8p$1pA| zyESy;>=}QS2!6EI=gC4@tdu!RUxX@Dz~O%+IFulBH$EmQy{JQ8VP&w*?|hhW4*;0L zp0}n}hMp9)=-KYNnl?9rpZp#{<?s%IX$Gq|LOg?7Tp;4f`UU0RjRp{s9gpT;L~g*= z!{ONiVDygR6nJ+(?<OC|!j@O$h9CZX+n2}UTJ<GohPvC3gwfeIiY%%1H;t}fvr}V( zz35R~SKrb#VpCX}qks6|&CPqRrojoVt7%@0M&%?046Es|frt}dZToEJ<sw5xx=Xe5 zWi*MVVHvel3Dw5Roal|~ttMj+o+_L|Vl~<*0-{dlq+|KYFb$bNhKB&2hc|Mqza$|h z8ETiOrl#TlN8EpP$#rdOf*9WPpvN9V8bj)q`k~c7Krh|ZrBaouRDEyVdmMQVJpqsa z0fHdBH-z_u_ud2Pz4zXGpOM~s?=$hFIlnpA-a8^AGa><2Y14r~WURf`n&0$>TFW#x zchy8)KJ`4kw6dgt5(Ba`(^6B@=!uUnYU$2>cx>z6|LtcFt$cBN`E_XM2MGo7E2wmn zz$?lQg)g&gH*q@H+|oD0G=+>-q$X4Aex$Z&Wu=C3ynnM4Tq2FYP$lrko+13iL|0R% zXLDMch*3Mk#tdt;;!G5)8+l$U3VwN))zQW~g@ht50yYD!9ch0vG?Roh4Ze7bK`c!V zx3_y?HOsa=P!LaL&hb=%&J~$?1>|R;0;ODPA`u=Iom`A-o9$?7v+&5=jpE}BU}1?y zOM#mZGI(jUrNkY<E8nBzPw=A<!tm9=4}oAeVHmk8a4WF%<#mkmuE*wadV^VyPwb=y z?$OlFn=>id2u5y&TR(4V|Bx4d@93_B*JC7?a$%^QYC4+QR&1iiA6i_T8tiB!W23&Q zTa}#F@JqXX+I=m8=F(7RD)M4boe7aoZhcAQ$j{G7e13l4{xeUr&DFsA5($iXEuu$Z zi`XTzNF^L^QfDaS=(Q}mnmL-~!`*i=sE8lOe`Pe6w7r~|;-<E}`OzWa@u?Y9!B<jR zT2a^3ULAh!=>51Hs+melNlVM1KcN98b@i=-^AiR4_H6vizy0jK@tT_pqYGFEBG6cu z8!Ptfz75$sqJST!IvTntX_@T`wAIDjNGZ?~-?GGEy?;O8As$enOay?$24(>BkInWs zH#xIH4e*d)A@M_uu;UzBHt<<Iq49!%&!<RSY3KM+)mVk)v7=l&lZvH)j9vYCs)!xx zb_}Fn<v?4qqu&Rk295?i$wTrtH7-0NK1<pJO?EVO+S)juj&=q%fi@$5*$l=TER4AP z(4tqo1$gVlv#)*M(6R#cU5L!#7A3YLC%XJ(M~Yux*n9K}_59*gO7!!V=HX}`UPF`V zX{<AsGX&o}bo6GT$d}397FSER%u-tQq1Gn-ovq~YX&aQZw7$ff2X~!+jl@l|xoK*( z)&HOHi}4*iY#<}z-pRvP-Z=6H;QmuXpInjB{TVVttbEI~^h!HJPY++uC1sqFDG`g% zIjCp}FXBsn$^XY*ZpxIWmmRH6pqlxV3~nb^Tv}e!)La>S^3dIwEIN?f{L(72@kgnU zPfnov;lV9m{Fe>S+Ls>)NnoyAHG!3nCT@FcO9QUv0Xlt*F=eyD0bo}7P<`gzvbJeK z68Qwd<`;67{F(6%SGU#6P>2T-7R^LRYZjj{$wPJ~LPX(DMSK4EE$T}ACCJo}Dl@)$ zmiY`|Sirgfjj*8!6WY(&2QAJwW<G!UCMGG9MjUgIGXXd!GbuJAA|jous_DAhntSaX zqvB7>EmdpAe>ihog8F!cg`wv13aewBFE}{=T$+`@IR^Zq=t}%_oLtW0N%Rktj$1#u z{A6dUf-fIB_cAVt%7gL>x$ed^4@dWZZYY|Qos}N*;>x)PX{hO68f<TA?;S(aSI@^{ zjn*H~eC45@wx*^Iam|mU-8**b0X1yl?%`a_K*4l<D5}m;U~2!LmiYF@nQP(YmJSEP zf$v17*C824Tj#NrfQX=oUazz>{NUh~BF<f9FQPR8!PtJn1N0%ohg{ou*ZJ;>tPHwu za$8naR@XOobk>DmIPo&4u8Ai84NSP_!ZwHBI)7~M*(j@@gMBpXL<<vv;>EeUmV1}a zPItLFC+KRWR8|0tlyo{3vDxUnmQ`{()&Voo_BF_dmPa&Ud~UYa)#{#<!f!6!c%;W5 zxlFlhGSZ?@vMM`-4!zPv__bB*D*5}MU~=9)kLThce?;1<WGzxc=fpr=F;_+V@ys=Z zJ-YVvePnt8d9k!lLHOIZ?_z5}X9F!Q&f0xeU_>_&tKa&C$sCtmk|(RY!s;03$6J_> zsGT7BG?J~t)Xm-dm`O>hir6%2QLOakb9Ir|F5L@?Oi0Pj;l`zy;DKsF0u+t!pdx!J z2oApc`!jL_(KFNEPTl{P$9d_G=7#(FM=hU~wcz6HXm49{tK^Q3W<9)c>s@q0N@i|h zAtRW=>QcPO{xTXCLM=ezLmytf8&&6EhwRYc8O91=X@@0S1mCw5Xz!#m`sk+%6>B(M z{pi9_XKNF6-e_y<=<4Yk9G~b+x^*YrJHsEZq9(5qi5L#!@vsDDhAOgYc`(5L7c<;x zw7IE|t#m;WKdf1B-vD+f@k8)L;gQz|P=vq~S#2R00G1zF8gFara+~o0=Mw*jXwWhi zlzq@BEReiMyBhb?gs^xuOrZ+<lGsIyxqS3L^4;^4_AoWp7<vCiMpJiZi!`TS^{IGw z>D>8i4?}49L`Ft>LUh2hJ2#$0BD;U7r>WH)zYYLn#)kp1`K8987l)ck%k93)zFxup zbBQ8px~RI^F^81$%Mk_Elvs)AuV$7kx}qQ6c^<?KIY?J5<96N@>85Zl*Ygv8voez6 zqF+6Jl{>_%PxW^8*bNZf-gj}RwV|=oWPCf-^`#kta2wMcmzqAm^)w_hJ~cf@5KPU( zc{MIRrld`3KTQ2U?mdh)bx-^=kSOf05wej;H-f-m`=Ccl_Ie?m@dq2uWvt<Bt&c9v z&5>_iW}=eBoyd6+WGX5>zm8|J4UTvlYqAbwDWG3|l6`2cxY*y+Hq7oKPU5ft%&q}6 z$bpv>Juz0<GNhZN0~rJ(sZygAB7&WX-3Ibx15@%HtxLmZ#}&Y6X3l>b|C85+*Meyg z;{1vdsAdF10F!kie>OWlLh}eFtL|=IfBgQlr%waYT7BK{e8t-{yLKM9eDBG#m(L&G zzj@)elUGCQ`Rf+gsqcJ0@eV_27S-7SU;|}&k%b{wNySGYSYXMX47jnxGswfEq18aM zR;>oSbCv6CO?dq>FeD-&nGwwK5ymiOd2>r03UtQDhKIh3DB{~(9PR5LbD!Q}Z+ot< zp|YABI)EI!XLcN8ae8c^s~@4ZiNc_l?*k&ZdpPy~FQcZ*vKn{)Aooxrb;o@3Hm=EW zoQMjtL4w}0Jd#1Oy)~as17!LG-pFM9;kO%uo2I8m`+ItHD6ln+u!ob#_#c`#s=wLU z*+moLc={dN%hU{!dm+vc2nRA>CpcQ1`63wo^L227Ksb4g1>j?Aq3)@68E1sD0$T#J zLJQZPboTRFjbyVXh+s)rgjy^QG7IE|Mw=Qv?E$1XidPr_=K2ZrLNhtLOq1SsvX=dU zAsZEekB(6^qX1UplO~6bu!`34^qc?im!E##wsqH)Xio>?viq4Ud42NNty^~OKXl~C z{yjTrN_hm@Z%lT$y4(dgyu;G6#1_34oK>M#1P{ADLI#7Gi%RnWDzpUG`A{*SPki5E zm8bw-DJV$a)R`UrJ}59e0Uh}{?+TG_?ubPLR%rB7M0i3a8yd3%{ljja4L5?E>!<l0 z?IR3eB<sORf*vP;^bCy_gH<(C8W|827>WM>R#=_P5~@PNxYoen@GR551*9aDHcvSV zG-!kDd<L+@ORO!fDu6%CJo@{e_5`MpavmEU6CFuUG(EBAiHV7$@k}xN#KpzYzoVl` zLCB)SJ1P_{EiNrBr+ElfG-5O-<W=SxDUsfvB(OxhmSuSQ$pJh+Ht1>^Vs?OvYyg;D zaKvmdyM^5@0I;T&dRc@i0<-}$SluXsVBz`vGt-@oT^?>M$VBxfYWj$#9Kd)6ttpwU z{g~X}Q@#e=#nRdlbw*wk^)nwBM(>chlzo5w>(}3X@sDqRzLaS7U0ms4=PKTw+O}!q zPg}SBvSsrxhwrC?MU6JQx;!jDW@Joq4*0qw8Fy;Q;L<YF?{5uP3Nu0WXfeep36Y|H zjU9smV2wPk!sdI+Qe%Px(a)O#-PFnq5A`9*MnC?T{1)Ee_`txpWmmz%!na%RJlWsb z1GdO-B~5==mot8m#p%&OuE_c@+mIO*8ifA;xp~w^&sr^$43jXbqAz#530^?rz?4Y| zx=|j5f=S(>c?++EGyC-OfB%o&*PlMPf15he+_-UFpPRSbo*VeT8}yOecOE`{{_<^L zU`SX*R8$nXDkGu@*a6R;XL}^o_;F#dfdOC%aenHv*i(yaU6gmo<O24fixF)4bi%Y) zc{#~;1bw(682FVfE)2G`cw{M<$P-I`coW$xjGQ6(S|k$u={uBfz?b3Tkx(JlKI4}d z*BIef6v2tabDP%x@WaOMzyE&cE%DN<_AJ!|oY?Z+S5#EJaqH3Ng;1wPTblYkO&^hs z0I*YeRuG$n4r2!oyUNSkea2+Wds(C^S0D{iSij_4O86p89+ogu8)K^+?MQuIY^Vgf zb7=+?2fHcFjJk&>M21Bsmv%GmCI^SLCxJ>uQ3)O2%B|$}@Ofz%5r(0ICMbXd+;<hH zQ2+nvBwCFZ!fLb}O}`5di_PR&d+ra1fd#;lbR;}V1TgluIxyy6eEIMHwEonkd$(`h zxOVO8)vLeDa}EEq?4dqTH*Vf}{Pe}^w{PFSe@}U|)U-1wEF|#tqnBAj@@AlZ?egS< zXc)kAT72^9)J>wXwXU7{sRCHKRd7^?IGdC+2w!uyK=U|G-hd!PM)wG_1-~_cM^004 zIf~Yy^Ff8CTjjJUwn$}w9)yM2;2*)F41ReFh;y+DjY);<o|~N<8yc3eJ0E&-o*&=w z^RGL8-MVT0=EINtKycNY;~W3+x6l6Z({FDo@fE$zZNtm1#R*_5|H|mo)^AwRq~WIW zO5BM*j}2fo6GQ|{?@i?6pjo3xCkKF6r=9V}4C<*Koxl^!d8h`(%BZ(ZYHT>ctP=M) zF(OSYA;?Ajl0dYVmxgN?M-PvRk-_Nn42btt#D|B5k;KPf23ajPJt2mc%cyhno#<uK zeqaMD-5>#1#D%3}=&N~oo%vT^|EItHxc&E=Po6z}^xy%FBfe*zJ9q9_zouV2;D`SF z{-ejw0)m2qLW4s?BO+MmCIKAw?CQ;Eag`|R@RfCh&mxh-T*aD<UGL;D;%Y!wL@BV; zb~BK`Y+7*bu^tS(d#jL?ieP*iCYKw4ku75PPZd1~iY2@eT+Sfv<)E~ywzoE8el>Cz zxg*>~Qa!mymR^y@(GQPJU=YQ0bIOxTCypII{o8NH5AOc;*W*uehkZe4uI$B;AHMni z*K>hL3ZCz%Ygt~y%?z5C);exAgRODhmRao3qRXq=-3^YFUqtUjz@w)xHZVLqm=WmV z!djWOt!1csF7!<>1-fahl}5Vr$RZ62j4NV=c4=%xGa|KPEFutqk5>SLkqccYh86tt zQl!+K7meobnKZ^l;_7)hlve&OG^KL6{Dnn=cs@lu!K1_mc6#Yn+v3#oum02DzTL8O z&yBm!pFMv3@WG>pcnGNS3(x2AqeoAkK6@V&5{8E$93C9-`svk^$6r(#1rH^2{@@Wd zFiUGUXSpvzTk+4A`d!T+Q#x48QfCPahnxEL5V=HI(8}MT`m;EC<uQk8UFl3uokf$v zr}<-C{>H?{O?6N|!FXn6L}}rV&@phAP^>^fGR+eSl~mY8<E&}?J48xd!mC@q-@O0$ z<%<{3p58pW|G>F7Wj>=xqoqODPn~;^gp`}fwt9D8yB?XQjf&gKsYI)53oj&04;x+_ zauI_4mBG9{V^7J^i-E|2ZMY(dDe`wqh}2)ZYqUE4`TggCk(mWDmZ2yoCF=e2X93yl z+*=wOhVlzF$}sqqO&(3zaj<sF68<oYaVbk}If0KKzlliBl`#;MUK|tf^686MdxncS zOVf;8=!P^mL#WJ~9a~(PbjBWk@gM*4`8Vr-*>?5Hqx%o;-MM||w%cPH!}_b6ckbN1 zPx6?6{N%~gM~@#pet7TZiM`u*J}6g4<V$V0!NXxBzGz`}pR8iev^R7xujix`?!?0O zC<B<oNIIp6Fa`yB6%HdhA|I_dqU}4i0KCxK&}vo2LW4%m4D>3N7Kj5wW0!ayj9`B_ znqRyN`aMXEzFT7c9Dtr2A08RwOjoj9U8zA&pS_}v$jPaxsmU=f?_R!gE3n*}WVF&U zG}<;Ts}>&{Y;u|28*ZN#%2sW|>3n7**a%_;u(mB9YAmnr^4ku^F&U=F@fr@2QmZip zNrfpgfIaj}9|t#D7V`VK3%6c{#L;<>IU4Zv#+4gSQ-EJ8BbO;fl7J^C%YH|1(F!IG z!MO%0)WFj9XXX6cQ=eSBbo24s$XH%3F6`BvE0^wv6)*QgXvCW~gn}!{#Db&UIH7$} zME|3&|M{<9eZS%R?b|P1yma@@o!hqvs5b?yH*b<li#%I5$UKH~i~f5J|IdF)IKOl2 z_MJP|P98tBYwMPMPb%yj7C-$p97d9x5Dw_;ZGHUtWK(?)zXRPlml22x%^kWq2M+-V zByI}%ugWgK+_jabA{ap={h`Hy2A8`vBcD|OPff5hf^)x&6HC7C6Srr6TwhLgXgFkP zq6-ytQ_Ek7lJUCin9vZKhfA(dDoe=CO^SZ^;@*>lYM%%u#Tl#2ch=Q=t9yonfT`P# zAQ^8KcL20BY0K=um-RPR*LHhNa9Zg^L<$S*WCeqg&6v8`21b_!)oE7CF?9dx>GC&c z_HjG!I}aW_ynF5Zkpn01C!+-x$zK>9?8K15IQfTN8eVTq%yXd%;~=qIKC=_B7P=B| z9@}%^^yTaKA3wT#<LuGB2hP7Q@#06+uR<mVC+-`%At|Fn!h8`;|J(gP?Kp7g$l*h0 z&YpSp<njA}cW>XkdiClBJ^1%adGH(0_<8>P*|R6lDL;V!e)90{m5XQ3oIY{%$b}#T z{uPP7)|Jl@fbGlpbO4XK>ia}(1C(SY2W!v*U=@kdPkaRzh337`-H4KE2IhGHeyFk0 zaUCExHvl8Af)>P#B6ULlK>)Ur#ncP~B@upy3BOREsq;-X&*P&SUj{He+1aV_;qTvs zr#ASRt~%9P+aM?D{$QgJPi`S#^FOvF%!F+xug&+nDr@2G_4g4!q99m&w2WXG_UL4a z{`35q(zj=JZ~5uhU3>QL-?e?)_QUtmkT^I>UEX+G29M&*V7rv}x%>pIVi$J=8+oua z&GojFewuuJ_lEC(_<6_9JrtbV`18qk6<*R>ah70q4gfRRm|k|i+5Tj1z^lNBXheV$ z6BB7{btxr^((o95xHE%{y)UP6Q01kiG~A6^V^UQV55~>OPK$}4VsNsCBf^3LBZ@V` zwFYHT0c>8=Kh!%8)#C?-Tn#p?P*6zbD2IUwz-%Up-%!!JqDm_!E$9d7sOnE}6WOCp zb$vD%Kmbkv!(NlH707)J=9)hw4q>hd1qi_{OpXo=jp{tF;l}i^fMA*j!~o`p28dE` zjmY58sN7b+<ls<4rDwsF#hMjX9st&)EGw2IE?V?2;-8!yq(mlbWP=}DbSN3dEWw## z#))7HM$j54X1+S$%=RBPZrrr_ryn+MIrK0KD%40HhLFMlLI)6$t0Mco1pZ8jSUiYM z5v*umoDzk6G~>pvU;X{dufP4~>o30k>BM_&S?jTPsN*((#Y*6|DiVD(dfRH-9P92G zraEbw4NWzJ9FFkgc)2=mc50}<n^K`WyL)+>VNYlG_}ca0bx?&Y^>Pi@u}m^B>INH{ z-FnyZs6aI9G<Y(Oe`%}Zoqb#87fV&vr1U!7Rvd4uvvopz6<Dcwge50V$~tWT`!6iK z+<^PZD1f16@rM^@s96NfVdP)WcUL6_F@BTMvS`FK9vb1DkrE#s5)zl?@?GAr&|XpQ zy`6^2MHc;T?kl%482GT1R~lFJhxx&Vvg+<N+^-M?<gfY_ET$-v7u^8t-xoIopV|8D zKfd_#A75-Z@Gu8~?%}=>1l^=m99_61awrJ)qC+dWLWy=Fm<a$EN6Zu$n$5bl^^3p# z=`Vl&(`Orx2blg>9(2omA5~Wvj-;uS(vlKe^eut?f$Q2o<1c4i=l0e9{*>qYnCn~Y zceS`#d5aPVMmIEMxWI2JP6+;?6-^u_9T;J7CJ4c}tvcN<0cSjN%1FLc03(w_ib^bR zqJDPmhq?SGgvY>;#~)JocXS$>+tO%beq3Nca8zO{B_2@|VmvgGK07m&TjxY3Rd|aG zIhPn~C@N|4>{wu4URag7>%6Mbf?w941q1qujNmGV(&FnFG!~Dgq(a1Eiei?0j8@|c zJ-6i_fBEy@zS{ku5UR*1<uHQ~<fbICSA?;?{4x>|wxU+B1Htk_{H4^%2zKyn*43^5 z_}72_r$2vtG_cX@ekB?ReyG6<iFcBjpq?}Zuzw87*O{*2&;5m>JAhZsO7~;+`ECQ? zxydm^_NXeBOPLLTHS!@|tW~}cmjqhHeS$^G$7i`A34d{SU5j1P2~ME(eZ(d>sg(kH zq6%3KQ~3fvjnLJ0t4@BfXMmRap9*|GO!t%}Mh3nQjiM|9>Ow)OuAItOT3Af|*)!7; zqJo1%5-L{pWG(hq7nHVo$FIDU$R0<=h9`~%zZPv<2(Bjt`*Dl93WN_hr-qTFREM2d zA8(el#QeT@^M;=eSorN7H>I?Qdm*n^<u6uQuB92V$gD;F);u3;?&Z?d;2@}EGVAVv zAHVx<`{`hp=f3sk;Q2N@iYv-EWsuB#^r3d}C<eOUNB2j3&|i+>0pPV6HOpRfwx^*L z8scz$UUpe0m-S;<AU712F3n79MkKCsB8U|rw+aFn_6XqHUYwQJj8w1gI+q0m*)2>b z6xa)Z(b(S+@%Tdl%!$IrBhEQ^;=P)vPYn+ZCYMGkr7RSd@;qy5qDX~vRLfRKO*RrD zL*G3QE?Whj)9q#X<(;dTQ6>Pb0QTn05*#?qLu{RDlPaov{G<#~9wn^f4q%~fHwnB3 z+V05>dU*RmcolwRqP=re@r#UJbdl3yW3_?3#45yGGH+*@!SH;^n=DTD4?w`rRD?ae zap!FSgFt-0`tnv5dJM{=Sjj*YDyq8G^74puuVIt^BiNf916lcbO&<ur?#ijZKj`%x zXSy5Om^jC)BOl&=pFc=PJ!b(JIRG3-0vt8O=Ur1!^NZQ9%mP(ib+Ieu{)O8y&Ah=L z4**Np80sE(CzEghnnxgLsKV0!qg~~b$fPg;UYwnxskswlOo@|~5igzug@*As>pTpI zCod%bO^pYsp9>>6I{5j+z?Bg^-c+1d;m!SQy$<(EkO#W5X-4Uk!U|w3!eZKVEew(` z+D|Q7s#}msV^nC)F6Z=ePsiZeNM^3DzPesKoikk>+`EN0gaEdRU?|f(2NI4XFMcxH zL$1oU=o=Q9(AA9g4ajQ^HBk}MN>zH6lA&ZHxzJK?Wh-v<MQhulUql9)raDbJPn$_G z9E4K+Wf$v4+H2}s{OjE0`@I;zY<=`+JwA2(R&po3#T?J%fCRPyjH4F!z=|h>oro99 zzL}}o_rLve@I^Uy1zQ=wJW+)-Aq*xo8F3B({}Gn~03)4jewuoAkB+t#WK{L{mW4jN z^DI0%J|&%cy71`c$|@d~LfvC{zBC~?J3Tr2?Tw2;Wh;o-QCD$c&FXba%+w@JLp&{B zRB3Sn+4w~zCS))nxUSzPZSdLK0A``cjr+KwpG!2gR90*pem?p@d)s<ZwZ&WE2)6VO zh5C;acHV_IOG~u_M|?t*ZkVm|Hgf}AUV^?h1?!vB4#Za`HO~?Ub_ejMZE*$6@Uq-* zRqFLnaRZ7nb-il<aBE(8MEXbc0QW9|dtB`-f%|fvo;&j}jny@(vlIYR8ZBB>p`cJA zNvm-L!M5no@M!S=&eR5++I8%81rPFCMFOKkHzcr^lvdwt$onVU-c|uj=R7so)j2TK zUGU`8&B)l-S1;ZUj7>=9an>}kn>w3H4=8Ht0t6T4WM?FY-a2+Mpwb(H7YAyKOX_|3 zxWs*<jorO^vm^}T1Tg&ocC|3zs%r3wU?+fiF#s5ON*(}~lloWy50e6|SwE(omnhL7 z5_MjB*D;|Tz&saMmq6VC;HAl~HeUxR&QI}Sc>}P`4nBH|E8!RLl_9DqniEj44yg`V z|0Qs5L1;)?!)iX0HBkJF0(iV8?)A&qDoXubqIYxxSYwkga98QU1@Wv3j>Opk;KlBY z7q_3Ku|>1kTi4{srDVK|(2=}dBn{aBmhW1_PL_Xk1ptrtw6*t+cBNnZ=DQ>3PaM7Y zDAF2d&EqtwX(F{?<o3ih6%|E=dDN9D<>~Q57vGgHNAN;VbwNq9&wOcdkMjK^2}g8k z1by{Uf_4Y6B6xnlRom#RG}!@Q@%GM1+n^Ny{E^2x+1@U$Ca%js78&+q*#!WmSJMZo z8Qdf$+9YmkIT?AKdFmd%N`DKvP0dK~4q$9u_x5R|<H_gHc>;s@Q28n&;ZY}#q~^7$ z&{MAL)UvL%<mjw&U-P|9(!gc3p|}`RxX6hG9eQ$-ynE=Uq|JuF`&RiXwFdZ3#EXS9 zob4#dDe2(1UFfa1ywD0y2^l*8jEKDWGXGEjs}0O5^y2hjPv6+|Xvv-RfBNp%y~i%S zO2Rnn;xcNoP)7se(L}Y8r&-H{_`K}QuxtAcoOxO7iQt*eih@#W^wCO3qoPOafenD& zYl8*V4gjO1(hzo2P2<4o_q`0j(scEY1@L@#6L%lB@GA(`@*-wRqC|LcVySfw1Ixsl zz~q&+iCQqx-q5=;?(iod3Sm*;Q5-2#6&e{ZwvzaV0T@;z?vM)@bwM4a_Hh6nsn1F; z?(jd+eN}cl-`AuLgXyth43VQu4i>;j<lu&AaAI-$R|X_<5?A;_W29)b-tsR_jY_fn zLU+9t2bNPI35*nf?k^}3m?F<)Sg8x^69usIMJ*>5ZD3&<^)HQYcYpK!PrJ`P2uh<? zznBa_^J#fHk7FKv1vM6@(Ev$L4(-@+^jWccM#p4pSz!e#K~{T=?uZW9@aRJTTirQC z4ATi4BT@oRkY$SC!KUhlzE$(V+yM;Nk^)!_L@1XZ69;x|ZK$OMo?>p0tNCNFgCUE+ zf1pXM<bIS_Fb+}mVo5fhY?KCgG_9;eI{+-^#xek_r&UPw(*exPz>pyS+5uon8I+V? zOuAUB1a_qdypON(skix{EB)ieLC5$2{yiFxM48Ysds9aRg6iN^URkN-Bh!soc~~AM z^Grv5m!U$OuseVyYlv7Ix)pe1<DYOT7J%)WZF;e9!^Uj~FTIS-%FW5i#Uvn}5O0QS z@n{|v!9_IbI_>50y<0c$yPxBvFVa~Gt9yMiQVYPUFsl#CYN=!Ww#a66W=TqiUJ`k- zsv5ezbvQJa>;$l;DJ=&uS`6X}SE~(Ok#45j8#_63P&>*AJ3?0iB>Gr>I4juh{3cfI z1i<1R;cPK=NW*cBXS%DQW5r!M0nFbZnw#y!g5oCJL$>%wJi4faNV%RHCh*i0NgM_+ ztz-k(-}TmY<c9<%Nd4NUKT9LcQVwhYP2<lwm(l_-(g1*9#F17Mzd*1UI;tgE_o81t z-qPqE5YbX_k-$=XE<NqUxncD`vtI7wFU3mauy<N@``7P&*narx+f*uCpsBAs*@H*( zSOBgkPgZ3`X;FS*an}3Ohkp6~+nsmvY$I)`uAs1<!fw7ElOJU)Ur#5r9UX=VsTkIr zEQ8>I2C8iEk&~@nXz>$yN?^bS_Nga;eeJ;d^PvV83t)8C@aX7;1x+N|lBmv;0bz(c zUIDBETOchTT^ep$Q3Pum2iT$b!JGhQR-z2yj{~qJenoBP$QiuQp9<g)W3`2)9kxBD zC+zDYRv@&|rluhqAzaJ=0J9B@I1-FfcR%!MD~Y_3Oe|Z3V1Z#*gQE#H01v)q0F2&7 zn3RC}V+s7r#rgt?&p$T+c6e9{ul@Ax#%)J#Fn}=#sJgaB1TY5V(Lc51#^PCg#l<-R z7mn@t?z1lsyfe*am-?#;N}856d-3`rawf3$Z57)1ui(Yw-`3fmB7?aTs6zykcG*x- z<0GR(G$c`#4S-FI1>%X3w{`%VEiLpkv_k;%3wr_>yHM?c-(z{a0-{??F{rwl^R7N= zU1XXXq^`iGOdgh$c40GO18X^<baDAZC9n-(>HdUELJt9wzzmCzl)$vv!A@@Etk0*J zijys_L4}FM)HD~G=fvn}XgMCb1XgWVk;1q;=BcPEcXvq+HM)k~2;2fNobw#Bq*O{o z<ShVWDW6eLpZJ9v0$Lo_1XC!xv+e8k+YVoSClZ(@dGRbwU{|N&QiE}BWlr7A^MWq@ zwr9hi{<P_yj<cTcs?0BI^S39kz)Fz{gxX0Q`hQ|bGKvMk(5D>-P0=J@2zCINtID84 zOPUgh4d^juj_(s&_KAu1=6<n&(FI8#R-w%(4spV%wdMKq#>Rr1i+PL`AE-puPcQVj z+E!96<<|HgFn9D)(>So53vF8oA4@n+;+9`yO;(msWIc<*bvjh8lV4GVUQOg6m2$@6 z5dAa&Pq(>X$Kgn1ushny($F`q2u79~NB9WAJaBB4+-oRF!v0ZG2wh8}1vt%t1`mk^ zY63mLiRA#WyBo_5z#l7(p*pH~!o4&F9NYZEPx~*wN#W{20We8mYn(MnU<NQt;If>6 z^S|xh@Ym0Nekd9C(`{vWt7cDnFe*0yqiVq^fF(i8gqB1XWj5xv)ulmKX_ccZpce?b zOJL02G<k+T0PM%1F7`CbfJrSN6F;1Ex^^GAD821G-VeV47+7&6DRC4MF`uR(AuC19 z1i+v%NlLI2IUL0dZq-Pi%J~(*%6rgC9wHxpZ@D6(UlRv*?${@Q-3i3YW%~VF^W80I z>rSVRFqc*nvKJa{B7t8?cIC!cD_g;`qSSh+We;frlZXCfp0cj3VfFG^17L06WJ_QJ zV83_a`-2vMO^(w@!IQ(kY}s?>Sv*(&k_{{>v<#TWf7AvpE-cM_ckalq-+%t?(J&YR zGtDIhRp?{l*Q1K9k-(;MP+%((*p|vxG|5v7T^gt@S>5JV03%exv<9YViW%VS{R9a- z+1!9o7LPv^_Z1?+3|^^sfoE9KZs9HQJR0cG%Hd4_SO5%%hdk5mwxiSY3lISja|B)z zD$ms|t^{DeZfC_08CBDSN5$_=Owj>gp?A=h-_NpQhEFsRM_Og<7@A@Mz}%37#-o}( zuXH(V1v3`$s;j)L7&_`|L_w0MZv6dIT@9Tk<YGJ$xI9U3LFJp26S5X2ArHR~#rFpd zfT7{x;{$n5PVC(N+oQP5%<LQ*ZdpO2@pv9RLzn+$d7+C-Q=gvRzis1&123w9-=>n1 zI!V3v>+uO-DJ4WO$za-|X*)4-v9G?efg|-RJxblsf#xJRh6BM;jbyAt>r~fxxP$eL zV(}YYK{7e`Ur4JICL|rpy;3w3Aj^VPJ60sHErJ(&8;}_2?QsGaRzB=ewn+cm0a&#f zO9E?Gk~LB4y2Xi}?!ifO{-5kJpXzX-lam0LJ9TnbXqr?+ZY+%ZoPml*L%?8^t%_j& zbKDX5y_$1Mi{tICUMm|xcMOlI+yv5g|C<1qNm&q__3YHX<M)GT{s7JCrZ_O=aR9*> z5YPXutSTxlDJaa3xPF-1%)W*NJkwNK>Ka-D{d)pfMVQK3h%*boY8IMzT<B|R5Cw^$ z(_dFsw=#l7yh;pC%@VY1Tmis-@gD0#lm{zWIJT~!!%=1GF&o9u{5d@d5cd3j@P7J7 zv#$if05AU0kB_uA53TTKMhO=$7IQp~>2N)g4gs>#2iAnARn9@Qc2Qke)~Z?~ohP6| zTMGRe$YGr;Co(j(R<|j(#o8{z{nPVZji`ka6`DOC1Yk0O$9cRlsnC*i!ik_5PvvVV zguk5tRvUPUuEvq9F7GYjLjf>90$@mAJvCp;`S<5y#jp!b0yRo5eOa&1pSbuqhQ?V_ zDH6@2X9Sb&OApCk%EYR!D9tY{$V+*Ca^K!VzlSv|ek)qn6op>~U@?H50Cpmn-%lxe zu`4??Ai37$kIeU06xFZj`IdMUs9OOnp*d~~EioH8RJH8<J2~^I`PO==n6v<lj+zj{ z#-fKUAeP|@mKI)5`MU$aOa;2oG-Z3OP&T4Qux?QRjHY%@06TWLwhemwv>NV0iY)W( zj3aGRBpRm*H9t-6b+t)P?gr$WW?G;Antd**2u3eb!YdDzg$SOcj@gjGqSlHJQ`&B< zrbZ*$C)t$pK;X^xH+47@nT)uQK|V55O~Oc$U+3nH_|#3p_om_r_|PxxD|mD5+?|j( zLNE>DqZ-0m9!Sr*(2U=jYRZK!pj67JyGIV5d76PEpJ^<s>GaqAEX&BTSzc({f5oEM zc3ue%L<H-^?}^gaXHVWsZa1Vc>B=wdT8U0@Cq}GEwXF1o#(ZxRuQ9sM8jp0MsS)}U z>Z;hNf*)E_vRLqn9W3U&_fUoUpP-t_Yg%l@&N^FK=IUJbqGpTeW3B*3ZnFM?$TL6D zwE8iK(1&}U)dUS930IW6QojPe#?K|!%`_zjM3wn2-0=5`Mq65VxEbFKMg~ne0nG5_ zf+TpN6?CiOS6z(`0E@yp(di!I0~g?%6z85GnEt~VE^-rCO%UMkR=j@B=G+iZ;4C^6 z_yhGme)#ZRL_$(JB}11`F(Ji%8Ny`$vivP8%BMDj$wAkTUI{1%>L;748fCC8?$)nY z(_>RL+44X`;e>HwYtig36!j3)FqD1oz@7`?4OY5WS8*YlBY1nDW~f$*u9T)>lu);v zs`)`biOpJPxWQ$J1k|8ICQy?kJ}tEb#OvWrRZ|T})Gpu`U>C=h<#Qiys`oZB+Yo|k zGjd1@V4fahn%X&*{xqtw+_eBOxDM?QLx5D|Q;7g%f;@iXmkauPa?>jP%OUWG@+Ui6 zdf{E-PT2r3F>dN=$2v48Qxc@$YE;(h>nlax*Z|fb(nyP2#+R@*e&}n>gl`_DM}uRG zxcFrA-tnq9V-0bk^i75EXnEAzK&l6(dVa1a<Pq^Og6nIks-FgG=42!%Mm@f8E4&_G zHdI&BVuj$P!r1rY31F@0R{+}r8E`fa5H?o&_Tt$`Deac;pr^FZZE&HJ!Ks3TL@d59 zqBS!c$*oV3Z!^ftmiil{=nB<Dpavs<QP*!F*uFc@lTkuv)k@U?*{v{Z3-RMEbzUnP z+!SbR5k6tmYhbRlvlWxB?a$?`e0}O^RnNJ&_ALNQA6s#@s!HnbYV3t>%&*k;1-`;M ztC5$kxY*y^j_5f63?~+JX!O)!NFnW$g@W5jFaKr{m}0<+5-l8-KRMm&u0dlx=3g9n z-~sD0olqwd>#eE?_V;8~-K+8y=%)}CDuYHU<AX!PsG)3TRsqd_rDnjGFI`RJ=!=RA zb2E}?K+oO#aWX8px3;=<%zB*_O+Aknaj4LS@(pSo|5bAXDk>iv;L=?X8J2Fh%bRX3 zDf8AV+DYBwRv=oV!C?p^*^?R62L6ciT<opY7@)9RdQ3T?wFOnGQ9JHU1d9`kA5aC0 zU}IuA^Z^bet(*_7M+w>joRHY45?Cd>t-1N;t-e12MG+Lu{&pnCa6Pb2{SyGM4TKEf z5m&poQC3T=@bz*QCmv~Q8Im$>%oim9kCXhR*$k}HvR2Kru}prWwtx2i<tEIoW!u7E zf$E|57PqMdkgjqrY_4I<9BzUcyMz)QI<$Y1Zq*ID0T>uoU-Vc_R(u4_!cC=;Ldu#f zqS5epC<QA&H=PGuzI~h4EBLLi?Q|pxG4J(t$haf%WCEGC(Yp-8pl09$88G<jxxtp^ zK1*kw?5-;Fm~J6NfWK`g7Jrcp_@=0(=uqm!@^1j<@=eWk)H;)QMW1BlncbdnbHfcS zYBWdcjP>LED!p<Gz-&PagdN8?Lj?_90!gZBm|Il3nI`~?qn%Y~4MAG~_I5e`T$p)h z^<fFmVYPz*Ou1j=_(moc*evw_mApdU7egG_O8>U*&kH53{<8L;&X9S^ZkeS;E+*hi zEC#T|ksyKTWz~uTKaw?9c)*fG3bW3k9^a|nW@S0n>F}38Scngc0nF!umDW7RXEhx0 zyIM(NVqnt4ouXtHV@=udG|f6Ol_qJDD~lRqQKx=Nprirusfm%Hp`l^faG%e0)YSJn z4NzyQ#VTj5L}#Z`dJ(_&Z@KHxZu^>QuP%2DE-MT+`XUf)*}&XqOaP3YSjGkhu*}Q) zPtDV<HEtE?l0awh%kY6BEm>Kj5HJ67xN?~^)FW;NzPP2VEOa+|^YPnnjUBQ_3DaX} zkK@>)j+IvDryqRP=SQ5ThO%F2;=|4wx86@aQ#stM7H1-d@HzkQ!Gj-~{~c&)gJHKM z?d7IP0wWMiuo5E}Mx&_E=%}}f86~0<<~^FNhyWgKce!P$>wBxm1{2lHcu|&(NN<s2 zQP%6@xP2XgsBRc9YEd5TOnz*#JvWZ}QYNNk<mQtWT|fndG*PpF#?dE628To^mqOc_ zX|8VQw~GhaqIOW}ssOenFeH>afbHQ(^812d!}%Qh9&f9xXdYSSeKHh)9V&4n&Cmc? zMl&da#V2kK)%#m}0pD~>HHIQt4+EHGFVhD<THgRUEEKRpE|zgZ)2oUl<IyByX}~3k zMQ)FfoY^Au!TCAaq6}cfTzEv^WP82{!Y6!}y@Amd*{r0VSYT5QAoxwH?8GvUxeDi{ z`u*l^YKw?qD&|Ll2Sy`}qbUc&m(>%52qZcyhqU4ehzX=MZK?^*^fh^m&6S^5R?0`h zri^rwhbqMP3eq(4Wz8qfKg>U51TY+h93f=@ad3<We9N~^wq(bIghVBzXVd(fLNkv( zGd(UUI6SVP1)rK|u4@@`NI$`Wbq+oNj13tT(*T%+m8L+r755kbyN@_n9B!_xTrQiG zSfM_P+9NCq05%?;dG5~7aX@32_{S9;M?TqT`cs<%F##~^XLxh~faZL8Po~r)A5#-- z8XR~W-B6SF5j9pQP%`}(!0J+xGE`}iDI#8h;h%})KV^Y}=rHF93CnqezsOr>X2`M+ zbQK`^|6b%=ZI(#Vq6CtlLvuDX<#h1GPwL8{4nrn^RlXR~mgz{0SmVQ59P98X6VuHK zwMp6^sX`KV=FpPpNox?n-d@VWzT7C@T@+c`CWQX1B68Z57WgJKA~7v1FOS+m)03N> znMOn7Lu2wq^7J><cNq7T5e9Hy_&8?B4NbU{sF5XrHG#=$&0z^<MX(jE<|StO8p>+A zmUaISLgIf3*~;1T8cf|_i;|1Oq;06%dTU=VZ|`lqp%M+|mxfx%{UW3S$t&`g{UkEN z1FRm5!kZ2)LR37Qs)Q>&O?5Z7N!y^|W|wC@gPgO$rEZZ^p|M4DjuD&G;!(aYW-ah= z|LjVq=I?2)qkJXU{xZnK-yd7`g%`S;;GIEUGVse@ER+OGUtu6vP=%|p)G&{)1u0p9 zK3o)iVs@ZS{M?==A?cRdS%Ga}A~wq0gd+z4MiVpq)Y|uH|Ac07NSXtyr=U6XOjdR@ zSsnTO;p>oiLU3U|$>7}VtdxYXcke@UJF$9qO>LJ|iGi|8*qgpz3QXG#z)l6)3cpy< zVAY`+=jw^Z`V-yt<+Xh)nZJBIMmZ8EF@|50fjG`w5v@fPz;dGIy?wvG-q?6U1^jqD zg^_{rRm1#CxXA>*f?yB{{8Bv2(u)estPHl53^Ei}CTBQSn-m<H)yB6m+T7@^=*qaT zg$Cg};l7*7_)W5kxRr1oe(&w$q5N?_xsDoofTMaOjepV$Pj<ETV|oH|D$o;45Uhzj zNLg1@33FX}Ip}e0F)%6d$L2>nJG_Uj<uW+ufH^6*A!n5xmy28SU{Sue==Bq}0G8w* z7Wp&_0&X*t(J@gGa`*1-M}e_4o-i{jEhQ;B@Y(&xfmtGVI_nyG>_QBYyhcy+d5g;T zV77_Y?ClY^t|<x-J;5*tav{`Kxg3e8%Xy&+U>v<tH?*2Da`B*DzS<>FYutPoz7LgF zBLMSBOjiV4Jas3&nOy;BMW|*lGWdXCh+t8`yc)q!^G)w?xI1|L#kROR$4@;iU@94H zYV>H6uN)lMH%5Y#&S8r*iXPDt6ulbF?f)MLc1ny@sAApp+_c!FP%GA&QnSK0kG8gt z@>h{wLY5O@cWe~HRiHxakWne%RGH}Q-u0xRK}jkHZfByWeaPFg3<0<!$hRkPV6>8# zns!~v7QsN0PqcXXfT~^`b?5IzIUErls@<n%4M?VIBJZ3%dEx%^_w>Ad@#xOwGuPgi zAfPeTR@-8^uY>@F$NR_SEo@mSOkOdp-ZkTIU|yqlJ3H7?UE8`!4z%?$e4xBX*udN@ ze{5_VO&NeHCK-M8wVvc;T^R#-tl-)4!&jpkSs9U-qsU-(A_2k7g~Sc*RXc$hgXll_ zGn`m_!gKXu=XW2tlQ|3t>~aUNUb^v&LWx3H7S<lq4OD2vudEJp{$9>n2#Tu(DEO=i zgRB1JYJ|FuOj4wsfRozz{TSk&>g((pkjThD2ZlW?(!E3eVlEbJV0%n3cdJ_AYIHkz zC(yV7AenCiZM`xEaHy-J3%0g-U?`*0kYo*!1}*-1i`Yc#TFWteepY~{4qB|oCa{dJ zCuPPGb2D{ew@w^Ae)|07%a_lb{_V(#Yr!&~cBHYkZP-yq<;#rlcmcR4#WH09#VV$I zOIf=?rATJ2%u_x=Vz19tUFSXh+ERs;7{o;2<QVDA!1pLoQnpM%_ozR2$|t`LR{=a# z9d`Tb^GxKDi0NbL(1KttO_Frbm2@F-gBk!6B*5d_lOJBV@~)H_0|D4;E~P|2Kvt9~ z&gB}0YzV*@V$PN5=rX6Kw&NANz0G8|tFfttpVp?PmX6M@o{^E^k>MfwYjALIfS&$= zzJY<hzP^6?r?0Q4r>m>0qobpxxq)VZQ@&4az01|iRpUCK*H1cKCmwqdg_iUBqe#3n zKQbgZCJ$!bVqfP7X+}#tUX=4FB^68BVu=X0=QFJOrU0;LIykoZ(XK8CvYE>G!1uw4 z+&tdE9X2rCI0C^Ow^CC|<u}OS6YYGw41JB97Bpx!5QSxMN{z;nNYGY=UOT?$;NfG( zj~qU5;Mlcr>Ao@4P}lCro|LU2cyH|U)gS<o2QQX%vXCyUCg;J?o5ohFk?a9N#rjh{ z4b}CQ0>6wsfip@E3`thkstG>SDFHB1H%9`YI;aR<D}pEMDtdUO{?eqlT;yaCp;#i= zlEduDLP;>chc_>lL(@kn*HmqcHD<;pl)!m4+Tzs<t=X2MV!+I29tFN{ZxJRiZxLeN zc`wWFXrVPTA|xy_Dl#%6B04TUDTlHEs;aB1D)=87k;N14D$C0%%1cViD95&>thAIf z1d59Cl9Q7XLIU2tdH&+{n>VkYKYbBZ=d(Ad<KEWch(wV9ar?zWy#c%<{?2a)51qIj z)5d=~+tWGB6O34irXUhjXvv1g#4#xCa8DukWaS5ZQiL!c;lg-t7pjovOP-(HyKDcs zS4EC6A3PaEYfy#85l3QLvxto${3%<+yC@qF->2f2)Gx|2ltMIffRmL$m-cS|W&5wc z{<8bn&8TMVv9GbA({ewHg$eya6mvh$UI7e+(FU+rGnh`;ZnP|Cyg1%bU+qFODld<G zw}hnCQwGwYZ)XD$-biRQs$hch#mD1^1J1GFWMd@&yfoU?J|Kzn5{t7XFa~MOQYt%x zQcZ2oS61`eNMLq)>3dA}b##y7G)LQ7hL>;EP@U))YzIjOJ+gk;^{Evb5YDVsIem5N zsdxX@iSpokH}2ejKz}`d_9h}CA}uvFBZ~&SXJ%#4Us)Oaq|=j@mYSAAe<i1+q^71O zCnm&1M819f?EbYYXHT9y_S=#DhwfyFi`EZnpiiyS4nz)q>i&b4UghKaI^(YVy7BAp zHtxI}0U12j*~RnvsIfa6!DC~@*;oX#0%j0w$aZzYRq)D(ru(}9*oBfO2RDBC#n(R` zdXi@&m_@C6p(%Bf1fpaeK*-5O$idiKaod#76BChS1tAc{5ffM?F!dJ{Esme@ig#zW zt^e-(4O<S}l<eo}w)&=Cbw5M(13o0x%v}>*PIK1pu>6<QAt!(lKC-KM+z`!@1V6qw z+EQKJ>V=?f-@I&4P$^*))?v|F1rk_WeNq(PQrbir^`T+9ZD`6>1pxCR@*h1#NtPEi z4LJj90C*R{mW3sLO7WL_NQ0r4Hrw2X21eIsZ;`)PtP#_?evDf`i3`ngVsYiS+ZNrd z2JB$6_|1*$ckVxY^z_M_$cUJ%%#7TeJZg`YMNUkDZW=v=-SpJdv}Asg@b83#q{O6@ z<oKBAu$RvsT|V>MzFog;{q<s+GsdzyQ7$d5<6#MK5a~5rYLVNKdl8cE-`o{*W#{^D zzWV0-4LdK#f?9_<dP&z^T9})n*_-r`Gg|HkO*B;miw4PGwc?Ai3S(MG&kuLQd%95a z^2mlSKKuM1UvD_{$nKA>4LQgQjq(W-w6qYcx9jFNwHcImMZigziZdZ@(MzF0V;thx zIPH%Eh}KVx6~8#P`TO;o58g?JIyc!|+XU}CV@U!ueCVP?TPRqWof(CdTRBSDgt@O} z>axY?s0omHVcO#nYt9c7epjeIR@!E6$@qm%Z@hm@-E?zk?mZ#Bf!Q!+JsJ}>@FO<e z_~e5hW?E|9iYP>ZW{GQOa^Qc|i?xCT76*ygzyL32h)Lz7c@_tn+bkmsFJ?R#qGV_| z3=&vk7wn3Z=8L>V-WHp|qLbKHvrJQ+Ee*VP|H;d@!GUpU8O0@}E|-*GDl|>v$j>jx zlZS@e(UX%$f8}IlXJ%*R<Yed4|7T~UCj`BFb^GeM1KW07PLmLYu^T+j)8VJ$ms&T6 ziaW_Rq>EEs&dVjp+pnPMwZ~oCwfV=*+qP}n^2@=S@r>Z5{;ocnf<h_GQ<Gz(qa=dG z4b2FKs%w11s{&ZvSn@s#;{${ItNDVbM}PY6+w~jPfB*HSBad>1%zcqriZC#|&^(O^ zUMxo>SRC1wz3IGb$JX4HSv?C;<wgD?q@~$=?A}oTQ)Ra03gxdJDSUnQ(BX40azI1F zuG*Gi)n3J`t^qD!82vpAiMhR(^*@%yiJue?mB?W$@Vm?-O@9U<PtWW?Q?2*Ogi4u! z156sRSok!tAyF?$zobiqcv7_npCPWu08`3Y{^rJ0?f8@V_Sz1o8V`E_$H<Sg9~MTB zj3}1&&``X5IT)adU(tu$QqE?3njAR;@)fE_DJ{c;K==jSFn)CcqtK1W7d{bixRuSE z*{U#-y`i!3Sq0_w)y>U~)WM;O9~$sp#s)AOy``n)#ihk1#U(|YA74~dSX@|CQb2u{ zN-9bVC|4jN`1!@7hp%J^fGyj~oB0oC2p`Hi#;?c#6Dswh%z2Rt&eL3Min?}i`}VyD zkNtM+=)nW0ZpAh8K@D{Fjgw@j3Be?SVFZiM94uU14p79PNUgxP1;BE1OH+d1iJXUr zfBtdP&)a|9zV(M6w;Z~crV1J7ju>^1uYx7MnMbWkGz$#FrkwP!^3~|t%Gp$Z*0$e^ z3>fC!RCL7wM5c5;PV>!^b!idN=`Or~Urk-dxcmuYUwkJ*A$;_(^OeB7<JWQ(N!Ucf zq;N%hGl9+Tp?4sEAtj*Jwz-dE(sdk4h$xDjVg|ZZ_bzfA;Akhq1Q*D;(E9rP?Z_@M zCuG09J0rAzf1#^ZI_hXLjM!BY1=eONfG-~=@}VV$?~OU|TM9R1R)&y+F&Oyc)1CDm z31`9y@RvBD!H41bq)XHhB8Ve7x2S_Xl=E9}VpGjxZRCp=fiX$NCABTCj&|}yb2Fv- z>e{MW>daDGT|=&{s&d9NO`R<#C|8zNkQa-EbSVkzipuhed}`Pd{_6I{hXptrRwqFe zo*Q?b1F6uE!0N&>y}DOpHC~8ovNrPik^KjboxgnT+V7XoA3uKPb|m{;mj*g|#;GI5 z+!W2QC+5uv7EgtVZV3G<L{=nQ1^3d_5Cqsz+TEkO_Z>TP>B`kBm(CnLu;=)lL^#d_ z8&tW<c*1Iu(j!qzVWmu<lA`Vlveq}^Ypn;Wjov%-HW9!KU{3xbnZd_y?PY#Ks@ayh zs%xbavW;JfH3~=oWoe_bg0PW4U{1%GNsv18GsX?=)d4NCS?q?ziSEY675nFy!!ueU z<CmqX@>%$>xU~u-u(an_{X?f*@tMl`dba@N#jPXlsqfI{!>p$wl}%g;Y6L?DbGQQ4 z<E+ejKNP+dxeT#mg)OS!<kcqH>$*L2`vt-JgYqL1=teVBvVkRKUsQ4^(I6Y-k|@<I z=Ov4E(XU>GCKp#UHMO?4Ha9laH#X8>j#~PQIxAJz)m2wikw~tos;;cAtSqIlQAKG* zNkv6TQ8A&JicU+*%c%4vJK@EnkaC<8*BeShD6dB<5}2G=^yXqHu}@gt0`ksYWulkg z9V!jJe)`PidoKe+BO*dV-aNi}`Qn|hTEf~~UuW+qWoy%nZzv~|lWbi8!*X!qfVD1m z)n6=342>{;I}+}nJ$32UlUG4uk>SDbpWeNE=E9?tMpL%U*<U)13GN7Ut8%Z3U`TzV zvf6ZI5tz+l6>@qY>T-q3$QF`%KhQ5qa(Kk;?Or)R-!auz-Kg0cFfJwL0ihxEhkJ6C zb$U4qqyK@LAaj`cstpY5*ZN<zjQRUTeIDs*YFQ!qN;fMSn{XJsqd)_U0%J!+Jn@V= zLYAtn^43P8t-=<?y=^u%;A(-BSo{ED|1yH4_=Qa$fiS!!bWGj^5nfc&Sve}rb8A%_ z5g79VW6gEWRA^Q9_&t>z#1LUUig^cGPcW6T|5IL0Z-&i$VNyW!vfEj#k9qYbvY?`= zrK^?j%iuKtX8B9uT}H10xRm-lP>ToFt*OrgBe<xDbZVMDo1GLI6ek0BB&9(@M9bE* z?b&rKKu`%SB&19RFKNH2<BgYbgyHh=r+4nX2#d|g$)mjeoQ#Bsw~rq_jjAGbZKkiY zXLxdsx;YU0CaEYj{p?{>;ovWNi6Iew8KhllFK*v?78ISDlSf8GVO~Z|!1H^L-la6F zcF4{241!G{Nt?TY)<jQ5La{O24AI)R;>NU%@KswKJW*Xx%)G_-A|q5qa7bE=^BHce zHl?>1Yh|)aROJ&08~m;y#6*PY%cu<un_E*3@k{8`lEWkq?tW=zpxveNpXk*2W{Ox# zufYE+enG!dGr@bLD;(vbQ07vzDDG6MQQhApbUO*$ItO>Erx|#dz{8zvP)x1(RVRty z7uu8bZvoMHITtb76={rgIP!#z;roZ0TtjZ#<(q-iP1w0$RDAlhLvCTtz8VM_uviB$ zv~=C(vvO4O^^5h<uiqu**SB<$`rJre(5N3NNnvhDT1zuI=z&FCTUA93TFUvMXfQv7 z+)^qUFDRmpOC=>4iNT?n=8fU0WNF}zU^m)YTBkxvWC1IGs$mFxy>c6O+N?}||MFdU zY)V#+c-nHQa6KmcZE$i8`S0iZJ39Nvxji&NnEpnZno*(+n_R}uy!^)e*w84;-=2by z7cWDjlZaas@ROI7ksKEm@HQ;BNz;p|44HU1YqTsan2T$p2JzEjM@S3M-L0}kLo~|O zSU@^dHjp={j~NCKEH<}PAlsWDldq;(vp0z1=%*lqk!@?m!z~fKI!_Y-tI7!dQV?wY z+X-Lp$qD@SHM=Bzt*0O*KDngJq0P!`;?ki2KsAH>75vH<bEOU?<Pd<Bx|s)wsw&{J z*o#FstKI5&YZGcIBm;`$ibN9<LJ~KLBc7z;oD~#8=<P;U@^Kn1MCx98?CD5`{Rw`> z{jXaT6+^Z-KCbyj9PF0ZlyGd_qOj3rn_H}peG`#h)6~)4(n9#9Hl#Eei|~uC!qqj^ z3}8~C$rKg<lO3$BS^(f;Dj6qbx-d5`Bq-I%a-afv(@~9BS;vWEa!C@b(e_EAU>o9= zPn)}Te&1M4dPGQQSPV5{B=F|&la-N@91#*8lTk~~S3+=G?-*AGO;M^id$EuSp!v{V zU(MUi&x{PilRHoz9}+~XrDpPKv|b)9mmD1y93E3(y0lPCLNs<6NsNoon@|}nV#d&% zQZQ43S=!0)<-+s;M0>U6uevWuI$=rXhTz=Jjg2(d)U+Tq9Of_HMd~0#!WpAYV@a#C zGaJCR2JPX*va=zq?C~b)w*R3i^!lmer|-u#dC|$>y^=fEz>Fo@SpJ&UNYYk?cd5cl zH8&OA7TwsV>V-qjkU{`{tExT<$KiUme9??$2_$K#$E#vuvolc^ct)7^sO1+L@9^jg zt<p)vuQ(vE4OZZ3k~NzN!lTgt+9*o+w65<J1$1&X(IGJfuGaSUmZk<*9RZj$=teex z*$S>BCAzAnf~I5DP`6<MFrk<Y-xA8nBHg*Pkmg2H>xcZp{FKn3v|%?A@P=Lo2cbCd zG~g?$wp^Z4tm<nP0efLRWA&MFAtB*hb(5V-h{BVdo}NI>pW^bk_2B$)XM5KmL6{|# zOs!BO7!Cs5B3;#L*;wR@7#x6x++UR*7919poXV@=$;r#jPEU#r4~|GFZc`adj%e;B zFFrFvYkW~O?As1^*f9kli{Hd@AB(N)P%n+~WTLjXS`|*T9r4g|oD3Zc9DZmL0<{&j z9Xv@B_!X&UlLm`po&Je|hrW~^ekswoVVWYI?v%gk%@r1jZOjdKQ;QTV-yCvw+xOpX z+;uI%a{8IQ+cMN*QR*0ia!IZ$Vo@Z4$6*AaqENzflE7#AOf0=k0c`|@J6l@lsc)9f zhtkW2ztJGr3I&^hg>pD3gr3|DzbOnAM>~hUOW@diQ2otKL!R1(9w4(~{18qMI=rcy zGlOuYbC8N)cu(w%PEW41SREIWT;}Q|{JIFh6h&eH*H>4QDqT$grl=CRp=$`m)fJri z%#JK_VKIOySX@X(a8UtOp5~@Sg{H3HtMJa*3BV}OhSeZ032}(xXe=F4f8}|AWA$lK zfx!{6DQQ_*+4(fotDqo1H$OKMT69=KRyDuNDEUu%N2unBGy6=&IxngYmg$jh@^vk% zPPN~6ajdVO<?ljQd1_c-Xlz1SMi#fLVHLWFi)}L!V<N*M(+Zo69ZW-`h}Hy8h$C6@ z0>oxYOjXAa<qE2!E~?sxfw5?<U~eLTg<$yV#rHz2Tf2T~nuB#v<E<5?wcR?p2C*N( zy<?0feI0!fzFS-+t3G%YegXaxqc5rq)^rGCq#zG}cDSQid*{^!o!!3vi!Z+1u=`rF z6?hZqiHWHSinT?<Y~WSkS_Y`lY?gpaIW<i7fTC>IjczQHU6!ynHqg*GjAJKLg1!xY z1SrlDMS`Kt|D#Di?2Yvz$c4))fF%fw(JTNkefum8A-3wSEru+&Xe-dL!lArFgXWZ9 zRs_rzMT=I>uReWSH#J+Dt4@r|t|Ix{>|y{n)bVg=0JyrA+|Urf?8Bn4F!d-UEt<qI zOJKrpSuy#s2*5>oB!M$x!xE)u>FQKqPL|@p925|GV1>c}*zy~IUToiq(IoKo1Euj1 z?*gfbDh(6i_A%Ukg1Rr}735~7Cq{*b$ETNaSKg`423Pwq)!KnaQfZ5(Qwp1$9cins zsIw-OEr0Ksp)Pcqo~h4`iwF#jCi%;(0;^H8IN}*tEhIcSvrYpwa{^#!>`ZQ!#1m&b zB7DNA2nrxvvqK{>_`isSS_-b_y2#JtQPvI1ZDMp(s9TEd6opH}4J9SDJ>oXP7;4G9 z;J>((7u+2#X<bIKwA$t2b+J4mfYu{%R7C>INa({egYC_7wzH*g&g|H<;rs75Y}ma2 zZkp|!6@w7>EM7hbfDs{O-HEkJ1~73&L*2$k)M&BRCy7a{Y{mg#gFr#?cyj~VW767y ziYm;c$)M9YH$-Al52qkVQyA#7b1`o%=K;U1vM>JlL~Fg(I}P~PZDOZ-hhl_tpo|)r zbN5uv7oFr=G?5augFy>`vT`~>hCb6ZX~~7PZ7t2s4K6Z)=^@ce045E(vX%fWUM&8H zb!c&8aZLls;Id-2en}hw!0`d0g+pHNf1shdvew{4FKKa+oLCNzn_QhJXy(@tH#UQI z9AaO7WMDu*NIZ@6q8_TG#}hjdhC%~G(vzq%BQ`Owi=o%m<YFOAIy1_JL^<Q*pevm2 ztuHAkmw7B+o~7~LPGsLtl_!OTg@i>Xr|0I9yIWRc##K!74$_lj!h^%YlPe_gb!k>c z5`zjL@&s=J6ducDLa(|}Ylm(C<}(mq4Y<4v88?ClU#W>-?4TVTouF!2c4Jv=dZE9z zsH9;)B3!y>;McgE5T+GDrtn!Qe1~1B#=z{>(xBCaWkRW<fWq(>{I)f9A?ax>|MltJ zzx=#&&#&8m*|P1(eN@ZJqjxQruJRpM#9I_Rz&sphCPe_20Xbp?o3}??#_<iJUK_fx zPgR`*<X!5JUOJ|k-L&@X;c?RJ2qpwea~qbbI2<EFZ6Z-V!Hz*W5a3t#PYcZrH8pC( zbG(3=6k~KK-69YyR>C+{-ALISGWK<gau&2cxW0zhBqC`6c&au%qo|>o9>uQ!n7vq( z$3YU<0x)$67yJ@{<zWER)Vn<Df0&;cAMh%&sJXkZe`LyC7n{g<e&^=>NSBcf$|KiJ zO+f2|IB^h@p<3On0lf1N+tS`Vdl$&|Z+2cjdBQ6yShue(M+#_O4q+-HGME~Pb5YV@ zb4?vNvlzn6{Ir)8xa!P+tGuLgr2#=xy=|?ygsI|y=Wl~$wcLCfT!Pi8LW>TdFfS`T zIW8h3=uLQ$RDUi}%t|JjBCcZ)EV$(!_%?%rn_h^`=2;>~a0nV-Gru-xB=}X?K_oXy z>7q>C$l(z#H`QHLRN5rH>!ke8*v%q{4U`RI5qGYH^1Sgf`8|OOy@u6r18hV*xf0XD zJ1{z?2FTrupXyG2bmri`LnqIizxdn!9XqxkzMo~8TG+NhAXG5RID~%|r3|!1+TkcG z8N&00yv4=DXQZ8N#0-NJaGWVN#vH}Stf7`hG}Yw}DpKr(!3dZJFaMQ}$<{D6WGQ%@ zi*X1bFIx->W1{i?r@LIHZy%0UG)ypLRicEkvzEb42{}^*TjUfViIphJM@5IKZ9*py z#m2Qs`<Qg)=9D)yy9mHe3G4tcN0C?pgKF6gUCwod+%mkB0Zamzk}3=H69b>VO~@^w z2x)0~U31qk<p#}x8hT#t`Dx=%SMxLqXhbRjSdIzQWdsb;VXcq}u2)FfKEZ{ixcfIB z2S>!E5TYohlicGp)4HaHW&jbWN{e#|!ST^S&tAmUvIaNSQd8Z~);~5aIeIuk`8G<B zY-_e_WZfutdZ5)M%_GM0p4_+_6p@gSN<&L9cc_|N^EEZq#Lg;M2&bpUM~6Il^gc`4 z#?A9}Kmr?&x84O}Jm8}+o?!NgPU;lC__YJNK(dLP!2DG(vS&^rEK1!Z@imQOtgW0h z3&<H(6~XA`G4BLXtX>zpK?zRTJAy$oKno=;I1)G1DABKH`;>ovVWQim)v&IpI~Pt} zxb@&oP)P8b$Jb6DKY08>hJ|1`2sNPebgV7%+cKnxM+tRnC{W|gB9)jaLN>{9$~)?r z+T??SkPDvfsB7h14jc?ZNDLvw;|z)^Ym;O!FT)AZ{8)}f2ayQ7Fs?j~1{of@INI8% zvk5I$ED$ze1YhT?lmrq1@QB$W`a_GIz<x#nvlv^--}zUHi0P)noXSQLz%335jBH91 z2u2*(3xLTDZ38%;+|aMy$LAJgr6p0NQd&k{QAKH0IeYv%?r-|yPoEu4cLOl1(9#(m zuga6a_#P}LkLoBY8k`JpraJuksjF|I5>qoU2B@N%r)lyKJ^~fxi4_&*<z}WNM8CXs zKeU`3j#EALRh6}^eWTNyYlu_|a}5hL%-5U5neK0CY!uPlmvaB~<>wJ`v|3(aDHVIb zF+hXEcxo7p4J*cKv9Ir3eV*11m60;AnUhYk_gfgeXnc}H!6hb^#5IEwJrJxMOGuIb zg^EO_OryENgGEI;pl&YMAOK@yizBYmLZevls>l|E>=G|LD+X)~OX?Q?n#n@Bq*n+- zhyf%J9Ciz6^NkYrX8V^<cy6S#NhU}w)Pz5|bLY|9=u~pwXJ@2DynB52+~wz)G9iLt zg~JdX5!)2W1l0wZq7c9%yhHj0cMB8&WmzSX*TGU!`615IGKcMxWu*%%4m7&h3T7i1 zAy~|WH9jneVM-ieY0m)W!9gobXwZ&WqLCm;2wqusuJqM6!BYmoj~PnB2Q0<k;1>;p zhzoPk4KpdkAHfN%Ez%1B%kY5m&VXa=P#98EQ9)S^;THhrfp(-q%WPTA<WK=@ByhD# zVD9_R045(6OW>T8u(x5UC6&bmIoVlR=_yHZu`$8n5oNO<x*u=<{`0>d&rol#0VBnM zk=@8wC4N;^p`c26JT`(yOW$8O^4s0e<dn>;d_q)JB>`8>cb<exqcn>P^0U&Df^J^A z6Cir+aC>cKMO}OM@c0bJbG$*;`Fk_{&2@EJjolr6?cl!40pu*p%BQ)1#0hXl^pL}k z7)DiDF;#P<r-VN^f8k*~$Dir`C~t%vib`y_3=&(IVkcUk?oY}-MUQnpvU$-K6vKS? za+Q)Vq1pG7RQ$vRS5z`NIV%d!OmBT@QB}7VhFKrypMnhLRDJ%nQxDb_7^^7IpdET6 zFkAjnmAS}mv*kNLGE3S^8)7w6wTZ7^y$Ok@>=z336;O})%*3dt51xh;*%=*7lZH*1 zvp}$j<136NF6m|fk5N93C^n)?APOc(wg|=|9HW6+r)^WvL|a2U_my7)gAfr25o{j5 zJXpc-EwfE;Rh2r)M08^1r*Iy#Q=5S{(pGPL&_<!+mjsEMEpm@zludvObJZ&&7<Ful zU_Jznbs^Gfz+u!;5QqS{y@UYl0)W{E?EzpUa##{rOyDZ0&=}l7xf}p+X>nd^ctA`} zjjN8m)D<Q9*(q^Rp|3(xCO(Y6+qdQ0Z_nf^%Qes>2@Jc5O&t!n;4Y+&N+g1LM1jzw z8_0QiZqMGcPg7Gea%hq!jp3`QqH*-(Ij4Uy2O>+jIKMC_Gd=Rrh0|AGW}?P_ZlJBc zs;17>-a9xpY4v~e2ITpv!JgK}h9>pjwnSgqwe9Hr$h53%68EG(*U}o+YLqBmO{?Y7 zY6;IT9zS&}ta6yXba8r;0VR%Tkr$4Dk^`M0I=nn$I4NP{(%~q8{R+k0L?2l9qK6XU zC#fwKD~978wI!wXJ=z-u`m^fJB8ZK$i?2cBCw-tlqgZCyBUYp`8&u$NKTJU`)ICKN zWe(HFCI?y?rD9;DHZ?LZFf1k|Gc%jh*C<e*nVA$D78sCJW=)t9!6fpRUPisS>Jt*} zl8KueGw6sMIZ@HvObi1r$NzwCJh-7#fuk4fbu}S79J7ZJr^5I<a9y#48Nt$<U!)&k z<9RFqFc=8EGj|<F9TUC4L`Qv-)19vUR#gB1|MW>jK~&2WZSbpln2v)G9fKnIieI`$ z^o|h;3@OYRB793SuL0ID-p2B*O?Q+Rm(>!0UCkDNxtKu(umLc^*fxO)z7$E4Ob#k! zU<u3sri75jmgc%zl85!xrTLku35ii9;~%C14)5OZ-Ps~f086k9WpM0G7n>gH6L_jT zifH4V=}No%+pcW~ZUj-g0rGtpmy}nN_-(`_O-do7l}Xl?6c^=ZW+uPBdh+CjC#lj9 zd7{6~MOi5|4b7dsBNN^+JU2Gj+fM0djZM9hzO>{DJGcGEU(UQrBLR}1S6os_VR7>C z$!at{yAG>SMn`r=!1dn_9KRY^%H|!_A&Wx<Ikg~h?Z>73+MouzG>l3VN7+7pTMob& zS$sH>MkWzpR=pIzAnqCVo-7Wxloyq{2CT`yoV71<SJipVT@Vt{q;*k##5dv%zQDC; zy39-Hr;IVJTN5?~Hak1f*WA<%_xC_$T1;R-sN~vkb$Nb16_uwZQu0f5N(HkzJVwK` z7!<#m__P5fCT{+lxRi=uo5UrHfX~dGZ0LU>3HbMMzRrD3v^S!4DK|cp8eqOGxS;uA zPc$XZo2(ILE%XJRN5dKk?g)oSVn|4tertB1xxsz(qUe;kOm=xexlsR^Y!NOjaz-*A z)>*j16LIB+b@Nt53+JygkeKeQC?W~m!Y(XGU@y7Q2n5%N6IxR#s}#Ug7)$`pFD@=f zjSPw_Zf<L(d=QE$H`Z2`<mY7N=MPM^Jvp#v)A#4{&26cPvyRO~q^E<p>1{dCL-qu= z2tCbar0PN(NV~Q7r!Cu#Ka3&FkOP_+31N~D#acgOiUwL&mzNY5P`oEI`0m-?4xN0M zBGatqCkMJ)8*549ZfI`p>KhowX~6|aP#{Z^z}wVNQ&ZR6-a9Jh`g~o$*=-wt*mX55 zpYyH?iz_HE&0ehztC0vUAnBYF`RMGy14pg~lo9WpqgWELaDFViQ?bXJ!!FSjPCLU{ z&^5nMBU8F7^T#=DgOABnuTqT$iwy1_FgiLs3=a?K!E=KRB?XnusJ*c8vB<MK1Q6Po z1o^jW3bTF&HJup=Oe`;1NBn!jXP^p*NsTWMtsKT5^5|wqx|^Fty0(=hM+9@O4e8I6 zWFt>jPDVy@OjuZ4W|QW4vPlOa#)5{W4iaAZYsDHR+(H7wLSzJs7NO?6xIpDV<wzY= z1MX*&x^*N&ZPZ_gc+wm*K}Ilq7Ic^*fk~xhHzatR7<b}`cH?beW&&V64}K{+%(<~n zmuF}aTSO;qzDl_5(KrBJZ!SO`8zp*VBN(cih+sWpoHHYVk)bgFl|X901T9m=3r)9^ z1ZDs?*Tb{}7DxbdAlMW$5P)k9fUE6XXsTi;r8qFBQZj(ULkPef?G$)zYoWBvn#!`0 zg3S1csK>t@*uQ1tc?GaqEerGO@TwdeFs3kkZz_ZwG!1ct(_5;1xM%(MTXvm&ot&FX z2^@tGz=~gnFd>-NB_lYWAocX}se^lddzPp1o%!jp!S42^riS{O>Z-ar7xmI?ZfR?4 zrFNX;vLgI9)Vm11l=q=m)f#?k%eU*d9l9G)NNt9weL)4;+b-c2vKl$gsw+ylb4fw; z^D9So?>ulVs%e(U7*?>P_b7B6@Y8D$hHP9mmMUxgjw&M}bB*qcd&k8qewnz3Nd(iF zi^aMAy2AX5_A%3Qf~c9bV(|t^#u4;9NDKL1QFqil^QI_*NW{l0RyjL%EG18ZpWp}c z99o|pY<D$5w$9dNL`MaNMkP}8Ex(9U1?VAOpPQS>vl1hcGb{Q`xKTxuVNh(A${x84 zMS@796es1vZbmRiyya8@bRa^6Fpf+SY$%BtlN<EtfBKu-sCDVm;+y~&Dl-9C#4rD& zsw`}A1}ZZ)&u<YmN!FALf&iWxXlY)Sk|_A4f8ljCcs0vBev<m~Q!JnNIED_4lDBUj zK|6%8B7@f>EVH!$I-P1Y02bd2ktJ);T+1&2uA?L@4kKw4iKD=nJj<z+gkT0R$-?5i zbW)*<n!8$?8VJBmq>odar6l3X#(($k{%P;YUpAc26A5e-Ljo`&dt8A5V;F3e9RVhv z8?r~VN#%Z1>E}26{oCya&%aKk?8*G1Vje`#nPV(|8Be6X*VPf@K(=G_%bVv8?$~oN zqS53dQMu66*id(SV=cAZq=)`pOXV8X{D0MTEgikXV|Iu157Py=e*Ws)%{xy%kEIzU z%q}Q?<hB~GNUQM>z=HU<H%{%}@#~3q)nxw7(=Cv=5RU|NTB1i>h59<w?_=x*3&aqI z=B99KB5NdJhrR=i0-*O1$x*X{3A%G;-qiP;WYCDKAg8j&gyH9g+FQFvX?_)TCIR9# z$w&pUkOc@sRWkYyD~6ub&bJ0f6SOywt6Uj=7=%l|AnzbWfBReNTVei9RYU{?2Zu%{ z(zxP0o>$E2FJx&^rVS;(BoKn*QcKLBKqMMLah4;Js1CM>-rh{zyh$kw7W!t=;dNPH ztCJn|2clFP-3@!QMCTkOI$?M7-Oard)LEJuA4)wJuf(X8QWSQ0qq^R*f;ATG6vCin zNpYk3g18nsgoWABu9hA-L;7N?eGeqLXe_V~=)ZKE!i0g};nCqChA`9&js}x&oIW6g z1GNOZ1gC=94vhx@E@K;*#E~a}Ehn_3QdUv~lxhhDz(}R!Vk8HEBSYc{z$}3~+M1dg zDcI6b9`W;kw{G44bKlJao6ZP;QAv$sT?bo3?n$^Q4$S(G;XHhZYQoHCoc->LAAdf4 z<!x#{=RcR0RaSBF6!2>UxPl>7R73#2aA^0A6M<C}&*i)(IsW<C@!|g7uFm#0dOF(M z+gsb(+dI0u2S%(3L-M90X%{zs{`Hn!r(Ps6fW5E_1u!L5<`pCb+&+6~`>x}!D;dC~ z;)*_I+?xVqY!jI_U{)4)HDGeETD~+^qRgkQFVKhwPgG(2jtvhF4GoQslLVgXs>mtr zVD~fcbf%knA7|AK&2futK4pj+D`3Jh*<McXL^Q?a?iwk6wRkT_Pk9GW21L_?{yf#^ zs*~p6!v*i3ybLD!n@+VK<f@=FIj$im!r_G1th9v4u!z900+Scbt>vWBL`wSv!L&u- zm(V*jM0NsGHyVxsz~Yb=bwYe8_<5mmc_d-maHPq$^1Q6P8c4^9j<&%WVr?wv8AJ>k zxC7x5#4=cg^Ng5U;Ue?Up@o}q5+$oR%z4<louIz5hyV;$<z-|SH))?o%GlB^Qt1Lz z7V(=|@^_fJvC|fLmI!kXoB)DZ4qe0MxuUq^g~q)Bm_(EWk&uVw05IWK^RNJ5<U$uv zE;LJE0Jw($+(upBTN>$y8*0P<v2NYE|LOOq=eD2Efhj80{(Q3Q=%i4o%cc(Z6486Z zx#>Uh@;E?Xs`TpSuQqKvVgO7MxQdKY)@dC8t_FZ1fiE1|wc|`+HTB1W9>RBkBo^YC z+^7Za1JDGu7BDpph}`jFV_BC4z|RxB0vI~9N?-->?%n4?T(ch*IsKl#m<<|4gkcg( z$U+ra&pn#E5u6Go3PzYx`EN*3mg#g}A|%E*eRgz&@H;$0MOU+<Eroep3QgQ<adB?2 zIOyi}XQ{4nk_skC0SpsSPx(qw3RE}K$(`O(D%A^PEI!98iW37;ZgIT3zDg31I#Qoq zz5OO4HYtq;ol@Tx>c&LrFBIaV{54LNL&-_-n}7^XcV&jd5P*(P`{O}`?3ECQ5{cho zo-i;tGD0$Vj4n)$R6WIJD@N-?b1*qI=sY%lhsr`9T>Jg{(`0xxhg;i+XGw^1r75gl zzAikZsY6+3)ld{yA;4t`l`uRcIaQemX(*HZ?VZTYZA*M|?edjd0fpLom}@Wvx8^QY z@bkL5#bMgwIJSskA~4JWW#MRwW%C~nx-&0oC2>mauqYSWsL))`&j2Q;tpRYYN?<nt z6MhN6NQE{4Ztdx8X>MTvy9iRQx+n(l|8h6+%7Lp{P$z^2m^9Z>>Iol|WPpmkNkBp# zD(+CPLa1zVhF`Yf;pVT_|GfYF>qIIABBhp8Xv?c4ZY)-z4S=6hugsnMuEjJ?E|OKM z$RO(hGDZR;R#F->2$WkxK>>oNOCRj~`m0Sljy;GL0DD^8b!0e`#ZASO6d;LvdF%B4 zUv``eZ<?H+BxcG2gJYL!P)!i%xG<Twh=h6mhe^y_2UDD7+d<=%kKnU>AUvg>kBZ`k ztn0C$V54bxXmDU~aF`k@&5X8`<kk~_xuxUcOh@Y7<43NBR}XX6zH}L2qU5lnQUyc- z8!e`eM(EVt;c6<OREb8&fXNU%23&>$2+Z>4Mq8^Yno!fx6mk2^`DalHTxvq0K2qH% zDVIoz<MiydFQ$Zb@<l(s`N-72P)wE?3w8>48cmjz%MsckjRzT|Llrw%98F+Kyc41o z{+me#;83Y01W#@#;SmGHFVF7Y^3&EmSL0Z7U+Qb^9Ht@{`iNM*>?%V*PMqE_hD9Zm z-kW?jZhkBYic3lxn9nR7-b{ao%)e`ixUz5S51Y0geUh);p^-PjIU`86w)Azl==c(` z#SxOhYAJA+20jV8cHW|bgIoBs9VL51+_1T<h*fA5Gmt0RO5-3qSOJWN9BcxU2b$c_ zrk<ZI8VkUMB7s}Gy2&xb0B$0uP;*24cLd=7H7Mit@te5_ZD{C?-eTRz5GUAh9xqkz za5H6)s@$Vgg~&tN$>d0HFSV6hD!%adKYhJ*&)MfO6ptX<C@CkWvgKBS8@i^3ns%Wf zZuH|zCk`Gu^QN$8hP)NhSBc@ns*aT&gKLorP05k~q}U<z;X`};<zLrt+;ZSfL_XC3 z7ZewjQxvHI-fnSXk(mGh=aXR<`SkbWdpCc#>sk58)JRWz&%h8fC{P?1H{dTWcoAe0 znE4;GMUVfYNgdyu`~$LPSBIEqnD@j{6}AkAW%$kD2#tdn?I_PJ>zO9$OZh`H-PzC1 zpSu@VKSDuUK3*<&F>Y2qYb+szz?nqo00pzo&ELw*P7*i}!2q@DPbnEuN(i&W*&$bD z1*$4%YeIiNdh}{Qa(a4JZXSu>azZb&bK>b7c%wi)#p%;h<DOl*a9^W*Xv5FD<qZ;g zx%x<x8)%C(+lPkx4AQh8cJ-i5A@2v06SE+NA@U)K?x`Z!f#0Em*QbB^VZ+Anf7*8| ziDmFycT4veISyENW+6x?YVd1EorN0aU|hr7=Y+7j<ms?UpJUB^i7P1E;4<xqxwK>B zx8HsH?N7&EVpbvZ3}#YzOPB`SC5Ts~EsYHE_#)mS@qNUT_yp+B!TsqkY*B%sw+42P zz@e*z2onIV695x^N)(vGrfxng@<4MMht%^6evJgS0NmL^o?QX3tF<YS0sL<x^56Y_ zuNV?oO0@Y|H#9gjGBUylX4RjxL4IKtR7|HlGt-oJ%}$T?wY7GR&h$n7^6&oXhhKIb zyB$KQ0XezFMP(I~MyY{W4bfJs7dkcY?zt1cU3`(#F)=?kO{ylb3(`;k0*)OKd*%2F zH@<@dLe*8}8I0grSIpHtTQ}{w5=71JbMlw3M&h3HM#$%#lM#IH>~DL2_}iCf)B9(} zdfMB&`-jLe!E2)2kNz6tE%LqqL_DB5w+DNc-;rM5`fC9oG#0vAPMjSjiA0v+KyOcP zZ~wsH$i(#cU|oK0b@#*^ZEA6Dv_3WHZFEToWpqwWjuM^Vgq7%pl^7=*wI-AK3hcsl zR~99E4?ZCYxT=0CC}stkj1LmOQ+@Si<t;3K`wQM*I(*=_`;i&xRO(q+T2Wq2X=^U( zw$@lr>1!l}k$;+%nHG5K#EA#VqD3!}+ko-QlmP0b{n5V&y+ecjeZ9TCeZ7QWe&`-? zs^d)MAe(Wf6&h$G2PPs8Y*K|3%ir9WXZQU4Gj$LDdFSD~XeBz`-9l5ecswinx#8(% zV&q@(|4KJ;XuaHfk&nmS4CXMfF|}D#6S`-|dOG?zgx3-K`<^YEe%kWWk3Vid@v1<x zIu@8~<0YAC@D_24Lqh|D{j|g0USh-)-eeGiSdm+)ghTk{nLXGkHitZ9qEbqnbpRM) zU?+gp2~Ae8IHBDE%$ZoKLKA?aA%RJS776U4#HXg@?+L*FTUd3-&1c1oiAAx^nMl`> zUBfaMmm${%bjd@PLa)nHQ`s3e*5BURGcws0^vma4PoF=2^zt)Gt<A|VA}<!{(C`ei zSZpLjacV^=72D?|zWn|C*_&^(+h!N$CdP@__1?8|8rtME$Lmo&271QPh>Zw!VW~6m z_Q9XGpLvmzMQI~NrIg6QVP{&7r7$-T<5(FfgxMJhZ?2!ea`EWTTP|meE|DSy5ll9X z+yvk!HJ`Xb=24<0x<8Hs@c083;_{~qVEWpTQ4&aW^|*OL@Gv2Gw6i)dr@C_-X@)by zEwxpRJ>w9-OfOOu&kUXW&_Wg%vq}Jre<VI(`D<7^F{uOM7qZN98M)2)CCcrrD*=8N znv)-#+PCM>rB^A$^Emsol9eRK4b{|ER#6KkniLTK^7Nh~_Yzw*gB+R(4hjHf^^EO% z0<i9}f1sbteY!`b8pHPiV1Wi`1|m+-rwVj;*2}X8cJ1DOgvY(@J9R&yi8eUV(cCk} zOq}=|9*)R?%kw{w@KXN-{2~Y>*=j0K*&38nLkn>7tW5UzFn$+YG1m|5*s*Kh{{6du z-M;Je^Xy)6u*_52e_=NK7xO1J5a{XeCoas_*gqgV$_>EGrLaBz56EXF0F#P?n2goZ zj+JQkVUZi!XwasXkR>oXp*cg2Y~aGY%;=!Fq80)$nZRvrs7`Ec5deplCEa~n##^T? z;B2SHCs+bgY=DUx1TL2VvNE?Izar&?giBxF$V5-ty&LZmqaIv5e?KNAJ&RH)xwt@U zm^lVa3NB?<6csXmkGg;P(!J39PI6VuaiE;lFQfyo(apMvs_d%18kL<FWVKREr=HaN zM|T~$7nPpDPH$SRo)9b=G%s7rStI$mR8koI{MPN)5n->M$F|IWm>KNuC00rj7|aQ~ zW7zPTvOVh`W*fK>Xpq(;au_PKIT8FB)MzC)`g$^d2l(Q9XgMCKHr`p8lULm{%1SMj zOOh2gN0~v|HXJTa%~GJR7GIXA&@6&YS|U398Y%@FV@z|Z>l`W4+}gy_y`jaB$vijO zQC(7wVSlZ$w-4{!vH#?q@SNNnQcX%J`_#B8kSteUS4CA^#d&0Qqz7Hz{maqY@hyn$ zkP5_Gg>-_pArhE)6phAY3EU3}O#V87mnfM02$_gJBL|6JuyHQZy({b4xg!UTp1yGD z(uMOU4j(&nKh8yeG)hg=CZ;JX6eD<mV9DB40WAJLsY&9HCW&0PbFnjA5z<+h8tUOH ziP_rd8%Ou<JACrOr3+_{AJ}u?!mBJPb0PU9&?EAPnLsPiE+K(siv(bjz)(w#I5R3V z_Gsj<*a=XfM_B?>DkYo1D$LvftclPL0BbFw1z>K-L0wiY0JpYxbWwwVhWZ9oq5n;2 zQQWh)^}K@xHCE_9>%e2V8!p6x5ES>H<G=X@Z6_8DJ(#9?=gHBQva-(6_VnjB9)!dt zax)Gfm|Shh%OF1qiWv%Xax+qs1MXgZ997;+CpSOE$?$BCN~R4Q-|z*(;Q_Y*f~%HC ziBoXou6i<_oj!IgAfEUIyRoRL0hc1tV)klzlrtI^^yF!9USnIUi?WdC#|HZPDY=5J zI98X)8^HpX;LA=d7Wlj-b|{(j=CR$3`Uhg$@yGck`H0vN#dpi!%;A;c!QKIqzXJn9 zoaDVY(O#BYP}@CWg*?!_oLweN?&=U{3KEyUWN5L7k(4EPYCO|^k#}n{jNz5F&Pk#J zbHlAw#pNv=Fd4~zbm-?TJCB^DTsg{yv;79@HbC-AEt?&M`9;~G*AD&s^S+z$kik4n z5<VW|-vOG)8^{hGQlQyDB>hs{3QRBxV72D?3}FSCms2M#k$6|$iwmdEUA_DKbpVY4 zdUp5f#VZeD>q*BN>ujeoQ|3vOut~=$WC9ZyS;<T$<cF5@MWk~$0W8sRHZLHS7iUI# zc;Ml5ZN#k$=P%!U`Z_Q$@a^+QH!fVb_Byjgl3SM~K}CGutR1sAgZ4$pB^#Jn6nH*v z7hB{CEbwsJ8QgTB1NiG{r^bm@$N(lgMG`4lIpl_RlE$G^R*;7U6Sz`}fw{3eOJLHV z3BZKlq70G1-EFNMT?AlCcp@7(nQh>I6I>eoGN>6W$nx^f5P(76cu!zg%wy<f5@pc` zHJND9J~qx=zB}{%i#ODBBQ-sTLX2hQl~kvIloLveqIN$lf0JV)Uf+KaSHVSHOLJ4q z>ewZ0(p{N!`Etx^8nw~&ST2!CBbU{m|N6@1N0C$^NyW$PQLP{ZW3~EPT8*WBYGPEx z`*)G~+W&ZQjJ(1e(vt!jCIt9PH6SGMMSFK51SN3fc<exuG8?=v-66h@h}ZUF_2c4c zEmAfnx+)8b>bj>TmzxL-tO*>8ppTzb(aVh}kipA?_z>)bp9+P8Zggr_XKUiG=5COy z50pDS*j!aw)sFa4SKRO0fBbp>Z<n7Wa^fV#&MEnYy!D#ts=0FIWz<J4zbHTQ{*mpQ zemZnthQtwV!25(G4%J4GXGV@XBJe>PT1|jvXo+%5|6;r&ASU3IBg9$qhGZA>J-I=5 zZ`^+ol9ZI5nVFuR8XNrL;e*#P^+ZY&-EBQ1Qyd49FtA3F(4rY8Fn^O(nz)R!@uUi) zQ!mYo_VbMSsoI3+ckVn5isRKX(^C^7Uq8D4G&HwG>sE~yL84cZXGRFd7;a`!;7^b= zCXA$-k}-FzXcE1egpo?w3%v}$nup~q238-I0+?M`0^kDjRS<xqg5pX@g(d*g)7;Wf z-%Khr1Ni?HSRDCWy1tWx6ka1b@^uEj8U>c)g5O>%ZV<Y~znB~siA_!jVfN%j1cZi0 zB&KE&f+<0uoCG7~ebGa8P=&b}<l&46eDx-&mJ7ERXULFdzaB&oXju_tFNfHOW&mia zwxuo&mAt$6;5{00U^TSk;D>}gwJ*reN{Ne(2oFgt?h!R<Zk&Ub2qIxY+A2mRNkX#h zP_j8BM@}3eZjb)9d_?{hXhTnc!i_jEF>AVV7E;8xDfB^l|Ke0vbzxB*T6uAbF+@C( zrzUcM{qsrV3{bJGD~mn|m%N7t4Mu>1Ta&CP8&UjD^);52Q1?sROjq2+?LYnm0Fxhr zV!%`_MgVq1>QMor0FHiqeD{{`e!371M;1rFG>?N{6527!7=}j(!Hi$gay83bUFdQw z63-Gg#O@}$d||PtB<AJw_monSNsWie-pk2IONa=17m(6GXG93@9G+%11p{0hp(KeT zF(X%uN@cMdYvVTG=9wDl<MAC+jTu2N-iF2{^J=tQPG&|@bnyFkF-4}Q6sk-3_^E}s z!~>yckeUJfj*&)6JW4D9QIX(lupUFF#CEYdg^>ygz^DbLzeE7LcXj7P4$Ft7-E`Cm z%_)l(fI}3(q(YMytD%tryn(&Y?+YSc#+pk)ek7eVWny984LYz&{uLKgO1UdOW9Owy zrP~4_Q4w55>9oP&aVZ&`L&8ZuTxr3R*oqmyaj}u%L1Af)ieHKBaULy92i9VEDe0+g zVMu|?OLK!kI|FaHIQ-RX&MHbJ8B7pHhiu{%Rb@1wAvZHQJ}R8ZqgpEXh!K-vIs%8W zsOqd2@|yG)7p+K29R0)VXu*aXdg1Yv>6{ENX>x|-Uu0zRy>cUAsRX7(EEtBAg-3)v zg-%~x)dfWj{oGE7JWiT5AdE!yW^fZj^_s>hb!r|lB#S!Xie`B({bSgBFUcERyk1va zTGu@(q&%2)cmGdY_8!0VD6xS04^a@fk{TbZ0N}#tCnxuB{(jS$D9Nehj7r+F2?8O# z0^VV^ggF&UR9g-dquLLDb2%zAILU=JNrsjQG2dUAL{oP-C7U`5a7`msG=k;EWw((G zp6(+APjZm~xucOBgW?Hr515&bSv4zlD`Dv}In>W;#8h)mTxe({3b3#o6;P%oMTdt* zB$ah(i3tWjA!C%OpNcg&krG^(@hcH%=N8dE-A0B63-~H<0Z65+vAc07fFXcUOUMl= z3BX9CwEJNhA6AJ4;H(%0Fgc;S+S*8kZYD1@034VX@hlE0Y)kM3z?->_XTeCwP6Osv zF@s4524ORit58^&A{B~{VQI7_H-Y-RlAe-9ifw5rddyLd52e~>rNu=@Mn=cywQx{! zi5vz{W@Y9loD!Cr#Zp9C3L5lkvnVhSi`$OYX3#7oB7)RRsw$)=0=ycU>gG~!_xQ-L z==5T3Ks7%x!s;_C>zsYXO<+{zu{fxWRtL*4xx4aT`G_Ry;c>8E)w229X;bW#<G=%~ z?Wq}*^iTJa7Tqw&2&O_LD^<zX+nJSsiy+BOv;Se_qAQ1+kdgm!vx1p)czzH5WU9NS zw4$*eX*TrCH$?ot_vf95&OM9=fLQ`lqhe<PNCP=4R02mlI<@Dg^;<6_4eK(PDhf_6 zwMZ6|;(Spg3KJJ*HZ1Np`Y4Lx^%f;X7x8MdiJ6{?^yuKAh{TjM8j72npO;4&K$+yU zhz$=<$mg`r`JwjCf$`~iN(Q4fO*S+l&8P-t`+t7b5_0BZl&8Qhfbr(SgitEAqHYtE zr$DRa<@0KZQDLF6DJ9xvhdC8rEN^p0A_VMXWdw`Ugtcp2v(^~P?eoz{wu0ua>n^9- z%Zo~Cph2UU-vMB5{Un1%X;L9&!C7-vxEL5FFqxp-A{i=lR!kVY(5ylOz>PM5bHbkr zfImRL0hO+k*VNK9_O+mIq*AcXrO^ajLsknD!-J#Kd^@uprSTy&6@frSjb2F%^Ft>_ zZDr#qQ=S?_ccXLJ+?14(BGbzVT<E3%hg6Ij#?7|2B<({US)@GIQJfqVM1AeJt$RU% zEXHa18EMqnJv1h(hO5)qMKMl<MuLJ;Q$T9k0R{^zaFH&e9wS}PtctCh>R^5k^?vfF zMfJ9{ZeiX?A3`}HnFu&dplY_8W$*wgbX>=vs<-+T@E>U9_{%D%u$J}Sv4k%`js@(6 zUJQq`G}c~ORM|3WmoLuLhF{sYbN`74(KJ9B045t)f_!QRixZ1%kHU<w`^R@~Ucdcr zfmOcDHoK@OFtboE$qE#mDl3;f<_a!H57h~PKy9D<#Z9)Cq(zeQltAv194ddolS?Iy zDTz^`)IGd`b1X(Wspeyfu3P=l@Gnr%fDLWV$)nj=L&L1xtoY0hbppSmHF*i4p;2)p ze{-mRI2YXTazrIGZ6Gqapj~?pQ?4u2D%g_jKf^8Z7TNgaieM;;Qb;Zusr;pt8bUBu zM~+egFt>=Y!ZAqVAPMXRz-0fDp323*05DBO;+A#*FzF69fIB(>;MU|HSpo+Xk_48b zK0yap-K@jJG3d>j=OQF7L}I7~`2&*R2mF(S8$-FxQb&1mIAJO=1-;h!W+>q?n|fnJ zhlVBQ*P|gUB^ZcTPjiv6l$;3;1hJFlE9x8A!f3v`BApN%5l;bOLkCoyPF<m+BST}d zjrg4gmiW<>U6FcH@J8McNe3{D6uwRCu@R)dW&TipL}apM6|<LmMi9&jrnG$Hm4K_c zp4x)KModIyE7-EX;UKgHy2Vm7#3|kyZ)6I?SUu6ANaJIRqitnHl^tk}Z`j>TZN$~X z`wrd+C0@t5a#VupnQBv6PF;^^8bIRv>xZ{({CdkB<oGP1e=6@9r^U4#?E8ZuEXe}E zukn<~S#WTRUq?t<@*V9BOg7~wL{dL*DoG|9p(Qz7LTRs5(wLqY5gHbkQOyV*>uPTA zAE!zpT3S-0Imm-)7u?HqvahAFrEhX&1Wyfg_px(zxI8f~I5?6rz-iV1O7!SKAEDIb zxX_TWqyl8R;K3nE@{oA4P!UXY1GNoCuk>%=Ez0HdCY8qvisY_l+qs}00M<lGZHEN_ z*NFhuG!7K=Yb_ysSOQ=oX#sF-Q4=I^SC<EXiy~gc4;uh$UFkaHlE55<B#@R-rn`~! zQILm!&`{Rm6k%ivYIJW+MpS4-EO{rOtYF+pdRk&kXjpPV<CswL6vx@rsRx~lP6EB$ zq}dQ3gsf?aU29dVr~&6aRGS?g6dX;iMNy6T$)v@?!{YOsFtC!G-BR>MccJoEeLY~e z0!v=m-lS<9<iN2*1e-UpE>7yv_%fMz`RdtfV;gbAa45;*rs=9R`9&^N%yaiteJm#- zOluBr8f6ULD-^xrtUWO-(w5C&^z<^;#oSN}H7@L;x;*%~)S)xm5Ow|7flKewI9D#e znB%}mFF?5orP^?=D+SM~y-wtVvj?_q`1{vq(gzo2#s>Pws1V!XDYK|sdKU1ZvTbMv zT#5Yy90+ppI9bpX4LOep434Ds;dEzYX>nB)*TC}PR8A2Z9-ENQWI5N{+|o5Xg(Q|a zPE{8Zm;*JGL^{%1T~X8S&@$YQXLhu^8v_rA^P@wsS}IpyQL`ytjW9xujw$s!j%M&g zrJ4T!e44mO_5o?lGwl)hMFNU4THT#ZHmqc5+g80M0&sCr1p&B8+i{qFc2xFm0a$%l z7J#)Dcntu4t^h`A9>`@K96Zw0j(e2~bCJ#vdL8hc2zo8au*8_0fN<%rN{$MNq7W^4 z3j|VG$%&C6VKKQ4h-r`mn)<O&LNbDS@VgqJW0?{LPB<7zwGlG#ltu&9$wBXfqY~4y z%wjod)Db#7G1~<Rv@}a>lnq~mBan2AxQ114Zno%P7+7QZqjad}pfO0iF%%R9q){;? z1A!N0-I6=j1Hn~!#mzbiR~0e9*tENVH%hH3J#QGgU`3t)7W@iI`Hti==K2~+OY6H? zG)aFq{jr6Xm>VZf+zU&|%;8L|@@nn_Xp&!0&%oKIMAQM-PaHmaVAEFzf*Xg2yIR@@ zrxEx9J-}LEza0(~YLq(lNhV<@>LQSgWJv&ZuNa!GjC%c+To<v)ndtssLIKbUdbl2{ zFo%MFap94HAq6n)2B{5S_vkb-zImuLs)LzcmX>CQS}IGc+lEBxSjOANdfM8V349pN z3Va<LLc>D1*)jJorGN$dRf%KJYK-8}fOk=)T3!f47_68h-$bUIUj|1jyh6fqA!np- zuCz1dje<U<DVAJyM|lwg*u?-wz)mGF^;~2Cs}D<Oi>d?`0Q18(FeGqc7E54b1FHm9 zCsqJS;5h73r~@T^=t?QpArq$vK{HT9?m~E~#^KD-EzOLLP**Gdn*P#+(03t;Dd>1e zF8i$1_|Ug+!ZI2Kza)UA8w<%NcwR+zsoe*yi)=Y%-li?7jUF78ePP2D(XXDpjYzP@ zi)N%og#|^V*8wK;u(c;C7-1G92Ci)yRQdvtvPp-y046*^EV4vDWvSGvLCM9_HH(JH zu4r~aBRPfdT(;g<T~OMl2&Uf^KZq))Zo0EFOPvA4FkMcipcPbZ@r%iy&-B!nls5LU z@h{z>Z0*|>ar5+*chrfOa^*+_Q`c@1zeHBt`<GH}XtZ=5b@GgRarxBEH$jiiT#2gd z@9&~cM$n|SYk-)-oVp+#qa^64Mu51hl;Jb)1(DDzI9`3SB<SJ8fUu~9l+4^bB2>y3 zpbo@T4MpJ!lr&PZKvdw9*V1Nws?*ib+%q~&L2>HM!x_?CjKros^|<CHhdLzA<7}pS zTbgA4Q-AuiyRX6`XtnG-nl+%SaRDV(<6h-a!A~BCP?I=)V9}~CT9UDipfQH8D$I~- zXt^vjq0+?wn0jIrRVsktYp_~E+W_XF3~*u*fKkj~09>*HfZe^&1mNchT9bjkhfE8Q zz?|=<s<XVKXq9pw2ERr%GS@RdK|Qe1R<J8S{Kcae0Z|D_Y3b=nan#NI{)4y4jbdpm zQFxv{$&77s0)`-4k+3FASASm9v7%UchI8n$)|CyFg*~`+=UH%6QaV3LVF53mzDua$ z=?zQsq&|;x`57;XDFV<gOxt>p8@}A`>uzn)lKTo+!@Fz-2G6}3dH^3R0TIE(Ft{Sb zbc<qEC<yMYDkzg_^dIQQ;r9{Un}sj^8#QujRN>u}i!6h${)UKP>rW>;YfCGds45;! zR+tw${;)Cn{;lU!4ot#`)H~$Lp>sE-+Ej82liUoV=b)!I9w#;rHs++1wo@E*1Zowj z{QP}tCZOt_xG*x5(W%1r28vpVbJd>KZua{~$*W5jA4ZUulNx##Q%0xo5qb@Jhl&a= zX{2yc*yC%@(-Fj)?{BQBZ|NDDnw@348seYKVm`fz{=T6J_arPihN=EmSCfoC?oEDp z?pA=TR%%v5CKSgvsc9>%mJs#g`i<8`2Ep8gldCy7(1=?kLRACUm`bXWqKrbx0{<1I zR9<4v09e}TG_e4-db*Pn8oAH{V4lffOkf_X0;7Vv{kltF4kJk%xLxDGEP*WmGqe~Z z>ku9#8n>oLaPxU%7Fum(jc{^SxdFlKWS;NI54`vL)rZgC1Ox`WdUEH=g{x1JI6x2l z(yUL)s3nD4Lh>>%5dHutf->mD$T=HN4sqzNlMNLI+&Xjm;@xMj-@bqU`sv;4*Pce3 zTrb8iDw~kDNls`fmlsh176k;mFDQuhGMT|B@~VMAXhV~tUl;__emJ$#T)i?3T1szr zk)lZ@&F}?a5+7o>!oC>0<{XS0KziPLRTEVxgKiYS<i4sbu51}%tCa^ni3)3>d&!mX z>^b$bOHR+pEu@k$DhRHrr!;a7pO;apTslQ!qhCLLpUKl#CVB?Q%$e4_WdWtWC>IGc zb=v?I+Yt7nI>j+?1mx^|`H|dbCyriv8K07j_W#`dpDOFPYciKKvK9|5Ao2CJ3#KS} zysfsTwz;E!lrB=6gqhvCiFU)#Ci`3JXvhQpw=L%O@iR|pwRF<f3BP7F=2}&h@k25= zJ10Fc=+>EYFLH;>H;4#kXND9fu>@wr8~8=9O|X1iy|g4li)t|`4Zoc0sw`v)j8sb1 zpgEP&PNaknixVlGJ}d)Z@?nW{k5%ZzGFGA6+C4I{{_WfRh!@FLGk$>=NnrTepyvw( z;Nk9vMr-D4vEbxH@azNygb{lf%71n7=x?XbU%qnb-0?$)PTY-Y&^|=O-lnIiPy!Yy z$eT~b9E*Sfc=A}$ZCs#xar;<#z{P|651lx7`O1|GXHK2HAI%N0*!*RN!lzBsMM-Pt z@r1Br_zvJlSNEJOsIYX1Jey}&2EWml<WT7U%n%VlFar^j-6v5fDZ@8uNrxkLp{G2* zq;*0NEb|#Gf3}V}1A2}4g`?17>=qdHy7*h{-y3ZzE3IiCrns}r3t<9t%K~YRf59zv z2*ISj5`@dkc@z!LwWOXpoaq`K78p?|xdAj&8E#2k36_HF5lI4cq?|U7OJpmbw}E1M zk-rLHvC_>mkn!mFj-&S?Qqt48XpPIr$PR}k&NJ+(2!-4KQ$O$Eo2O3Sjcvlu%?~zH z;%8%X=K%7`S72tc#LRG4Q*Cvl_TO#@y?W%}rS~bBoH5U<Q2~dP*2`+>9!}$=V;-N~ zf8tT5na>DTCE0bPWl(0ZY*C#Zx<zPh(8k10aTCAvCUadC4ggbvuRfUnqluKvK~YNx z4H~n7%T)q<0Wf)?sh*G%IW!mge|?`H@hZgwz%*WzozUW$Wo6D5g@CG2=xo|{9_c&< zTt^{k$MYT>*tTWYuARU9yyfR3cj6jV*Wr_)gOR#uhLeb3KuVp?3SdiBHjK@~B6X1R zWO=})eLrv6wrkIx-8*)j3#bL%(S%RMFXc^eag}EAD1K!<@FfPYuqvoPvXJ4Z`aecH zl0Pt94ex61QiL!!#$e{n){{&fQHE$Jd7-BwzpPbdu*hCbRAK)!oIgSpOdP^h-C?`Z z|1AwQl$O<XkHc;@u~%_`nP;&sEt~>1WNzegJf)-vx*KP|&=BX;nDCH@n4CK4HZv<J zWct9CWq=~gf=o~nPmoS*<4e+&cC8bg1m1J^J|aCSHxF*vahl6Ox$gt{t_V@6X_TT< z(gjMnj4V4l@#)#$PF@eI7Op?h+d{=s)%C5^A&nZ#dA7kauQ)Z-*;H3s-`F)Qz%PA& zX3y>ecVn~AWrB9<wi<d&RFoD_Q|yelSNH8Waxc~DB*ZEqr{(h&1;Enk1Wd}XSN2{( zRTEb3)Snr^ofU-zl`=1c1MXH3N%F9e$RXW0Od1vdOl%cCENT==5}4}=v*JP^fm@`Q z!C8&;zA)ldq`tHs!V=F17XOtv5tUZ)E2k1`i(v7QDwWKSQ86)OaQoZ+-+cGO4;yLt z?2-G)W<)WXh{<3|o)xIop{mU?o*?BFPb;rz5N610yejDOo=qEm*!<HE>o=c`hXk4B zLSOPx(zg=1ahoc{5XD?G@hJtc;>CTz<<4mN9iu7<;05^Xj>NcMi6kM4h<a*dq=G%! z<wOe(J6H@$MKIgbdhSL!0Dgs^_<9xw8mW0sKN4#AjW9?9t2%yoz9lDt=B`GO3)s$m zDW)RAtkmS_u&~&iY8gH{NBLEfAIp!}P*515V!%RVEdyyB%%eE_%7pHP5%SssV6%K1 zmsI?)_exM!9(AOahWymH1?eQ{|4)6FwCzJ?z?Bn6j$V9MESBlg=s;UzEolnX4Xqu0 z)TwBS243KG*ve;$8tLn5YorkY4Q;(be;+3EpB(>X%bwp}q*CG)=dMuW7OZBb4PZ3_ zFvW%=?;iX4=L6T{xT63)?Aai^(j{`0w-72k6)+*hhXuATY!(|;gTXp#8a__|u2%rV z2hIOL0NVg&^#=_pwU*FwLOTH*77qZokP5B!z*5lvZvu;>UWI!An7q(Lad=TXd?WA$ zDOn=eiC~AJLkR94<r8#0-1O%!Hf;E2{igj7GK`q#a3Xp!qV)<Il%e-Hc!e?yT0~sW z(jv<|79~4mzfIQEFXqB8-+%kv`fvaK_gz8g%|f*+Gt63e;yd>SVgPGdl}0GlgT=%q z#-h_SkXvy)lF+DVlK-e{O<Vskf^{~gP&WY>MG6dRSwIo7)LWTXq+P}(bwEqgMN3s> zUX^HJ?!M4VR5wsxQ7f}kpd(oNv-^)O^%f_G2hv=IG)_w5*4flQoRS*S;wcF#j-u26 zEVU0CLl&F)I&7Bt72XgT!@{H35F&*dN#wR)-{y4o>ix-AfBEXW9}nM&DCA^D8bDh? zCb-I9z}Q70mWoo!{wc@_xq1HBo;}B(7U}FgO4sdet}ZPtB@oxs41l)Ij?S*0p6>3h z&Q7XxcX16`Rb6Y(u<71AQ*?L#58rJ$bnaay1v6<eT}_hDIQY%0mGNpt1+h;~@A~0~ zUDs12FHyJx>(Jvo7oLX1>VR+BB4S2Ho>@v804xWur?${pkq-ddX&hY4;8lY*b45)* z9TLC{U@j*tF3nGjh%W_z+qycaoY3yb@oz%QWA271)6t897g}<#kZ;N_B($w?vH|Qt z7v_KG#|H<<^)Zxo=BuxE?BBa%&&elQ*6?=%6J0*ld!Stp$4Jq2+XKJC&_r-ppz=b& zPPsHw6LM+aufOcuv+?gg+^w7;5*!_q>VNKhNy-p+2;xcW$b>hvCITO;Igsgnk8U5q z51|~0e-`42dp`*4<~j-G-N@Pmaq}@+RWf7;=N5N}R~|X&(otAAnRubaBDa`|PXN#K zHB{C2Sq+ath0-3-<5}t|PKcl>uq1;SzDy`NIT^_b(P809<*m{oZDMeUvKZ|j#8&x* z1iwn%+&_vFu_SFkxUgC!a;WYjof_UA`0DcwTaQ1ArSJ{4LMo|{US^^}OZRYYrGl|Q z5qB@2+`aYZ)8R6LhtFwlw5OHk@Kkfqm_kog+>MX$z-=|FIT@w3YhcnOf0F+y<luLI zU%&16mGDfe?BUfam#xOVOKFH$QBnM>OZ$KNZvCORF2w;ULa6uTb{kBn+>BZ>Qylo! z`v+UbMS<M(b?3Uu^NZX8jM>1p1<We6n7{_WTnr2+G`$k1H4uPH0pJqK#4;^)&=X5K zas*WcTn}t?yI+n2^KHny2zN73N!)zioiuDZS>&|J(aw|`zugQDfA{=VblI@}2oZsp zPt3c~8U+C>8%~N51r%0yP@q>e(pq=kmG<V*<AA_NXHPya8KZ1;X_(16I~(07x0kdL zr8SjxY5@Q%M&_@I7N=B(@gQaf*fQNPCR3uUP+63?6rf_+?t;1Qio&uEG&)6=lV)Fm zIur<MzJMfrYtWNDjSbD5XYD{8vlS<kGo;m;7xRV+3DUATO3$rZa<aL0D>}VgoIkS@ z!vn+6#H~k0xQNC|ZVYOoEK`eUlPEh?hrYhM*i>?|_EYm>*WbV1xc$uISe~enhxY$Q z9!mFc@-0<Y77>1n@}eJJJH3C)kNcii+h4FSJ2~9f-O=9M)aYuYc3w@?=A8aZ1H?Le z`i91*olfbc>IYjs|J!%FPTq*jBY{ty(`Z_Vt*)D41Jt>N0i5{y>fvqQezW7TK?Cz* zDi~zNO#}@CnCFBUqgUw#az=OQ4q%qRMcnqpJ&}^j<82p~n!o@s`69S8s0V;W0+%#( zbaGc&62pzeh7`d6OIYrU>o00OsFeUr8Z?Rv)r7LuArEf8f?l^YJw80rQ=XVyIXKkQ z(lX%iWU`Hj!f-wql=bn!h`py?J-|o=@QTh??*JQZt844+ug{9hZW^OnP2=@uU1&;l zcJ(Gw+ft*p!$>5_s0;cAia^fNwFQ8dGt!7BnEB|wB0em2NkOK{%M*h0OWPoWS>5G2 zNj6&{;l#LO%v(IumkK@6>1yhkTv+0AU8@9v8&@iT-F|+iHTU(CX8|!;R2T~YXJ^Jm zg@nbILsMFu8Xcn26#I-NK%z!Dl3k4#i>w5AB4GrB^BA>Xl7ifWv~BP9{NtO=+s-@{ z0Gome2wwx>Is!03s)PW1{rs-YKkj*4sjm)Q2d%Ux$A+n66?I(a!7dcaqGLuE8@Fev z?Cz#N6M&Bkfb&Y11DLyqV>JfwwIka%e7o;myZI7vLxV$+22J~uP=d-|QMy2*mgx0( z0dit_0NCp3u7iPX9~S0{iZf9jW??WhRE4I3{&pHvipK5?;D)%bxvgwq+|x7nYL)>Q ztssmTuyi;ttlaa=tpA^#92@9t>9$hD<qz10$w4H_RYK1L1~BqkRWDP6f+u}j=B78O zTEys;suy~i+XiVQkugPx+PH@m--IM?LKjlCUGR&)1eErAJ|LqIX7MQQVhLiic;YlR zQNEyiL1*U`#Tc<Dq^mf$R7_Ub&i339b&W$kHxkrazJlXj$2yu?hZa68bXQSLPo-5K zXIo_M=Q!6K`{2su`){J-Q_|8>lBkIL_0y+8dGJ(_`8zo1%rFLtil+|$<}Ioo#XTt5 zK17TK(uoat(PS*%VJ$rpd*a*gH*GufIEqwg9)U+PQ7fXvjinM80FHS0`<cC)e>(iW z0Y5JTQ&6alH{mn#MjQ6;)jj*=Z-4t{+p(*mMgmtF32Z6s1Yk=76M#1yiyV?K;FITk zJ@`&k&`>`%$xOt~EVl0kVF%IBT?l}wd`QB;3ShXfkV@%rLMwpbfp!9zCVfK!lMQSp zGf?tPb6wPztU_Ony1wsjg(rYHgpC2{A^~jIjVE4LA#tiNq%;{fg-!s>HZTc9>Evi7 zT~muUW!<C&0ZrERTi3J_r(1T7BmINplSb;(is+YtN)}jau(~B^sTTohFWl6fiLXu} zB4ogBVBm`1p6BSY`Gn#bVNu*ZLUUA{Ch2T@ab8)6_-OFw7KBAvHA$4dgfF?ThT5CZ zH>frJ&F$-Vp2s)Zrl8q_`?t*1gk3&%;^NJFPhY-%{ep8}?!A$53=1?5a&X*nb1)Lr z1Xj&OZ;|vUMCPQ4ro(|H=cy(M!+{D_=szRT`#<~QyDi6Vhf#S8H6M1jN;#{ON8oY$ zf094pw=W;tv2EAy$x<zcLO)8Sq&9!z4)k$1ltUSRX2a)SZQXw%Ajh(SX}+#@50{ad zI=_RQSkKPw`r)fD4@R;RYi@FylR(iZAEppjAZu*K;bTN!ZUf)t@3YiXPI2JcI?|vU z$y0}J9CjMVDgeg7DxPdc61YeJoLJJ*(e9$rDmojfPDZQz-_AWfzWZvKCxEB9-!7B4 z9F!5k%TH{zQ(TxB?ACCc^@E%l#CRev51FJU4@*)iEI0wb2ELvuyYFk`zQP@S=q{kh zkhD0qW~h`@04!c2DU*W>$|Hp5lQ{GP!c*v{&HQSJ28J(Jv!K(YjyO?;1}A21V!pj3 zr%Xr2v(2T2BNEwyuogqhmk)Yju&tFleSGLhynTG<uRD(1jB57Wf+usDsd#t(z^^+F z9zT8gD)neQdHGE~kTN$(%@>!I=vkax6b+g~3_mnG7KAB6$&gvspc*!rZSt5N?4g9} znd%4M{qLWz-?Z=YTk7Xc>S1XWC4!-QxEZ45qT~wl3sXOt%%Cf$5AHmC&Flou6ZS4l zh(Y2*{PI?sLr(p?VdLIY&r{hQ#9f!1y~=GbG|gtr3BPl6*AIXHFYE7AOp>dtYjBFV zC%lo2UvObNRYi8lW)}=1-ljLYT<oqYU;xWxU<m^|^RRfR3O9g47?^`dlnaf1Is{<u zOu+!ANn#4%CK_&r>4a1of#GI9{2$h>`@iozzkk#3<(>eRwlSJz0z=dfAIdVCUl{3Z z)^2kAXX3+QRZ``XCRK<uMD$bi5<Qe<N8%55@e-r0t$oIT6S>IEKD2MQ`XVH%BNrj~ z^%t}5pA$EYAedhtMM=CvHWRda6C$J<F66s*L}eE`i*rgkCGZ0c6=irv_Nsz_pIPnw z=KETjhe5H?*AHy_>Br4m58Q}10|piS%fDf|BJjeFAAi`oefQ2?yAE6mtwGMl+{EzE zh#melyTy-Vhw3E<adWVnt$b9tgC+751bv)SKdExJsjIIk^3cEj<>%eM{(9<ZLS|MD z&%h(^F}jCi1|BKU+&)}}&?Y}Ucl6+IcN5hnMaG)wH9R4Z{U%y|V_nE{4Xr8c%ATLL z9eogwPS{wD%dhM)@MLgH`~Rfpmk;gR_wyHD{+7@&+SlGTFb<~-F)563<5~^y4b%Wj zi3_K<+IQ*Yf|hzJ7{FRfC}|wDM{6pQ)B+=s(&@wEZXAdr@xuTvW(i!@+|k;|0H#DN zdh5!f@Kc}tPyh43|Ka48^%s`|7#g&Z0>H0*N~;sPlg?)QyLvPzDF_CBd4?@#3qyxy z3z!RaP!J#i9T7a9^y)=HS&5{VMmxHtQ~;<@i72!t${t1I8P}>o(`Vo@^|mp$-}I_q ztGOqREDq~)JP65UJcop*=pfOIwPVp}6i~X_LVHPeS*Mw@Dq6HK7V(a#0A7{B%=9+5 zah2DCEAs08?LYtW%eJk*9J=eCVCRhk%v8KSz3sd2H~g?^<L0BU#FaTSIxygHUs?M{ z2uwzaV~;eq(`-=yC5NigS6<z5p!1_Won2k^(U%Wh3!r8JM{kFwrln`*6;d)bODGXf zm;z6MS!&3io1GPL_vCM9p5)lcjnHdIk>b!gvd1+?5G#oba@jF;B;Gyz>+b8J8Cltd zls3Y7Uv8^$7e6j%NR7IG_SB7c0rxIG%4i=R?CBe&KBD9>W7Q2duom)jv`@4Q#ji~h z%MnZf&MT^vJPzbxkqOKI);uh$l7R#;I?6hISQdZ_ipq;~S%q$D<ME;`&6KuAT&E~6 zIre?PqXWBleE;o*Wi~Li6Nj@6LUTpp_ARnzq&!$24J3k-ihrI`p`}C`{u|+I94TFc zy!VQ_nK9df6R7~+jrkJd!UB4Q7Uj|new`$+iqLZ|%Luk>qv4EV>gEJ!?!m_1OD1kH zZ?QwS=8_BTrFrF+45mXzmjGm*%Xz2<y|M%z?`{R3oTv!Bc6iU;y$25L-?MYi@%vdr zjvMm2nVHg;M>l=-`Pbik`T4e|&HU-<!M=e}O`OnMldCfUZ>9+`Kcu7(Jj#@wG9$JG zum{VSrYS>hrHP5P!+n|e&tH8_-EF8HuwsfT8ZiNzGbyR74;u2ny>j;VH)j4AOklb= zo{dO&LR~JOD5Fd`KeHFTMdwlV=RG^M|I{mLRZdAOr6uK*ID*0ntX5Z3!QF>*s2nNq z?$sw5t^G}<#jZh0frSSYox9l*qPYv`#eq->=SIlIs0+l9_cA;zGJt7FCsp(V!0f`J zi34r`=7x3{s)9T$t|b&N76BNQ^ps;$R!#t>Fj5;0_{N;2sxq2jm7ZBN@S*$d?oD5P zb$*!*jHZ(!f!&GQ!lK8^uB74Fh6*1lL=>)Gm^U;Nlz5nc71U7={K|EB(68fvy->Ez z`xy+dN!jY=ppIni+C2hfK$sW#>q+q|%6nx^aAZLQOP&&Q46qEg_+{#|5l`-$S?Daw zFSTT_Mqxyj;l#Xc-*Nm4qa7`n`ZG}Q?)PJdjvYUJ?(FH4M-NhJey$`Hc{x7w+mj_P zk8j=h!{%@P^2O;avO1;+zqa?l!Fok|R#&u~DH`B%whC8-N{$2cYt<U~&E54E67HQH zEKo-?U)_5V5s{FbnZ?-^6}3pnAY9c@hc_9pmYNjt@Y0<CtH6)yE+xwx8L`YVjMH1) zC1QtSLHC;)FMfUgx7#6c$><(VeU7Vn*Z@Dg8h0ScO5<MT58vgo3t(z^l;RhX0M1S< z9z980<ksjYVMDqOgqskmF1B3u^NaKnfGe0^G#MW>o50$QgG0fhK_ih8j{ul8XwHPT z0Gyv35nt3uL(K^NwKWyRRCAILA67z3gzen$+2?0V-S2s69ZX=g552zHGG^oBH`LIF zV@8rpQ5;0n%@UX^RuNxQhtNvwV6CgF(I(lAaD0!Ab3_M0BnjiGDr6~NE6cgn76)m| zYUn}$@x-}bEP)~O#lNg-rN<)kZN)j|-8vsY(?Q^awq1EETj+CxG!UELtuN=z)iY<W z-h2Au&FfbWZ=XN9|ICYgoq%h<yXXEU%R_Emyn6HeFB=X7HI9uB_6&HqufzcYSOAj3 zgC!EIToGMfB}A$L3;wvF8^?;&??I&da9-ex!0@PeYSB#XIM|cJ2qxW<YZ^<7N&Y6r zyt{KZv|QUi@YnIzBZrUJKDXl6@-E?Y;%fDVUrLBB54e8gO$1Lg=K#4tM!)U>D4=Bc zqJom^CQ=h)!$RML3A<Y&QLFw>x-qu%;i!{Nb`k`}HH*?N_?6>X{w#GH09!#McL1ZK zECX1?uaqLG4~vAa0Jxy6EI*NY*;Lij>^VA};@pgsq_~(@p?Py37T^E!#h?CivdClY zbr|_ZuP0?_A4k;A?^IUB=L|OurfG9j2aF8@SiGE03-QyJ<zr<LZ1N7Yqp%1I(Pu@6 z_F_D(jalf0LZd@@Aq!yU7({FsuV@mX9gbOhe>1JcxfN1<j!Z?E$_ik4zZIV;npzDi z@6HK+a_`Yg8at4ZlA0VJ@#ev`E7#r@4*S~2d{<RTWnEG5t-I0HJrwtIWIyYVn)Pu` z;CY~9>D<T`DR%|tDp}@FM$PcP?9ABk7;LJ6VrpZ9?%_FwZ2VQ0qxnB~{|A9m_wcvR z!zxUt30fGXt*p3lFJjcI^DXj0F{B(3tL4WvT^&l(b;6>#qfRkaljtik3o60NO-+sp zkBCYr<pOA$Q9vDl_2rQbO>CHl`8oJLcT(mBy=v@k`}P80GJ@?=Boe?*07C+^`V1eI z0GRMwQdW`^7aWqBUs8~pLseB-=_#pc8PTyxl)f?ic>SOM^FJTS^8#R=w$0S|2f&vv z-ZBzJqh-!!Q8#QENurg)^^b?H=TEX0YKaS0+NtX}C*8BDW(4pj*!b4DffWmQu@|&7 zR~`i$fd&O?_+O5~{h4Vk&8zA)GT216;Ewl5W%BsJ$-WNBm1)b1eE&8$HUVABsp({P zYHZlk2hYMvhkPMe{=B0gv$UyaP^);n{*0LVV8Pg;(Q24SNqx0Ar~&d7H2)b+(By9) ztxbyy3nc_+QARX1)nN|~_hh7+#yrArcyMrVe5H+FWN~ma4sM<gJ4ii|h$4u$KwjD# z?Mzn3zkU-C8bdOe+Z=OGEb$mo83W-rIy5vfw;syMEHzIv9ss^eWUFB89d}`3_p>Nc zh>`gwRJMUxg|_-(krj-7SQtvk8npIwX9>)QV7JpjB?AMPwCbYF=y&g<(layC)6!`2 zXJKh=b9G~VJH2T4%`gAUfB2_EnI5}dCu#L^FwS6rf5fo-Q>s~UWjS+9L=Yi?rMBKm zqlB~(k@N8&*5yI^BJ(A&f|YinHPrSAp42A&0~QknQ&e(@C%9-4xq|mYe3xQudvhmE zw-y;0EZ!oGI{5(bC<VM>u5}g1h6RVk#HZ5KA4V`e>G9D)@82hv5Bqg#Gc<9hYY<&5 zy*#Qy^R-x8)RGNOs6!=^7HCTLt@Rxq*SIv@-`x+6Gu2w07#tEFm&DD(C2xU^KT6Qb zN{I~(ij2;zku-6ErNo|@Ze(PnCRK>4B4ApDV&-a7!$Sk9|39@!rLk_h8h53n26~af z!3jlD!7)8DFk&Tuqil|%C73;^joU=~Fbv8kjRL?3J!=?Pry@x=I|48(15yl($=)`A zr4)&!Fvo+_!(YFP;TFxMRkcm+gOf|<o;q%P^RNH(m*bgs_ir56Ix`Z$(aFK*%dT+m z7Mw(#6?uqKG{{5o4LHtawR`Z36fNkBMG6&KN@p;KnO#ayXhq~p2FIsy49goS@de%@ zCk*jqW1h^4F$G|Vpf%%FcHhiYbADEp&Z=cbfG={xx|a(WZkMi$3vI<IVSynLiBw(0 za|cKOQ*mH2_g9WeZ*<79l@D;Ny^V4gR=8v_gBc{)fNW9AkyxXJeu*S*`BRCFGwzlx zxHLJ?J%G^Sd{=o=NKkkJb>yeE;WPzE28rZm5`F{2<MLXZ0Z1g>Q1S@u5?EfQVH++I z0(dnFoo~sG3ke9O6UxZU%_T_iYE(ig6_g2O9q3*<Gu&^R5Nr>C4WpGUPiW&?RJJcv z;|mky#41n#YaSN4p)q|=0IVjk4d4nRfl-R2c^pMWx#?j6amB4Xm|oi(nRD%Zb7=dv zz4wZ}0GK=ce?oqPGER$ws)q;i7g;>S*~pf`O&}{uXqJz0rDO5>2c92x@O~o_#ihh} zVp>CKpEOm_t6x!t_TQH#@>fML(J}2%@<loRAl^$}PNP;{VKmj4lU>!X-cPtX-6WZp zpIIDk>i{?>8}n%t1~qxakOL|Z<e>vOIYgWh!J*Mq*5RA+&33z*MKXHj!-`;3M~hX$ zfD$H!ThuInL*A<-NiB}|_YBFnrvAzln&1(eLcM+RsF^%BcF&=Pz%k)L;mL*V4w_`v z&yF*&MbT=k0&8_EiDI)dC!X&tObibQiHf5$qSd(36bXB(pbQTSOR4OF<~K3aJ7^V9 zGJL`L(RV~_V7*1Y9OxuI0o+qwP%IMI9l+Aj-2fO3?Vv(el%OA0G38G>09=@r9Gy_% z&`0b$nktD53=Ge4<m}+jNCFGN;hep{rv3J-ZNoB5pyTlM)7P>pL;-oBZt2}4oDDHV zUD4O!tVC?ipOd5z1R&TaY&eFAB0<~p;~sp|KW-C5z`I}-T1J6ki(12C!oVwC`-H0? zw@MUZ(W0H2sFzou><x(?kCahY)WERlL~7EC;{0OD3@jk&l9?JG85$a&UgI0VlO4_7 zR#VlLU@TWCM=D$7X}YpS%2I|Q1lQYY_9%y%Y2-QfNz=_}idJlLmbT+3{8CS@(4gSN zk}d}ikX0dp=h3bgvv|<6O&oqWDI@b&BAo7$L^7-+l4<ImKGX>-Au2pFxdIg&G^U00 zXR~)GZ=7>PgvtQMaARce8QsVq_D%qX1a1O=k*q>pe5`(0JQa!1D*!H00CO!cX$K16 zJgThB&rV8kL<HTgXOYWg9EOkVo&n5(7XSE+FZvd?h%b}7*BHwb`S#Ff2+4!eN$1ny z<ROBkUlj*}Wmr5^Xwlh4NA(Cg``XOPf3DnLlt|=a5$h)73B`m`DX1&1Kw>j31=&@7 zO1R*5tG&!*TSGhSwyv~yZvq0sxNA8zc|;mKG6ASUFg-OcntZ+SB}2ZpH8(PV7JDmW zS1yrx3mp3_p4b@SppJyrIc}l3W-EBG%$HL<cxW8&K2j1B@HRX?lWH1ioFq-8%S??8 zdG$8D%xeE2Kf?}3)}bMRiEc2k+M&>zLo<<JuiNM=i+T4dfZCAc5i0n}&P<934T&kh zVsqovKG%`K0y75Q)+u5bq(Yl5;ui5zy2>io)I(h<%WLZzB@C>CMV)zA7J!{5useW@ z3iC3O5=$MmoxU!U0j#AA3O(OH;qwzl#bgnz)J=@dN;8zWEZR4Gr08At2BK4$i6apC zNZsUk9%xO3oWaQ-uq-46)IHfE=Kyf-CIeX8U%JT^&sUyqF37F!_ajH2esH3#u>(qG zQ}m-pZ-T-pq$(3ud7vxLI4GkO_^hn7gy`Uqcag<D5$vrytMz^sslrr{2p3sGLfvwU z2Ed?hU&3&1j3%N1!2?CX_aD3r=FxQ7JkKiP?ZexTLJK|d3(hY}JMmyBZlbl*^=ihN zS#uRi94v`^a`WNaNOEOmQ}$$fV$_=_&%%mPfi*i$GZvj%JBt(bdlP_J<g4PgIu~|d zzE1&cmlDDR_GoBF0WIUh(po}G0<#Z`034rCyfy$+F%p&cK|1+itNTPRm^U7A@@O%s zT)k4aIhWPLp8hPQ+)?5$(0Pzd37@cX3~u6T8gl=U90QSTanvDsQ=C{%09(4AH_K$o zRhZ|A;CY(sunf~n!>ujd{JZm&!PEj<XB^Pb5SnpLeU>@Br>dfiu0AI%Au{aUvw$3_ z$ot602C(YT))rwP@>FD`syNh3NT?N=;sW*Cl9Y~tl*iYuUc3MDO+fJb*U#@?zjXda zK!L~0f&?{%4?ZPnGKMZ=5;M1j;i`Oitd!bpUAlhv`P;z2!1vGZ-@bMGbuRR0nq4{U zET9yb&l4os^fH>8$x|0v_I;R3J(UFoB!Q_}9}+1!mD0VVEPT)wfTa|PwI_BxbE_k0 z(0S<zu?0R19QT)@jvQK*tr;%9-__?QuxA7cb%3LB(b`Gy$}xO?m0us=C=xV21fHb> zjFcZE1As4IbatP<M8B3(9tA%wT-?apWdOqo&7~oh@wD<6PPy{(YIvT6_006OG_(zR zR8=qZH#LLECkkGlKXLUfr4?so+fxTHEQMwqaEEj@Dgz(fe3d)w?>1KZ9Ozb!V7n`p z!_O`TsZ#eUBu-Pe2So<=r9VA??AWPumo8sEbNukW1Lt4mJJkghtZ>Z3sl+lLZJ4x$ zEmrh*Z)3&pF6`U0|Kyp=S1(^Y^V_lW&vTG|HA@Xh+%rg7IfD@_ZfKK9DR<~l+*Vy# z0L;z0q?lg;tlc=I6v>#t;=__!!V&?n29fe}(&J;Z*K~iBiNz|P=%AlM;Et08#{y|{ z^ESd00Bna?v=nK@v^0P32%p2cVo_TH5pg6kgayFtF%x3@l>NEAlxQmgVB<CetpUIq zwerC+#v9!cJl|K7ms#i$37YC|YQcSuWj#7|fGYEn)2K3!rw$+^5ox|u)I)Pah?i%l zrNlkEa`}btoGc$Fj5o)>M9Yv&4%BEuk21;LO5L`q;q`kL#s&vQpt6o;KRmqs*I#z- z+`e`5PuowuDq5!Q(^uKye89=RMR*+ilZQC5(ty+3H*WrA2XznMwe#qMJP5WqYGB~B zf1y37(oT#Ygvz(5`Na+%<>Sm4z!lXr`9e%!q;Xg-EX-tp04~*zvPJ^4M?mthSc5Li zNsEoi_Gtt;U&R8jonX2q{J4KunJDlCR}KQfhy&BrYmD@dl80DKiAMk|{gF)|*t&Wv zWa&5i_H_iJSQ#f4d+I0+UYuCmUkt{B7>KJZIo^<)S7%?=bbE19Tw1l8P#*1QY=vLB zH~Hq_-FvTuWYDzGd>WHNNxnLDfV)o6tg?y{YI&TMnezV5i8C+r?8*jTJ6ZA1<wRwV z?0U2TjFy_}i8SivswX=)I?y)^89W?wcFX!7e*9tmci(S2^F~Gznn&HJ@K$hGR?E6M zsDs=XdHe_Phe@ix`sw@i>woxZ^AB5oixmIWNMApux4Esn$l2HI_hwOpWKk~BGkTPg znI8bQB(MV5YG|i}fgJ$mC@|+jGk_%xivUce9cu@$3>w2l_~4{|(Sk5<hYc(MMuH3S zg!Noj%t!ZY700y;Ml1=8>L4oxfNPz>OPLh?vSs{RUUn!V7)rVT*cSO*C@5ljl`kBv z%gt{XHXoSjEJ;hssk8o{WYIuVZ5zh~7aAh2?ArS4f&0-p+@Rfk>Ht^B*Kn;XPg_Wj zesW^Z*=LzO{_SIxPief{Y*A~<q?AFt(De9el+2Iz_6{(DCu5I({n?jae*V|b)*pOY z;Mgj^hz2sz`9j#RxFTg99u8FVIQ-n)RKdgD>p%PK^RK`B?6aLAyxQDgZ_kKl3YsQ; zqiX@QcI59_(F;Epb5o(!2`vD&CwrGuF@s%8XaKB<&<x;$JOZ!`YV`L(99V3NKSDkU z9}t%q!o8B=BJpvlb(b_lf2=2e_aFd<4lTJOeD#K7Kp_5s@Kq%PkuufU8NeoKNOF|a z&+bcUAFIvDuQz18G}>HIR@-g6Am@7Pt6V7FuY7%S>-vp5Pd-V=p~2<^V9Yq+?lfp_ z!M~_1FDj&fa9--GbGvpOznhG7{ZD!9gi-J)Y1(KCycECICHf+sx#8Zf{+SO;wRgV# z|NhHA{_(dzf4TQzzI(`8Jw=+rwj98?M8Aw~d)E`$w|0K{*S~%B#lQT2{(PZu{=>{* zmrPG}Jgh;pgAD1S&=sY6!qk!b%k}}_O1=y`iX<vDXJVP5Dq2fONzdf95D9GZDD#R+ z2*4>Z9|_=3kILdu<Qi=CORXp46johG1sHz9zfg)VQpB<VlmRdsGun|7hMd0_vC>NJ z><!;$0L)U~4Zv0u*q7BkT$P<?A$W0Ou+L5}_%PK~SJ{m8tCn|%Hhl5TrhQie($VjU z%H*WGlr?pL4B_&!B5qET`TqC4TYfokBhh^bmap?${^zP=sAo_s`uR*XOUbyf^jv&! zf0Du7{iB`9XTJMx?}_8Pcb$3V8SOM*AdG*We8S?{7YS@CLf6Rm#|mDZ-nakwnFHVa zd0#}!&_Hkh_;PxavQS>p02sa#%Sq>t6Pi49m3eStS$SC2PzC^4O<({RgMkUaT+7ey zD=~oq;M|Ou=<KygU`*K3;`+5;^NK%#7$RpH!YQnY!V(QI^7oIB_`1FbejC7uSyEJ1 zE<z{g`A2I0oq-Kt?oMg^bR0%9Hn6Q@toDtARXKT59OL<nG*?!O{kxcZY2#o1{LL>1 zZ$wfS1T|<aAwqG^IN<g)^_8W?WE>aehTQn=rysuCb}hr}xB9m`;f630U?x~CIrL1` z%y)WdeO=}fB`@|gXT5nClvkRQm?9C`Wsi6U5nPuHK3Y&TH}MGDY}ik}zt~=olAK?e z^Zv^HWLIDRup{Z(kPd>&?2A+Yqk00xNKPlT&-Dy|DHBWbuy`CZNnjK+)Cz!gu9*d3 zc0xM<O!AlkoMZb%{J1W5Vp#z8<#zGo`^-mh+>$En0I;@JaHw8u_{vp2sxDJzrCb0- z+8+Fu3Sdy7C4qfj#cJ!AKeHr0Tfi94AdYqmz)mG&wLK11<>WUkuR&NEY^bQ#<~x(A zr@s8xzka*@;N56S>ZSBajOoO5A=4t=v`j53$&J2CzSn>JednvDPdr*1z@%P60!yYp z5ArY}7JCU_0H*lONKboxSv6u}%RX&MIouS2Iuu4ib{pR!d(8yEYu^-pq`Rn~wr9v{ zg70{5R0}f8z(@}XbrbX8Ejo2}E_YjXZ5zPqgyx|P2EdjEZL83nMhOYbL11x07Z(zM z<30+&oSY+lf6Uo_#7S8!4Ob+r)YOI1Jvhq344giG5ie&6Cnd{U3<5C#Mxn-kbpW%v z$BDvRJHh3PYX~3?)sQF4Q(DgU)>qbdYqsB9-nC7C``dTF9C;8A02fljMK1tGhvky| zi2E1zZ2kLRe|lKIMq2m03^xE9my!TjGDRIhS-&oFVYIKSeZV^m%opHWA@UW#TF-Cw z6<y<|%*UrY+q$hmXwL6YEkgiIJReFsT_e}XyBXcS7IpyGM1cWdJf;?y^02ISIxvB4 z08@K=N^B<p$L9D|Q)b>rB(McwU$5!=&y719+vjsZVJ9W1VWgc<x0&JN*S-5*5}y!y zLtGYx*&+}*D(eQ|KWItL9f8U&5*T^Av`16V4=RKg+V?{;*tUb^<72J0RZW8yska56 z`0=Z+HXWcje;xqVQJwafFaq$si~E21`t$8?yep}`-^YAH4it#8TuO9{0I;wqJD=U3 zebN<;_O^F=*X-@IaEZYI!0d^XMogN1%PX2QU7I2`)Yj4Ot%8!Th{KxVYz2UcM@fN? zk-+{PnF5%7Sjzy6T0)F9qi)dB4@*p78^9!hONvVg!13{Uz6(+uuVexEk5Zp4Z=w^x z%-87ZIf?`Tb3<Wy3IDF%*BSD+2*+f1BA1nLF9#_-mlZ$RiRJzZ?f_OEB}TWUU-}8) z4+9lhx%E!2JK9=RCGIPE=BnSF+Vt(FotHy$XzouD2JPB5uuL7G7U@L=WCQ1i-8!{* z+t*(oj9L>JEIVM+mq8Ob5L@TcATCDIi6a(({l3G6fmT=7@-Y$!T!0odv@TUJG$TjL z>k;QPx9In3jy=tGHMWm<`#~l{8^FjoVkJZJI7D&tMSJ?^3SjbL34rTag|1Tp?B;}a z`mihs%o;QUI5Q!kaJiwr$~*kw05<9E$iqWxcT>lr)%6Yl!}avXJ%|Tz4gf?x0F1KE z|9SwHF-O!AoLL6a;Ms`<e&KHp9vwkXMP|0kssUXbYO1PfbIXUFs|q}`ZS&7(U-OIu zGo(aj9H<%GP)i*iDU+utC*=1dyElLN-N{6+MWy~7Hs6anv1lVmazK76o1~y_<f*J3 zz%)mrxyxIouL4*>DhcL1<O;z+t!4NW0FSpf_j@f7V2LjIu#$qyGT#8$nS1S<OpOX{ z@~|uuSQ}EJqpS`VB`0(_6_S;b05&!-1DJj<FFQG@%-QPK=Y^pwrS!x4csLPI?1jwN zunSX~8*!UvT)lV`RUS%^)c47(xP_%TyJrEuMz}Qh(VG=GG2IEC{s0N=_NFR<1;A)5 zt7-5~0Q)?A^MT&d^lX>b*w6OXRn&EPP}_W6@R?mdAA6cW#rrfiq@t1=9%~$!M&+^( zi(15S94X<=`MujW{p0fkVWdJ&j!G%tS|2@4RiO#M+_eA+b)N{}4-<XE9vvm{ZgRGU zHke~*pLGLZ_IpDhI!oC6r=97c{uRU;?NRd;B!^zg2_b>4j6v%KS35@rFtxEYQDE*T z>*m7(fYH-kI?B>RwS>kAO^Ou&T#%ELT)a}Z1+U8sfcaoPK9_^~c#khXOlgV6S1+wf zRE4(1ljG{vN@4i?+)$sS*qTQJdaOfpVJG{PYyf|9@uIy$<~!1b3%nam3qA?JOFhM@ zDubuG>&olU``PVTs0}!?ci;7pRLZ3!H*`g{Oda5-QD>BJ*YfPl;5*0nA3m_@FIyfI zclWlnba=(fO2=)s=ni0%h<E~6n4$#!{Ra}&RC(qx+Ek#fM#*c`HhNwF?6`0L$!5;$ zvf?;d3BcH*F5!ENJ<9;B#lV!wAsV#ybVo;7Q;K8>;JiWrxFkO<KBLX+zQ#wWJHm2) z><(c6PsH)b`5|go>@J^#tJ40p<(mO8rI;EQt=_xulUebdX1iND#~eS8yO6XY_&*GQ zA(zn^^phS3fT4IPfT<4609ZnnvPE`c8r#nIvP)e>DcKGElau|;)fEleZO0wKRRQM@ zUw)fJ#Ynj<f*HX)NQ<Wq)X@AK@<HcOkLCE67f+mj{Pxbly*E=`Esc$>!`>;^`zx&g zU~%!dOJJv!@QDWtTH$}`BTUhmN=a;3<e_zkpS+}e0lQ)pz#?fZ39P!JyqG^cs;68e zFy<0UDWUYkV*FCoCp73PZ3(UTb!gDAf!PX9i;BwCA(qZdT53v*4hf7bUFM;-;=msj zW5W`Yy{+wDJm2KrGu}Owz+9?h3WK0P`*kualm9?V`=Hxs5H0DKsO*XWUYq~YT7DG( zOGiVrFm?hM<l!5={E5ZRqO|PNx`wLKs+M7|KQmtyaP{i*h}e|0T$*-IL_u>rOgR$c zw>Y2536nzapSu}a)!UTxHoTy@t-aIjeEfSArC8er)`VCFFj+#z!y};tI3xYu<?1i6 z3V_|FP5Hfz)jnteSX!2vc&7uvVtRc%fH9Q81Hfh|gMig(0&^Y~J>^B25pN@ND(e~> zn>+f)Y*HPFzj|=TPkUc23l4rVfR`qRsNty>K948_#x~kvB(g26FcSZ%Kdf!#YnUGx z7#ef7Mv)E@oXH_!BomfZsjuJkkpOmk50$`>wOo)X07mkrM#}6`JO2o7usT0GH?OR& zdnF&_Vr|F+>M_CnbZFdtSt(_6um`KErn;h(@LR~mgb{%cA4R)p!Lf$AmL5tx`nbLF zy;uO2u2?F8-2kkE`~C<3GoEY!o0>AoXva0$64;+vqrQ(^0gO-)0IdB}9X7DTS>p#E z?ybnpHxd|gMV%UStx8}AfJ<Ql8x=Z-f(slME-%fBdiy>hn`SuCESjS7n)=q}_P&V^ zOD%8ref=;0{;!ujhZBDA0I;6|!#*II4BXq%Iqc=cAYw7(8=8rBl~n-CaI;SY@P~<k z!QrtPr)ZQU08HW%06XKrt2a*fed&%*7yvWFZ~_=909K^T?-&Gs^LSTdZDZH6S{ZxM z#hS<$Z)n6pVrCA{4Jj*U%?vXR%F3v1YC28*34ilGSuCj0zMkQgTF3g_shbV#0I+e< ziepgPo*N}ozjVz6BtK^ZSYTr!&kSH`Eo!OIe<Xk<^ayicbpZQ3vJW&Hsh|uhGzWt1 zb~@HzVEC}`pcYsGEO}T+gk}I&mgmL<g{0(D7whcIjEt1Tg!qK`#Da$Ys(`)U{>#7l zr}Lh}2^GMa$gy@u&+KS_x2ufWJCS>0((03~m%^vR{ged2+H_SU@B+*ay*b~f<M|14 z_mkgyxTdtWdw9&TEF!_^FNjnul!aLVJuCLS_Vt$iga?4h=oSfVw=niUjAVWJ+|=@p zI?k1+>(augIcpqG{^5}vpav4gB!2U$?NfAEL_|!Uv>lxqcC=mmxc#CWNfH~41hxST z)x#TrKWZ%%hq53_$7}%0tWPI^KaxjylQ9q@!Z9#Y%eH|X!3+Ng)dsL_1DhzY4ppIA zLQUf!0GEpdR{S!6IkmE~q98FeBD<`%vZTC(2EQdmhld3RkU7*Gd1mwH|L;FtU0H?J zt`=*%fa&4B-uBX<YuDe!Cq#rq7dXpM*#MO4AoM-w_JZu5SCz#8_+vmkU6&FX9Fv^< z?)vT6#=)^M2D4%0bQy3*AP-*aI%&)t!boxxAE#A%oD057a&<IYlseg(&exiGj|KlY zYNI!pY08QU2?~v)u6ERxgEH^%6w=VHOqx0n8lId}D?O&hsRzcIqKWqQtQYnKup>yS z#SF#<_N19L@7WuGCHq>s%5wP8mcZuIYa><9Pcs=n?u$E4t8Sz#rL9Lf+3@OwqX1?f zmKmyIrE!=%EDU+knG8}(Xz;55rZ#6qN#QXCb<HkU9l0ip3p0{qW22%nyE?M3?Em^d zeSV|Kb02mwgJ>~pu}T*w2YUKP2TC7r{rmU7Zr`?b_oeV=cS>Lzm>Yz0Dm2=mIRR{a zR4?4$d!H<Na`cyNzwX-c)t|S%t{a;g(YA;9KGB7wJ(-cf4#(Li0@$W*PXKe<b2k7h zb^E(1|EO`Ptso&JAe{Q8((sLZ>ZL?;4)UnQGLHxgiAXDN18Nt?`n3awf8Xl%DaQ*t zB{2G9hy=zg55p4IWF@ThIu1xe9!mWaW~-PCJ{!PmqtO*l0OYQ@0}%PBDKniXjJMSS zu+L(Keo>*VN(OtdsI!tm0Bk#<WiT+8GOz?LFR!jCN{WmrY;13Drup7=)MzC?D?2?a zuc0mB;o%?u^WSf`_yX`6WX9rHAC2hv@L@3az+eCOzkT-SKmBR_$#8cLf!5GG_L`G; zq&!!%<v!kbIbHN@|5yL|FMs{ppZ~*uIhahTwUdJb(lku~j6ScN_U8aFRKY)1g@y!% z@`X7*Y;}7B@JB#swI8A3hVdbR5hR0ixiT1&8M3LZdu(`EOh&D=<Cz`q=^Oe;`RiEQ zNMOYisM`r(<8%7Mb}0Ih!7t}ROIJI)oY0Yd{mH9ZR<~Hds<U(Qm*#$%c&DFa(_5AA z1TfW`I1?#NEujOzTuaE!D7BvsS;eKL4B)iLxWcB6_O_O`=ElbAs!~d@qY|a}PfwoQ z^ye>bFPFe}M-G+1{vOTJWPk4fGKR{oZ~pQhUw{4i-@p0gLP(?i^R#t%_gMa#Mh7Od z5n%IoDd*>C()^JhzxwQpZ@>QgXIt*q@gGeNlfTsx<6O-E-fdOqntI?*k{0eSt17hk zTO8$t-mBd|W}hqk%v@VRbWmtSB8~c^oGeUM$xbKtb9h{S1CkVZ>dzm6U#$*-jfigf zjznSYa$>2_A9az-HfYXN4KIw9{%-(ab;?LJk|`%N1sf|_3CnLsROp)8S}4)%gC+o@ z7}%1)JnoeL5+9aUGUVk;H9vKzWB^werA5aTHg<HjbaXT~HBnQZimJkhD?7ga>fni8 zfBWVRhZx)*Zm9!70_AxPH?cT1)F<`PQ#m(xZ}?%;rj6f!_rvZhVGZ_|;3@=8geSB% zGE=cW7Ql0*uTF3O@w*>3Z`rbO<NimLSZr#z-<otoi9F(kmY|MS&a5Fd*&np=*GV;! z21zAuB~C0(!!uU5KVRnSGf?!b56v{EzJL8TJP}HCZc#1`kxh;ZkBG@_KnC8z#Bl$B z4Cei`M@UyTf-%q97|F9EhbCcs+G3yvC`piqydv_;odEtr*s%SYNX9WfEJLT-QpYOj z7sbu5y$OJwGZ|C@QwT{r%EE`G0Jdrg-2hCnK?ZPXOGjrLVYsQej@;Q*C9l{2_y5QL z$A;ezfAjs_l>iKX%US@uG&MLRev<Lx=O=dT+;i~Ap*=gcY}tD`w82gUgcn-jL;%*F zc6>`83E=t4_osIJxars32M!+Gy?y`1aA6lSBZI@nl?9f;s*v;`H#)ojyws2TBGp2v zO*6mDbV4=|i6QEYZ+^E=_nEon|B}8@75n1;{kLJUsWfkwCX}Sdg$BF|Omj)sR7$uT za%)@e$8MH?M7X&{-zeyZcrxR*HNjj`ar~ojUoT<+tZr}9n$R@0Q)K%MD4)wAo6dxR zA!s~$Vu?BKFQGDkDZ|w<RE2$55WqTA1p*j8EI6S>0+S&G3Cy*Gq(d73ceZzQGJxy3 zReb65|Fmx1|LLa}7q|X!x7l-FG+Kol87qK&?b`bDC3YPFzk|6iFCII7?%J(ex32$w z_R#)g*TQP;xlz&_1@ce;j0xW&@%?0N&Uc!w4mh`W=h0J_Z_;vC&zv}UJ*<kWZkDD- zhes8`OH#~$?qt(k4=fk)hx&xUmerb<zR)UxO+Q1dh&T5_-D@OxMTqrN6BQwME?vI< z<aJ0`baZs^+ouojKaZ{ferHB$>W|C={M5%dcu>?W6<%gqucOztZtzoAv<y;~zRdp+ zm34Hboa1hYJZ(z>yv8G3;V^jmqI@mVe;feT3CKz}{;ak#fMqZ+w}i%26|H1&2QZ~^ z5PSu|k#WT>1Ymlan+U-5P1Vo;-MV%E-MP@WyMBGN+y<u6Dgdx1hWdB!^OK{R1J#}J z_Rf{-kKczzN5@5lynA}%(v?S%){Hzhg6Cw?3FZdL)f+sm*`GLC9(?WGxvNj!2S-Im zM+Urkc=P&`h*C8Cof)Tr>u_Z)Es>T7KyfWN$wM`}t=0Uwj+KuAKP}vV^=GoUCGKoy zBhmkIb{<ore`o3Mr|hqrED!$u_~GLhuHU`?=+4cn7p^>xt7ZHyPK^u?jXM%s{QYWg zpECev>Sh4Xvs*z%t4PmPX>MkI^wTzr?-8BdII%1M!-@4@rz+Gk5$G1(01Ucu5UL*s zX#k9JLTf4#OJFnETMChE0GB`l=R*QhZ6Q4+2Ea|7ogE$BG>Dy&-Ca$!um0n@b^qr} zC4pCVzgkx4Aj8cVz-!PkXGRBA{to1YK6~;iI4U)VdcEZ2WW|QOc=+&DQoU78j`Cau zuy$i%ey1)>KMuz6k+JgV$G7gkmJxRad6~(PK`)=Zi77`S_RPcx@e~jOsY3`OVTgcf zVXRjE+E!fY(-y6<O%DKb%n}0_9klkxtYt&Q0?AnU`%C+F?$~?ex8IH*K6LV7d?OpZ zq!oEg{rQv^&@G~|nboQnE#?e>jau_5t2prQCh}#Ni){m2b*QT?wq_<GY#2r4I?z<c zG11yK8}?Ia?@<-Ho?F^ErXm5r)ux}FvzAbt&=!D;OQ}kjBycK8U;wzQlO%9mqpPL< zJ*m+D*Q>>;zn^;TIUX3(3ArBF@IZfVV{UkGQ1s{VnwU3%q0vbhnK?8|IWI4Z;?Cjk zUx#L+pD|<=B}2o3Ifa20X70JzPHQ{yk-C(C*8$;iX&G3HR!d8cqST}mDW#nq8zuxJ zKEFufLdJ`tslV-0THAsvpM?X!I(z~E=Aj&Bc>N#jHsg1}1SmX%g|E+&D`4xkpSNz_ zaUl$P)%?`x&>vv_;?npZ%ZDY^gnWtUY-W1QvHpP%nV;~7bXLWmYP4v|Kw?GO6iJIJ zQ%6qMyP{>X_VvYZgf^j*8HDj`#?hK);&C-nStWJi@BlE{=~T;LU@ZnN;;FD)%D^3E z8Nlp>rqoJg#})#>q(OIeb+oiJHZ-_eTmcN=>y;(9F9)@I?$R`Nm)T!_L5j+M`^Vv^ znyO6?eIFd1Kr<Y(bL2@+iVY13i_NiS{J^0oc~R&XB~8y|y6BqlG*p)!6%rU0lay{P zmX($m6B-tq+YH@#Zeny~e1?fiLszn*mBiyGEA@vCgt}42BGU;8yD~&TM)z4p!m0%8 z&r0SqxE|Y}9?E}yV$1j6ZCwBD7aLC}vkC&Q#MB?)ezxAqxarXFO#sYIb&xG8TlC*Y z>)%#YgXUw^5={*FW&qp16Ps+-L_QvGV18B|8MsBw7zBXj7R6ER*E+owIR#}^4B%>N zr(^fCvj7bAY97{#0IsesHURGE>gZ^pa?xf1@c-p%Nx}Oo@ts}(%ux@?^Y`mjrw4lm zCh+m`>XeXxpoqlOOq$q32|>h3XjXhuY(#Kqd`|7KE=4AkG@Oy1Shh*(=gH{T3{<7Z z1O<o1rP6#^W?HgZdO~z~a7>PbQ07U89G{-&5>HAyFylp~w}Re;;NVjp{b^=F;{Tw$ z5mMPDTU6!)D|JH|@U@taKeug652Ir!_vw)>G-c@PKmY6QP}ZwR{*HcR@sYRVu&jLa z3B&|d0kF9C4S+#4*1taGT;*q>(CSDnWF~80Xz9Et`8c0?gR+p&JLE5mUm0Z0otR{c z>^o5w<sZo)k%It?mRJq|s}q`ss@MRw8``lGS|u>&wpV%pm?Us>yDN|Ze5t4~;BNe~ zZXHz6PxFDrqweYM^m-rDL*0F%9}ktM1icH6j!(<T%H_m9>Zn$jn@xIce0XqhTv~;h z4Zv<;k-!=Vwo@A|KIrS}=evsIB7%Y=;!|j~Y)W6C#W;t7a)4t(gCjEP&;e?GdTeBT zn!lcS2KsZ;MNrm(T!nW$`GlC4SHs2gfyv#o(@f?AyAAl3<S$<cUUlczPYd0`3#&gc zQuzAHiPPtgZ~AQOlZM$3b7Lc8YZ?r_`iTp}LrVq$FycruAK0FLjWaM?{OFD958_bK z*;|G@vt!VGKCrONPd!w}d-7qTtBTaz5P)?OJ=2YBo$1E9#ML5ZJr%hOU=;ML4+~9Y z-G{1B9LcoPfe(vRX!x)wivz_e1mN_@B&g6GU2Pq03gG`t0KQm|8}ue|S*t>H<iMLk zT=<kwGsArYh*->blq3hg3yh-DnB3d~u8yH`r-cOtlv$9R5E&R0kyO}Wq!p(o15jci z!hI=jGhe{fKcBBniwX@6j)<icLRu`J`a;oaw0BBFBAq=rBE7r|+T-lx#MlfoB))$X zqM1p}vgW6_hAm0MY}>GJbbK>S?RXZoDD4PLcnD2D_v-kVIUkA0>ab7q=OgtwDe2ki zuP<E*b4|`nj!*mn>a&Ny7mu*Cu9pc{GF}vZPi4a*6#c!(70!UU6TS#5a!iM0KF<nd zixg(JWdwinp*jROpRa%vk#2ECiU};bqLq*1dw)IU0$|pmwHCOBGO-lER7(gGm;p@P z2kmNp17NK#V*tk*0Cy08T_k~<0|DTioPgK)%US}G4a{X>%4mGX^JZzhs-$1Ja-u^5 zf*HSgdDIQD2=iVjA&f@FXQw7a2M50oOg9QUi(uAFn6X)1A}xmDo3NK^!e70n#bQZ) zrYal?ffvzg)WV=JpAz|#V#C5BV+&n)uf^%9Now4)xPZa#eDkUc34Qp@GM2xTP25ON zvh**WAt2I1vS^9;Gy<WXAbgc?3h=U`{1A%?>2e9iV86%I)WXtaOHp=pKL>c+hVFgL za&DAu>|5jD5$dLT4Xfqb0v~}i^ZmHhbi=9{834n#zy)QN6N@yrS*;0$wfCta*jg7~ z#6n-@!VAmbk`%c`mNcfZfp5A|0CP)O1~3a>PNn3jNYW1r0H(gs2EbZN$SO3o(}53* z8m$n3V-&z7gj<?i4XvH7z<*x1?ti$Lm-FsT(Q*}<6FD$m6#UNznC2#ihoPvARm22` z1cXE<r{|LJEuyt6tE;QaDNs$Q%F9Ymj0z8U{wk$Sua=b)R-s`8GslB2<geFksW$lb z-8Ugo@u`%;UtCN)tej4zx}3903Bp+^G2y}CAqh3oNOh5t;Ag1F4|7hqiH|Y684Lak zeb19{2q!_WcyVN?4yMP9+j;Qlv-F20kBGW10tzSRe7B|1!QqL?so7;$w{}!HS(K22 zNMPv=Ow>)oC&a_U_Ncu@2X(J`QOD21t$<bG5=IFOwJAa)OmSj;pt}T1^NlB8Qb8#} z0W6VjmcQdXU_&NZlU~h?+EZ!wzQv_plECFvlnZSKk&p{*4Q0^D-l9QU#lYf&<}ff} zh(7HB;AWD*ovt7T@Rgjbx37wpsaXgkS=C{7;-A;oB>CGn#GHO2Kj`_3pfGChl3P$p zjD-|^WRVfBxVuYUb|$rlczWYOe3O(3EwPA#5zK>gm0@6*iyv1pUlVZl^!<qFgcQOr zR-=?Po=Y#Q<>zFiQZoOmmr<o)PfO&$B9GY|{l$;6QWjnkx>_@hIcNdWLgB>tgn`KQ zlH`OQ8xsJt3T@ym(RKNPk6Kq2v=D6EV~+1yWMs{JRQFhSBDcR&g`7YM1!YpMF*QCm zjsY8>Zb@qwF1&nitM8T@NVpw}#1u_#n^Y6BQiF*AGMd47KjjuZe%=>eWif%j$F^~% zIzSaG(t+|&afiDV`n~mI-nYgQxV#D|a72O8kP>svDvSng_rv01U?+g9DhR-(sZkCI zOm)G{oh=rCUl%WXf2s#&5v)$yRbO*qdbGc-u3?bUadV#CydMx5p9K7JoJ;KX8X6D) z1k;eFl=%0z&fU`#zYlZ7PKnGBm&Mg1bp*~~Uso|x_U_!?%Wvb7(=$l^(r8T{?L|}R z=`UK1+fn4CrzS=PJ$dvlf0%g7;P51OUxN#aSF?%>Bt-nt`W_P)aHz_PfRwB!>1Q}G zMiLksWQ#<$DCqkr<eH0;KqWI)(J{r|;c3_MiTRP?k+DhlHnjL7`E&o*c6`$6hb02o z0GPUavyy=Z846(RZOvS9adK$X6H3Ab_}_pk+R7?`8BNCKhOg!$6{)3(5%($&y-3_5 zuP7Wt^Sy;i<rY0`FRzEnPAqo-BNy5Nuw??<#lSXzxe}>_1n@EdHwl3Mg(UE$ESA7t z0c=n0wYki)G>fI_;r^c1;>g#rjcsZ7&s=&OO_0jWD<u3<i&KV_Jhc@SC8hbfS(z!( zkI$dF8C*u7qK9jAITk@D<#6vUXNb#wXR_$!shx-KM5bosu>DJ_I=4iohN{#Knf^@( zrqwbjrQ`Y4tFJTbDl$_mdZ(wUxM6}R4IG0ZC8;W6v-z>=@{d?@)F@vf4N<9s-t{s~ zUV7@N_Q~IZnQ<TUm<1t#0b`ayEc7rrh(ScZJ<;3M=ctBWChz@S+lgPLR~7d{+-x8M z!0uaAJUI+=-&<Xp=xOU;rZQM&iMqW-s~MlfP%X52H+&xz6#nkZ@j43w9bKc2<}JeE zz%lqp$>O3Q(y}eG9qh@6y)3@eU0zVg0CwhKRhX90m@5hsSXx4}%gPi3!wFre0IpyO zoG4ysv4IJ|O+o*<Zr%TQDJ$dci$X5|)-a2(Bl}=HU5itF?QNZ|^qV{O-+g=Y(4i~u zl2X$k5-TffsmFLjBRv#$rU*96;DX%Ttd#ece*5iOV7?5C=b|Kp5N$WKKesTL`{dZK zKc9G&N|9!oO;5>Y1YZ{|Ro~d?ay2wS1{Y*!rlr2Qe(KzvC%4XDiD{ag9_;QJp5*07 zg%%H{k%%5j^co34r41hy1g+)?V|=|JSm)}9<;2-jAI&n9z*uJ&0Sr|SK^C?R=r}3Q ze0-pHz^YzA;0FxDLcec3d457(Tw|_+8f~*aIWZwF9w5p}HN#-$HJsyYe@m0lg!2J0 zh%l5D#p}%)t<~EMa-R?N<GOqgw6^v+Lv6MM=7e9f;<&b7bZk+vVP4l;4&fq6;CxR2 zvjny#dvhF^0gP}B04)7<xEQ#QL@*?9RplxG&RPw?>`q5EhjkO~@LC*hYijH5F1Y^9 zKW*H*d*{)c;hepZTTB)yH7IrwpfIb}ObIC95Kq|M(}#{+e3jA3miHoyDLN$$BKb*J zy=nK3Zri-$a!@w)T%`flrOYi{Sd3PqnIbjh%POVSa<W4ooH=xG_mAHn3~8R4>~C-D zAD!WAfm2w+hlu`s9Q(E|kL^+QVM)IN_CgbY$@^h7EkG&<bE=QhFx|;o7^&q^Vh@6J zk|zywc5ZHZd~DKoY#7&|^BVm;X?uejPLw5iD+`*XMEE5<A;DZcSk@NTqGl|N^|f~_ z3ulUD0%3?K5^}#-9!_#>U0oT%75Ns|#xitovwhutBTmteuS2*<BG1HzX+`$dXx$C` z9AFm`7uUxNw_5Bh&CM@U3GA3FDgdTjXonB0)Bu>1kqE^+8Mv5YI28n7O5|8k0%yH{ z?oEZJpbK)9fMD=m!}^`N-{NFn&(O?Lf5@-@`Cm6|-gWwATn=H1MI!YcApA0TF>Q;K zXt<WB*;>q_3rF|tK5;*-ok)xVJ4nSMbK8HC>Px=9`^Qbc?0+1So1dFc)A!1&DLGW8 zdhx#-8)|AuWiKWG=f*z2d}zlHUvD^<KDab9*x55UE;_V{$uf#rltCuSD+s=p$pH`1 zz#p<CnpUl{M}(7jB<FxVJQRp!>q#QPFj7UOaa+*a&Q&FM{E_`i_yX181Tiv;2|*oB zOePsTOQ~nN8{D5;U}yOby;+d<aTxKdx+NS4tgefZz&wg|3^q!wqzceC{E^lcRuji_ z6NBB|()-8#<oU!5TTm5alDOie#PjJbgbm{s`3^tAxiHZ`Fyb8YZ5EVJ0&HNuMdldn zJTbS(InjI*W<{?OxT`ETzXSl*L`v@IZl`fzDw3vgpc@BEU;|+C<8T^>0kCmmwRN;K zHyIoFf4r2F_5MY{vU6KUs;%j~3MZYae#^+4Cf4xp<(&D)U)OKlfAxJzP60uRY*G@y zB!A^0OwqW2+RCEh0#fx8-ds7kZ_Cd|o)z&>SfVvv$sfJhyyZl}-5uY3^V6=AFOv&s za92T58BO)#p<ZS=T8%_-NhxuQ{G|8SkN>)9<IV@g#AIj3MtC|QZo;%+gZc%Bkc}B9 zRsc9J5CaIrT?1LjpTa3=CYC5)EP<KUNOmCnpivg#8tx04MfFRTpNPdS<g|EIL)uW< zQEG?zi?b-zFoHo8d;u|>OAg+nS1Vp1=kN3Xn{A7rfqxOd5Vajy6{OG-p14$phdw&D z2$m>;Y7YoIe@9oPisf!sP4lv(F{9Ps<dkKI3azyTEbT>=(pyx&t69=IGjB{%7awTr z=p)~VlY8(US&!nDBjPnfEWuo&t_j`Vc1Yq2+<DMKrvSLV0byV?q;#fnRJliy1i(gv zW}TWeXhJYa;B@1Krc5l@!0omd`lT&_&GH0blp{&fiE3-OLfy3cc`Rg}|K_ueKOean zoW_tMr&0x5z%u8O|3!b-$f(QW;?(!o&mP#iVf&@TE*3=O?RKNp)%dim+8uRr{Xf3l za`5cS44%AKSX5R~Z>`2lVYNyO)+|g7y?=7|*3Ek#6f<=!5o0oeV0K~hO#pfpg4e=H zmJ@{nT56F%-mLB+2fz+`7-p#X04tN0^G|FrsR$SCQdL&SL>BoRBqd>i7$5*A<P9z( z4k3S?XATCSEJg4OQ&ikXqFzFUMqU(xbLt%ghk^w5&YYbnUKk%9=x<1Q^E$1vuA-#8 z)tQ#SugtCm&BK!UIIKd;Xm~rU19`7Y`ge(AO+^J|^|kro!RZZyBcl$RLnG@LqR9m* zv_Y_8Ym2D364i|{fz5d16$`3Dvk%M6WLTDmWm?KQOkhSaY0w-UrNK!SfT^QSn*p#D z2hMr-DsLGLu>|H!4vy;p!Fb%1Oy|#x#vc9RZySC-ayyg&Ohze1bx0-xNw7-siyDGd z0omoL?{8l`^z#o}&qi_))FKxm3GZ5%nHn1z92}5maByg7bbM;o3JzKeb_5^(?jP&7 z9i+jy1YoxG*@fl48ad5mwe*Plr}u8%wC83v>VsL}i%UtBXkp)S_qt8D)3Bwae?U_? z#^Qq3nPLwQ-@Ou>Nu(7{h~6z;<dJt7EQcg&n^KJ>fZ>f*0HaF+lQulmBJ`E_LWtU0 zttF#v5$Q$l+YAHnwG>QNp=o2ZLr#X~bR16Q&|m_NO*2ak!*bBL+cNWG{rw{YHE;L+ zu<!iu=gwVvp5b2J%I{D7h}V-AT>KDMq)yGIO4DcvdW#O8;VyBU>vpF;I(O#Wm5YZq z?R-=+NV!Oko<np_5WpmX3BZ$+w8=@xd`ej`Tg0Ji7J)fnPfyBHPbsHTR`XB>$-@!} zj65vL#L`NJ3OKPGPH1BSi-KLH64=$=4gj~gWn$&Md!6qs6N?e7-U`TIAsz4hdm!@2 zmw)<h^TC^|0$7Gk6M%1?KfHDGuU8V$G(%*>?Bw`RUuT=EjvH@ME(X0bN5AVD+B*A2 z>=x}Jfn!c=_~N^52T%J2;IO+VcWvIh=WZq|>>orYf=?Lc6S7BO<{MVJCT)IYP@{N} zsC#mJa+1iLiA}=5M*RY13E{aZ9p0sf#onzS5b=wDvFd6%+(010=tiQUgu4ywp-6k< z87uC?@De^9^jVd`^+Mf<u?V0hH8<Jbq8oypi1OSZ<<a+z%`f#u?fU0`{^IMezWjRo zl~_l4oQMwGmxz2u)5J96Nr$UgiWJ|WaVGjy<a&~>Zu|Q0Uw!-c|NI{}KC7QuoERDy zv)d5Mv10g>@C>rL)lp|%qWBirkXcdBSm@-Yc1+9l0$?(MYblWu{je0kZ01rTr2?4U zS14qF4+{vVpJ5d`p@;!Y<%Dg>g{D+W%7y+PE*9jye_1f>d4cP=`2a582q>ii?`f4| zX;(IX_VwodHv&B+uo}S*rM5Wv{f*Oye*N{>%Q8+=Cb>%~_rrZ{jnw_RhH}m*=tLSY zC!YzMq6lw8OV^O2CT_au;m&Wr`DxFomx-)G=aa&2tI+NWdtqU6$eknGH~n<%c{x^N zwN|_lCUrzND1If~r5=Y*B3Ml*FLFl?2w+n8v=t`Yw33kp*h>2}Rl!ttuehkC1xa*9 zlNKeZ(H6kGBs*M~x+UL2wP?gxY&+H;eZtZNgvZdjntTj%6ao<vc$5K*3{^Oy#Z?E_ zx3UWrkg}%72B!ym`!No-^5*)#{Pl~kKKty;ZI@zb4!Ly+;`C)(3pxfwJ{>A+QjoyP z6`@Con&P&ey;CRa=t{h`^UKdZ`|69&{>xXV)43R6lKRP*c|5GN<6yBOoB70tnGLg} zPEr=YSD+pW*%&8++rci86RUuoShWq71a`F3kxF0zu==nRz!<FoAJ%dJx42g$6$Lzx zA9BCWr4Q@qKB%A&yiE>9M6i*-o>W#JaB{=f-~W2)Z4%r{JS@J3W=yMFNt{@fB!Tlt ztBrkm>G*+tCmv)X>Nh(z)Z5YKqR4G^Z4*gbQdKzhbZl&Rcxa%fyS>F#TTxn8S=Z7% zWEm*~$v5_G-m>HP<5*dZoLCLE6U(edfnZuKG2rTf9lsvDkpz;Mo0(+Rt?5{j1;7Y~ znFxDEB;s<t)*pg*{|t-ZNw{d4c@x)A2}~Y$k)4hejX%u!4esxN{}XK%_Ljkt&>2f7 zC>K)`Oy5G?n&kl4iS}g3&30zElbhR;I0u#9B4|Wc5g|*q2-@}$ccML#mLUR4|4>u| z-J*4--p+7}>eysnX7%%(8^2rs!-j9a-?;C3oZVxB8J)t3UHdG7*=<I9geHX|5pTEX zW)OK2Y-j4-!<)bVcEjfN-+ll8W9>h~^t{sZKoHl?HP>p^9$)L3S<kLyOR_zlv1fNZ z+TF2t<dG~{mMyPkwbW{LH@nI1W;5r|%mgz?0w6$w1POr1xeA3s<(zZQIp>@MD)QIf z_x+sne&1L16#%mR5{W?7ci#6s=YH~YKhK<~QO(-YEEu5zQ%AW3JQ8A9S`tsl2Ml)6 zJ))k8(F~JJJJ#6>12C9iseoxghv;<3XXkqWX+W002^ECi4Pbs#OGBW6(ToH}j`r?Q zKk)T4sk0FW2T#7ws(0;xJNY6M^B$v|?)9dtZ$J8rN8df4Szc07QVGN%<VH-{)zQ)2 z-pX-X%mXK#dhe|_KR#=Y&dT&~A3S{A&**g6G$VIEXy9F%pBx+LMG&v0qi57l_L<B* z{@T+|zI;3hA7^PKO{TYe6@O__-3V5zNIP@jS1-JIJiSN!Q0uU1Eu3hN7jpB%54RpP zuvNc3blrDgh=81@WoC9PNb5z0N3e6dz3a4NO*4N?q&V@SI27+rV#gYhTnQEv>Z>?w zQ27v2N?dvMD=}=)cP3`&2_ui(juqYFwxX@+Y8qu;%0FCMoDbz?Evn?@zDW%UM9Tl& zZxVzd(=)~cF_dxSg(seR_SvVOc>JM9UOArK7y5DuJl3W%us}E|GH6oK9a3ZL-61pl zaoxS{Q0`Z6KJm!oPdttFo_z6>M2#ldS_XTG*TE(-sDNc;@TGD=)*J;Q!^|gB!7`+G zEwnj;Jg_vdRYJ>x7Jx}ei8?F+Se)*>Y_zvEGB5%w4U9Araw-IH&*0#IOlV`|P(%OW z+M4S}Qz9y0xX}Qx8JQNx5`-=B7)@8;zBf8z-+l7&H%}!ND-VngDEO~TB!w4pAgWYe zS`ho``yYH3TS@$GFOGm^zN5Q;^iD%RHg7M^j`VkeOS5}u&R)`N@tL=ufAQn%C>trS zKqr!0&4dN*bry1<C8?z7*73Jre(PjbpWK^GC}7c2T2LumLOGbYv*rODz9S30t*u>s z1HAhC`vylx$LHjft*y<B3=Iwrj^F}cQ8)H!KpjwU4x|sU_dIQWIXm74O)m~TM0X0u z0Kk&&?&d6%Wm!m5z;Z`<G2X&Q6lbFy?od?8ReyzjN)%bVOJtbbHs8WY46UlpKIq-m zMJuduL0YaDLa<l-CUSO3|1I$T&Z%R0qbL2u`>*Xk@X05K4!-xsuU^>yReE<Ag6%o^ zjI^P-BHR)wL}lk_5Ez1WR%J<r)Xi@E4&;2f|5wky`p$<RA3S(q|Jxs&NNJ~o1y)r| zwe+^IQtJwv$&gyc04Souss>Hz>#b-(Zx`)YYkj!Bq@q?XumCIwI{>Sf&{@#p!?H50 z0Kf=Bv!71@ZmSCeuuN!hVv*GDH;**beswTm2P>u1z$V!hws4nAAv(btd9&R&554s2 zk(k_qqSBHw*wE}PaEV!zQUX#cr7SJVx^(#C<M9o&+P9_#QEfReIxEt-J6+pri?FnN zJ3ITvZM@G))us1deCteRK}l%^3pZ5?jpf=@^~E|41feU?&v5<7{`b!0j##nlI<^9m z6lRfBumvh`0t^u9B63!$nbCGzCNoybPrUi7S6_eY?YG}~_x+C#9yxyf%GKDktemX) z>z6NG{Pgglg9i_O^x^yOzV-V4!*T7ZGGp|^4!8DRTW^<N29aW!>w%SNkiv~=%@BT_ zBIZ50yLAef_fG@bL<z!Xa@RPuHK;cero5}~9&x9Q5n3_O`A&6)tw{Vz!%8wpJ4plc zcxy#35gmeqm#Vku=?+4gc>DIk{JijcyDRV9X9qv|>QW4@tEY|~djHVbtlprOOmRA1 zSWuNCctocVt+U%bB43Z5HE@O;!kn~pN31{l%qQ=Ec=)ReT<tPgh(9}@)JB=RwXz5X z6IU3G&!Ghk1<Y-nS1y4P!^EQPqR9;HqDd#y#=*5U(%=E?>aeJTrGfomU}@m6R>BZ~ z>pXzbj#yWa8ff6Y9%x{)Qi4|YHxJd99Qp7{ZzOoOw`f9>CzNMH@O8mrFGSV*8e|IX zySw8LzxDptso8mjC8bos>_uWZGyp~XHq=&PU_gFW!pS42k~)}_T^{M~>KmSpI{kJ# zq7hw(d2MxW0<`o4GkQTAO;--Q^;vwjS|@7iA><%1Pz9~!sDNQWmlWoto;&>U`64&p z6z%-LFM<&aE-HlSoGZyE1F-uekF6QDPC0%varr0z%kTWoZ~voz@<090|NMXb-~N9O zJn+jG-rE1>8*jY%=3B2l{@_pV`?Ejz!{7h?fB7%|*WdfS|L^zSD`H$9cTCYO1Unjm z2n2J*um!!nDTC1v?7`$A?!Vgh1iwiBSU?E`T+BQZz-I1QsE&YT4n}oDcDl_>4nE!_ zg<o-p%<%6+-|gO(ml$k#roJ~5I&ix~hK&cXHDK|V5Md?%2KY7oyWEo(d*<}T*p%Gj z;^M-B?8M7wPMnM>3<^7NyQ;iq*o;kO{-shOdORsQXphKebTZM&yKqxudocgf=f_W7 zipwm-YQ_2KaaYfsy_(U*Ko&SW=e#F}53yP^JR+VDUN=h!jKVE&6#OGvy|D{!ghCAK zgAL_YiRJmQ1Yq_O3c%qmup12QCVP`kr`l=YodE7b%oe=Rm;ViTp$}CiAA03{*yu6I z%FTV2hj5`<au8@I-FYK;jXc!FDGb5wsmBj~ekF+wx-8`ordrV))Y=X&w}B0QC3zWX zmrs11+Qp#3{6Kg2aP)b#n@iK<^Sgn)wXp=3xo^}Od>gMF{Nzkh1_)%zk$A>x*8IfP z5HG8)DKA9(@zqmbTqtxjT-&CA1t%VPglU5_$z!fA1RYa5w$5mE5_S0GpZ)fK^LPI* z|K0!fxBu}!`~4sM_-8M^EBpe%`}e=|&J#cV(O>-U|Kk7s|N6au{?Go|@BQiPIg;l9 z@Z$WutNWw*XI+d=KQV^sL&WxWJ==~)a5$J8Vhw(NFpS5qH8Mya@^CwmA)ir&o!+SR zPv$Tj8pZ7&*s!h3Cm^g!-2iN=M`B&}<r?#3)K2tE7~@f{CoGa>Qqj7;Br?Jd%r>(A zRz0!SR~&!iMnXE6RmyOINIW;?=GDuIB?Cce7HhrLt3e+h5<|6=vS`h&2@>A^5B5ZU z8@&|f!5J@$J$D(l6F5`397f(__P~vVf*#s-+tk6qFb^Zt;S&<U3S+V0O~DMO^=V9L zd7EQm`x7YP_2Ifw2Vhr+<q9dmX4lYwBCCiPR>*>e4;%m(X{6THkOm&sWCj4Z>HHsI zw95N8ufF->nI1!+3#8!|_KC;ZZ$==v-Ql(a=6BkE?>AdLSr<;7y_p1x3@Sw^Ve1HP zYinwOMO#%?nxDxQ`%KzKTQfs_gHyW_(Dq>q!(E*NQ+lChGzMiZYm1X317mVAw;N-Q ze|<9{Bd4gi90@b5rci<C1F%{}aeiiU!i6)jWlA^WT1T=Om+d@_p*21ReFWP9V}#|C zh2cp}F1#kLJn+YV_@{sN7yt1;{^biF9l4s3oOts_Ol)jiY|M?Dw-VD5j~{#=(U(Ub zdf>-Dc=S*SA8Zp;Tn1pt3~SeMaRs?h9*4n#R(s(tYrt_D(}!6dfcdu}G)Wp6ekn0{ z+Mq6IWVqAqO-y^hKnc4~x7tr!VJkXwM3UM8*y%Q>@ny0rMT!-5xE*1>i__`(WY#zg z>%d@je_Y`Ig6>y}Yq%-{1Im-ZV+u^^D#!$-Swcp2P?TjHn2dU354oU?$l(>_5}aam zkLWkiNkzZx#&|>ejq5kCSRMwja;>7G93c2sMpdu8GnCsdtk^IQl9#hz(sohp4AzP2 zWQGY2nb2-GZMwUUN#e*2)s~mBl#*#+H`zO!4@&^{Q&mDPaHX<HqO{@IGY??Q2gZCe zKO3p$?4Rx1_xGQ_bmrNoPj?3(bP4-?44jg2LFdiF1i^8$`W|!LBAwTXvbf7}Hxn~+ zO3Et{T0$qXGP&R#Ku8JQ{OL&;7@tR0yVZ%|(dp$~cCy{a)^txxQ`a~_plz^&W;ogg zf6v(XjAF{I@fTxmCZ=T-ltN&jZG(Y5tp=Y0eTx}M@i$|Vs_AX>t7$+>J<%4T{?+Dd z<d`$Nya^ou*x+K{znFLU^>>dP`{-BC?0@%IdPZ7G;;n>)cw7ky1aMmF`S;#_|M1!C z7f&2H7SqhLfCZgCTsA!Uy|?;5*tH(QW;OE_8<<>(%X(rA23C$C;o>B|cERjt*_Pz% zgTz>vUqHXCoo-5CMt3aW&h>l%&50;hu{i9SJXYVHu;v|gy#k@pehCAxg?AR_<`!hM zD?JxD!g{L?!)!7%*%-p_(u^CKu`y7S8W(pfB|V>Tq6+3{<D9hk*qb@k-A0HcGzm_U zi4qx3D!Mq9p3w^;y-g<!_0od#4Mc%-@kU~LE>;76LAHp+^3s#y<5H`Jj7WSLa5XL> zF^jT_LqgFxUjc&ME_y+1HEMLgUA;L!YpAZY4CY}+SQ@xBf{{`HW*J9V49k~s0KkAR zN}-{F^HMW8;M)M)j$)AZ>PwIOv%mibzdHNjQ%{}>G_YP3bk083eme2SnK!1PBGteS z16uEBsx~|ER%`+$O_x+wh>%NxHjvtZqzcr~2^m@CgLs__6T=fryQA*@J<ktzw)IXk zCubC`vdnm*^aY#CQ)3g--Q9V~$?-|)q|jppww9}{MM}J)9NZttw~`WbTU?78SZrC- zN^?)vm%L!}5>1dIl;tfA=Y>+3(sXopHCU2g)!KCH?H~S+|I45L(I5TmKm3C~{^LKg z>yQ8V5B~69|Ixqt{r~%4ev;ME*HTv8Fvafytql{}3tZ9ap>6N2Kt^3HPQ{v?VOChk zeRC#`@GHC7IlU%H2`AxFAF2W~c=$^^-GNCf&1`E5#t3LgJje$!nIWipW6FbA7PQ?{ z5UsH@ptmK7A$N3nWeI-l-28%qN_s?^H`+4`cm*2VnQiW6t}V_^&nx@7)>)bm6LTvq z8_`dqmsfFdX?|8pLd=b{;#MbrfnY_1SvP_UBEuT|w3GfBy|)mEK$CbOEwj*FmJtim z)XcmB80xlINpWF*Zbo8UOmbPD%567b+sihffK(|oWR!%IUyMn1)57MWNa#5iIAX<h zq>&8380qVR&~C6OU0^Gvj0CW&!(uCv0L)$n0T=_m2Zsj+Y(8*fLql!qSMR*^;?Ymv zd-REukpRZd?KA3Z$C5%R?!<4%%CtkbGxxR7Q<ilr4hY6r24rC^y~V!1A`rbMCTA5l zO>BO%y)ZsD6Lf#bJt9^EG0AE2qqEBjedq{5k60Ga3Zu8z<|fVh9;z!$jgL<yiLF*+ z^-4`eWqDaaZdzh|Vt#dxBis}vG!!u4#4HPP5Y$=D0MiOQ*=AfiL)zJVAtPfG0(z_N zga2mVp4Z=fxfZGy<h7DBAPic>Y2%VO>Xt>s0e9s?UT|3dVF*s)?wa0+LpL;#N0ZA7 zFn5Aru<HFR-LV8XA+XC8#WqGGih_zIIjkBrQAKIs^r6RY=+)bL_9k4yQ<VTAY?#B% zC6%<odH^tE3wFMVU}x4^?_FTA%NMe1V{v+VLHM0-&yTwnlbDf{FKS>`*5TLcijo4% zH;x6rX-z;R4zF8fShO)PvyNdU%j{@flDN4kd8Taqdka&*lMPu3aWU~J9HU%D>SbH4 zqO7baGYR~}#jWGqI#eHk=4+j=fpSrs===nxFZi<U5v5jSKs$TI*+{$rJtxvgAZ!DG z5e>2wQZQIF7^>m`92UcZ1||z6V^{%ziwNMM!GXS^-tMlJ#=7eA@}k0u+~gC--+Jir zQ{h1@DV=@Xf2B)tKxBS7pC;IN8DFNN!kl)Lv-DNx(0yS%k=?q$6)sS%=cFbjXI6Bh z=W}CmY9=T<bph2KwmACyt)Erv26m!?GCb3p%X4$$iydz*O^HuP%h8VD(rOsZkOQMA zxv+82TVTxSaqqGD>MS9G)e?@&7uxQAL{C>5cD{RG{~z}T@bA3JrbTyA<=bIfVC+n( zD+W^Kwb}MZ2n;i2y+0b*gJ!}ydGCE#ZHb2GDb(n4vIv**0j2Z#j7);qBbo){8aM(3 zYr&Ay?UwZGxmPa<Dk-Xc*fNp872zEUz=9L;yK2YV7PMWn5SI5%Jb*WsVdirqH^v(a zZeES$7>_dgL8MWI0aXVfTvCvio&b*1)Cyl1y|pQuosVczk&Z&JqD5?Ui~f-6_b`Dt zT9JI?CWdxV-lIy73)NvokhN7JV3HIcpHxs|Dg1R9Gq-_Y`rRwISzUO&M&76Ar~AdX zszAT(iw{`v|LqX04FbTm;DvSoRu-6Ck2cmUq=6fZkh0qK5*mQbf~5v-t}9ATuWIk_ z@9pdBZEvcpC@#p&E2wB6%s>D6TMs>Y(g9dLkRV9_D{XFJdfg};E{U5UJYdd}Vw9mH zzB*W)ek(39y`ZQF@U@_LIfk92C8cDSch7HQ?Do|BilnbGmFWXRet)<!;8)mbcYHCt z9fh<uAtZ(1nf78#q6f7*yeCz$pc{(%Hz6S{ziHS7$xM>sur29$FRxe((=0w$lSL8@ zv-&8#z42&|=<aEIxV=05=nwzt-}x{9D_(y)bn$=x%is8&zc`v+-|EgAV$f(LrNEF4 z?aX#15_zzxJngm8j<qHqGsU7@HmcTrfmyNk?YdNRV<9XoM*EU0dPjj3kIqpD+eIz7 z=X!P<Zbixo-mR8ZGRF%HTF}IkELy%(HQC$n$B42O?Xqh+qf}m7wga%*SC*a}1N;^M zzalY*$A=VtJ)FYI@`AjK<oFwxZxqw%;)PuVzc*Hd(T=x@IyYwYbx&N=neKY0VTM$2 zpoR;sp1Trv3o(-t)ZaR?i$?I-plzTMK37sgd~$kmyV-1@A;u_x&2@CIF=9pliwn~p z(cZcC&;GNqqjqpCh@ek_4_rY2qd_NB#vuT^G7eeLwVdmXCyoR#Ea++n;P&Ra{N%Lq z)-IGfAVpeTnwOE9l9F1`*H!rSC$IhNp)Wh^AsrfV52k@>Dwx0H>uP-r)ntwxB;34w zH2<QO2TBsJBqV0#7nC^oa$sP3a#Bi3Cvv#AXC_sz=1(k!G|MfEu%SI-BsBD{OzPQA zDR#CAY89?I*_4-@n2^S7l3T8{Fefu5DKVpR&}Sh~sKl+;CQt+Ov^np|g0;bJNJt4H z4#V0H_iQ~G@iDhz4!{1=>-*n+`@M+k?YH;8`O=#QFDJ*`NFTBjU=oA8vZ@}jCJL|i zJ+Gc~iA}*eJ33IlPVa{QwfWF?dO+>Po0lY#I>Zw$VWjyimR#T?1`618qC0T@5d%T7 zV?EwSIR5MwxefXlMW5wy6HMlj&d;mg&RK2Nu8F&|`!vBXFVRlfI*684bG+7(eJdv3 zGka?cAJT#11y&(!K|xMR;)N5J@*R;lyx^4;LP>tU5Ui>?y;Y@zovmSwUp%2<RTU%o zXFofQF<Kad2XCvk5v<2t4RKa5AcBTCKRZ1EQ!O)E9Fh3?D%t_qP-ys-(&tlKJy>9A z=(V~ZUTg$#SQ|n^e_b;aZ~)*ShGm^b-UUVk$CqK1%7hjl7G)VLv07_$lVDJSV;$8U z6~(z(>6uwsIW?WFX`g@a;{Crk)?{ziTtU9=eX12#wW&_HVVJy2ie~Ch+8m2v(wGQQ zKrDCVU%PPe7OZHfL@LFyqMYQIYjL?9)2O+bnVbcFX)3ydsBeuh!vmQqKTL1OgdY7a zc^{N;n_xQOnHaB2iM<$`=2pXc#d#SwuU?C<=yUjWV+o-Sx%C7w<`uDhhB*S68GJzg zM`zoi!`+^}61$;=@~bDV<Ys4K5);jJne2Aad`FNyD=RzW#>v<knFi}*Gn7K4yCwuH z4S{M4ooqr+uwvh}odUr|FV{4lI<h@n15rlk;$`qZz7a_V_T@65Wb08QYDqLVNNkY7 zks3-h2>ub>dbWYqxnfYWe{k=Co2=K5*W{%+(??bYji4FYPRy)v)xzG_ckk32Q2ZQo ziq=<G7p5oijy5~f&YZsPn7xe|7{OI!@?9nnWqSZs%$J{>%jvVCtgUsRX#q0IZ=*Uj zEtExfFKkW3ZOoYVhiN$L<blJNQqyztg<n{*SPjczHPEcr)|8=aFC*pVg-eM|wA=8o zoI#J|^UAW~3TD@k9w{)U{K0X%$Q50bk1Q{|)&^<`;9#to$~eS_<$8gUF|iny01UiT zRA9<=2*5xv^2M#~h@Hn}m!a1Id^-sDRMkQB^o~rl+&uXD)A!wfq}Its2gZ$!eb^4O zGEKZeg;^<is3t!+SPsA82yRV1|HZMduiVPa&MPR$%Snm9bo$E+X-x<SuTD?Qu29o! zu8xylLU35{Jq*C^z?tS!;*onrzXKX_c|r3`Co1Ajetzom4GuId%F9f>8FS(DlQFq{ zjusgop&DT*3+}uU0w%n@l_4bAf0PmU#VHMciVeYIh1brfl~>odwRH9L^z`#W3H0C~ z|A4>1{Hpru;;buIOB90!fZ-p`&N`W)dT7Z+9X2NwU3HN>Sp%(?YR-o=P%981eJhhl z+D5ui%1|c?_{9@C?Icsf6^)u9<@|kpdSqE=uwd99>^88h>}A8RMQ;dWTznegmm+Z% z2$sk&yT)$H2N=v@q}WiP7MAJa(!ywcQPt37YwF3Pr*0wwSy)yI{5G^OIbyXqt)LY} z?^;=LK~Cz~Lm!{c?6S=4Iv$cX#>_0kkt=v+?W0<}d2?DyCY4sSh>5<lFXQvK-uNso zE4Qe)tQr|ktcJ+2R%<40d36=^Om1e%<>SW_o5m;l+6ETE4Y-V<6CkcP{MsXWrEkj3 z9U8t=C-Iy*HUzH@)Ru<>ST1k?VCq-1psf;``VMt01hO<RsAiBx0)U&FtFmHmWR;=8 z0r%e8H8@Msc1W4F>+ikv*pGkqNtFa#ke68BKpF`iJI@=N?^I-?%l#=ZAe_Du3%pQe zuWO|(_0&i29z6E-`STagpFeZr(}Rb;xW$It+cV=cE9+cHTEm%kW<5p}k=k2l9N(Wg zcU&a_IZ&Do%JS?iH+HJz;=y-6{Pe`xbC)llJNwmV2S5DeY@XVW_*A}Rm&V@A%nbDf zy&5QC=@Fj(KvbE<!5_9Ro=Y=kbT@+qSK|vR>qxf=P9j{wFfaTWf7J<Br7}O|W(iBn zLEeMojk6~GL{nNdU=D6FLj7Cxg_h1L(?2P;8hnx2`@uJu4M%aNW;cd*(1c0+B4LR( zOqLzU_13@f5rty+!h_(QUtb>`x@@CEi`kdizcaloQvwfz&P6^Mz=RbSu%Ib@XA{V( z$74X^+h<V)vy^UPYJR#U=EILJC*AlI70>Be`N&t0N4%|-m9V5RB@Hn##oGD&yi1?# z|KO{X7MpRk1`~P~n+Q=1%6zJQ9Z=^-I1Ia8<OaF}xzUq+^p)q|JDZhPSj1i%>z3;P z5i#6KTMd42Nnu|0jn6+ic0DuY{Au*RY=cOgbvTPSH{3=@ezV*8jC!H`&%GaaK4st# z4H6woy|tAUsPhdC78R#Ery?2IMyQNq7l5k)VCI1v_zmUhH<Qad`}zk^J`u(o(i?wx z|BFw(c)C$VPZl?1!e(tBgM7SIqQy2&%FiEf$sXHR%4p|dL2!EncVwJA@cQff-~9;f zB_F)?#yiInn_<wdPmfM5BCO5tl<8-ge_)Xi-jx@oOQF|cvO}kzb}7ye?gSd^HU=*6 z*5}L5z5n7%ufB5t%_Z->@yaV7oXzcb(_4gJ>0c-d;1@eV`wRcCNESYdPl$W5v*}NR zsr*2|a5FXr^Ad8(YA6q-B_c1|qNW<uj}&y#cBi!mIPtLIbOTRtOJTT+Hxm8*TGAfM z4qzle9hd{`1oy+u;LQrZ(mhm$>T&n@on>Oy>tOAhoFS|2kiBUNG7O~Q%Nba0bKRe{ zp!^qea|K|zhKuOio}Q(YB7z~Lq=k*bAWSauli+8e`FnU^bY{B#_|L!h=(}&d`qt+$ zd1yx=jcF4)$iX76_7`w_15+(*M*%T#(wFbN`OdLh4VqWJzOpz!$Co+>DMhvu0oa(% zv}MjvFbRiZSyL#j@rR#({P{ySIkB3QZNP79CmPnZT6bq_Crb5e%Gte^a`M1?A0B$+ ziRaI?tZXcek4_M|SP_p%si=sgJ)#3eu#3u{iPpf<(ptC=pDJnL>#!VvWkQ4QDk^}f zfKi8K049E$YAdrdDuyE`ZSeD_DwAU_p1)c!%;&`WHL;I7*oT^K-YG8}ae7kRH@qzT zAoRj_$DB#~PLJTtzO0k)y!67$uf6lu8?RualH2h>>(e8X%j;+bH?851uCo#u7d546 zmxW0sQnWeTDa`s~RfJ_ZAqj5J&j`Uw73bf5?%8KvdgYZDpLzC$ch3|Ln>4^gBxW9z zU!grajSEJt=|um0dO#;lwTM|Ax;>My+Ki3<oOCK+cutxZ1D;KP5zxRdnxGmgOY@66 z;VW#f(dWid!`AZ*xM;Lo6Ba<ojNqs1g;IprdhR_MqJqDW*3(^bHoY0+kOO)Tu7gnc zotp)v*z`2Y4xG>Cw$OdEA)YHrW(A*b;z8onUs_PFf<JY0T9CJIuMYAFtIW-kzl?aY zRExBtiA4pq?9R1aux^(o2Kz_mmwK-~@~7W>=!svwdp3zY;uTeBAP<N|*%C?wyN>R% z%yS3deEE%o*DC3mtfK)DD{>dvlcZRN1dS@CIn^4cMSb{^igp}l>#u$A)FY3*@_91q zHb52!%M{J7Xk1h4sS$}c)q}zmb7`|L9Nhov^AFws{FUz8Ycpd*V^gz`QM@1(ogg+? z@F7>E-rPIYi<M8q-*uK3d#fwT_-q8Q#i4y2mJKDO1#Qj1<^osCga&}?U{)&+3;-jx zS6)yQQLN!GvNb=79^ru*LK~qTGtziN`yj*_3SnKm{?maobB!CLKiD4o-`$CKwHDuO z_h)|f*7MIi@yydtz3}?6lrCEAlY=933>C`UQ$2-1Z{xPr8Wa>g^M<U1g8&wOH7H$o zqch9Hh+2u6iAf@Ox#GgxPd@tS!w*07*t7f37W?)ik=o$2DR&6!!>P&1NhpjNi_{vW zu{~h;BjO1)5Z07F&oy`Bc29nOakU1`p?A@owE)YCy|5O$uBx=OWfph8vNVUIHlxFa zKf!ZjKw6iba!&r{d$gBoKg9}bm(IVx@RiD5+us7iVmh^p&p_3HC!Cv^<}*%BQ(@o{ zaj|yPJtX}GTSzN~@1p)PVnw@$U_lx_{@$hR&D)-xo1UDS;EFVAwW8gTvkCAP`IL4@ zfT(5c!Q9q23kC1|==(o=^3{(nXS1BKvJU;Atz_m8ry*`?s;?sHX#TY$@4Wo%3-4d6 z2dmlo(gIlzDKYSDuo2-0%Q}EwP{{&?K6QlIID*k?^VR(i|Lmb>_n%2;<gvOAHZ6rj zKtl`wx5Md1yLv@Me$4TAUU}xB$3M&--Pl|J-Omh#;v}DNj&?guDL$ey-+D^DQ+ur% zckNs<oted+nu@X-3MT;=F)X^k3SwE2Vo(UZ1Hi~p2LMLRR&7aMxjWP0IxhUrh$=~} z+qG|IdPW#V<v3cIc?fv2Si+=xCJ!OBVQ}f2e6rI*KAVF%r}jVd=pzq5`TDWM4v2`Y zNpvrOR-Nrx<U6<i4#{@8(0u#hy_D>VB78S!Ao13)CYVhW?lg)7<l5JkCWppou`X3z zeD~>xe*W`cKK0f)*FLx{(o>crv)T^~J(J@TV`CGOINoN1DWau2vD@KUvq#i%Hamg0 zsLfdFEG?>RYKN~2UkxrVr^fgT|7(BU-cnal**vxN&BiJv29_KjpPZV(>r|*mFO;1v zCKx%u*Ip&o=E?+c*lP{muU<L-0l%)=@0$5wg~2R^0({^hOyd#p9}tWSe{GMbu$?*^ zF(s2L+Nb%)jJBX|!x2DgG1L=sJ^pc?Q5{||EV1DD1TMZ*M(o_b*drob74bB(Yk4}> zOAh|*z6YOp{YY#fc*FtVNFH%&MXF#7*Fe;!B;m{VUw!(SmyTu)Y`}zu6(!D6Jlq^r zA_SN92SZjc+{zRVenJs5+)oWWo^$B2pWgq-%kQ1bgFY++fT<Eq0f$JBWwBROmnEF} zVE+qGzx;Ut6#n)qQqIKh1m5Wsjtym$y=}LPd`KsBxho<03kD?|`MGYaSQ{RM4g;|A zNWPQ7xxiin6Tld*jW1w<e`8H?L3xNKOxg_(x)Z-n40D##KA4({6wGP+*|N>^Vq(}f z((R_5BcU3KRj1xD!EO&1ocrMA7k~BkS7{yCwe88CzVXFXMCJL?MdQF3Rc3FH0#giJ zVP-Td)J*?!1e$3BV4l0>?+1ze+w-ISqq3sw;ts#|?6a?Ye7Q_fU?yUT5gu{u0=Hpo ze0*$dYzl`BM;)G`L=?9IXVcma{8K?**|XXsu`qUfuC2PP9>!faV$cj>A@Cer{D1sK z7lu(FDc>@_gx+x2&y$nmSaW=Gl6Zndqzvc9nodE&zf%XO(2L#qr!b9cIv3a=Ecpa@ zID9yc7v#m**!T#Za&meKhb?$S>>^j>fB0U%Sj1=Uy`TvTdq1cu)H~y=!^6z*3CG7r z$J`_G@AdCcQ0@^a`Q5p}i(FfmO}m`+&QI_A#Zzw{iz^hXnL=2Oeb{)BQ2j4rU_h!Q z@x;M5pL^n&_v5>7Z*QzD0>6_J)05K^(^z?!!@fpFN5GFVK0*Iz9yKECsvc(xv2@8m z!rKr2=;xpzzEn_M4gixw%~{Y!z(fj{Rs(QlS<<-!Z@uu$^Pi-XGG-lR(X&%{L~f&` zB6pFp!-T)RRd;UOnQ=I{jUejAT#o@5PvhA*!ZomOMPeP64?>rr9II00Xc$+IVl4o; z9stfQ4zYw;pA?glz8eT7W8(BT35y%rhXde`o0*y7wsx|ce>7DbCSbjN$5@HWf{j%t zoj-XdwotW6m|ZnIw@jvF`JjduO_{?FcrFIuu*^FLH=_nfUX3C@P#*Yhb*wuD#ANQ; z+~~j<kHu<d&gE05E~T}oB3<<Y)B_MeG@p6Au?=I;7d+jNPTUBFZ5?nWOQ{m2-Y8A& ziHKhc^6kmi>dK~0u<7*oi&v+w&-itMKj9ycPim{HX&YKbz63Ed9d8HVS(-Fv)JO=* z5OaFaUZox};-xxNNipl+a8K00?!-9p1RrgVaZ(3htvF3>fxqS>IuT6X40p!N$Ov1} ztNPILT1*>F_+dr<N57XQg!&f(08aosCZiZWgIaVu6#ijmJKVl)Cu1i0)gS-hp=SZ$ z5(2oUPEKhUvv)KAf0O`Tq^;F?X#MGlv5`TrBX@{kN;Sra^pcIG2V6%J^NT2=;+C0? z8c2F~7l2zq(4?^g5df~LsH{jmcVPeXPdt4vne|`DRL;?I8-r9F*QwDXO8>$oa;^f8 zjm#MRZqA2k;2EcZ5i-GDlG2VExW)LeLY)i&fT4f|V7b8cwa6l&VhdkeQ<PO8-Y&bg z0Sm=o;oPZ%Ord_QYew7>d|-wpY$q72H-9av^JKnKa4G!fwEN;<b4_Ef2$>fLkiCKk zRw<lwm2^lf+n{6(*+0U18Z3(>2(wqtd4-~IG4F!`{mu22>7fBsh~S#)YN%@&G0q)! zAK?J<>sXA=3=%9_S$njF6qBGg<HRTJQU_Omn4ROs*F-_LHPKXE+ujA(_VwT=RWARm z%l)~h4=TC6uBv4OomL=NnxCGU28L<S%D%Lyg3!kZK=?b=;$hb=k2HAo?lx%(yXdpG zXq^cSbB{KLgBcg2yJ5TNMUworNH2S*3#|Wlp0dRsD8Y?qQ<f{=DV}d?f=0AVXsfU= zADGq;-F&U15DK5q>5Q3-_wN6jpFj25XR$>#$s-s9;2;$NV3^RaJ@d@V$8z8WZm(jB z!^Fr?cY8B2fE+0(#Q76lq?&t=!ePL8cya-i%<i~P7ae`-r$2q%o6ur0btZHefXxSn z20r`V>(4y?t7BP=gRa9|R9s<v0%p5jDh()iY8cC~Lu0>Kn8JmH<aW)`2d-^VhC%>F z2n%!*5rxnSVL1&f0OJY)m|u%qE6B_b2QVOOhs6la6}SpNKC2932_cFoA_!rbBnwAc z(mc3Afm8lT;XjnJxt9m<=}#LYojsH6-~@hy@<OJnsIZlba<%;-F+<QWwWU<73%nA> z7Fbmz3oi@AMN8v-1EzJ!9qfgaz6D~6V9{w~3>w}O!V%CNjJE{OXSZRQGUt`^Nfpaf zQb12ITwhrS0Eg*Z{uvyB5&F2Vy{@8Z2(>&L?9+i(1c+_pUEEvk{oZ%5Fqz_I;qNqv z1^bt5<xMWYY4>S#r-}(vCep5fnPGD+nAlMPiFFBC+?(O+;1jstbQ0aQYeCm6@4nte zq5X>dOgs$?8@M7^PKR4QJ~o%39ShQ0#>wTL+?lbw&RXrM=fFwy(nnVd%H1rj9n-Do z14Hr92WAlKm1kf4_+|?-gWId~6N5dSZB4cH7@*hLH#7?20S!4uV|rkq2Yt8f(rfPO zADLP59I;*T??3*Fhn|1uY!(b!2C-nU!v_wL9^2p_jI%@!MckKfz4+|&?_R9qky=wN zPViE>i|(BoFf2N6`=QHnbKET<z@pF`R$x;ZSZ!u>I<Aqy4Hor`vOy4<F)X;ijqGtp zG_N{8qbLl(h%lijZFPk+?07zPI9y)PZeySImpJ&^UHOVNh37*V4xcg%aIC_eovr#) zot<L~>rlYd2zIRW@h<Xi`d7`j;n`rA2d=iyWmR<C0|-+BA&0y+KinB2Uoil)X~v|D z#v`~a(wyQSz^}><@HtB8Su9-7ZK+QsShS+$C1m$)43wAEv_Jzx&+gE`@__LV{Fk2g z+KSp<%;wz!zZ|8;6dY9MTP$lutHH`0ERXBo<<55+Aj)+rm|V02qIj<TR5H%Op>#`J z$i)(~Na-wC*9O*8p32pJSTR-b(4nP*zt-Kk6*crwIcxo;U`c8*>tbMxhnXuCI`A2p zDZqLV`U+XuG7>&kWnl+nBLDdF4?pzGd*@S783-C;fRXcI{d`F%;Li582E<_z7tXwJ z@a<P#KNM5X&hFcDBk0C~QtId#9-m$ESxeOcBR#n^KQ%tw-`xR}w6yn+&6_p0(RTB| z(+@rIn$k!LnJEe#%+B;tXeN@fuO5Ew`4`?jTQE)=d<|w4_E5<=#h_Vb4&3SyT~(d( z>wL(N45mlu^1zrge`f$IiR3DwsemnuL;xec1pp(5L;z<MMgSNE5^EZN#PF}mjf`<f z0tH*Nk6~h$t9ByA3OA^bq?A;7WxrT8t(8Rk!tNbq8OsA5y|esIr#_|Kc~OSp=~eX` zS$mEbPqJMVTU)UR@6Xi{IN`4H0KDeuo{q5{F*zG0OSwa>ZAFH5+EiF!Hz0+pA_Xgk zck;|0P6f)=TB1|XjmEGh?mI|5QNW{%(PuH~*<T^0*wI>5Zafl91S^3!qs%k=3!Igs zlg-97D^Lu6s#q!XHbXC!_v5~hvYp@OMZQcn!bYJ5h3l;9fGJrOt0?Uhv7!oTB)Ylc zt_5ulVAz8EqfUk-oF0OOo65~;L6_>@@rZi=tPNlXimPt$MZ#mbC&29e=9ic!ZKY9- zZK$lUSz6SL-R&L916P(6rG9;2|64~AScr>Cf_@}p8e6-^j16G-g_FIqG((hwm91-7 z?i-jN5)Qub^b0KHVAk1ah>i2uR_kn2`$T0$Nj3tnFTa1jkhC$N-IJZcSE^bpf<nhe zFGIpfyGU)}DueB``Woz|K2YkQZaGW?J3>3(N{9(6HEc#wCxaNlfM3S2kOk&&U;r2l zQPp`_ks25k4puU63XWT5v&?KeSxPAmAh&C(EL8EW?{@IT7h%P_R<!GojX#B{(%Ueg zCze@}A*yrpU-d3jBH}hz&6^QhqV`7nP?x24hP-ce)eKaG8iqT&r$gVW{F5t9VA_gp zK}uY*20(|~<2O*fzMa8|CO!pT2%E0_gRHg{mQ*z(*Bi=K8gg0r=l>4>+*n;w)<*Md zQ+2!M8JfMW@@sGEgvw~GgTVG;#}#^~uF=FsqiQP*ANq|i(jnNv36H3PZ-3mJ9<<V3 z6HjjU-KGV5=XcTFlk6#13GETdQ$d-*?o7qHtzMMM$)6a>PLsNZU9HBW?Y3#M`0RTx zzI-?)pF|vJE}&9`1jO6rbe(P`W-&MiJcw71zW4s|<PKKW-Ja+JO=8c;v}x8oFYsMX z5BFo*M|1atRpbq%9DV6mD5d0T<u&!31kg=^K_X(UMjBIePZY!-fBTI?7t2On<Aqfa z$dHoPWgdx{748{bvA7e4f>of3Rt6CFCV(9u7OObq0?UMED^fUsMG!&&YtBkIfGhJe zi~1v>L8kjKHmE?;X?xMkpuM2vrgGvg*ajGu)FS4uu>Ms_0N+O%>T3RGbF!y>c!9+- zZd3vNHfKef2DZl7T>uu}=_Y0n2a7pHAn_-=MKx>dbA283J9V*7QQsliFV%y!48cl| zTD_2Ow~}k1Mh$$FdK-1xg7#Z4ROail^DFCB#=)^`9<ssj?(f?gtBQ-ndJRrH$_%T9 z)`E8NWShdb1$D2og!Gt^I@qxpI2q=pBMVRs!6Mi+m1uZEX_{Pa;nx*WG9hY3t6`5Q z80!NgR^%=?g!>z_D2a6=x!8xPeUD(38JbX*{U*Ljwdy!BZ1-rk#crGCYpx#N|KZu> z+=9Xqlu}A562p!exUH!U#f_*=PCa}0@R_`Re%s<OhI);KkIC8_!^i?mk73|e#{gQ; zaZP4_`8H^XbHG~;0E6@xt2rwQf5I?YtyYkJ`N(^p-mIUs59S~MR&J>Ln#FW<R$MGd zkEpk*UfV!GS?{w`U#kN(Wo2OG2m#oQH47$t(}IQuRxe=)!2Bx#m?11`V3^Pm<n2h& zI66kx*K0*j{(rXi8GLOYtkF*Yc`Xs5or$!-tV!5CLjcId!S?RS+gqIMDeuV}&<Mad z5upecja4-zg)ZaibW+1=qB+yj;TH#(=Z~U!tfPC<NCF(Sn9inY07J0v)B&6ve!b6Y zU*#@JC%p`7%cconw=-Rxo>!xkyoV}VSKZ}c&3|sF$jz$}5hi!v7^B$8pf(nh+P0wK zL;}P7j}Ws?xE^-hz|NKM=7@hd^S<Qx@V#0=2UWfT{O&SI=bGLG*<b<NupO7)xfx^5 zCko!Ci_oZ{kXoMsep(sCFDwq784IZBojTG1d#U^x#*eYmmhjof$FGCm#%PGuU*Ia- zzzp123m!EPM#h}_^g^ME80Lq1d&lOZ5+Q=d3SkE)zr7&e1cryZ+q*@R^UZ9**#n0! zr)HsX+;=nh-Y3we(tze_w@!chc|xliCxBnj5~}1|RunRSPXD?`v}5Cxi&YYOek?Eb z*M@3K1Yp$J+GOu=0HYQ<Y^aI@uv(FXX~gMR#^C_07MU<)couVO;t%*B%!1wofCKnC z$^rF*x%%XQK9QnEd@o)NJI&>wZWi(OR8Pn70-{ZZq`-#epK!<mqfUU|+0kH(#CC42 zuZ^Xy1_Sw4GRn4Qdpk!=1yh4ai{N|I4JUt5VIG&~F#IZPWQx%I0z9CMA9tbyN+owk z6XmH{m1H+*Mx8zK{y`zMDP;~twQPNLPDZ(SoY0Mi7zoOe#aE%QuUWvNj?j{(=Ytgu zNS<*{Y<6~uRmc8E;>DT|os~hvP}edy1(k38R_ZEHe8u#q2a}0czMnu~gh*(lAwvst zHM6Olk&hK!pOg?Rdx{<+%0vVFnp9=iHgA#d)N$M>$<G!1DO~GF{`#v6?B_2d4KV_) zc!NMNc+9~=T#Lqa@IWM9Idfgaz+1=`j?YE+eAi}%21jO<ED*`7XIaB6tSQX1x0A6@ zdhz(#gygiG5|DquLH6Cpm>JU2O#XmEaQIyN`b<KrH_$<<LIhI`BW=N)iR@={>UnZ@ zJfhy0Kq8JATm&#Vv6KdOlf6S(B-BC^z-09aG%!eY48Ya3m>O(BXlUT#oD$=S2rh~H z5Lt}atwI9;j2GG_MzTy<C&#$dv>%=lJ(A8)^mNAMD9U&D@oQu7fLD<3(d-_XAxhCI z46OquH{9LO4g`nz6CHx(Ss8#0f+{In9z~Q)4;QdI<LhadO5HJdO>KexJ}M`}ule4> zui4xlAfg4cZ3q<bH$%lq>80RAU=T%fnh9CE!sp(!G?!<k6-#4m62PQ?F;CR!<TX^t zXp~Iu1+ve{z}>IZj0*qO^&QfT;?3}8h9c4gFiR<Xgw8#nCz)ecu~sx>x|O3Y=vLI8 zm_l|Alvxk<N+pb$VRtDqldC3HbcbI0c;#e5F*t)8JvrB|#DNf+4TU5XrM-yrioh#d z3yN~H(~=TyBv%r@w`a#E<^rDg$g}*-;z(C}_n2VnpHEN4{==o|(cuwg8E0!^uf!yP zKhFYL>eCZF6;^`-oDUwvTi0ST+C8nAG){=ahceNb814}*MPjH8UZ~qFyTi4?x{~r5 zXF>zQJNdBOSTh5#ENB;lrUl)IAT;rd*68ZuypkQY(BUuAB$vamaE-|f5;fQl#+D`a zsT=&ZJC&`s<dv`e?krg2)-o_I4R-X;BXNbWx4bo7<P;=;18<P$Ni(S;H%EmgIso)d zCHGwTz|1rX7-rljyF0;mX%C{a9(+B&NRpKC2ofmD9rXcHXDf&f%X26OB1nI5_tTeu zE2RY7@iu5qy+>ge{|`U$uT7OXNjbd^z$jdj{mkdKv+cx$+y!RNj8)Fw9PJzZw)@h1 zb^6!v=hSu(WYU{;3{{LKS*S&^WO2$yn9a6Ne#>`mqB{!)yO2%77sONGjbw9!nM$IM zFB`+WEgM@v0E@-ej*ZD@ot9vWw}&gz<6~kI$nuIdKSx8179Hp%5PO4JHYq8m8G?Cx zX=*Yo?kw#Pc1{4`HUOA^Wui$QkgEDn5{Cho<I_~niw&8HNuVL-YE^Y%tJQ&zBR?l4 z;buZYNv~J(_>|jg)~ji>U-pPNcK-9Vf0{et{9aRCyxh%g4A%(2Fe_XcM?h#7j5Tv* z9MJ#_zd}-m04|T1K)6GKc?8?*#ZLh^FfiTbyJ;I<DC0%#M6WxCLT@lUX?wP(a|{ZY zrBPH9!KFF`9WpPeo#_*CclJVz9~uUkD?151Eo~L{X`#P!$ON=hC(h0`%Q~FZEgzAU z6$<aLphVehgOgYP(rv_vG_Q%Y;FxT5<lam!tY@DpjIS2bu{ad#PpswB-?uiGX5CEd zlrr!`Ik+GT?U`<nxvq^jaS@`+H%;eHK!jLy2j5htv!fl+t3po75HmYzH7k@E=HPn^ z!wmp)em$Qt7<aWp0Q+?%fc<(Tn0LJJ+6N15Qe-&NAT~QoU@+F@^^zk^c8_Qw1=(<6 zZtPTJZUPXDVICj`1}`v!vW)9gV!R6Qo03`5j+ETi?4%n)s_nJM2s<Tf(?k6ubE>lz z7ruLJvuE)Q%Z`S4t*a~}F+sHD<iONQ%)*v~wJjU?P0p?z^w^^lrb-}1GR$x@xxZ<T zDBUYZ#L;dVAHRtycXt~@7%xfys}dUiuO<Tnl|dn8P={3=rh##5>?L$AFyisGWd&6( zBNhd^!C%Sh&`aLO8f9sWAXcrnW?O2%Io`L3lg59P`K%Y`%!tv>fjK-S-6kAmwIEr3 zBMiWNBYON@Lsn^&OAGMill&KLW6pv$I0(SVF!c1zn#*nD1$0z!{}Mwgmk9t&=g|B@ zgRs<@vt@O}B)aWE{L5KuOOLyiR|ECij4A<agZR*7LHqwPmZkc#)VQQ}-N+gzGoYKx z3U$2tHTZe}2Nca7NFmsSzgaWrz0vEnqM=z2VVOxBHgS-<Q780H>?^pQn~&h0&`9LN z75>hh3~r6fnFw%}n5C7JOu|b=(XA!bxh*~<C#%v7cJsX4r|$&cd|O^ZED)TVTU>(9 z1*Jo)t1Bvs^3qchQuAxNK@zz>H$AuF_SW=y1X~?mHRqwY7^du6mfz5jm!RTK%ui2i zfapMVValzf)Eo#5tyWzP4r;I-gEciFKE1ec%vbWssS@D=ePH?}##LaPJx=2Y!5aTZ zI-Ahz47>yYxRe0qTyHD&^Z?%3iWHd8*3Hitv;!~>SYtzJp`S2vCjguM=>Y80v+jV0 z1{8*loVWBM&Ve9APuN3op{IKUuOAH*EUJ(-X^J=iu=7I=z&kGnqHXq!WIy9K3Osqz zLjsu2&fH+Hx{~AtJ3PAJsg1bNq%k{e#talVz$Q#}p3QD>!2mh&4#KN-N!Q}C%0Y+) zS<0C)Oz7!X|2qj$o0}VIij%L#HR-!HG|NSmj95`o4+(C=9|x=0)Hv<DJK*k}nxG87 z!o;U!i+ze(ZirC22>`H&Y!MPx2GD$D$wp0D@PgGoSt3f7f=Mf<AA^;H1$8)K)VN3p zpFwW0JR;T_a%zE0cJuNTRFF~0X%`_4ANGi0n>^o|pAr|B%*ke;6~$C*O!0vJ1;JcG zYC+>Lwsd`NcFF8oie&S~cc@^N-r3%px$eUsycIp<=IY`CPsiF=Q(jV>k(h!Tj*H=U z@R+8?-%2TNwmvp~j%jfd{A|IRLx|8lqK16?@i=@-X01p8yO|eW?i0W;p<$p&2MfSq zmC&x2&=o?P4=e!Jp^g$4I~kxP@I4iUWjlgc{zj1x4kCMg6ER+t<+&zKore|<U@r^< zB^x}p{f#LvzrtjD_Y|fvFoMbPmny~Mp$-7-Tth{Ub_1B7hV5~-qs|8^$XFq5hs6Q- zo7>~veMaf4u(dP)_*II-Y9pBRune#{hjzT3V{d|jw;pZU`btgwh1k@h>iTB!35s&N zPGS_~;NBp@3$HFOO1yltL4te};+un^>5eeh?Krj#dNjR4r`uk=dw1d1p+lDU?Fnn5 z$*E(hBfSI5CBbO7DL#fLcx$>$8W<11{6ZVn?k|OY{9pNPGd$aSv<1BmCWfq(gu94l zYlsY2-=O!YcWQQS@Q8tS(gwMow$yA(UOY#e<$`b#g_Y#^EW>oO<b=fZx>3Bx+cUE( zIu;63=<^jf-*x&NfF(P4K;UmF0^lm?)|QkVnygQajZ4bRD->aQ70l;S<d4$gZzg27 z%=m-s&2U+b>c4^^WuBMG;UME`;Z9zmDQcnpTOX_?fUOYPl1Suq4-O0nDHVoRFJS;+ zgrz}six`#zFh&Db<z`lmMhU@>HG-4AtZT=R!0m7LS$&j5oi+knO!?=uf<I^;Z_d&T z9YTW0y^PI~)}C3M4lAW{#SAWxWln`==(#<K24GHWa`<%yBg<VppB~?(WbAZrkE_Nq z{bYM=2BxVCd5DH6M_C`>m$3C745g^w$>8_Z>Ko^;r{)w_k!B2-tz(+qUlf+O7|yIJ z%Z<Nyt<Eel2`op|7>aW{ndr9Of;)yLC;Ng$Lt0p3%#MlyQNC9Y$Wq1(&j=^j=9!Xw z%PC(2uU-eS6N0TtS+}g2njxPdOeNc{o0f5kRem?gKHcyMjX5!=%gh<Oz0e~DtJ<^b z0Qtw9ZOyoH@mf+=5wc0}{!sp0QjnDxb0x8S1Yff{qsk41{CsR%@QLt(gIA`Tl%{4$ z6bpo9T@nB5i#E)oBIf+nTbamR*>Y87C3$K1t4y0{rHh}!gQGe=H{48e-x+Qu6P=8b zprfts&wuFf0KgcXxdXsxW(aeE<%g3_hlSA6z|1Q_MKso`mym86BBR-HiKVSw-DsDb zUJAt!<_b?Ae(#MB<9Z{`E8dI%Oa-S~v(s%yz|N5u-vL>-Nx$F_h5>k`zpWo}2(}y> z4VzUYDH83X0%lq6B~<N<DQ_(U)QmJ|Ihr2U;X^9e;?TMkcfYok%)jD%Y4jH)sa3H$ zPsa4Go9rr#*aPmkmaA`^zMPz0R94ODhg7?q%i%BnnYHII$cnS$F2tAyMlqHy93z_= z;9PdTQWJ$9y}`?iJOd#s+5?!kX2!k?nMlFfM-#xStiIP|IsmLdQ@=VJR$bt1bhif0 zi#^mAUz~e?ww<=6wlQv1r(Ct1oo?xTmSDM*zB}A{J|{X1v;l}|0fg3q4sJ*}d;F`j zacOx{!o|6%vFA^mjxA?P{o2e7OEknoY!(+q1aB!Cf<w+0zKlj%I9)1Q6Xau!=UqDf z#p!DaSw$S>QIwaJc=f9<&LxNNOOMP^JmSczBh`&;^=i%1s7^;nT?CkjI5+FVQ2;DP z%CNz}N+LM`vz38iY5qI;u;8T;z-={ISFfjIdKAh|s~TFn21ZB58I>Qn`OXvffB)y7 z*ZXttkN-ZU<DGTpHqmz7-DqHdaVzxG#cg%If)p_RVICzGocLueFyyxK7b#`*mlD|< z+L2vpBqtd(B*|+W1F+M<!XLkCVW7)9!MYzQ0i)$1fNlD<HbVV-stq-vAjzaNp_94` zy!?yRs;ehY$E2j^B4t^_Y&$MFY`nx@Us;XRM`=-B+KuzqYFsRYvKcJ8CV6-(=FBU$ zVy{&)FSPp(!1xyT;31*t5ukr?wy9h`J}UQ0KB+4-S3sESNeM~_>)S#jw!I&ur`;{E z{5I<L^gm|r>vd6NsGLC+GHl>ihm|Xw40Mys_TUjCB!A?B^9{F-eenLFug+hOiI0!D ze&)+hKK$fdG4m#CGt*0mE@MduT;onNuZh>LjWV(Aj)}}P2VkS0;Yb%DIOp_-?|=B& z*H>=bym{l=g%h8Bc;M)by4m34B&;MD`G{_$IGzy4#`K1~E;&KiIy*nMg*$I)69c}> zNo1;a!k`kGWze+WY89_?WgODLY6ey-p(C_o|37Be*XPFF$iTmrmlPKj7Ut#T6y_B- z4NSMkzxV9V{?m_+*kp!aBRQRrZS0nbcOH<*(*U^PFE3&@?4*SLdAhrMf{a*{*a}@T zz)gRGxnL{zbDp*r`8)STCrGElRS6;X7c!w06XLfl4R;N@8aVBic_lUi%#T{9ws7+? z6rgoyO*V$py;06GKW@4F(wC<$-AGE!M&%!dsFhM#*nCQA4g7BfDu)X4ax)Vye|@Dg zG~>+hhNWDx%yvH5a^WLD@UA0iyJDAVF&pIQ>}k2f(#L#8g`w5HZ)GF$fAN*h+%yD5 zipap$@T%8-53T4{mR0Exj6dL`eHcreCz_hh$d*Y(=OaoQ>JHt~VU|tgYhGwcI`Z1{ zzk2oEgNF`%bl{DbUpsK7SR|A)Qwv~+;1~~=6LHp;S?Ie?iozczV<0QlWhZag)h2`E zO5WmR!B_jizVz0CgNF{j^X9Lfd+Gg))ou)}_hKld=;@mijC{Vr?DmLuIXhl&mq?Cg zxowTq6_-{Ez^)F<IvGp@!$`JFmg=w!z@+0Kr91686}B+R(bm~ma4V^>mXqsitICUW z(vq3bu54>hKf3?%AKrglS&z^K0IR^lM4jybw?N&x`g3TPcf7+e6U_c)Yoe=XhLl*& zr!WLZ0dSy;q9BL>wm`jqd1gA>CFc&oj*+ebKMYu)aix2(rBs{?FOA$B(7@DARN?;H z?Gd#FyAOqXz`4AWM?d@O>+{#I#iyiZ<Yi}N=j32K4KDtgm7SfNk&%wTOMKk5v&YXA z8o_{JL8IHGyKKb(zownMt-A9x1|JamBoAaKNzIPLPbJx$pU+Y^x}#LUP9fQrIhE_~ zDyr5sNfP*SUZT=$mlO(9Zx%L_%6F4DB{O7R*ru3Pa;MuY^5B)YHxqi~+g(XVUwZ8E zr=NT2SI<B5<n!;IE}P-unVp!!7+Rhkg`?PJE8|P$l2L4E-l^WSy9=*_nGBU5ylO)& zX9`ce{x}#+pLqPSUp)BG(;r?_v$5YW6N-=;>fxZKF~iL~V0%PWH@WT8(G5Lc*Z~dz z%u-5e;JpDH6k?eR3>6F)SO7+wM{{9nDt%z^4z)DZlwsB<FkH~xmHYL_&;RrnCn9=< z`L4}`M)|T?#vWW@cj+H?uVd%`eq*e&U#Ho0h2}Mes<FZ}u-q4u5xXu%Ncqnu+bR8= z6CBKfz_)BnboaPqw}~5PAX5V?3QcA&`G*R(D7fKIn%jyfN5bDrU-GdJKRR;s)6Y+Q zeer6{jd;`pBqZS{eoeyf5QsN!T)lSn;>B}kjvxIp(@_X+fPR3Co-`3`(xR<sJ8$?i znHb%0-}xpCuu9T7y>6}oUx|en$opqC750FE0`v%u_I`IP6E21A7O8x7zkwQdNd=?W zQB6Bn^a3_`M8(CNiE+oHvelD%__+t~yZ?b-{Nfi6zjCsifZCp&m<Nj%<DU#Cxt3R1 zR9-&pymQ^7*O3rwguJu5^;DaSbJD?!#iw3*=tn>K@sEG{lLwwS5Z4-Bq{&aPqoyKr z6j0Jhu+A>9MLEyQjCHTl0tp#;Lz^RYrP9Evg*HCBa6T+oOA_iuk_Am4*~PF_abN&W zuj&BhTHio#TWe!=X=y=zL3w9?=BYz3J@DY^9RU7DK`cwt=zKT{vkSihrb+G475Tqw z!|gV5)ghj9*43wKHnjB>1-_w<bJUGC*G9IYbItVz!@hQFvbP7*hjp3hCahTOl1Ubq zMk0v?v$7^hIqJ~dv>g(Cdu0j?mQ%2uR@Sz+=Nl4Ee0u!UxpU{wU%7T8Atf~hqs%h1 zcuD`Jr>CVRCC1;papUHVOJ^=*^)i2n&hp9O(V_l<(IsgxQ~GW>C^ffkm~L`+zxPp> zY6t|s^8ifYxMZ1FG+FS+0t554onpNsfWkM>-Gymwp;uBvU^E4{<tpNgcbna1&V~*X ziqhNuUiVl#eE$Yh4?gyz?|=UXKYsAVFN+AM?aATkWq7Ybk_u-njHNV^dKPwms%@iL z@Mh@*`3n56zIt<MM#;vNic>G$|NX!Ci|_r-qwmLc`0@?CDT_`iUdqF1=|?=Gy02B3 z8pwSw*FwmMJpG#^^&Y?+Ylh0m2ms4|M(=L`V2fcP3oIvD8khiX3jho%#on&2mgYJX zpycOeCtdsaz)L@WI2wS(GKVXyJU845+Uqd*cN)Cg)uHxa%BQ}G714sP0a%R*=mHWp z&B==nVCU3Iyt++{+`;YHzMje8yLreBzchDLY^Z6N<{(-Vr`rgx4<qxFD}yby==|>N z>g?+6AMC2mijPmu$jZsh&dtjQn{hR$6j>GBhN{YD1f?4|CYo8y%8J75tctGj>B+I- z!M;uue$>~uGYYUx&yhz@vO@TEfj>O(y(wVHCPkFI&+cS^UXJ3>Bv(^;s^$Xi@iM<1 zlnufj!FZ{1DjCCK99q=98d2m!?RHP@5yNfEUCTy_uEDgAp8V;L?tAE^lf}Z=^uX8> zD_sn~L4%?j!(~&YcR`qon~<ld^dsV=lkH_}%#Q2RH>$sW`R70U{*NF3FupVVgXHL| zIMNFa3q<SKSYW|C6M<INP*laH#kPiPOQ?Z^7?uDGvJhjWbfuiNy8#S7$}j+TgaLQ} z)J+)3*4R{$_WA3NJ@VH3um0lU(~+%)Sa=^`<}EPqXzfxIcRU9E=qwMkvzmqvBdSk? z0$m}8!h1%mW*XSPlsypaWWOQUOwq`%T<Gf@_jx2MO9(WSRZv6kGYd?PK8x^#c4D^? zJJV8_k)Bn`Kov4`b(phNS%v5Wg=iyM`hn^p3@04oh(Z#}a<*AV3+Np>JJDR)fSJxM zjkJVHc-7fh8(F&aN@S5ni^33~cLSYMs6tiv3y{R3vtWnpuAg&HDAo!tNJE=OZ%n6~ zrEvI<+_SKuX-PpSnl-N?c|D?usC!xoUo@0;;@#KZJan~22%8%mo+V+D+%5-Ti$W`N z=zQ$R&o+O=0B9K}s{>H{-_>B>o*I)$xK?-V;Hxjcb0V`l^cfC}_Lv$7i5Dt1a%N0a z&aO#b>ZkRg0dF)$1IS3d0L)%O)?v{DMlH1Q=~xUph+(mSh1m_oums>5uYtjmU7VUm z6MCSJI=H<9a~!KLKk`5Q=I=fJ`I`?u6a~Pvpz-`NnVgi_xebx<33h46ek~8QjVL6$ zIM6dN3Cn03UD8&DB>*e1r+NzS5$>TjXp9MSIwATFt+_Sb-#023W~r}zG>HDnymsHB zjs_Y-M(XMWsnwy=)N%njJFEUNr|PrfZe^8mU=GH$0=SsH#i4|pONfCC7)>|`N^wFM z)RaTL#4l(1kQSzye2V3zMMcHM1zE`{X?ay6HoV4%mCO$Qb{Ny~@E(Ra&{5SkpX%QA z`CYLUwxX{f(F#HaeMB5?6k<Ur`r>jY6}^bs3%=3*e!it3HKVNGvVwy{9DBt)pk>oT zHndZ((E^Sty!H7mz}@J*+=+1qW?|G?{J$A0PfN*dnhAdg`Vs{fC8QKQF&Zc_5gN0F z!P^36&d1kh>=sp9Q2=Z~XifGuK09YY1Hc-O#6oBQm}7$j0Cy9>l>l&G-w*)YiP=6K zb!Y#>zJ0&*<k?Rid+b#2j(yyw29^_HnrTnZbdUYlTd;py>}%8MU2M*{nN&WEH;0J{ zj#rZL7H95Bs98uS>Sdp(lVb>me9=DN9w@$fJyk)7#oqSOP?3r&EyCB!b5b=ll!ZdH z8jL0>uAShP?ee{+o3j$KS|_F_hDXLmFnWNT|JX|w4U!?9BkRNl#c=@BGa!q{*d@+2 znHU=$9_a0AZ)rhobVFlBenwhWB})=i$qSd;nU~*2HH8jG==FR{{NEL+dwoIR6q$B1 zGs)Z%V**hWOYpUrgL^~);oDhl_?Go0>st8c_F(T+Bz^^8sugh=NQy)`Eq0eYxP+QD zO}lWVx1u+vM|^AE@?s>rma~TWoWieUhdrW^w}n5VyqU0jh;nqd4ZteJaxrMeu&fe` z0Io9tvyif)OsyR1WUxFj=x6aw=yQ_>&Z_J(0QdBgmA<Fx{2%Yz_usx3d+oWWPWSBG zJ*1H+z7RmLP}_HRrdFU9nME2%|MI}6H%Toh0IPk)0;bf!@;L4cVEwCwCWK&l%m{Q; zU3mAkBU#*$rT+Gj@MwgEcXie@PFzgy8mXr0O|}60&5j~D=9=>}YQn;A(dCL1A-r1! z%FNP3{qy`h#z0^S#K^>0e^XIbc9oj3r5K#V_%83%4v5=~UuRFg8<>@6vkDoRL6*28 zQ$NI_3-1KEQJOy#`~m#G<(k{0-DJlP)4%q1&4#A*mZsf(E=@i<BSG<Jk6#-x&TD0S zXnHR-AzdZS>K@UU5-=B7MZXjZ`d72?d_Ew00TN!oSlvzlw;;wG0<bJ-0vIJ$s^XAV zMhu#jSWv)iO&C4_05=z>2LSHt$4ukyp0-PWvTxsi|50`9;pflojzW{MQg>?3)IGZ~ zyWY!kUmG3Mjn0HaZ+vvEZWeE6-O@-34H)C8D><-`Y1Fm!_e$-$<HOs-Vw<A{$6tQ> z{bWvWfx8_7us%l`Ljes439KYaeV0Tst6j*AswiO2<+g|9!JQ8vA*_AJiGiAig@Lxd znK=w~neDC4bc=V|m>jIZ=Nz0~l{aESJ%q{7@_$pzCVos#eL@q3<Y`v<-)DL73Y zl1wxWY%Z|Hpq-+|YjxkW>qGB;YcsulGqiI#1jq`2<c<=+La;+o^mnKuB55C#eb^t} z9c?cR56tehp_EdT4Q6)B%&<ueuGCx3G<*07Vf#Sa%4o*p_Q>7<4vjSn0a&d_nt#e( zLIIeq<_^G}17<?^VYG2~U&nO-__sc($vX7@g<YLW`z(LvO#N>uJtMw+#q8Scq3o|e zJ)O~sBphbfvmn}{&@K_|3|hu4_AsLPTJ>I)98!3K0N$Riz5dDjCkiQ1m-{-yOlXE) z<PKT&n@x|Q%y2ck{;-)P=Jp`$)}ev3yP{O<1v*9iH2lGnfk#?jXP*@gG$zuZJ#~R& zuof3*2kUclszh>UDIhcaqUXEs=|%5QYMZm;qvM==j1hWcqa!1n_BE=Zrlb!Ng@I_P zZGf*vGTHFY<z?{PbEpAFqfB9L<K$v=-#JWXm>Hy$JwrT#us%#I*L=|~)fD!KcSq~) z$6gugq5>8_zt9_E7vZ!@18~$Z7E@OiNOty`i(*+++94S9w8Pf97UeP{+$=ZD8fNIk z8E&pw!*!lo&#cL{JwMB9;K({G)k4$B4Y|Oj=)$54Y`uhXfz`=C03$ToTn-H!0x-fc z1KlzI76AUVzV?g5H=+QTDR5fPAs)f+vJo&>20F&*n67jdW|Xwe5Qi#H3j?r79Ms`? z2LN+7xhc+Z)qe1f)<&u`l8gJe#L_^gmhzWvB9b?hnc4}su!~Eo+2w-L6+7zcL*G5$ zoSV~a4P2J}<blwf2A1g2HPXO>75=cfR*=#faRORMxW$+_GC2($JlvR<>ohPvz-;xv zfc|dpG(y-f_0-j2x;;`_A{S^uxen$eb|Wm_+hrpZyYZtNKkyfk7gA)PhTseU_GVPo z^n~iiB2HxJF7?8s;8>`Lw3Px2s%a;^pcoF#ObYC_@A8OS<K2TQ-;<~90POjJTq7xM z!{}iwofMOm@|IoPTE?#f+}uEK(D)MmsAjdfXuD}(X6D#<V~>bqXO-pQkGMC20~0y` zFsG_0hP4C0sKiAQ*t+>;K_i6;7Z?C;!_>CURspzw&@?b|9ld=5@NXWet&BUI8Zmm5 z546wGyi;U-M_bRmmzBW|i$X7t4UaF#>fHrk3}zsnEG)5y2KK&<cEyFFbvD*#M}~}1 z7W300c18A{X<%v#2yqSwCzZT{iC!4EBB-5?!d!E9eutvlD8(dl<?&G!fE`D~=DJjT z4Ag37A1PKfL=EU2g>IXio}U?RF3dInGmT`@-P>E=<#6v5_OlH+nYl&9C18muDXZey zXsAQ*3{?PZ35Psqn^Y~}3GxY2)>NZ`4k>H)V3gz6%Bq6G!koN<ysVV;3XPGBdO2&| z-jxY7Il%-lNaW=S`4R_dVSd?ncD?5NdM8jq$rP{)L0i3#Vi#&LGLG7)01hc&yGxaA z$si7ey;jG1ec5f4$5rUZ4jKyxP~Ap4XkW$Qst3H)e8)W$fH6Ilwa|X9XgGis!x9S# z>gjz9+PT06;6@}Q3E<N73;}q60LBoI-ofrz0{CEcRqTnhU9p;dRspU=i{jAV`MN#a z?ef6RVSqAJBG{Pi=&va<z*nZ+{GK+n>$f!dFC%)#yPF>jRbuh{$TZeAVAEA-s0p3S z0;_*QSxrghXqzz8m|fD&!r5&?mui5yPEMSsi%VUOANY+UiAcGE37>F#G2#>BC?_$o z55sFmIfrSqxg@L7032kIzWdSMy$>_hH?PO1re|d4=9i!pzN!LEuGQdlWQ!E4N^~j4 z2^$Sf82k?fC-@`&7K}0^p(;h6T484FwX7&EgI~}&ds0x+QLbNJ@01~0rs|j?^|r15 zhVO84FbQv9K_-`cAL(G>$Ign3LjpKz#Kc-(X$m+pM4v};;U~MVg@L}HW?;u1dQ~AG zi+LoCdqTe?!&odi(lhEs+&zpjjwtjF06RV`NL5Z1byJac0T^uy4#21u>gm`4;4Waf zJNDlJz#mtZ#azkUWjgJ%!f_dxp-kZ2_hL5^)<?U;dxU5eS!00!Y?T~AQN^7AY{^>N z8cRfm7eaGWW(Rtw!*4)4p|7_PF#wD_F!J%Lt2JbY`B6LWeWoeDsDqLXbhuKz>?7u6 zGU#5HN>Vn79<OE%bI7*gm+BYz9hu-@v!RZ%yh`yz+v&F8`F{@GYuhnf5py;sBfq$^ z5&|1+$4pp2+P6XIgRa`q-inJ}#uzS)al#-c&MC*Bat=El92)EGu1mU{+<6bTC1Cmf z33lsfCaz*wA^MhIQvvsPk28G8#JOrVWj+~zIYx_Bg369W%Ok0_R}eN!-<NVIZ(*iA zuGNX&!RTJFZk^w%{!cpjIyR_<w)%4IqK{tr_qFGH^BNf2p*jv$NBY6Q#@}vPU;{9- zNK7k%PnNAnOaqG%zNaf3z`cE4aFd364Zx-4F&E3D0oatH#f78X-#u)#-qgle*HE~E z2iv_mJT#&~;Y;p{Dtid2J0EUB*mSBHI1x9oIn&=C&fI6J+*v|wX4FoglY$D>0ocMC zQI*AXb476*_n7m=<v-JECVrU+=4kds&1>OEKuoLGd~3t+IPePuk4}sOz*D20l_fzQ z*qJon*|rRc&_MdnS6#o9Qrj~)JUqft^~hNx9)&T;n);~=v(7Y`ngp<m_;qn*kuE!n zra695HJ9kyE{#v^xU)TItJ_;8xUAid0M;~8*=*XH2<>#QCnb2ctx1fFm9r(gHypqU zBgqL?4k4OpNQ04%pL*BKQgfvoQk~wwn;Ynv+#_bk6YrFSBM#!ZQ5s36VnD}mcLn?n zqtMX6;Vv-f+${_23n>EtGY{+mj4Uu~{_X(a?pPFZ{DY6nORrt3-X)8mf#t88q5rM7 zAWT(nPjwFlO@8u731Cglv*4bk*8pE(N_(=$dS<%$Sgto^g0(is!-T3~QUyz<_juMY zg_#>cLM*4k4ZyaMJ5~jN3)?6V*o~;6ruKu=t*Lqq#h`%1w9@%STF;n#I2pn(Lc0?% zp=U-q>q@Gmfvum)rLMwW(RcY{NUAP2BqUZ2Ykm*y_&GG^axlB~i}*_eDA|Dk+mp{5 z<qdDO<>c*3Cq~|yeV3WgQf*X?9E_;M6<ZC=y9qtwcRD$@hh1r%;7d>2o6zQlYJM0N z*&)D#dzIrPYfYCS*rbaOS|X@A+A|W?J?_6*3Pg`51C1&eX*mMeom0g=os7DNrvrdX zstmwR0sCg)$U;i5ft5v4Ge7Bc8ele&Z@g=#28Itj+<lV(K3rOS^-}e&Bg8Zkxu&eL z>>eb|-iL5*U|`0XC1%Rf1r^<{12EXY+4*F3jV>y@*T*>r%)epF3^+l&Hr729xg`qt z3c=h#!cac2xl+>O{_~=&H`i8C+@dLibbhIOp|pSskOTuE_)q$Gj@4K&pyyDFH3{bz z^&6&tf!}eALY$i(Zm%wF3;;}<Ca|Et<BK($!OPXH_N<)diKUhKxtZyiX{4`+Ud_Q2 z!;W!)!onqnH&~A@Peh*)p@BBqa!PcYcf3LvHYE(p#C%`}V0XIRXWYXHkFwhQKp$8T znFChukyNmm&>;Xz5=K|S%Hs0<m@#1eEV>NUc2irk{k=207Wc7pAs^q*V?!TUng)-E zH)xlY8Qkq{eFF_#L;$mwFdV?H4lC5nPfiHcaiBLzGZ`EomXVKl0KjQM5DO+W0o-@P z0r+w>03)kODj22h?|z$i`iiCgzG)p=#Vx6R9e{1jnJUz9yi8tfikfH7%L;%cAr)5) zc81@vI^5$Zbt1&6c0!$D7R2(D(1u^9ETXJA-&<bTYykF^pN3y#RiS-}lSQP9fZqAJ zX$-gqd||EvxG<iHU;IEaX?A9~y{4i$48SHce!X|9*Xci`H$SU>ba8%W8l&nbk-0(+ z8a4qN;1F{Ml<77=N3y<yhAz!!uynDQi3|hoEaLUGW)>@5eJ>X`!fJ&bfbDeOLr==x zKYeSe*E-1A^`stPr-BtolnRCh=Iu)mMR}DvATAwD73>i#(Pd^OvLYkBW4mY`-M{%{ znc5jx?``#abn`<#!aZ%`7y;Y>09zrYbAfl!>5$aLTwnlLgp>wgS<oQ>4=4&P0QUpH ze+~_Nu(<H@rK(+Tbswo)<?-KBtS#*OcfHTs!#!3zPJcwhu~dJ@p-};VS>S34|85%C z?n!z#D5(S#`T2{3y%Qmw;!FqJJ_WHWh6aFbXq#$k17F6zcE=?E&w2oR=a(e?7I=pF zZ1{!ojPMoAXZgQ$ejR>UUNJW_+*VWFY?WAnf9Uks-4FA<d_{kLcKyig{0s{@P?W*S zYz(vIKx)=;!0jbZrMm7}zY2R$t^jo!fsCk-iGr1;tkMuI<J}h4`<FfCgIIJB?R5W| zPQvPtg*}Z{&P~@a?W=kY`t49I3^G&IM)L;v-8#E=KOVqR$R5DACwhl>u(A4Rh-nB@ z5)^s#_8fhxFQC6yDQo~nM}Gidy1=5-am~PrVR;2C00X^<VWE@31Gr5ZIK8snYN5jc z{JQ{fbQ78mjSraqTKWP>d6L>$OwrY*DGE&hqq)zDZ2auQJ18gplc`J-z99q)xAOzN z5z{B^9cvS*ELiqO0Iyg+-W+a=N=CJYRtCz8XhLtJOoM?dC4Lux2G%t}{{p^hXQ1;7 z{K9(1e+oYvey3nTqZ|qVuB~m=joGQVC&7I;{DlAeV19PpD1zYAW23lWx}$~!vSf-# z27aeClW~s0a$}!UKZZ~&ib17D@Oewk+2xd1_j+L$te6s%Blr~h!-0MIYuOm{y<L-x zK?8U$;;c}TH=^A@4OfV>r@iJpbrUI;5>=3tM@NsiHQm=2;?Z$WEm7`Ogi9llLB{A8 z9m$F1Lhdb-Fdhlu5Fb|H0=p0v$~Y9mVptjguCEILxV?>0=)D1aWe*?NM5(!3_qwam zzHX{#K$4ERLzzQ(5tc@BK`aX`vSvmm(Va|a2Vf!30w(f;Z9{r@Zipe?AsyD9^)m3R zapt9EWp!uK{QS+ns-osO+z(<{^nMw&RoaM3jpp+#@yp;dF5!1Pz%L-I_%9$nJ=|JT z(_xau0Q~E`%V^&_Qk2&?3ZNo+H99&11W(Zy$Ioeq7g`5%n4Q1@WR~-C`D?y>=Cx&! zs8p^!ziO98y5qf)G)gu!!`T{Y=Bjb*yY9_N+`YnNXO~`=0L;1#YZIZT<$h=A+#=q4 z5FuCz068&D1-naLaIgb&{XM&!U=LtxXRrgy*e7|IY!s%e(z@4O9Iubiz+nK6j6qkR z-8>S&p)68+Yfo=mc?iH($YCb*o*I~iaUpeaueTd@zvp{;T@*_pMeTztq*Onlwdbn& zNg;+kH{PV4;u99ice`VdzdhP(nm+6@04t(sy{lBg9B!{fqDiQ|w8iE?MSdentZ~OY zqJXfpm-H_RCK<RAK4y?YqRIn)*-a<~j1<lUQA7w0w^mnony7aG{<Yrb?pHifUeGiO zHH)Y>0Sp^}osGDqNrD$YA#n`B%6cgSrdkwUs7#?PjZa<eD5{O*(!9H*aZxO$=0svk zqwUwVptncb`<WGC^vMxgg=t{fYpQ2eU6oElwEHw;P5Fl~0Lw@7Uyla$=mY<#wrs2D zdSUw&XJ_nHex-y!n4Y=gb_&3(#PWo80jGOtFfdE72w-a_L=c*#l&Ghp2~8>h6mkH- z8Cl+h27tSQAl9BfuqQpZmrz^uo%Rp5GK9J~JHOV!!mO%~LOTGvW`;Wjl_b*@Lgl5P zqAUB+mTWBy^m|6E;C}EAvYZHDsT*wsO=!srIo%GxyS8C{prWu58hC4Mh1DC@1<dF( z^e@#gdId0Z3oS>)@8k?MFz_q?*Wni+f|eG5El(G|-rdo0uU|1#R@^c&kAT`V5lkz3 ze0&n%4M#9;)azhEn8O4O!3b0n5fp%31r@XRx~BU&v?SqpqZ)^^7fk_sq4+I7DfH#H zhdKu(h_P>e`Uay|#-0`c*g7ZnDp9cL>rNHyxGddTE1)6X)otcfuunlLk3{Kh0A?IN zB>3;;5hnuxqfFg1%6d8-R$|csM#-E5FnfUoV6+kfzl{Pg3ORNHxD$mOK@>Ww56tkr ztc_pCd^S*QPr9h0vcT#JvO$Hc<B%h!VKbHn4wI03y&u{2La(KG%?!Rh)-$xz0t`2y zSxZU!mtX*hiPAs;?*cG1aA6Bf2LM<pB!^$(V2)<AH=o(IK=dL24gVAP@%RObrU3KN z4iDfUefXb41#hjdt+L%@W3s8Fq+@b^0a@rN2#|0D1IBXFS!lu=HXSSk!<yj0YUp29 zQL%nzt0y<DhBhU}hOU5%`CcyaMWPm(sX0nTr?!4Qr)znj+qI;)Dk`g{Bzz6Q3`C1W z4Vy2i9__M#iBj)&Nf}4jTeru$`*&r6J%BBYWyLDAz!*C*rsX@^Z9DIU0IrY*CV)jq zsWJ}5upEF{^J)NQCqp&oiVDCSr6fY>)~=pN4UBf+usrbf%hB?{x>fG0UeI^USlZ(( z_4g<$L9d3YkV@D9%$SNZp{=&YSw(w@4cjYkL-YPZ0A3vI8IL%1I!4}-(oVRlzZKPu z1X&1uQIvDAIapQL2mn(AtHD=cAodBGMe4m@YC7N-*fI3bj21fwe$LJ=0Kiq19f1kG zx5*y4^(&K8^E({^-X%z=7N>@~n(Hb{OG?2eUshI}ms8d`wS?Y4nC(hp!H|{?W?mY( zVH(o9WgwVtut%_h(qtJ~MOh0zyEpOlg_QiFqWrx4{G!t8rmm5>)osn(-EnQLF3rps z4=d_otr80u3k9J=QIqc=s^<IqgMwI<;e-GT6steiC9L)aurt+Uhr8l1N3R<8D4WyW z=4^*uIt#W(0f2c}9dE8Xq(1o=O>*q`I}hMCpG9&2c6C_Nzyfe70BnIR4F;wK4FGG5 zJkm%#ZDrvmG`f-cQA+75v0^S7iCFlhZX`%72Vje3eb)=slrCVexIAkb#Z0L-X$N4r zI|?^hA}QK(Zd+U&TIC3aLwx-PVv4i7ZcyN~uTo77>o|}>QM<bjLhlJ+XyB%4s5nNi zS$3uB4dItwC4d1)%m5-DzeLU`$~PE+CVt0Z#?Ao1t<{xbKCr3$yS>epi*LVn@N$)# zSdPcrSXr1H?rv)UohWAMWu@J^asArWD_5>wx*8jwR?#=Jv`7FG!3JT6VEE<^!RV9X z98d+aEFvvd6xq=-p}*;mKlt9^FHfF2dE(^R3)gPMV+KV@MSXK;@95N`ueZdPE!QPo z`0CTIGSz~rw_^YX&aApZMI!QQBDe8w&uqK5Inm=Q_w@fkKZ9>(FaV2Ljt0~oK|vGW z^0iC@TSzD3gv@oe?aZ6)1~8Prk3zd3mOjWiUVFLV!8#EDW@@*-9xSCHLOUyjuA~A+ zE1>{P2N?ZiMyJD)_MHIkVLM^}ps$54jk#F5yB695*wtd){m9)3-7~%Ya~AG3Cm4Gm z9~c0p238!@2#jPF?O8n%?24<Ca|}ED<Q0Ul!pXVqb}Z_pGhhIQF=S;)Mh<ClcKgDe z4<H|S5?_RYIyms`7i5hDsj!e_W#$MWW*058@(tk^mlQBAref!&M>}dOy$>9=^>>tp zYso+RAAb7}9=(h<&-MP+=K6-VwgwD7EG@{+PD>#Hb;7M1vDYqNID7v5`Kt-pmHqPs zuw3s51j`Xdl?hdF7=q21KtZ(ggKw*gdLaIzH$OOh?D+97zC3g8(zV#wn+YiynK^~U z6}3%m9iS#|>h7Q2UhBH?_G3T#cRxB@D`m9->Uzer31B8?Bixd`?Atp%`|Z)L$a*^8 zQfO&l`-M?x&MP*IMwJYzxTOtErQkzZkzcvk*|M|rECgV)yERgiMKG*5!f<L8zJz&R zIMsJ{HXMK%!%`WCkzwruFh=vZUSI&Yo&%^IfK|u=0<4e*2CZx#s888W`0uS7>DuM= zUHLH6z*cq_o=CbkDY|omRz~_Jgf0Ux!&n$c$*_<L{;Wz|l^phN_O#dyXBG>R4=X9m zze0z$Lfzq)?S@e%b1FDQsmwjKv=}!}0N~vSCV-n@`fp%14y!kS-^Do=KMTK19kF<W z(Oy@6CB0|(C4vDS0C;hBIPihhXC8Un_IRJ`aeww3|Hc2~!K+XZ)oE8_64NpYa24g} z<mTk&=N9B;=VYg*CMU+l#9WPuPsyw4Usze3V=UYu*c@R>7elZD=1{-@F{`&1eO6fI zp>Xa5;Nirh?;if*)Y-F`JQ1IonqQcklaq}V^YaVAj9ZkGnvtAT*fP)*^UkB+`&WPV zPK{nQ9Sj0EsPlI+%E`|=im9moxYFMhq87DJAp^BFgjq|HRIsa!+%ra_6XI2{k9S6{ zc)P1{X9M&e0A?IoHDCa6@WIhNuN@EN0Bn@9HkL3Tv~!HIEWvVhltwZOFS)T1d0=W_ zPE`T}B>|jKE>=naxEK9oXy}h~{lGD&(st$lLIA$2wRaDDgfQ0NqMmmrfLU>G09Jjv zm*0E&zy`CxN3lc!KQ~$k%gKLfYsv>jp`E|x9PT^uuWk-h71d8{Y#V?v##-55*v<eh z8wY`4OSn$SYIeb+K>xBa2>@Q09qOp6h|s|Ia<)_d;{W)6`d2SzqFFHQ#JP*H={Y$C zrR+09H$J<3@oPzOZf<s3>aF<X%%b`c#MwwAfIzr(FtbTSF#n1OmI{{54=dUsSW$KM zRzaf4gdR)#?Bk<nFU7>)O3%!zud78fG5Y?&0#F66dJM$NNV*&!U((o~apLWV|Ks;Q zYSVK7PG}HuHk4Cz-%ZN9a|B+bF>UGA(&RLof_Z41?zO6J0@#8Wq>H)3`4nZ9a=~5& z+bz#bo5I@YuH8w9ZlIJ4tf-eQ%^;TVdo>Mw4~O2qBml5YMFN0bE0W`c)?m>PfU(D< zFs2I(03(KltGzW6z`X`wqtpQ-NBPx{({~lII{^Qh(W~Gwmxp@C6_TMbYe8rgazFz! zEUZc_<NK3m8w!F%c~O=iP%W;aSbXQ3^ZmVhmI0axO#ovj$V9EqRdbC(7TB&+w>eN< zSU-vGomDDe;FkcV11$Bc-Xn#tfM1qRTKXmezovml+W=r|sI(RD1;9Cf^BaHrPxhC7 z^UY}D^~-6w1tsN`_2}j07>IgQ);7Wv1BMIpbCMEMGs~JsmY{)kJF=jIgfNoP4#CO@ z6Tv|~Np7$%yno))MAq@cpI^L{oSsuy-Q3d5WpIEn*aHN)^;KLfCncq*p(X3$kzf7Q zk3Q+vb1*%}SuSh0tsiu^r+Lq3-M(<SziUi3)ks}o5nLGl(N+IQ2lKR`oZEPkJoiV` zH4JE>gpl)qmpY4cD+g$EY<AZ4NBd3#Fu&b3T)~7!7}^>pza@Z?2QI2WSD+hf1_09q zRx`ijbXN^DG_ZGp!vHJ|OaNmRLkTr-Z*O1k0Dg9KboC5$h!g8bW$mXQCq$vtVZV-C zbi(OdZo=*_pB@;H7tEldj3A!~7EQBj5_4VJ&hov(n$CO<z02F9ePM*M{ySAEt5ky3 z-4no8$l(DT=0fcT@L*+8{UmzuNL<c53}aZpv1wn!FChc8gz#&aRuWc?xE{cY66!47 z8-NRb{2TxEpS*sqZ=m8vY(555*3>n(clPv<H6D{(np-eu5>9bNVL@7IdS+SU7|KlM zrGin-X*$@IRjQ_AW(qP#Kdk&jnJ{)_pd3qXumkW{N4|(j%E~K&=x>472J@{AbG16V zyW87aYO7GNTTzf!l6dutqp$zXeV_IkfcaKc$PsXy{Cc%!%l(~FCo`4Tzc`W9OkL>! z%wwWtFe^_OF$+7PQ4R|?o&s8;+LAx~s<oc9;|I^=bB&FT>Ztvb5dbC^QzU@7i}#F) zafqRchI$X+z<~A&Sd`Enz=AXYT<>F8*a9o$=x?t8fZIX<?gW6Z3&3?bhu*&=+T!qQ zAMX1<CxE{h?;Tan4Pa7#2f21dD9jo)PC_(7rEr}X9l_3M@*b>(plAB6T64$c0#u$u zQ2<sU$Gri#y08HNM$rlItJp2^>+(m!ubO{d*p~%Rj9^*#%J54QdTzMAqN4rV0=V$L z|LQmX?GImg^rLsaNGS(F1E#rjfD5UotE&S5Zf${jtgEA1%*;&B27njWmX{C`SM)3l z!3e6U$ASn(*bTBr_+>O&2u3=X9ZM@p7ENS-dGy5fjH0rprg~K0H=q-yy`!y*#2t|N z%^2v@P?351`ImqB&Ihmm@F$-;0E4Y}4*-8RvF`yqly>y>cg|Iy6po>8)lk~6;zn}P z0>e`7*u16)j?V;};k!_K{`IHdx!Gj^wujhtY{E2f6aYK7E&BP~@wdAGEFDaeGF4(Z z3)%&t@fXz&z;&3Q1TpOa+-m?vAA|Y89gyb63w@yc%E4!^>>@MU$GEKzDE(*9!07cG zAk82V%#APrD~)6t*mCoH*LSp^Wj@O;a2BxC`qD^0H#*8zSP+W{77e+ITJP0_9)<}$ zw!Xcw%$Tj=7eOHSz|>_9zr?K5zl<Q^e**lfz7mihYp)IfY>`o3cRAe!_x-K^?)QKA zTmR?(;{Wqnd@VI@b7vQ~jsR|HMQaN>TIy;s5;{90JFBE&48)iV=tqLXYXzMutF+bz zLoobc-a2Z>SQu^jBnw58a8Vj~EaR&qU&rT`VlYfYJ-cU`TcCl#Knwu)cQ&^)wzgDX zefanO?!W%oC$HT1lg~|gZT{y5@KRrwH1J^Nv3EYaTr=wdtP*+)fU5gN2}C+j(Sy+Z zHu_mK`gBxW*~d3?H5cD{@jxQ)eyekr26ho!0hk_vBU6hop?ON(QM<d0B7iYc%M;o` zx$Xck+X$;2fI$uF0n9O^0x-liX8HiYX%4^;;{dQGGyLJcegE~_7q343?75zuXWwaH zi$dS+wB1n@`Da`h8j}j%HVv#iuq(x~+8X0bu+aZqgqstPzOQ6$av*vqy2A=S(@g?l z;e8~4gZ<xaLIc3kz~FiI`j_1c7JxSW8*V=vehFadU;Q$RqUjL;Sln8w1HESe|K0!o z2mki(?c4W%c;H4IFx%AJ(S-=42XIRhX(wx|tIG;9^KyzC#+Ggaz!p=(9SFd3%L4@S zw$$5zA3;V~AXaZ7Z*L;=#HSZhi{W3_)?pNsS<oHOz>xa=9T>yd(N%f+f8V$7Z@>8A zyZ7CH%mbKYB`~3_NXgPjwtaU$-O;w$19-kZ@xryjen;+ZsyC>|a${Vq0d+3~yVo67 z5zY11`f|^mh^b=YbgR2|rw<$kU>-&SSoWfE7P#2iw+3(>ToPZ0<;I$k%vTzi7Br?J z$p>aLKj=7E#?jPJ2N7D2xx($Oo$UZ{Sz4B9U>af=!-d&MXJA7Ay+=-e{OF@!?(*e* z6q<Ro@46LuMKkS{B^52!CO$JdqjD@!G+QBuE>5$x7BNS9BEIascRz?j`;)RcKVpsi z8~ruK#XevZIvmz{$eK8f+qR+upWpXiw)+%p4%ZYljjf~X$dr{YpQQdZgc2x${|g4H zo%o%cnO|6%1AxmrTrKpy`@r}8*8lv=r~cNyef$0<p|z)t8W^LU`+B-D8@2_tIZcRS z)znp0Ru|>w<(AfsEMd&2YO<Ns0*nL0fb1X>ibkuo0?d23f0l7GBc_s$z=R%6KXLqO zb{#Z3n8m>WV*rK=49}~-3jprwsr%xe?c4X;PbD3>|0kb@1DN%&VF0#d*>|fQ@IkC^ z=DHeMjPyn{hz`G&vjB^}Er(L0Jwn3HQZp}DacEcbu{P3J+b)A`v!{M{6j~8fABFZ! zFuMTk;;eU<Q3zrcqm(iP;2?<<0x%3IE2IQ~T@V^EYXX=_Bq(42xD5cVXzNoNi2&Ag z!UzBU-}xs$Km6LyesZFBmj;e3<hYAQ-0Po*vQB;Y?tx>8o%(|5QLE+<Ef)A848Tky z1pxL9g$B|+K2|YGYiiIoERK!H0bZ%Pba4M$2hJ4iFsCgU=uBvvo@=F877McqlijCn zbEKxQVQh6B{jO|Z5OW=wC)vAi@hfA`vG{XH|B@HWrC(>Df#*irsv-gGj@BLDY3@V+ z;NQIb(LV-&|2ny|hmk7*7&A<}+FIISQv<+oqsl9b3v=_!Yloc%rcuDQMw;{DwRKvU z2v$az0XRGadMrrhH78;(gt6oUkEWeG9aB+@;g(26;`AVV0v8w|EXaHTxM!g8%YTT0 zcqdZNJn@sy?97nl8)l6~p*>E19RRNk1*OnxlHwYy!3hVj4QOZSmup#%{w@O>Is(9) zP;DmO?ViS+(OaFUFaT>b;*KDeAL4aSnk@uirh!FB8O$Yw0+t3QfK>=h07L&G3(Tak z2XJRQ0bHJzRn{Q@_w;nNw?apkCw=zvgAcs%`g4Ez(=Ti@!mb^qly^LAd;a5a`p1v` z<i|gK`0W@WcztYC#O@@P4F|BFRb=F{cQT6HO7wez5{#{tsWA%?Ri1qIfxrI2eNTOw zHye3N1TY)Jpz6iNXoUb<8wOy*({4kI0InND_DPk8^c%@MiQl7?Z|s3z0(b#wq;C)4 zya)gAPc9w(0|5BP8Qlah%3(Pe)@k5YXke1HSC*HQ6c(1(4lb=NgVc^qjnuWYq=jGy zVd`MRwlZK6Ln!H>3Z{b(6PgEiFyrjGbOgMsYYAZT(@Fyqz%ZfP+uC}DT2K5V0Qh8m z!V8ZbHMc7qz&3a@#9bd|M%`Ui`7K)??Tswt;Bj%RvNYTjhc=0CVQB7L^p95^mJDfE z54|JcwbIkNv!5^ufR*%Q8cFj!Ozr#h<6ecFq4Vbf+y<5E>aYR;dq&wn0n-H*fa|G% zkq4Fw>;ar10Qb<3!arA+m*(f?-n#bw`w#u6zxguCa5LY`u%{xtE2xLl4?XdN|Mb1T z{K3QT-_&j|k4-E~x5Adiz$lx#%BYgL7upaTcXHRy*2n0pR%gal2)bEw`o;VH;y?a} zKmXA)pBL@W!Pe5xjHS3#1z=Ri2HipWteuBoeYB>iZfq3*h7GOIE&azk;a4e}F#QXt z03@R=0I+Xn2yOkHAF=R}KYa0G;=dArdk5fv0>Ds&05F4CG@*guYE;6PmXwrMv_JzR zjbyCUb{Ccq_6SCB+~VRwu+IoP-<}g!`S8OTmo8@%gB6~|KpY8xc`ZmdVu%NHe-{GM zeIxCs1>pX)Baa_t95*U}ZTy5}>RtD7_ZMtV_L)KDE{KFM03-ORX<G8RIjqb~vAvce zwq<|$TFQv^=DXW=l7NK)*g;<t0SI8ZUhBr<5~?4#+apex3Ed(9!~eBP4o}CSI%ubW z0~Z)yLG<EBy#U+}4U9^xwDi)pZceC1MSN{}QDJU&K~>*G_K8;>{Ifd)_`B{zfAZny z?!WIxKmPGg?tlD1YzIGPacok11CrO<tfXgXK(&-EJ`ix{-`(-{FK%OgLLDU=rC+}E zzz_Z!*Y|(=?D2w#yqMKug#%d9X$OFJo~8BCS^#*NCbaO&dPF*qrr;vVugrdS_+`>Y z1<1g!Oz8F~0KVJ47ryrIUQdtzeFHGi(}s>R0=Uxw7*Q+$xT>NO@U5t58Cpc0Hxz3a zf*FcthocW=8G=F6VGLfDO!98<Dn;f{&b0&pn4=o%>rgR*Y!v{^DLfqJ0du-<y#4e) z0f4{isy+Pt$#w%U-655ys@`1HO96nt1Ab9^);}25Bcv)i&b4x-l;p{^Ftls!3#-N1 zwVX^fMnKGlRx&vBMcdO|owGZ>ClbJRYB*a(02cAY4glZn5yu;fipv3D#IOiphOkg) zrLktX1Yjs&8!YN#SOPF3SSsUi0B$KuO)YL{!$D|os;?}}&rD5BN-G^5E;;(rPyhW7 zj`i-m4;RGZd?`xOyPdb)kFnj8bojYnKJ>_APd)L}qmMrKahxje<|n4DCK@kAwa_ev zRwb4+u!}9-%X03HwwGq5e{Yu_fBxt9-T#aG@#DUqzxa7hSYk{@6e~Hj5h8ZC2uPR) zj<OE~aP9E&I!XoE{mTrD_^(XCg_lnT_*L%Ll%U~v7TmKV?G@$ifd-a;b@%X2$!m|k zmK*!OMFMzWptrjd8o0d`c_je2rmCW%q`0i2mKu0<K{eWne)ATUOp1bF)^sqAuA(ft z!LXy(7+xGIh)YZ_F#y+NEN!EL(1>9T4D=1a2bKl~fPee*mb$MGoUl?#@bvHKM&eA9 zJtM<+JMVOBq|g8WhzLnUK~(tn<)MC&%Ie(dNRYV4T40!dbP!ga)5+kyKGk+!^oJp0 zj^N%l#=H7<&J@}KVA6J4Kk%Iayf;1^fDy$C01Q?;5!xvWyaT}SUuZ)Uz(^yZio*f8 zudO&KF~6e5+@=Dww4|mbr`PuMCLehEhkx?@V^$Uyc6k8%;^TXG@eyBgyFKCH3y(kX z{Hy!ldGDP!Uw;0TgK?7B^J7z-z>Zv!?<ZU~o5+Qs)sc4Zw%69my!_vl($AlJ@PS94 zd-?VKuf6#AFCTjGSXNJ%9j=;7Io|3<^67vuPddu;ZI0Cz)D5FqiU0<FrME;rxeLGS zAy5FACTxITpdC?Y_`nsV0f3cgxrdk8vj3^0*;feQpJopXIt?rUceN707KRpp%WLXd zM;F%!V32ZHewrC!<&q*0ES@d|qg9d>a)S}ZS|xyo3sd7$iz)!%Y5<rTSPGZ`9-tN9 z(Kpgz0B)+f_Q5#|;D)smT0gMwA-IQ!jQ%CJLHBB%(CjxNFQug|RKF(^+Bg~TuQZ|c zI-`nwpK*6%l0x+y&P7{A-_uTB*$4oKYN6Rs_}w({7)<DLj0+VVhb-vGUczcAU}<2L zaS*;C04oR$6S}jfxhNqny|}!zsHh0T=t|0~QHa+yG}j*c#xKA3$KU(J%%N}q2iybv z%X?9Y5#PSra`Vt@ufFl|XQ$4bJ#*&EqX+iCedJavPs!Z))RO93tvlBm`dNx)Dwxvy zo=&)y+gzFzerHO)eB+f@-aT>(?R95QeRkl@*Wdd*Eo?ZqjunrZ^1vRz{;XNk;jRk+ zF06(IUR@FSBt1tC4c&=fg4gV4vrz;4S!`4bs|(|u)gcWWX~gY)$m>r$c`WS`ec+#F z_W{5d8j2`1!qAFB(+NgEvl@Ni#W2w7TE`dB-$f=_SnjwF$q;o$MIzX4kyTk#!wf}R zAZuAB^k_+1LOKA97#4kCgt}c82@87wp96sZ;b#pMSB~AX)T6qk%|8qQ*q9W)lM9UR z8t)o*Yyqr*C9N#ZhC)~3s3(F=;EM&3Mq*Tv=x)JBJa?<$Wl%uu`c8GiSr}UGfJp6N zwy9~$k{1y^@ZIE;1F*F+1THWYFnd$H0`>s5AT%s(sNe=`MQX)vqnx!N??!BDk?5mq zo4ZD4SJAwQwY#pp{NVTh^skRLM+30c`YWGzFG?fqBUYN?k01Q_i;Fi>vkHof^Rkj+ zPJe#nL}Dui>+I;*0$%#oI(mY^I?h^X@hR~DSQz@A7u&=PZGQ1|$<-rAK0AFiIlG{= zv^YEY#`!Nl`RrU)XCPj=9jFwsD729q`Kol=tY}dXYT)V-0GQ*1f&i9G)G+%w3VuN* z>mx;=fM1wkC6+UxwfpySv>VU9`dRt~`oJLo14hUr0l*lyAq`wx4FH#v*EDpE&%=bq zO#+z_2;ON$djylOnv}C_OhQl63IV)5TAPxPUJOPT#IT$ORuEbm7)C%lH1HV#xVG%_ z*?13NmqrqvoR$lY!aZ+g`1zac9I&)GCp#N}HCUAO0>mycEE*=MV2e}jfg{^jQezn) z-3{88FGOpA@c_2!EjeDQREY$zJ2Q7fFaG^r0gP;tMx9XsBM6Ns7NUqM!xDhoYxCk0 zOIo`J2FIqC!e(F(Cw%b2!w)=lru7a0)*HHqTMd25Mn}&1lV@X6^GYzp5>si*N((dN zuUxpA*@nFQ_Uy>$91?M`qDhD5ni(WzMY3@3?$g%7wEW-6+Qf@zW0G@<%BrfcTt!(? zUTWO=bFsyPA<D8~E3Ba(9pN@n+(IBxA8&JlCiE)8yT|}r0NT$U+)@4<u75cj!Qq#j z9nioNT~+0+mgq8<jDNVBmC<$P%}-M=hXWXCq}>3nsv>}!ddI=nzGN=?G#PHy$REWI zR#_!=u-VYeC8?Zp1#fD5q9HjU4MPqI;5tR2+bj*d6Tru6OD>&>H<0OkqZSi&9Owt# z3E*#aZ2T9`_V!s63)zaTEhBcfY;5quh)l&#MK+*l^4C7W5`;Setla<BY@ZE)*m1dT zH-ozvpg0`K1K1I}yAyNwbO``lR9**p7!cZd7uacF#-L$BI{>qjfiWz+e{2A2X$0W* zmb(0`iro}^-z)&tKq|l0+`4%B#QFT)%?z3@%Hw_KvZ!b~bh|(Q<`u+4@`_5z%1TPg zk*h4q%S^c$pOD|qH#R>yGQG?>=bYGyFti1+0u%aPH+^GaT4!jwDedNsTd8QGK}A{_ zmMkkN%1uv*i%lvwc0=u?CPlI)&OB~6{n+W>r~uxYs4u7<M$NYLFDnoYzv1OqAfR;d zXXgMr5-KS}hOuZuch!0TOQ`QHGQysG{Pa6VQZL>Cz^de^27pUTYg&3I8HHYez_6|( z#nM>MK@A*XMVqG%7|$Alp@li+i2&Z5G5}Yj6zeVkt}eOob+*NS5W`|%foxT5=njoW z;yb<j`Hr^PU@@JN=mmf`9e}L@IxwLv4-8rzD{<Z<DClxo1h9`{c}EzZzBUz^uL`>r zCuy0fuz>*N#BxLsUWwnMQX8)?E`ks23n}FSyP*s$<FFXC1)&+%5`d8fCVm}&fnPLq zRuz};Y8m7mFOT&1_6*GIdXM`s8_A{<ehZV<K4q!9Bsn%VAtk2}6XP{r8i*=F;4I-* zT2cEfzhZc3V*WN>Dk8kr(C@;~DyDRRyW8e3PfzFwO*ZBy#okQLLDQY4R%1D=my?!o z^JZ36e~?jB5K9E1T2B3>!jn!)@JrZ>*qo>@tQ!FJ54bL@1u07Tq|YCjb4eH2g1m;` zIpn$F0|UU}ywLYze@&i#`<?+@-O@jfNCGslrFi88<7U~=zXQReQ!43DK?gZHFkV7! z4J+_AHpd%MLI9=$*i!?C1DLbF)X;A#*y^DJt0oYQ-@=C581J<b%18iX4KtxN=E==x zpqji(qQo??ZMWT^xiKqay&6Isez}97=!lI#W-YV<n9r#C0sDl#47VMhI9^{+R8eC= zXw_jkIvp#z0++i7u+?FS&~68SQ9{$wR8>;9Gh!Z1_yvE*>4c;_a1KVa*T2V>%y$*1 z#l+rB%PuG?E%k^hD=p5?N{)|r2woi<f)XYRhc#%EYtY$5CfL?M@Dy(9@4DBGh4FDc z&{%z5LTp@eW<gPT2*9PKg;{Cwakp}+di_&xqbDsKz;~bHLle4saA|#co~lat758&^ z`Ljxnef(+%et{7V7+aX=fC(L9rM$PTA2@v%6FShqC8gCZeUkvNxCV3)!8T~kAvmb$ zz|3MR%7UGbz9f~0vQa}Cc%nW9fzEr=z?aUX*qhbxz7T*7Cii-}_c(%R4wY>Sp$iih zC(&Eb-USwsDf?eU%dt1RyJWM}sZzlPU`ERE4_gaEQKl1`_HZ7vENCoFr<;{n-vz)3 zq!g72zyYJI$~c0_-Ui@mDqy<6;Q$7s0-J#e;QET<ZwX+dee)rgdzYWHt@&xOv2iI` z`GrMgpk$#+gn<vGSdf*Ra4RLRp62?-RDb{2>?#=cIVVqzV&bWC8hB&6zrAbNDyO4f ztJC9C>{Hq9FV9HCY8ko3C0IwR;kU91td<%ddo#VHJwWglcS4+4#vfpvGY(HtB1@Z- zwS`sv3oMWzGHmvd4et&we|EGwPXCgK($p{UJ2$@sAGo8cbf*TsqwwTEHlBUyUV>Ov z7R2g<3B5$KT_!ZVU?EsaSTtE7E1I->MzljuT_!Z!`=x<LYm?%A5X<|(dk3)`34{Q= zN>V!`%lGQZp77q!P52vG8tT<NOP5Eo@q{epa3L%vldN{n5PSzG*!jSMt_QFs^42E% zA_mV#ZiyAj(}cFxIh$eb+=PJm=^h>t04^qgjZVi|(5{<bY&szg3>6G)vlXnVt^uut zybQoCE%oIE)w_u6?sSSc;5!81Fnj+lTQXCb8h0}`J|(9B&Tkp~bjTFi_7&x&B?Xz# z!6_+)gIsueuxDsuc6E&%TO6yR-M~*RwK&*RS<^NVg%?@(yg5HMI?J!yY)+3)j01k* zZiBvwVF4~zg$frWyHgWx#3y7n`sd~p0gFOI7rR3Ea9e0+EDIXAuyPOp1~f<?JI?H? z$1lgHgvzfh0nG6X;rOMC2`66w4s|2l8=q4B*H3(ra@RBx^1$@4>Uv~Cvl5HhAx5GV z#+qRkn4L+x5zO8sa(js?Xkl>)0Nx%hN{-(<jnu9@a9A3tS9@XObCF|Fp|E!`?<vy0 z=lMe>*xJkJx%&B{t`1tYIMx&DI3Uy$yvJt|+w_qm0Biw7Oc&i{LHkd^$R+nAHc3Qs zpF_-%DskcIh|I+uK!IE&0qpp&WI;EE3MqF0xWTG8>S1mRz^wpqI~*DCD3#?`MsIoF z<H-SFMTFH}e~<n;K58`o+PT=+TWLA4Xe(IIgT@MuS|h5;iwknn6XN4yGPLze!(E;I z6N{@Z5<&3Fz@gk;?5!)SY>h$_tGivE7#@<>zEK-<_DbBXG{mn;!M-Lc5-bNXR#$__ zcXoPG{EaI&g9j&vu?Mhg2zOy<m)eQk2Wa5@>VY{hx}(aN_+@<)ho^Y<E8qU>;#bB* z>69-CFrX1R(=()jO{gm>csJEl|MBBTGNTuAFb~XWl~%}6TwGey&@qmJG5G3=e@7sg z&4mGiU26k$u*`n>>qPLvqBQVeVe&02<ZyXl-%S{$kR#^(*bsnM9j{q%y6?SIIPCa^ zUdi@E?~v&1G*TKiw9!%0-J<e!gNkTElkJ(jNqb?~02~TpnFTE+Ff-7<lhxhbj2r-i zJQmmdMUzoBAJ`%%7OVERzxQ^I)j0se31%6G0BnVnV&hN{T4fx#0APH92XIp>AdHIu zZYaqs|8@Yj0dUR-zSp$;K<4SszrK-}mQ_$vS%s!>ae3)#uCJ>qD=*4ROO88pI^CL+ zMmt+NhGv!#%~G^m%vDC}zB=C7)Yd;2mhTE}^!f~Rx4B5wXAYmZaVtGLuLRNp(<spQ zZWqFQRaNESKTl3L^VO9SA7fYN49zc6`1p86P<Fj@6E-L7@~iq50APfldEQwYVfa<; zMo_*%YIl`L(|%>g5^Yn}UBU-m4F|A`poF`Kdu)CEtB=2yeJxrkCHjFQODRjs0N~pI zFnfJz7qd=-*<cGs2MCTR$_nGUBZ8Np@HPkY6XID)iFO9%fuodCcDYKdn$sVgGyt1f z<2Y9>5p4T;_j1uabO%NBaPNd0<ssY5H}cCF6)h5*8H8Y~Z{B-3=L5Sav=v43>@1D; z@0bQ3+>T34L;#rU+6;4@Q*XK1?%hcmgOP(8xZag<*ko@|ocTh^2msT9h5};W1IMbg z0>5CilLiKWqfcVn<1HeH<<fdo!T0FPv?qV|;jznbNb}3et5iPL+J-u?c2vb9s99T6 zR$h{qnRw~g@uYSs+UcH_mad_h#Wg>_BM@n;GZRxR_t<r9!1V4N6M@8L_38IMJd>K0 zlV1W`oktFZ-nd$^8u%)zz}lFXnSAYwqi6Dc0A8cGtohszlefbb&D-9bY{-WXybNHt z9-m138mMVF({eWaB0D1$Y}9ekZpe~J1H18}qEggpyNmEHdhPqKrN-?5uy1DY09G?Y zaan0i>nOalWu<{_AfaW0Y1n%NhZSY9L`!UyhIcY<F4BbV&AEzZ2F&JRGlQ>%j@Ha@ zyuI#|w@+A;w*YJr9^uJ_p@VMEZ{r6C?*!8s28>ZwwUohdLbZ{jkDO6x;#U)rw10On zYSdIHE$j_x-u6_qK^_K2gQp%v#O@4!TM4}ce+a<$lAtjSO#F(|-2faG!}0(|kuzSq z6;i@shAJX}X+b*x=azjt04paz^F!M4u7ZYN&=z;-m3K}gXTW|YqMDji#wkqE4{xll zDX)MTee?K%V{uKYl3E-@vZ7NtrJYhNY5;3>cCfR(Pv-MCtK}zOdF8YCtlT2TaU?DL zYUn+Ofmu~qhSd^Jd~o2)9J$@NR2FBWRmAJ>EZV4L6`ND_1r-Ae%k(W76k=^+<n#qn zUqrSKTJVZ>(}XVpyc`Z-qi1q~75`47%J2MF{^-T?H}23*sBR>-6BgrTH;=9Wz~Zb9 z5Ue<~d~^80s;b<X5C+qoA$W0q={Amef6kR_nZ*?~u;ywlhz0q}ZU#`9Mzj-t)suDj z$&)<>VDk_)v`8T(KB9ZVyZH%G1ho6B<$)ffA?6Tq1(L`|Ngx>=v7=FQxxhO(dAbEF z*D(O=?#QCn?dmlnZo<CYQ9T$#3@0F~3x-sBqH=+oXV&w*_?D)D!vP$)z$&CP0HZ$A z*mPJ2UEk1RE-)D>=>kgw=YC5KEE|)L9rkwaxFH*jSKfR2nUAjI=H(ZamDkjwk`_hS z;6d#Gg&r`BNLoz|s-z0j&wTjy;cFIC+ZgX|ZbGZ;$kdXCOyB8RU!3gk>gaZc&s@Qm zFFpLm>5M#Nn=7ko>szo0*22|^)!Knz$P0A4=Uw{vwKtAs_SmPR`pZqyQ_fQK0fwpF z*XCqnK~?{p0a)=X8lj?oM(LHNAIW&O__Mj6aw`qLQo*b=o9L`4ZFZ$a76OsV2y^+O zEMD;FAN=)&qXh7eGQ`Lcy`jGxxwFE8iso@>;3c}VW<K*y%t#JHaCljz*edC;tJ(y& zNew)Zap7`iX%&JAuA!gqSJa07nuIr>IBo#uybA@DY&L`8M1KA~o$tLie5$8kRkBjS z0<c<<s0h`Did2Fcf~`Vh@1^(|$RUL^Fl(oo1?laH>H*t*n;Mn^wnhrf)?qEQ2`N6J z1y3S&F*-UF#Hy{gxr9Lsi?z_!iiE<!fDemPk>moSjuHyk1DJd)(Exl$IPOyosvHcn zP;}klTjtA8zxL=ae|0pWsHmj0tfry4iHyQsf)u29dpkOsYil^fsVL@?{jYs^rf^gr zxiHb!iSD@ezR}rb@OAIf#J2F(>g)&x!gTeGy5hIN)WgsG^0D`0uvmFT1uI?9HWRGY z2{XE>zNWmaqP#5b`0LNTbR?nG8j&eW)!D+s78KP)^%B;nnu@A>=av^{X665KZVK^> z@N+Qy$iS=8L?6GhIVNh>g9=_;U799<6*TvioBX3C=<KaV327BS^w0m~;QOT1xi6`G z4@w=>?UYxR=3@j|<0yRKRjPc>dvT>C5eQa)e`Je4We?>JL(wbrfd|sgUW^AL2Q<59 z<md<hEJ~drqty8#E%vELj`!;3HyPpqTRzK`RSaw0Nd9R9fPPDDygAw(&=3>Atb}&O zl(eBCG5kPcb-&zE7mC%+O<GXW38vr3K;$UP;CMTCQIwP_#8UQ3eBunHIoFH$-m!~& zfMXm0uGj%!659E(ggCv3VHu$v=XyH;H;IxGK`dxs0Jw<&-bLJar(h_2V6ULKBf&oG z1>)J_FJ5@)!H4&s%>YG2S!Go{LM`pUuUWN3aBC|dg;;cXdE%GvzxwjqCo)_${PNsL zAH2G@&c4Bs(aD(w)a5zm65Iis`DUlbM_|IWcMnc2yF2N+@&4oY|Mc0<k|Dn;aNhW& zTn)kkt3eq9!59Wsfz{H^zW@BwFMf2rK`MXUCN*0)(UppdVJqwj-5)oH>I*CTQ0D-` zbi=RoFH@_geogs`sD`mC_6G<)PW@5?lQeg-v)TjLR}x^e!vGvDCSCl{Kl;N*UidrI z!12u>wR4<UBDKS&S~p=$b!BxyZe}*P_twZiPm$r&Dr0HRMVA$gyEHR8MABjUSqgi8 z5dhvE$~<%KX0Eg45at%8PS<WyyWe^y?b9b73h_d#)egBi`Xxr9uUvvgSa}(>`}N-C zZx#mzlncfOg4M{4MFMsO-z5%n2{f=3jzkBLlO%KoWkO@u@u9b;hAfV<$7MnY-$4MY z-D(MOK1*HEaC1>eU)mlB;wT?CR##jY2H>EVFcQG(C4?X701Qf5j3Z?pm_cZ-fp;^n z-l1BNK`creOL{~c@MwqqcFl>WfBcgNpN0ipiIKIe-X@!^5JgZ4!3YlH$W_&(pZj?K z3(vgvX@+aM-&$Lk9_{UH!>t0P;BOhiH9R~rGBP|oGz1nPbi%ZC4vfzS-9^3E-u&ec zfAsU$Pi3PYr=q;77Bn+ER%>r-KwoQRc~$oHL$5vY#IqmAchITYq6XGslPonmTF<!a z<u4Baz`fwJBY+LPybye*KK8no#wudZNWR+CqyWF1VKNU2%+<;6s<P&3og}_ar=P3@ ze@~;P?4jTNM-Tk_-`cnDH+~*d1N`owl|{1|oF%Briu{a>EO76wZQWiX@4yZOGZt+X zpuRzvet;FCjH)Kuh8Hr3^-W*anbWb^WhjN_Suy~_dg|)#4bjSe^)L4A`)^<R<fDfk zbUbQk3uTg2WlF{+9z3EB&bLOc|AwhPb5hlYqGYVK1B>F-EoeUQoiwlqum#8Q<$UW~ z^TQ+2>k`$A<R&`EVdlt8I{9FpkO?gSTQtmeG+g&bL&kV@Api_SqL4CtDpF`La78ee zP-Htap&chQ^1#X>!GvxsDcG%n?_?397TVvb>Y;<Ljh@7uNqgf*e{tVqFCU4?S2<J- zau6*9uDkFD*aA?&1aRJ^Pu_j;vBzFJT^Y<r-@d&xH9E|8S8#^3l206%Z9`NU+O)f; ze{dLOTcNYCkpJ<|zyJN8JoL_m>{_f=2@9GEIAS%J?6z7#?6J3=e)OT2zbvQIv$bx# zq{g8bDrvO`j5uz~{fz~cJz!s*mGdixDTiNaVOO|;c&}p5DnxefFBv@eW1eLrGXQX- zq^HyQmWs4@y4L|OdGL3C=g)uk|NN)F^QUjdSD~wn01k-VG437Wxei&wvf|A2l#IfL z3Glwa2e!cxGK-N7mTd83UW8!l5cZt!qtwepIBK>L#M&IlIs5h1tfI0y<k9QNCGSYF z#7fy=#O@b<@jv{nfA#p$cOLqs0eE}UGCQ8uOm3s3qF(2{gn7atzCAP8J80pnt<m8b zE61W1r1^>w5LCfNMl3UmVQ5`<$Ro*f(F`qxta)22V?*WuV<cW@pJc1Q4Dj?Cc{otV z3D>}Ap)J=PvfRutjqEGijbQX>78b&zL|m%Ly7^UVWOO>BgvMxZKUfqNGy%*h!m^;P z8Q1_^R`4x@ST-y$Na=;CsHk!#;g!Goi(fqT+R-=xxT+Rou@F-tZfQZ=A6gp#sj8Z~ zyepp_c=?G3pE{fq5g3OzwKy{|HZ(Yh!hwFf28Kq)C+Fr@HX;uCP~6Mk|Brw5z|-$v zEFggKkxj7IcdRA=S5;LN#h-Zh`Ntl7?z5s9?vjcEtPBq>4hp|477^v4mio&JDtcxX zP?pVkVd407mNQ~ous|{Lz)GN81{mbCXw%~i2WsHe)v504vIYlW?{({7-pPe2eeiew z;rE|9@JY<+)2St_h|y>j5Q?H5m}FG|a6?^VMJW>N$>{(vhbU43Q|~Jitc;d8?0`_t zY7&)~*eW%(0pknl6*vUXgKThPAnWX@tEmMgrFFIVY>ZX`faL^ZGDA;W6C_4mb=HaJ zo_hTKBOm<ymtS=2&@-;jG9^PW)1*!%n#8)7OiKtp8!Z`EFI`F~SK@ws+(=AG3oRNu z)4-g@#<B3mP$m1x+0fyVARLkgU>Wy1Mz^PjjmvJL{MPxeucWu^(#ED@*=?g~)*+c8 zH^I`t^nvsv^oUWU@%9KbFaXRLmS^J#E8`$oY_6Gt&;oFM2*7fIc{Mkd7gm0|G}5~D zyemknv*zr~=ru$u>HB~9R}Vh>`WFOn`Cb49q*(7*aQ(9buRi(9r#{Y994q3n)j@6i zM~=EIiWSxy^WtCr`S*YJ^!rx`VALJ#1z@fQ0KfO*6A%6Bgz0;WXo`m1SJeb%2a!s6 zp{u;Gx(^+J({LX(dC-OrniFj4BjGo!{7OBx9KbS<Ul$1A_0_4K>e3n=$v_~Qyl{IT zRS6gU?6?2PeTOp^zv)Z3k(tjpJLpBh3JnXT1(F%|EhIVyexq+PDYd9+LMAkgc0;h( z_lRJXRXUEHNCf+WZen|8etGkojlryQr>~-ktgNiwW+OodC^y&L-QC*E0Axu;etJ>T z)zin{yZ>hfV3M1uzMS|qsxgArEKH4N4i3!St?8|%i|;-E<g>4Qnku@U+oNNeNlQVC z(asLP^nqO%+6xTT4DR*uc68~`0>nB2^CM$&#wN3lz53MS&%A%BCStA@Kgu0^y1>@( zOsicb`{JU8uP>@gk;(^VbhJD004AlZC#2jBVD%CjfGvvz4XjE^ynVR9Fh!dxi>jr7 z?sx?uhwX3np-)J~jj|@JKSSa5JwBlP@clo0@afl%I1P;IZKr`1RFZO36bm}Brr^q_ z@BQkrN1pq<ki}tiGw!~(5z9`d?EmqffB&aXzH1t|LK@f%_CVjan!c~9Du_M)?h8*m z`pUUR9R@}-8Ny=iy%`v`S;`(nJm6w`X?|tT6adWfD+@o9`ih+bMqNkvimcMuvRHaW z{K|OdI5bQ@KniiTr>eL{8kpxgNF<?I)_IH3&R)U&zxj`U@>vtKMAC(ex3cn!OR7Ol z+R=^zDb$N1hSl6qU0sX_R>I9&DTPhw?7##GqE}|L)4>ug9>JDdGRA1CVVj1^3U5fG zS+ss__GO(veJLq3x1hMBvY{D=si6TYH8oKIG**@6=VYhfN-Aq^&Aod3&HL^@8faj1 z5Jgnv+uaSp6#d@1iKd<SO2YrX^~!7a|KR(7egD%3lO^zG1|1DCq`F#x8NxC$QxF(9 z4J<?P&NO;Fx@uj~30Ryo+S=)?!%zJ9`+xP<zj*arZ3KettEq!+Caqb})=%h$dN}XP zluHP~&HxWPtlJ~1g%&4tG!5)5XvMI|#=%4|{beMP0AE&O0l*yqaCKSTJv1|f($fHN z7;~e!1yNlZj4I>(mL2$;zxvrzFCD&|T`sQ_Wh7x<Dd2@57K~cf>DA<1KJ?BDPdt0z zhA4K(`nz$5a9R|Jal7W^(|_~5A3ePPocX}j;81MsK%Clz%!1X>;82lu{gbzzd+_Ja zoNj>FT>;)e!APgd%rB=gWDq$4<&V@#M@f1`7ce<7KC%<PRw5z&>lB^<EZysBuoeJd zWDnO@XL_oOt5gf7>Yl(WVY|D9J8j=19yII6|F_@$;U`r{c-;K@{MDQ3ERLx}q91`d zNNN;XRFoFw=VYcPvvVXLCiK>Zxc8zW*jg<D1Y0;-U6Bf^<KJeN)-W^(CiI1yN$Ht6 zz;IPvRSjNk1xYHwy;TMp;;iJWH{y#rLAUbBOMmlI$D;-fEIc{K#KMAhzUk=Wzi<!5 zJ>-t?tv&f#%eA*21b)B&H}^kzC`|~S9-Zb9(Ifztafr&4Bk_=54{;GI6?_L3?0i~# z!&@tpV=|eia*jUr<G=XcU;d{b{POklmDX&cO`;T+6`}AM6VNM~A%bV5kW%K^SCF_s zq*HEDO=uKyl-I(qr3<WHU{pc}g_J=ONwv`)z{mo_M?xKz0L-z_ZB3P>b<yZUqM(B& z%QsE~E0g4mXDQ)81^e^1xi~U3wYoJL_vF9*PrrEV*#l?OnMM+ah~mP+lx23>+bjxQ zm3I2WS6_G;ljmp?pvg~Y`c~nN`J&IC`^k?Uc;#dUjuxWO^{k={TaABY%$q$>DHlF^ z^_d6%=DxSmM^~1{hla@i#s*|})WYfxxO-tQWTi7Ft*jSg3?|1oBaHgjQ$HJiWjebS zT-85A`x$=GrDynEybS>NRu@*8vk*GmF8Cqc5IQ@d)zg0b_y6(t-pPPwXv|8<&d+DN zb7^r&QE_2GVR2z`enD<ZazgyA8&@u!zn++1?*L5aTT@f0gN?XOI@r}@Suol--(5yY zelVFsHojTyOgZ`a*B7tG#@$Lt$;imgDFE|-UT%J2VKEbfm1PA*g)m9R+f$Ce_4Hr= z=wO2$i2z17(~`_fzElO3M5RuP#;X4JfLFwxFV<at=h6Eg`1ykm{o>I_o;{i_kvB6j zYXw<ygJnc>B%X#^!bG&RtjaXh)3B!*9f~#Go|}{=8&3P=g`eMl|NRf#_v8B?e*JVA zjllrIzU-1pm_=YV1V}ZwEFe%wn?|$??%Mjnw}*pj8x!&{IRgq<bG?aQjP{ng)mY$A z78oS6feTCkw?+WCxwfQo7i~@y^x7-Hy`hl9I62(i%DPm%FY?-$9q8#FAFKWRr+@zF zYcId>#)(^nAkslxxN&zLxTP6+U}TvRK7aew{YP%p&hn#>hH%c4ORhzgDLemiw(Rt) zzkJ}SPZLPOfwHfit92^mT~$$9Qj~DwgZ*#5{OHeqb+uz*eyk4wW>o-IH6K{jSmvrZ zMd){8xidGZup5Y+27n3PkOA!#8hB|8zzjjFsF)V4eh9z|E350b=liP)Oap(T6ltLJ zZ9N+ByPkPH>&bulFMs-8B1PQ%<S<fcorpy?)Kry$+9WeQ^;Z0i>sK$GJ$>@Ti4*7J zvg$^W2focTk_a@3V9;251S3%tj$lhDMId-~c5!Wcq4n11hmW2-eg6FUi<hs)#K$Kl zp(?hptfHm?k*vPH;jz(4;C#D3_4vEbKJd_I24H28K#b=nPI(P1pUZc7-NV+-Ra|)I zsYf4w?$y^`eeGAzKmW>SDJ&D%o*A39!uL=wlG)JWl2==|cY*G3a6(y>jYZ>8>q|KN z++z<t^2D>xKK0nc4?X(YiM(*a8WnCST*VC5Dt&J7r@DzQLGn?dZFg#-$3d|WgIEE8 zO#!o)p8!S>n)ETgj3W}jz;8$ccXYJY73J1WMR~-@Rt#CG8`#x(yN~_#3Mwkh7qsl` zl5#5(gG1vZ73bbMa5?eo_uu$5CMUlrAEnTZO{{IiI9q4d!UI+%7Wx^k9DM78FH<b` zhmE0FgDACpz`ZKs<+_V+KlbE%7Yk5|rAn-}P9&RcwJxmO)(8cRO8<h~>tB3)<ZR5P z&rW9cEw9c_On?bQEaBWArx8O2bfgB(OU&v<nbP#c81xlDfFFqGLaD)0=5L%XBnw(< zcafD)_+@bsze4%afL^`5wZ70_=`=7{(0v}!KPc5k6xFd^_vN!szjL}kGEQ=CeRX+m za%7;hsiCH{AU!!g?)s&RXHK6ydFs@Kn6&EAHAJDwYG(-M6%<wa7Jn<Nq#LY+k|J`- z2_u^{zqqzJ-xmMH(J#+j#C7R%Oe|Wd3(BjT+qwtFrr7iuyqf9aYbOrB^O3a^ZlOIy z<f1C|XTNM9q<FkdG?{+dQ$O-cM$68>`@##azJKWR&p-d{@Vl?Ry#F(e@ZFez6^(D^ zEDunqfnreb<v=!TNODY==HNxgu%g9wZ7j~}*md9h=%p84dHcYTW1k;AeBjMje)Yx| zSwo@krdZ|KP#p&~u-VY;=%?#t2gj-{Ltb!%9QF%t4b|jh_#6_!)WFVyX2-fs_70<j zb}le_4iUm?#P}Smg+>HRhq^u|A+@Y?aA<UD-Z*#dnkhQ>=?Cu|N!UFb$uaNBO>}WA zx-_zgBHq*Og}K?Op0b?k@u@nnyPir;&&fqCH2hNB1iVpHLbDVa<zQ&IC<nb=!l@5F z{yMAMWCmhoF8ra=3di<pw(K1@eXZ&GyU)G#Wnx}YDHJ}vV639bYc8j{O*9ndW~N>E z@>D|YP=8Zn|HAE65Xk7LISM_OvJ7oR_>-;l<i}=pO`{Z=Mkot4WS?@}!ooaeeUr3( zVF4S9pS0<gajNtu(4Vnof;C_3IQRf?ezoK~3VRe9@jBQY?%nSc<h!+*X@#|eJCEcR z=-a19`#W0DoLQ8Yot>4Fot2)PQ9iUnAD9yqVFajzL<kPbDn-&^SAbwwTFLIn$=QXq zjoGGzi!oUx6(vRFQmJle?HZl}Wu-XZ!>_I3#<Iff{1&BBVL%bTP{DG7ZEh<ckf0Ss zFn3V_LI<&E+IVZA==>)ieti5KT2a%|QWCG9{o>HU&r^Evy|-t^r<c`}j|3p8F)$5v znLaR`V5^3{cd>taVV<do?Y3K=zyIOqXJT$9XJn)%-n{VDkq-}@FCGdkAzGU1W3;)5 zev&nZc&Px)1ixS|(_PP}SnrN^_08r`O(6j6=bBLiQvnme%mS+yn1qxrhGm@4y8+zY z-BfThCbbaMHi$2E^o`9fF0ON9dau3l*!_R?vtx}r7v4vYL!?8Zo}oF!8;zQqUt3<B z8DnYMdPCfauVa$aa{(%JGx+{KcKETEp_=&3O^^BV$oaf}-&~;fTv22=6>Q#<Dq`%t z7?gKi8!fR1-ux^kmEj$%#%?6vj?~Tx_SIEorFmH?H_o3+ZlTP&4VPdI+YZx$St?RP zyPfb}g1KwKLMvVQH&W{+7Z&FcV&)7I^J)=8!G_vcC&pCplRw1vLXIyu9;jmDA2`Dn zAGtVC1%7Eh0)rnW*u#QXJeyGp9=1`qx0g#N$+rUA9^C8;Q@xdW<pa03*8yNdurkmV z8@Gl*1*5|e>}cP~@1=C`#Pq`L+Y^o1+0FBtP~|ZEccM1p^`rA?iR};cO%WcZPbzkA zQ^BF*ZP6o_fpl?DKB_i2?AjhFx$*UhGuM-H(Mo}<q9il%+PSYUWw!HBO^-~>uPG4( z*T)Z)CV&||5s>awkrciTq#wi0n;l8#zC3j`F{?<cRh8$b$6Yw}^^MXH4Y9?rEQ^Fv z$|ak^sz&l1kEj%t6Twle0FJnn3B9w7BYdu?b@PLeLRy;5z|z2oVKpObNDbWE)0}@Z zCZ!0pHU-73|1Ynqu59j}nQOcH>VtpzCx3aceiwjU)4P>^%1yNTAqz<Ru(W;K)@`^z z{KHyZ@|ElHi6G=Cg^X!zz<sz5T}+fGq6)Io5-**+nCIpyqXJ*)0qgIxUKXs!Fq)HU zQu@yG-XY&MTW=iw<V<2}c3u&>k6C_itC7QxjH_kEx#=m1aWR=KmLwn{2k0n8zZHyf zv2=lI4=fNJGU8Xda%1DGhESZS#vRzwAjrWqd;b$^R{!Ux^-$juy!6YMf52p6VsK-z zyQ-*ago1%lO`HlHI;jl_afLlCQm9w^ZLf`v!m>VSV6fVuZd+b>2*E1pFa*N^VDYw# zWSJRlMOh=`)3eKqqxA)Kp<wL2-31je0lc_M4J<)yBPLz+lRz*R!SHLBtDFj!7^_ab zeEDV~h((K0yiT*SC@&-BM$D~3+G*>PK=5s;J4U=^Lt{ZoOqDj?a|Yw~g6!wbzQXHQ zt|w>a7NdefS80Au>aD9+)2qfpZ{JKMRzj~qKubo6|5(14%QE@si5}4<B6sZJ)=(V) zTpb2rHX?Z!*v};l2Qb;QP^QyL`&mI~TwT3AZN<sAa!QfKL4QtJVNP0dN^(+OO<!}u zhc7(vAAa~r#AF8E!#+FXCQmI}DuclR*zJVhf-RVflG#g5If;pJ38{EFsIOoXhFu!u zQ&wD<ostlH@mi5{H@2V=m0mOBOJ|yU?`j-e3f?4kl*7HzmU!mtm|H1XLNJPzY%MbC z!hS9*%E?GhNKP&2a5Vqx5EM|tt}4%3!^~zEpj5G9K(cGGGyi%_e#hA8;Nal!$QXjP zjDGU)@HhMfpE4vfM;idsfU}h{Kq)BmuuStBjLYZ;uJ8aRdJVx&W>_LiVMEhQ-vz;a z#brGU8=N2^1XKG42)3duhu~SzK{I+TD_ZRh4#A@na1aLTidw&=_~5u28nk=`G%r25 zw?nYrDp}`(LIRK92xD`yJ}dsljik(+q7txN<9wEaRWuiymzY}F2a|Vec64HPg`sV< zq8NVZkkW=$^|jsf-EMt*Wp<YK^Tu#hYFzBC)LfLDl|z*wx(~|KoaCD~60+;ZLY9ZJ zz%tb=@J$UYGFu}sw@{Wz{(wnFn;34zeX})ET@U~`Y_6!8&;oF^FXJE^hYFz)g!TYd z7Pt!l?x;*nDyl<~F-JpJ7UiTSCMG18bav-{_3l$Ydf;<oSKw=K_pndWhJha4teLmk z43nlhY9V#8xs1j+A-Ja^J25sM2!@tNQLRX^&|^^tma1ZSq)7=k6HEN$Kw4s~YNZ#< zl{|tioTcf3VPZSt#pq@?+Ouz5yBVJdPP<YtaEZ-;9UTxB#BW;Ct)!gVKEp3Y96|k} zTvNeBqmp;MB`O3Efc0ShRm^te$6ZS=hi^?QrmKH=3}qXfCPYKkxx%bJo~L*gsI6cJ zrG@ATLhfl~XmDt7bfmkvqNsXU8rammw%%lh0a#BKg7Cd5ztC6p6cqI=K?5Uh#vqo( zu)G!R80LeL4uF`=&Ay}q(K!@Vj*d;v&Gc6nG~cr}v%>-nMGKlCJ2xT6y;3{eq0{XG z{q7kfoyDoTED!@HX5@gGu!#5tfXh*1mXUljA*Z4T+qXSGHZr-uH>P<!2t5!@h9|=> z`n+w%@t)V#{P-mCyV6&a6Bidx);0pzR)faROu{69y!z3waXfeiD&Q3<U~RBt^07#y zeyW<z?_*$9g`^3BSOxjiz^K2mAeJd$1Mp5hEC*m8!?IQ+;J2%{ucI<Oy|}rX&0%eA z4Rsa8x!KwI<^BCdUw{14&mTTv!<x<Mlq%RK>TEx*$U|7tGz?UsSGI=Wib@sNMjP|u zW8%{>=)_EWyQ;t)k)N58keHlR8Q@n{aoh*jO=_hh!E5m;+K>TeB~zhmqpLV6AucWf z!aHI$<bPphB-~6cX*P;*glJI;hd2oR8CC>{$kxTpY)u1j*ym5T<R`?%=Wx;pf`~00 zXp|Zp9Y#V4S*77&)-fSJLm;3N$@sEHhlWRo@!K$pmU|EhZ-yC!*j;s5N!1_^#uhm^ zLkPy2)|1S`;3U;|P{Ld7xrLno@NMK{iCg8e_={3n$YV1dY-N=!AXDMC6fnZ-s4Qcd z+1LaMF8eET>caz^JF&1cd`Yqlw&)`2F5&|BP6G(r3AYA+=Ylys5MgFaG-SqKi%m#J z!Wq=SP)N{79FJ3wlaYEeKEoJ!mqrFh=2wYeAaxnhL!KLJ>ZcajT$&mhwyLc?uFaXz zaX#EqXGu;RLS?xy*UKu(7)a7;#kpCDH{+7>YWo8O^Zvm^%t9<YB6HoV%jk5qbho3{ zF;~G_{IQRI6P1<LwGIFm&<FNGXjsre7TDugI8hOn5!%riY;J6z2`vM<t81XI2LLW< z>F&kJLU&$EBa%mD2;WvGojUyLFCY85#{*bW6X%!!b{3Ires{uk+``3a@V-{(rlwYS z*PG)_c{gL?Qz1}UBxSS%NO+YLfFv?Ly|Bf#HEzSBA%KNn?gXMsj#yZWP+!^IgozA! zjA8q~K2(KSX0ZvdqPh9*LUOGjSNQGJq}lCt*t5&PFPPs{2v25NLvJ8VUAByNw3B5M zjRi>wiRpzEh;!7{)t2RFW7b5eW#6k%fn8hO?3y*YI#8j)7g|zMTvS|Kl$({F2bxS| zq45`mdHMNZx5VkeG$^ZdFbfR7yLYMQ)mwF$wD6N?d5Um@XNRA>){>JC0B>)sP&H8- zQeCJyn9#z6L<G)>VE#b*OMey#0W1oOOas63Gkp~~b)k~Nh!lW=$u3+&ji*f!QHEY9 z(`T}wB^AxYlpKb?U};ESTr641ZT077d!Q`+=Ji<UU&JCy;R%t67{8Ji7~^<u-Ac`A zWa4&ptbcG4$?9$FA<bw;4`tBG1zw%%ZE5bB+&L>W1m>m5(P>)8Gfg=uan$x$tpYXs z*jT^`P3k2jpe?@@mzY-4<x{Feq>W^Pje)#_yx_o1lCBAVMCl%XR$U4l03NI=B7ni_ zs5&fqz%1kl<`TN0DyqZ6*Ej$-(FKkQU`|_Se=Ue=tFta0d+UP_j=cVhM@~5aduRZ_ zB+)h-Q^|74Qn|p|N0X@$l5}l;YK{c|bRLUt#m1*)=EERDrkejzBW3`<Ib~gr$%G*# zrUO)C%FK>t(3zbsMt(Cb1y@NnJKH?W5khvRy)YFoJ|n*fgCLj}$Io*3G^vRRsTDm+ z`k_jAZgCmH0TCC=^Ee~gX9OHknO0OtQP*5gJwRC5&@<3KI5ON>dh7g&vzM-1xpMW| zm8;idZ^Wf#WTd5~>O$@#AvWgPr3)9%pF8vQ*T+9Sb}hF7dw}tQYLBjLn?O8O6@ex= z!b}<`IouOElUkq^a0OobgUdPEw42adSZ&VE?*#JT1#^a;Y<NB<VGK7MvWv=Ci7&g@ zYJoBj=EP<JW3d6vFU|IsXF2Y0D^S29CN2Z{!Tm4<GQy*|eImGFMonX4LkKp<ivV`6 zkPn_nMg==~yDcX!CMGr|gEZo(X~%eLZ)jGP78hiLhWKVu1$&3KW(NC)CKphdfX8Hx zjyWaGD8y|pjdj%5wi<;;lxuZ**!l-Y3*&FZ$0w6Uyd0gTq&=2dTZhmPiNxb?#KmRQ z`$(SVX~Aa0p~2)wdq#UgC;meKHa9;kF6l+o#!$61Fq?r{hqW8P<^nemz_g&z^2JUD zbP^&6-Q+beDtRiiq=C_!-PhC2rrY-Fn5TdLpZ>uspMCJ~qmH0V&u;rg09$!FHp}8} z*fb4acSg3;jG_0n2FH;6!tgV?@@~c5!nh(-RdV1Mh7}d$q4*#%qq5J-c<jDndyFb# z?=@S+MU`|y49XVYa~>l9COFN(y7QeSsfqE)Ag3%X#dHQ@xTqjAEg?CrqR$#j;gc@0 z5`pY5wx%floeAyZbY|Nc$FRMKRXotbg0m{uJCjcwIr7EvlV6`cd+zLoOYw0xZ^rp6 zmj83@+}W>Bp)%_8BM097=vw3a8ZzY5lcU4vj~sz<f`(iARNnE{<~vR0!m`4!p(QXn z9Ecs7o$ORZkrH3`x!jzS-^H<y1eAU-BJ9fkmE$6gnfQYH?k<G8SnI*Ww)&W11JCxA zWjN|#Cq^kHOjs*6;Cww{*tjCK2ox|s6rZnjg4;(I;_-sthfYim2YWYH7k}n7vawkO z7~-L(NsD@dR1_^cNLqkM{KkbV#!0v|+}S-mxqvm+*9l$og5(3E<Ey2qdoubUfc2T7 zKI0+oPd#_$I�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 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/restaurant_floor_sml.png b/src/main/resources/com/unicenta/images/restaurant_floor_sml.png new file mode 100644 index 0000000000000000000000000000000000000000..f63105749014e794d09ccdb2b9313815520af81d GIT binary patch literal 29443 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/roles.png b/src/main/resources/com/unicenta/images/roles.png new file mode 100644 index 0000000000000000000000000000000000000000..d9194e60c4a236724426e44ac156f586763babbd GIT binary patch literal 742 zcmV<C0vY{@P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyA9O`nbVF}&d2(rIXmkKlPgy}sR9PTKQbk1|Oi4pUPE$o7-r0+3 z0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK0uxC@K~z{r?Uh+l z!axv)`v^ILN8kuKN{-+W<|cVi%N3)zAZi&c*SEZ@B`%1f!l0H*xwYL0LYRbvA@Rws z`l_a8{{Fj}$qWGh5w-*SUjp{OBpe_%;4#nrN$h>vu=j}}*y;AL`(eWF2S$)duZf*^ z0Xy#)L5fGQ{U%`h4I@agfvr~ywq7v;E4?FN=gk+7z!1E2i?h4?Y!EJiUGSWdegmxv z8&4V7coI!g{PMZr`lCVE1U6C6dHvDqSZ8fQyRmw2z}kaHU<VR-z7;<j*`-k*rL_mq zrQ@84TT`gJR16gg^>!kURgLNU9tw3k(1-JQEihK3NsBB9W<?GIqpnMzUz88$vqp)0 z&4GLkHE?}i`I?B~5pWdCRRlf!4J=nh44;4omhKRASiJQ=NK1EC3?KDo!NLt{QdEv} z;l}IX74m}SDiU%P>=Q1ez5zU!tGEGPZlJ#L3+Asa0{fsy+TIV){B?#jqDhPwbneQ8 zxhsc|1V-S$N>14Tr)>Y`IA!&md9LNlTFyx%W-kqxz4Qp|K+?Ef;77xAof^(bpowhB zg=`4}XkWK%NrY(p*SPN;nYl1w<^n^RJ|70AmxevGW9rO-sWTi9N4q{uo?;?scQ8>z zNCK?}#!rS|`~(w0s{u|LJC+0vi2pCWuV%)MEf_t*fnbk;V&u?-kwb@&1jdB5oYT01 Y-~Pa?wz}*5jsO4v07*qoM6N<$f-wC!@c;k- literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/run_script.png b/src/main/resources/com/unicenta/images/run_script.png new file mode 100644 index 0000000000000000000000000000000000000000..36c2e0ccfcd431dbecf4aa30759cbe19a709ebc6 GIT binary patch literal 3283 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/sale.png b/src/main/resources/com/unicenta/images/sale.png new file mode 100644 index 0000000000000000000000000000000000000000..85e0074836bf9edba734a366f95700f096516268 GIT binary patch literal 753 zcmV<N0uKF&P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyA9O`nbVF}&d2(rIXmkKlPgy}sR9PTKQbk1|Oi4pUPE$o7-r0+3 z0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK0v<_3K~z{r?Ur3q z+b|Hv_Xs*dj=&LmgdV|1$Ps)4j*tgvfd^_D@<9SbFr`i3@(yjy11$~tPy!?{rDTx| zPGrTlq$chYn)%IW<=wykyH;ib@Vc547rr7U(wz9voRI7W_2m&kkDHx=&wmm0(CiGH zJh*W3fLgM1kf8kO4?>hT|JTFueG887Q6j^85ZBt#-6|a2p#<f7!eIeo*~ZT`uB4gL z6dk_>Iz|P;V-_G59oxl?QEpB%@w+xg1R5iZaCp12&^<W3&ChA33Lf0F;NS)&@(UT5 z*K4Kg?O(6L{xwQ?K|y^;_!$c@iDx;ome^|=st+ChGMrKy%wAX@GJb9r3j?)5RO?wc zmp*~oAjb<a!XEp#d$7kmMN2dO&|0<cL$!|*_V=LLCyIv9Gt{Z{3Q*~xL}5C%a+mOP z79f@yhl!P*qi6^{&G^IOa@XO)IHlC_BL>P{#-Gg$$Z?oh>Ua^2a@TPDLZH;i!R{3* z7`o^6yH_Np-f;Y32gNpnVjCr#^xG>vEw&w{Ry1SYKp^$;x5vRHVKM%&k)6vt>|ElK zupGZI@!{tR2bY5P%X0kT6t*u4uzi6G;u_zb*TlIAY@HL>I;R|bLF`H5q-^uGBj5BX zZ2G8>{CC|pUu$6F2SOZ4g|_)x1Mj{e#PR-n{LjiZUu$6fjKcaEDkOgb+kCBowNnCX jr<8*)h<)-UG|Ybj1WB*UQ?=cH00000NkvXXu0mjfCfG>$ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/sale_delete.png b/src/main/resources/com/unicenta/images/sale_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..bafc2c947408fc3121d0bed8e00d7198c433fa33 GIT binary patch literal 585 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP(r@M zHKN2hzo4=xGd-h(A;>?{(I+HQ!7a$uRl+0`%DRpH*v?o6OkDUj0O{Irtt#G+J& zfW*wa5<NfH5QQ>hJyShH1A{L`3xN(R^K@|x@$lX{Dc6fBP^7JY?E%#-y=4!DqE2P9 zUgrCySlf}&rQtQjHPZh1{x6D)G#2%^1kNbk^*knDO0HSjn3;c{e)03lsfMhx*X>^4 zvs2VTYwO;RXI}9xstx|0ke<D(Zl9_D;kW8~7N+wTHvV%=nV0!*M^y2@NzZou<lvdY zVN_tt4W_>Kv3apb?x;B}p}~0QzW$#_Qx)tA{@yS7=d?k^#4@Vn{u#N{2XAI3c;0%_ z?D}7uT{}G{t>5Uv3?Yjj-%Xck+%=DGHwx(IkkMJ|4&}@iu!xA7y`bcNj_fIiQlAG2 znWa6KYB!f^Fi#b1Y+gE5(ChozYYTa%w6pL{o7N81Bn8qW1=Y0CAE;?#KSWcj98goM z97NNT-9Syxc0)8xcn#Dv>or8vfs?|GkAD<if3gg0@qvrXjx`$0?cZ5GF62qMt(bCK eL|C$}^#0xh@+akYXTJr;6N9I#pUXO@geCybtmfMQ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/sale_editline.png b/src/main/resources/com/unicenta/images/sale_editline.png new file mode 100644 index 0000000000000000000000000000000000000000..b74d944c125e7a055f9b2cbeb23be83f208de48f GIT binary patch literal 665 zcmV;K0%rY*P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyM07=1bVF}&d2(rIXmkKWa%Ew3X?A5GLvL+uZ*FrSL3DI-X<~JB zX>V>IPH%24LvL+uWpZO_VQe5yZy-cva%py9bZK^Fb9>#epa1{>8gxZibW?9;ba!EL zWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900E&%L_t(YORd!FQNlnF2k<R{5-fodD8Ul0 z1WKR-O1KaBLX?Ooi1HA`M-9G$D2ga73J8d>ZWv@VKoSl!^P9=t=Kh<^<PKnw>wMsc z3!<U(fzI5E#Qj}+)|YVBCliFzuYYKg?@7q_$bwM+l3Z89$tT&$brqUqI})-TGSMN| zb@SY`n$P){WIp_G+@>j9<B;RFoTxkMkZuV`w`c}A&PX*~6VKQ-NHzqdnq(>2kdSP+ znQnRxt@DrG1suK80+wetNYn)+>ZAza@Xg{ciq`}jASps#XR+C0RROUoDME<XEW-C* z1nj?(BII=z;n9kKXoVCZud_LWB4va~nG_)GKHG%vJb7T}i4-8Oad3KuOFjsfXif;) zql0i`Cv4qou>C+R!{q4R7|()Sa~N(k2o;eL^A2}js3=EcW6liuh2{tk7Tgdl(1>Te zwSxuuYyPK>uz5E}xRJJ@dl`*ruzu^|dmqz(%^P)ObA}rY)^0RLHgs;R5N<SBxk6aI zCKH{<k_omn`$Tk730x8cE|F>6%*zztbb7OI@|*-a_3g9)00000NkvXXu0mjfpdJsC literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/sale_new.png b/src/main/resources/com/unicenta/images/sale_new.png new file mode 100644 index 0000000000000000000000000000000000000000..7545f1eb5f052727aedc78b5607751fb730dfd47 GIT binary patch literal 647 zcmV;20(kw2P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyA9O`nbVF}&d2(rIXmkKlPgy}sR9PTKQbk1|Oi4pUPE$o7-r0+3 z0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK0kla(K~zXfwUk*> z!axv)`v@F?BjgA<LXN-@IKte3Bk&+7SVd7HtE>VlZ@dc{tfDB9u!9JwZFWP*kg!eF zSLw<8oxi6u3BcJ$4LPVGv4A^`_tP%|jmIDN@g@)72y{Hh8&uaERM$kOvMNGlg)08z z4a`p{FTGG+qRjmle|m$`f`QTk4X|oV#H-sjmMSVO>Z-18U0`88gu)zEJW%{3BCIU7 ziwkqckc-v^`B@b5GnC0q_j?bysZY<%&nPX<PP~wvpv>J^+2-BYFVA<y${MfdW+y)D z9b`rfWJaiy9=gOtR)nYq*0DKHno~!5h@g=gIQyzo1D~Fg9@?D1WWNZ>KFTBnWvdCn zt==OWu~ub5;PsqjpVA&p9Pbf`_fX~kxFrPX;mV0J#_=9w&`Wtc+9M_3ey}2_6YIL@ z{S;SXU7tbk@B_VhM>q_d_GqO>J4J|g@BnPuqZvfn97Ni<CzRjA&IX@zG2G(d`i;nh zTh=eyiN><V5YIt~M+4j2ccP&-;PS-}SFgB%S?okZH3&8d1e>^lS?okZH3&3ZaPeFh hL770qv!%7s`~hCNMyV9WsiFV?002ovPDHLkV1lA34Q~Jd literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/sale_pending.png b/src/main/resources/com/unicenta/images/sale_pending.png new file mode 100644 index 0000000000000000000000000000000000000000..277b3728433449d285fe9c5148536a292426c9ce GIT binary patch literal 595 zcmV-Z0<8UsP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy8gxZibW?9;ba!ELWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900FB> zL_t(YORdvyRsm5I0Pwp6OK1siDVAUfEn#*rOYlKS$fS}#iKyt?d{>$fspOG}irbx& z#56oJIOlg9@BVx5%>Y>DlOHj-LTQ;)>p8h0gWQlqew4OeEULKpWN`V#36eDr$PO5s ze{h0hYaEd2GsyHgWCu8r>1(v+5FJ_^Pxly{y>o&lR7m$$7?SETNOd{E1yqXJ7?SKT zNOm}!zM)XEqfxG#NK@GS>q)d3oV;>^E70pV{tt<_7{pr~5^c0Vp<LM{-(*0HyCBA; zF`2$Kf(xV}+H?@rkmC}+L3)N>eEi}jIERzg)tOkdxn%R{Ekqh_h&0eZfum>Dux6vV zKIrhtK{SF>jK6I*|2;{#E<?DErVbugY_1R4e~<{8_-U@x7~w=+?g1OKLRASuRh*&J z{&pU!@~N0?eMqn(L9l`od-t=~60E2*@nFSiZAhTZAW-H6iTRxe%JMjl;4g7v@@HE# zRxc10`AbgNz2gLl&F3LHyHDEypQaLoom;mk-G1C#l)+m>vWC}q-Zr*xT(EVmfv3Ri h?^IN&H}@1azX6y03gw@Rnv(zk002ovPDHLkV1ga?{Ote$ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/sale_split_sml.png b/src/main/resources/com/unicenta/images/sale_split_sml.png new file mode 100644 index 0000000000000000000000000000000000000000..1804dc6be36792428e9e05b7b13d3e37bed90900 GIT binary patch literal 814 zcmV+}1JV46P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyM07=1bVF}&d2(rIXmkKWa%Ew3X?A5GLvL+uZ*FrSL3DI-X<~JB zX>V>IPH%24LvL+uWpZO_VQe5yZy-cva%py9bZK^Fb9>#epa1{>8gxZibW?9;ba!EL zWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900K5iL_t(YOTCm`PTNorg=Yy~LYCkqWC>nE zmXaN034WkJ6hRFw1px&EDTOz`Q^1O73oV5Ul)t8w=^Wqd_&-U5)R8{fnKS2%V<#s1 zFSXA#+GmgUo~;+}Lk6;tIjFtox`Z=*{NuiO0Wy$<%t7rw)oJ&MBR>3YPP_!(I0u=7 z>h|l@?Q@F8KQHO_8@Y_sf}LMA+J58|O3v-Emtc1L5uPLinVH&paB1s-2l)4j{QJ=l z9W$6sdy!Qr3~t^jfl~yuaa+9v+U8x5^9;GLjax?oIm7#(UgfQVmY+w)&|1IoX#IvW ztX;PX9`y2a@Q$ptYl~K|l)yQXU)JhXqeNE(?^v~R>Cnn0mtac|lxZVwO@8z8MT?d% zIK#Uiia@@P*@<fDJfNj>9zifsc4T_{y+&`oDS<0cGBd_~UpTdB;j|@$w0OpH41{L1 zWbw=ryr`cAJspl&c(gY(S!VI;FBW-U1A&E5@C9W)>#v{a=nvE2MFz40LN?8Rb_Eua z2L&PNhepSYW579xHCKn3LYCI$l`(h1Lh(V(omkRWM#oI@C&Ib*0n8Mi12Umgr^kZ6 z-}&nFe4{HlCLuWQ^w5LXukbb_o!TJ_<wNZ-G`dp=X@`!{!qNrEL^jPH`vTL<Q6n=r zbL2+-+2iW>3pDM`zMhe#y>j8xhqj;u76PGZj`8Q>{f)0=`q0YF!t0wXWZHW4)hC;# s4t#-AxYDl<kC$L(>cGu;{U}rFFW?8Z+qWNG#Q*>R07*qoM6N<$f+<;O?*IS* literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/saleedit.png b/src/main/resources/com/unicenta/images/saleedit.png new file mode 100644 index 0000000000000000000000000000000000000000..80b182d6c87c9169e76ee9f47b9cdb0848b82e08 GIT binary patch literal 1068 zcmV+{1k?M8P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004XF*Lt006O% z3;baP0000VbVXQnLvL_-a%pF1bO2IMSwT!xSs+GIMMWS?Nkc_WQ$--&*^6la000_v zMObuGZ)S9NVRB^vP+@6qbS_RsR3LUUE;TMOFfjCTp#T5_l1W5CR9HvtR?klpK^Xmr zQDeMpOpFPd*cd&Skcbz9Uet^6Vq&})4<_~KjsL)!h#v85OgMmwKq)PhQhqH6h<d@q zg9Ol`6iT76g;GFDJHDB+-QBj^-A1^%$xC<I`QCf;=9}FT9n{q}_n6$_X9q=JnzwE4 zCd9vxXCY1A#TM#ZI$>Tgo^jD9#!NAu3DI~)vb_>__&mhxAifH52Jt9$ue_!n<xFvo zk7-8MaM?284j+g3Er?I<i8F{Zh<~TP^`|tjajuYOY?qNWWSa&~Lfn@V_s6(6gE)iu zB*~i(X?XjTk!v*NqR|wygdGPRkvi&#@Yort;=OBJoI#w?hd(nkvQuM+iZGGo;YP{A zj>rXww~{Zq1o0>ZRvB^e{zO)MXv+(}CrG=>o`K=*3B<*8u<irz;$^J<8pOMD;)6-f z5rz0Y;1~=Xwr5~ys~)boa}_e~B|s72SFy3Yxd!nxR=!JF@obW#sp}B0K#fbsSz=N0 z=3Nn;5fa9VfIEB?pW2uk>Q7W+zmqv}Za%w}DTrTzAx8nHX&i$|NvuGRfsJZ0zvb5p zYMZ-*j=zn_Yp~~+5c^fE{5iw}qUluevE3Ao`72R3uu)sUS#m%66BD9|G}Maut-r(6 zKCj@oMPT3?49rt7K8@oR*L8gMc#mhsVBnCbE99Ff-4A{1_2LX`@Q4C;_$9hMRpPku z*fTJYhJmx9rgu%s<Kn#81({yGYfjP4DuVHB^Kr7kY692<K4bh<q%@e!py?JMK8epA ze7BzC4#tgKSx!f31Hrfh(J}*il<HiOKXwGaod(fGh~LM)KY;inbbJ+7UuhukQ9OBE z7V)dqfz^<BsAwpRtv^wb6C2sl?llgcn4W{*Tg0yxcds;v7m9`kT>=umR|NRwj~T}r zhcl0Z^I62N7W-pP@myEYwHz`S@W&MVrWw$W)rnop9s`FzW;1?H(6#Ik-EM?U_o(k& zl8V&Zj9*=WFRI|!F&&(xyI1$CFY3&z<%_Yu072zl^oV!-{-BKb)rE9KYQ=kge^6%p z+(i3)HNf@-o`o{wS5t6@8}JBb{|J}u-uXYVAc6O@61|_50k#KzFPSD)?tIJ0n?o`+ zhgcrW|E`xi-_pRlpNxvZtgzhqmImI;Fe-+(KZ+l#a_3tbXquL(X`1E1d<)8*Z)u=$ mN}|Ro8DM+h_vTG#bN*i-n6tQ=g~nk30000<MNUMnLSTZ|$^Uo& literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/sales.png b/src/main/resources/com/unicenta/images/sales.png new file mode 100644 index 0000000000000000000000000000000000000000..faafa865737908ab8c353f69a793de0b0b72352d GIT binary patch literal 656 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvVv45dj$D1FjT2AFf_C<F#G}vHN0S8C^cYUc$L7wU^Rn*LA+qju0R{0giDEQ zM2T~LL1j^9dPWI@b5UwyNoHB9f^&XuZhl^|f@4WZQD#zUNoIbYf?s}~E=WAJC^<7R z2gp@$NiE7O18XR*zPn)o&^#%SdBOQ<CFO}lsSE*$nRz98ey$-3WyX4@dWHrDUy2q2 zT|dLq#W5tp{q6K>Zze~Pqvzdc^zXUvdbsONr<+u+|6AjXh>5lrJr<W&-FAKUuB5&7 zW?JO`%m?g6de7&a-skY({|oI4^R%`sSM=-TQhe8C{d0?&VwAAf41>rAPi7nNS2RD? zKV<WOwa<>Tj>RqP!JMPZn#-H`pS`a6v2f1j8{7Z8eQ>PvkJ)@fe4kLw1nwPa8}r|{ zK4^|PVA@@~`#g*M6Q*^MZ?gM1?M|>xTJz*>Mj!L)=GtDtgX}vS&KZ3@<`F4tbH7sQ zhl2Qp$jn`)_v=)CD0G*E&B{Cb+PO*kr0rUM=5HsI=1yG}{rOhIgC@xcX$=^EEqfEU zQ9$*kSJU!8&wJ3Mb7|h1T~BZCP~M@?y+wU>-p_0KoO&me-kw|)z3*yv)5%-DpSB#| z|J6tAZ|L@#t9A#E=&brCdj1L1t;s;Xb~uZ$<cjplmtprlsUCC@dl?zGYwGqAM}vv3 zRnw;DJ=L8jTxVR(p=~SrveEFg_x!IPSANmZ(w2)$c-R9BqsAh0m!00M$$w0>OGUiq g8Z>b!y$iDcFjaomKd+ZEz?fw4boFyt=akR{05TR8JOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/scale.png b/src/main/resources/com/unicenta/images/scale.png new file mode 100644 index 0000000000000000000000000000000000000000..e5c0dc3aaa14d9bbe3b3d5725326105771507fc3 GIT binary patch literal 714 zcmV;*0yX`KP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy8gxZibW?9;ba!ELWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900JUO zL_t(YORbe_ZrVT;h3^u)1eV|>cnMwtOYjoz4p@SJG>xJ><Tfb<g20d{Y5(Pa(+K6E zwn-@_h*zVux5pl^G1#%)cBD_5x%Zqo_KXEYMaD<5ipYy;Km0c6{MSV>QxWyqGt=3# z6tQe-PoFG0eUiV#%MS0(FX-f_4SK)<yn>6lEc&Z;FZ6WhW_pM_)u=O5XWW_Tz>bMK zGe%8-5!O4i64q|8?#>O&E9n94NtxVf^p&{N_=UPtMqfY_(4JUWm%~lllNUaM*4Uxe zxD<+8;|kXL%9^nj5Cv>{?3gDsH%A&ZNAdLL$V4rA<>rX77N7$1c*20j(4^x>-Z;O; zFbehi$BzP3Kx0_OJUY^)dDRncSodtId(m+$8>{uY$Iu8+0d>zoNOYu;$3btcUK=D| zPHkY)`yc8lYXb%XR6uQ@zMl0_8<ay&(0ljYq-sC;^Q!hW^i_DZ&p?2Y+Y=a%9&DhV zDrp=&IOvxE0|~Usqi1>o!P{>=prwir?=AE#I=p8fzyQ5ez1p(^%1ZO*tK@*8@$t1r z4!y5q72tevfn;Ey&kKz|&*upO4(@c|0ZBpqCLP@IqHpB(gy*<_tJB_%2V@PK_HWhw z?A`F9X9Vk)Jc$>yd#%y#wFP*A+GsgcT|iXN@+1bO6?b|}J3RsM;6j_Mi?^>#+P;z$ w{=@(C)}=$QKT9fGm-;`w0KNJo8E{s>AC8!3y7hjWH2?qr07*qoM6N<$g1E&(r~m)} literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/search24.png b/src/main/resources/com/unicenta/images/search24.png new file mode 100644 index 0000000000000000000000000000000000000000..cb8a8aa9216f6621992d470186047e6327cd10a9 GIT binary patch literal 712 zcmV;(0yq7MP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyA9O`nbVF}&d2(rIXmkKlPgy}sR9PTKQbk1|Oi4pUPE$o7-r0+3 z0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK0rg2lK~zXft&>|) z>Oc^N8&{Aeu!Ow&<`Ue2SprMQ4lGx|gZFCyMYJplDC%S0)pN!>sK{8BD2m$lgfRw8 zGRZl1)mO>P{C{`P)JzJJ#KDI~@(eKssZ_epikPGE1Pl*VlBE3B?!Aq|{yQg7fdzYS zqLBnq>l#q&q7Oz%Ou}%#wXQX=?$9`9k)0PEc3;tlIHI4i`<f<=<LP!@taw|fc5JA2 zP%^4CRXdJPKN79CpLD1^qa>?LE(De5wCAy(6uT(5O(?ff(tm5Bs+HSW&llO%_M-{g zkLZ#lV*9opvat1l1WS^i^oH~)8r!@#Ve=kcl0<CZ1~*`Xqf4n}#I8|lG3it6ywuWQ z{f-kzFeo<Fk7xZZBlW^#s+%e{O-hU|YqvHLUS#do@U+DyS2t9+&OqTh4XZZ}ff7b@ z2Ju~}r^)&>LL2cY^9>F14U0g6yG8O1M~=nZ7c5{7-3CI#y3)Y9av)bn4>1<=xw=X4 zzBRutSGQ?R4^O^)p~1?fLtp^CXWwhUAj|<G5)0$fxlS-xzQ7R1)i)wcv2d!x;u$9} zkfrk&*DWmh{D}_pC!D}Q7Ea?ou)rE~jKdtm5dJf{s5tY-A#eZ=vwuha{mlK&>0=G1 uj~RgyPG7~1NLqU8NQcQo?jrtwF+Kq+`wmU+rry~A0000<MNUMnLSTaV*e_cE literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/search32.png b/src/main/resources/com/unicenta/images/search32.png new file mode 100644 index 0000000000000000000000000000000000000000..8f098c51c5fa1808b8893f2890ab4cc3c6767810 GIT binary patch literal 866 zcmV-o1D*VdP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyA9O`nbVF}&d2(rIXmkKlPgy}sR9PTKQbk1|Oi4pUPE$o7-r0+3 z0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK0*^^VK~z{rwUk>{ z8bJ_-i>zRlFiV)%yv-733G5)*$(*c!2MtNQgs22Cr~~5Vkvwb2c#Ba9v_VD0OQq^K zke*3Kx(DfVzB7HP`m4I9yHYT2+kUV};uT>-DrJV`5cg<YA>P2t7hlH>753k{H(~4E zgY5@Yf^FI7S=#2E1Dkh(Kuy@k883&8TL(67F@m76OW1@Nz<r+MwWxi<Bx-#VYJEYV zgiC!Rc2~Ss>$8pQ!x{;GN44j{`VC5?m5+1%CLQu+Ev;6$wxHTW30KRXjjKI3q`{iX z&Ff~s>tcX_%60s)$BD9!*A<dZMmavLUHJqC=<j|IY3<6DbbR#$Rxc6$VyinwELSgW zNe9(*${hn%E>I%D4Gu!BT$mv(r3}g)6UrSN^5u8(1lU*BQc8f0md{Zl`7c;Lw?kUW z36z8nC4m9SFJVczl8(kDEVeUHY-50cLQDS{vQM!sBpr=sSZG-k6eaXeq0n+88XAR& z|JCPT9)UyhP4!aDwz4m4X}5gSgnUyFIArO}g{8Cj-@$8aBl|pRXuPDwQx_IbeZnFf z0wV|-vyDxd0o>;~UW?j0YMWm;F<{{&M__=UuSGZn_XqQ;U-nT9o;x<+)6Y7A5qx-D zGYRiM>rwl`m~9o0{o@aVg479&p$=@rEq81Y8G;jw+VdQ*Y25btBMat_d<uXgNL~$N zFTmWP1#^djz!B6bN&Q0f<jtEsuweE;5IBMyCHKt1XZF)DvyTdBluosW2Jm4oO`rl3 z2+m2q_fdh@s{7Hm%QoteZD1_#zN^=J{pjS8Z5Z(On;`HXvW*D`A7nheYr*ucATWUY s6L{xO9nsW|1yegBK%;UcI`^T|A6t)lG|W+a6aWAK07*qoM6N<$g0V(&UH||9 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/slip.png b/src/main/resources/com/unicenta/images/slip.png new file mode 100644 index 0000000000000000000000000000000000000000..ca87493b6b2cad7521c3fe1f681c1a87b548f783 GIT binary patch literal 777 zcmV+k1NQuhP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004XF*Lt006O% z3;baP0000)bVXQnLvL_-a%pF1bO1wgWnpw_c4Z(#Z*6UFZgU_(baZlQVs&(BZ*Cw? zZ*DC^Z*6U5a${*>Y#>f=AVg(yX?9_BX?A6Ed)=_00000QbVXQnQ*UN;cVTj608n9R zZgehAMN}YmGcGkQF)%Rna-jeK0!m3lK~z{r?U&C_6HySyUyM;B@wfOpUObq1@ZiCV zqT<j0&ws(hG|`Ayi9l2g$fZ#t)&|<x!Y<3cTIi2JO|cxtnbp~DcjvW-ZNsHaKKq)P zc{AV6zMZy84PJu|U<aPe7a`1Jv`IYrT!b(W(I)W#?GpFVPI%3yjokuy1FxgFN8;XG z5hU)SJ<J`n5sEiRL1g2=@H&D%iQ8zGxHVe@33c<6hF+1i9GG8e<@@4RKv%aq=2tgR zK(BBd2ej5uDwUvIE<>$WgL=K*F~7P#qoEhf<ZLhr__ncatf8)b)DVY-<s9Vmd9W<Y z6YwI}$~V4R_BzmLG@#jRLiNvXq?Wq+K|>rSfBf_XB$k{=uB2V{1=#gw#ILTr*AN%( zfGH1mK=P~0(=Nn?1(@=%0LiZ|Ot}z;iFE50Jj<*_a*bK7TkyTM6Y;A{*nx`%Ov28i zXy)ru`yqV3?7}(p6E6#!ZHKV3vkPa@PMrCV;$U`!R}KuX!;>xqna=)u3ZyxZt!%?7 zjF(WS(ZQI4PGXG23A8g$7tM1ZRoa5%?_4-0pvVzM3MAW6fg@-m(uMX8%-S3NB&0() zG_me+ID}$H+?59r-GYU+UtTdD#X$kVItSjagF1wPoj8d8ZY0tx{v;#;93K=Q<=B@* z0sB!!T!N#R1aQ8ffYj#iNF7B2yh}`ynF1s-HcaIlNUgeU`GVgCkveZk0A2QqaS}k6 zz2Y?spf~+w4D*}t3wH|Yr_cLo+^xVX`~>}A@TX|d0qnqE##)Tf%YdTL00000NkvXX Hu0mjfc|c)^ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/sort_incr.png b/src/main/resources/com/unicenta/images/sort_incr.png new file mode 100644 index 0000000000000000000000000000000000000000..4595ddc52d8aea0ffab66ebf6fe57d9a2aa2f50e GIT binary patch literal 431 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEa{HEjtmSN`?>!lvI6-oC9V-A z&iMtEMVaXtB@E6*sfi_-WvL3z`MJ6IdBqBjB_&0fNu?#3`FRR{`FXk^@zkQ^%)}fZ zSHUH<D6<T#p}6|)h6O<Lq(J5c=ckpFCl;kL1SDqWmFW4ohA5O7>zV2q8W?;jS_oA2 z!PCVt#KSu|MS=BAh5msL-{04;sV!sYndj8HBtvyg+2LZ=Hs15+jdN;0&rf{b{-0;J z{aN)joe`qh^Cb+{RR5Zn__+Ij0r$6>f9E&6*A~@@EWF>4c=hmi2kw8#5d{x^*S8(s zudyNJU@2?c((-%Ex<C4lH~r^1{_mTxw8V;6)9&OYM3jBEcjWH-|J#2a>xo_0>>~RG zU8?s>1mqc<X({!WHqcox@1?_JH(dpZIg1@lq+D2>8x}Cl5)n1gf0Gdx(|m|G=;55@ zzOBsNGep0$Hi!Y)Q#*4wvzGd&>9*-xHqO$GzP~2@#>ah)39Fj57#QAb)uykxc)AAY OcLq;aKbLh*2~7Z%7_4jn literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/stockdiary.png b/src/main/resources/com/unicenta/images/stockdiary.png new file mode 100644 index 0000000000000000000000000000000000000000..11e390e689bac8588e5c7ed7a0248c0e1cb7cb1c GIT binary patch literal 506 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvVv45dj$D1FjT2AFf_C<F#G}vHN0S8C^cYUc$L7wU^Rn*LA+qju0R{0gj9)Z zL`iUdT1k0gQ7S_~VrE{6o}X)oLYc9ish**M!Iz?iK-+>mT^vIq+>c&#_dDz$(f08C zoP-^m(PfrQ?vL1H4suUAA#%}0)YsvZQ8k!3vqMecX|j%W1IwfBP4$T{C%)ZiTle<k zhs$AaCCzOf_8k1Y=y8tOrq+uKAKq7AUBat%S8A2*DgpbYcRmKb3+R;y$cmnFD@2)1 zW{=>kBMpDUohD0c`0kV;#9TI?(>LkBIpKw#JU8l8Ogb5(`CHTs6F$$opu(23g##$J zOBE=ZT@DicIt?hg=8gc+h^N^gBT8I>Mu_Qyj5x#!G-8ImI#6+OI!N)iDHoEDeoubZ z68}R_P2GOVQ`yVMU2<$rXI?&UTIzDd%}$QX>G8Q-qkH@9PS_n4Vo?<Q{pV|-gTSqn zJ@vH{YP%YeE-$*V<g>qbK*kRZlNlX-#eJUp+v@ik$D5zHp3Nt^B%<jBvl@TzW9w^) eZTndFFi$^rR3~%hCq-Z!FnGH9xvX<aXaWFU62-*; literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/stockmaint.png b/src/main/resources/com/unicenta/images/stockmaint.png new file mode 100644 index 0000000000000000000000000000000000000000..de2374bebbb1ef4c2a9e1dd0db25afbf2a009099 GIT binary patch literal 592 zcmV-W0<ZmvP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy8gxZibW?9;ba!ELWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900F2; zL_t(oN9~ngPQpMC#^(ro1dhTHJOW4X2)%(v;K9F$ipGc#B9&;=H{ShML`7r75+adk zblh!sY=Kp`cAgBI`~sbw`M!^)YyqZgdIyd_95_K_L1`skNAC!nBo1)+hQLYU00*xK zoFop=7$R^&0UAU92VJ$730wDHkQEB>yRLp<>jMN%C_tnc{WIzVA-x>!=Z39&&&Ub| zAYIclF|t?dBXB~7q-hFJ>o>LM3_!JqtdJq;ngUdNdF?p|Q1Ou!G9+D7fQmmGc<w$m z0m@xug$yHI2X-FCNRD#X`SO&T$O<{x>caK|vO)oDbz$osS)l;7y0CfYNRWx}&?$9< zwH~bB2uU`^=mVn!Cwt=k<KIOPpw!7~a<FmhNze$aUHj4iHTl47e1!qj9`$|qnS36K zZPa)&jDXcEA+Oz7-3@ALuh{ltb(%{z4~3R5K}jz7;f0o~uT_l*UmU6@s>S#JI`2=O zQ!5^V3Db#Ys->NWr3*B&e3`Mzkaivx&s_<Qq2JvW5z@}X!kK{iQ&)l-H>laJwDYz; e)4qRm2R;E#B(lCnI~foF0000<MNUMnLSTYF>+s<K literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/subcategory.png b/src/main/resources/com/unicenta/images/subcategory.png new file mode 100644 index 0000000000000000000000000000000000000000..40c621930f5e98bfeb8cfee3862bc74ed3a00867 GIT binary patch literal 443 zcmV;s0Yv_ZP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru-2@F0H6Y<7@O1zH0Z2(i zK~z}7?Uu1l#4rqoKerJZ2sVTmc?m#lFeAjs!*G2VSkdjrgmk<Ftmrn73Jan!OM7i- z#U-TD0ar_wA}4lS$Nu}ns*7-MM~GZ{omS1*PezU{#J?k+FfBC5=^&N)dRlA(&oLD+ zsQ%nL#<!FNRf4oBhvo&<EI3B3nQ-?W_8CWO(q|JItX=99m_FWd#S^%Fjl_XT9+tuJ zdfkMR{D0s;$Q);m_sK>y4lu|d10!NQ+XCKz4?ySkdW~Z{-FEHcS+!S>HW<K`F<a>I z6^QbVgSyBOfSacZjGB8zdAS!#8LTa$YS{jri|^&}jOc8qxhJTmrHXGngKAL5Ejiz9 zK2dNre+47bWhd~*8PWA4i1_19bEH*+d%$hjtB3CC_=duCRUq*I4r!oV(I+cPP_0xJ ls6jP#yf5~MU_*kcd;;GtSS2-2!wCQY002ovPDHLkV1g9hxl{lE literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/supplier_sml.png b/src/main/resources/com/unicenta/images/supplier_sml.png new file mode 100644 index 0000000000000000000000000000000000000000..7dcb34dc367c325125f532cb98c73cd1fce00069 GIT binary patch literal 582 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP(r@M zHKN2hzo4=xGd-h(A;>?{(I+HQ!7a$uRl+0`%DRpH*v?o6OkDUj0O{Irtt#G+J& zfW*wa5<NfH5QQ>hJyShH1A{L`3qcO^ba4#v@IE`)+mFdnpe@_xpv*z#GuQ6Q9GrbZ z@E6+)&Ik=I#RVs_9bGtBroR!L%gN{(H(7v#r72ZBDM#j+;$?2_pK5bo?tlIM)vK@r z{x&r&JKnH}JT1_5H~IOUr;pF?uTJ^(E8&SN)?a8WFlfFN)O<_G_QE&wm3k5(;x8C) z-(O&q9x!t;J0s62W45P~RRRYVm|R_8;>yqTrGf8zp3t)e%#8UL%fEL$77#hk#%_LL z#=T?py@xzn4{01poRfS!_tKr|ZCh6DFDhb|{p8%;%(N@Fu+GCOFxfHh!Nm_b@sE|Z zOniI)HqVRu`MKNj8K2&e-2PrGrHYMR_Qy)4%a>zI*aGyTm+a=b6kD?J;PWfICS{l3 zRn%NxFLr0oLhU6VSKnTxaP^|%RmYPY;>tJECgdzmX-W3lBB2tcA$d?C&!}TIh)y%; zkOa~XUb(iPPM^Z{^iEgCWXCO?lWu(EJMs3BXZz>l9Lo<Lw0Fu@dM)Er!=yILSzhE% SRv0jn7(8A5T-G@yGywp7=I18> literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/tables.png b/src/main/resources/com/unicenta/images/tables.png new file mode 100644 index 0000000000000000000000000000000000000000..1fbefc297dd5b65204af6989a8f920b521cc39fd GIT binary patch literal 568 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP{O6e zHKN2hzo4=xGd-h(!MP|ku_UuBRlzwwH#a}8Si!NRq$o3~v?Mb>Pr)xgPZuPfT9llb zm;>Z0xTF?kmVq@CSKr;R0BD{R$h_eEw370~qEv=}#LT=BJwMkFg)(D3Q$0figD*u3 zfv$J(ba4#v@V+|5F^kDjz%{#wsee*#p5e~Gy9bn06uXpWUCa>)6mgwCd8<a3MwVHZ zM%N;H)5wU^KX3Ec%y8XXcfq$@VX?c8;|Hxw`44*e`WNrtcp*6J^UP%&A9RiOG`q~_ z=6f%{gn8mYUKKfsJ5x$@F6?hQ!u)sjq(0Uv@d*_R$^$QLbokCA#9wmW%S!CU9EV4Z z=R7@+Grd*zu(@ET^)g~XDMKfF6uYV{x5;;fj}FD_mn1hH(=(Z(@Oe*0Z*1EP|7$$K z`M>QYR^&VX{B<$pRrLKuPv#frbZ1FV_@Q{+Eb`Ju=e}z|ja$wEtz4xIv~pJv(8^R! zA^wnQKr1!$fmVKU0$RD$(!(ZTmNw8z3+7JtE@PmTBFlg}6ITJP{KKLmcfud&{t42@ m**N|@Jk{%*WEW}tkM-ExSzjAp#_k4&ID@CFpUXO@geCwwE7vIi literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/ticket_print.png b/src/main/resources/com/unicenta/images/ticket_print.png new file mode 100644 index 0000000000000000000000000000000000000000..5b28b70b5d31e01cc38d30473fc177b8447edfc4 GIT binary patch literal 639 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvVv45dj$D1FjT2AFf_C<F#G}vHN0S8C^cYUc$L7wU^Rn*LA+qju0R{0giDEQ zM2T~LL1j^9dPWI@b5UwyNoHB9f^&XuZhl^|f@4WZQD#zUNoIbYf?s}~E=WAJC^<7R z2gp@$NiE7O18XR*zPn)o&^#%SdBOQ<CFO}lsSE*$nRz98ey$-3WyX4@dWHrDUy2q2 zUEl8M;usR)espT4-=P2rSN(Mh^p3}tc)npZebB(%Atm@&r0$cv=}|^@0dI$%;2ob7 zw`68=e{rmuEIe!a^kV%+2c9_1vaR<vHb(fwU3E6wxMhRIP7gMb-E%Z2Z|Bd8`zO?t z<y5U#$KhzY(DwQLmIbpe%-gK*6yTe2{-wI&3bifIpEL`E7;jvDp>y$tha9Vz_sqHU z)MMY;hd<`dTfrys+BWOx#Qe+RR~a4iULFhVZUl+h=LiKhF;AY@^w<2{%%Jn@`6r~O z%NOyUlf3&&>Z#N(5Akntmf@R9s~c=~|DLe6cwI`CYD(6xhD#peW$_Z4H!9PXB>e82 z*tFK&jq6e<U%@|T-t(dLU3+a_X5D#p^qB4M9goZH-YV#yf7YD#ecgS*ChNNAmx0#C z?^gX+SjTesb0+uQ?|0{gxV|ore7=%Pu!UoC+qK=vZ1;+-e6o*6)L-iO&h_GSfx{&O z=J%Ge-x?IQm;6rq+9nVpd~0)&FUKm*w~_ml(oSB<R|zzms8Q^8<38v03HIMu*1vDh S(cJ)yI0jEwKbLh*2~7ZFq6TIF literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/timer.png b/src/main/resources/com/unicenta/images/timer.png new file mode 100644 index 0000000000000000000000000000000000000000..7aaa1f2660b657c3ed034b5178f7f24037d8ad7f GIT binary patch literal 894 zcmV-^1A+XBP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy8gxZibW?9;ba!ELWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900P!Y zL_t(oN4=IwR@*=jhRZkb5qtzKv-A;s1RcRg@C|YVFCc~x2L(b5u>p}eJMAH+<2WV| zVicRfnJZN)=~*%wT3XQWeNRLG^;dOwc_=~N@g6ZY<X)+i*Q%KQ-9Lmlin$etdh-W? zdHc8K5j+>LDi-qkH-b>}k>@)buYMuKac2c^qL)80!kr{Pm>F;|YY;ZP_<<4loy=7d zYdM&iUMyd84g01B_KhM?6Pt9^NDlkPjKpdcuzy{K{cDTB5H{V{iRuFUZc%&R%d>xN zE_gJv^Y307uy^GU=ws3K_V(^xRzWCxrmWe!Vr>woLihYmBYAIHhTc?>DH1M`d}g8% zdQ*##t>+ktozL%HY9#02?!+b|HgpLib-P3tr8{Yo2QR|#J$T;9-gZ_z|85fK(Vb*> zYoNV-mDRGxd@kCUu@&vO3U*v1EUk(~yNE+cr6+i>muT#C&+Q8nwlC19qE*0LAH+En zKTpmk+ZUCPZ_1H&#!cvqk<eQ`n~Ofcq5Ej^U=^LQ?duxJ3)?zZ@a!8Bb*<I2Nc4<D z#3vVB-PffY!`3;1pwTRTiK2Ii<m4=6Pu4#Ds*)GCd4?e97qEHekZF2y&d8pDe_{n2 zrwBqyqi7#aRJd_k^}SR6H$3@*An5OaZawTN-fnV;b>f0`f`on(>K4GB;+@ij>mv)+ zM+lEUXMADkW)11slfBnR@(UR|+CvlCL-eT>NR#AS3Hhe<S9@57N1t2*3H>jltV-ES zJX1b`fyvsS0c!*FF|)ig=hp^i$gh^E_XH0=Is_6ftg7N4NseU?@ygLx9Js1DIl{`Z zOXS}Pj^SALSXGKB>#aUetsEQB>bnH`Sai*9OxCpetPSE66;f~)TYUo_d~gU1Vbgt` zs4l?ocrL1K^>eN~Zl9Kq8nAri5~ztHUH)TBJ)@<=GAtdMghjXnE}-bS>1lF~{|mPe U3^CChtN;K207*qoM6N<$f-Db>IRF3v literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/uniCenta_logo_vert_100.png b/src/main/resources/com/unicenta/images/uniCenta_logo_vert_100.png new file mode 100644 index 0000000000000000000000000000000000000000..5b0e3dd984edb88db2775ce71db422a2592c0ee6 GIT binary patch literal 4175 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/uniCenta_splash_dark.png b/src/main/resources/com/unicenta/images/uniCenta_splash_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..f7557f1b910d553723c7f342c4f2478e3780dc64 GIT binary patch literal 29374 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/unicenta.png b/src/main/resources/com/unicenta/images/unicenta.png new file mode 100644 index 0000000000000000000000000000000000000000..acc2d2ec66d739fe2af35749c77efa344a74d8e8 GIT binary patch literal 8592 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 V<@NoCw4WdVFfDyZwWj@x{|A0hhBW{H literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/unicentaopos.ico b/src/main/resources/com/unicenta/images/unicentaopos.ico new file mode 100644 index 0000000000000000000000000000000000000000..506032704034db4f53677ee6e532b622225b10a7 GIT binary patch literal 21656 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 N2wfwc4_Xe9{{w;<_@w{< literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/unicentaopos.png b/src/main/resources/com/unicenta/images/unicentaopos.png new file mode 100644 index 0000000000000000000000000000000000000000..c5f9a878f6f81cfc7def2c814fb2efa08da5d95c GIT binary patch literal 27680 zcmb?>V|%1s({*gyNyoNr+qP|E;!JGY)A1yk*q(_ov27<4zkS`u@%)4LL-&WXdu!FM zs<o=l@2bi&$Or@oU|?X#a<Y=@U|`^W|9#+KKu`Q3^@YH|@OJ$*bv@P1e8^ngU99aK zt;jt6T&>8geC@2kz<k&0@@%{*g#07FEU=9s+;vg*_?jVEwr8N}TFu)mySPj=lzt-g z6FP(0Pkvs15#5`-PcTVgYW(OpbbP@yaO}NTXiXBi{JeDR4%rr|5DM|Q-sWi_^)-fU z*!2?&>F%6<JDq`Mv1q^j4ALkn`uEyBcMs_t_yv_vyS=<Fch?)zeZ6-t?IaRBQJ2}K zK|Dh^b&PwhS@<=wY$s&=;BtSJAfB#mUcB>x!mRuGw96M>{1tfe{P=lEdVS{O;Jdqj zJOwx2b=cFb|HdtP9rk{g_k#Daye$m1{e1kkE5UfrA^m=L2+JJgE7Fa!zl}m<Y;&+3 z;u_{qlzIPtov$^snzZzo{oOWLdlC6pKnJo3QH0>eA9j(*FO0sdw}pQ{eyz*>&MNS} z;V|+jtR>nnHK^~}e+nvaW*<3eW9jx632MJyQVqOMdv8a3+)rdFiNvO#$PLaz^Ih+o z9@%tTCwA%lJ^trb>$*Ls>-6hr?EP|R`#syEQvAR%C;|Ka4#-$pGI{FKD<!_+cf_;_ z*7q*B;Ih4lS|Ja!fb3xvx|uk}B<&tz&#)l~+nePZ)RN3$CFCL+gD1d-k30TtikUL2 zfN2Z&IL3lXtRUwN?Sl-GnW`_lJPBaw65C*G;i2UA+$H>S@yNX*Nv=L#lAMRbKM~8O zCPJlcUtN`KE>BmL3Y24dByyjmJ2w0&TA!tAE=QH6Zf{qytZJdewXE*o)XK9BftRiC zT(R_5|9Z<4=4_+p{$pBTD2a7XmLiG$%(hJBx6Npdb)nVYRcn*rNNB~{?%%+gy553S zvXMlA%kDq*U6;Ytt(eM!rw1C!LYEKAwL;CWr^mQ@9y7Hsd2~Sy-PQ>{N^~r3u3>5A z`6+Cq#P}?~!JscQI1G&9jdL`n9q&1%?iAVSc&z!X;;}|A1NpDGd_vft%er$kL(+M^ z8Yb~8uD&Qdq85Xu*Kzd>_B#AHo=(I^7GXM3p-TIe4C6PW1qP1!<yZ2^67^>ibIxDP zpSn&TBZ9t+W_F$!GB2<C@}>?IEslQ=Pj<W=YRRxzz9W6a<<vJzFdpaS9p;KE7<EqW z%Ujnuh!{`2b*2&qcHZq5AMuoZI;r00seN%*zf4t|pb$hWP>?{%4O`muP+V<^D=xXn zKXz4gHo$V&sX44CNGV)EeW<$I4DU>D1U;&M$n6{dl~=wh7kBY$87*whOusDt`~i7? zo{md^oPSx<*?d}8Jmbj9=_g51kTJ)`bdXQaako(K%KqW6541oIUfl@&^+_Fjw9YzD zA*5Q9!;&Z%pd4Lkt~G$VZGAJ9$%X0LPo&P%aVeMf#oqFx3(m6@Z~EKNOoEy~tg7Dr z<i>;8_aqYk`_GtO?@a}@{O?vpMt_M{=GK6Y%O>@QQvpodU%rp``p%^_Nwax1Uxq-! z59f{RXf6@Fwyx<?*l|90GM@qXN$L|dLte~(WXIG6`f^Tz4>+#S3}6k%hfH9-kkz<> zoN<W4s23^YmA)hmM~7KiIzSj}QYR_eZDvvL7g6gW*@_kt`PTKNljBk}Wy0R_ef+Tt zgyg3Y1fL2zggr-ZV3m59=_?Za1Cy0!vcKy>t2dH^HcwsY8qM5_vkFHW@_FN)d=fUQ zKjw}kO-CRjD^XCjrmxX2$#uP#n}@duHEzKn`OHsvV(bT!mQH+RYX{no(h*M?H%z<; z#7(=8@lBar4{DPm`60PwR=9>7G8P;2r=cqjYh|H9bvkJ+{;dA?v@6;BT4<M{Xo1SY z;+ln&*{<2B4hVD<0tt!1j37!ppc5}2w&KQG2`v+$XPECy=wJZh@C9wiLn6&jM%v@> z&9w||_SL7-yh$>|c3Pn<0b5t<AAp4)&+zwX2S{pDEi$we<4S%j>_}a|u2`q!p!ivX zRXo}<Gqw?WD%U8a^mD1@PL}HE6f_!iBV7Yr%oL5kYmS*pOHK<ECpr$ZNBKCsf^Yp| z{=TwS3_%-eoby{fHoQt(V(Z=#Fd!&Qv^^yaR;mP5#Mh#pGmy^*MtnLcoO$0|-W2BP zwBnI*0K=;&?1sHzswZi~v{`;IPfu8Z3{OV+<fIqPAZtmo-*1_%CZ=JvExks6Y9ztZ zg*nQ(eDZc-C740voU(^|m#v&Y<^)O0!}*OVl)yQ`O6NhEbexRo*K;xV)25mvXXL8h zlnEPiOwHU0?2-OU(Z@aim{?DWOmZ*<y)=Xq9n<TIh-ei*1sptw;Y#~;>GErA=gL-a zNQa=u%X(K|_fJLU?Z)w9tA+AtG?D6JRv8bE^pWaWBG1#&di+a`F~baBaL0SJHKAyF z+Q(M33(gsPCP4AL-5jLVq6H1Ym3%R#ER}Vs#&y`YZnY&lFDO#zGg_Yb@UoXl(Il=2 zoLMvp<CAj3+&{bmXFbl9*z^3HEcked5D%Ur!Im0!WX!+oN%83LbKM>P@xN*8&|CY^ z()wtY4yDnchT@!AUCq*k|5DFcEX}2WznGhhQSeQ8S-`!G@T^8A9HmbOo6R=0ET=-; zY)P?4yCDD9yHEx{8yf`e?+5iL!n(INaSQ&-_TUr7d%H(ne9dPZp6NQXt~Ps`DGzA` zv+Z_6urMwndIOHkiA2^wWul}UTtVcA%y3BQ{t!I|9xX<gFni_Y4V|W$yaZQxWGj-J z?~l1xtcGZbtpF8BMtSmPuv7&tNrAnQO$qK;eRIcB`*(2WZ|Q1uFD1ljBUP+xq7!Aq z>^n{!>$VS$zi*(JTDS>_>md&Stzq%sqo`HJVN$bm=ri_`L~D_-#cEGbSJjKn$cR** zA@jkgvvo12{NgdRXj#Mw>|&LQASOinF9N3%Y=iJ|c96!yjyHrCZ?@`H$D5NWN6>ed z&IZx(?a7(77Jr^nS6kDVK0PG?+lo0fpA*x+RN1j+435MWU3_1r4oQ9aLR%xU&_z3; z-0K@*A7BAIHaiBmu|_0HHEyWkj))<XSp2pqL8kqB-Z7ZuJ-|eAm`-n_>?-xsm)7o- zB$~}B>>CqF#(|&%{8RSdRDRBFk99}3M%uEcEb*(F&hMGa`KFbCv%K_cwmUJeBQPii z9#7q;y-Q+15VWVugdmy~oD<E+`E&g@ENa(c`=u@t!CW}!P6Qw9V#W=EyL*I@SJ|-E zkRYxi5!X^nq^fPs#N-Vwy&cz^<l9-1hY-VWw55CrXl~gZx*Ufhw<uPt(D*5|m58=P zne7a%*Zc9NT4gKEX~obeBQa<w<W<f%X#>ocOVp3FxW@>><i5qLY%~*qSa4GWb=LU5 z$<uWiyIjdGhIl6x2ft*0lOZDVgZ<gsS>b|_&gF)nA5Qwz4z<bvtS|1qx0HH2$EwpH zGNj<1!&7HM&>L8e?k%Y}3lds)&Gw>q*4o>q3kPx<%0$i!r%x!{_GR|IXukE~l*|2e z!-EorLhq3Zx7Lk-*kUfZ>(ovpo=G)~{=p7;22X{yu~&1**!jRX&NN=Hf{ORYM|V}M z|6W%mIk}-WuuePa7gIk=vU@UfGD>#-v_QXL7-l<8<F7o4<uZyN@}s*RKo4C@#eS%1 zITEmiZ?=0wzVAN@?A>*|&4$?3c~F>5rqF_ig?xUleY>&BXVZ`3i!u76=gb7vPsi<) z?74jwguc)hz(u<KZ-AjQ;OEbU%<ZbMfO&%`@Yd)x6mT%YS+6zeJBXU~qJELo!1)(N zBX^tQLk}2KE1SWv@g}Hse31jhxC-3*g~DNoqWGK4ABZ;&2upG*%X@)dHQ?yBimW6Q zyy8+;fVyb8gxhHEBOiqo{mP|evhRx!JTa^-438;@%Y#?$cTh~^8W_AG*$uWnzW1{V z4QtiHt#bipk%FX8h&_}YUJ0w<fTGxQAj9SF5^;vXsvid`%76Exe!vHyqkX$XLs+O= z#2-iv`WZ-v7duP3hMlWG80oA4o`E(f%q59|rU+>J4#>tvODQ&NnXLRfA*u=VltiBz zWJrtIM^LL5XB<w6+G9e)W0BJ!!ylfK2lVg7kZABlB=B9UyB|p-;n@L&8|7`I@cT3< zzI?g1L%{!mSDes<Eu}oTM*g}`v#yXJgxvX_KAM~#yOr$lfPf`rE*2QZw<Z`G4&f?M zH=rc@86%L!JuLHca3wLx-i98|UZYhzH`73sx0vO3YcVfchU*5|MoYu_nm^;f9$ec6 zMJIJeFUF_?c%UW*3=!40D94r2C-~cB=lZDEj>>;d83vkX;mf7$4O)-Nja3njmN0mQ z?mu|s1^3i!fK@O%0QCpNwEVdZ(_XISUB`GbY5CG=b8U!W2-0x8g5P1fH0?sa(%{c4 z7UQjnu&Tr3YR|-uR;Zl^^D8~EQo`oM_C-UBLp*(($C$X}2~m=eP1ij4X)M|M#7q0S zg`Fd|rJ~ZAe{Z;LT>kodW2wuaS@JYgbdye(GY7#O??QIfk2p)p<S@$vTgl((51=Y$ zbBylvwAF!%Sp!?;RhIS+>-V-khgPD2QFQe?WTQZj&Sb`da$1^rwB!FBn{Hh;!_W01 z2ZzIpL>?J@{+;CAh1j^pC4DCjExme7hrC)Hax2#1yf}Y)`ett5fb<+r0_c>&l*45% zvkU9Fv`N;4#aAwAM}C&N@IoJlDiI4+2g#BVZ{%VhYW@vz5J8R_0wS_W*y*~CsR%|w z{c~;IQ5*P4P4_m#t?v0y(f7W|5JWsVng+H8IRW3?uO5zX4i@eW`1gC>-cjxV$4xeb z+!vthzl91<TH8Q#x8%4o;bBybsTAh;lnh&=UtO%U8&kN|X$OR6Z17y0JAybkP;+z@ z`4NAO9R$SZiz0weMS3lLqdh?U2tOg42II%`Eae!nXgeY?A4ByFhyO)FFgy-^lm~7> zFnL%>+QaNP>RQKGV5Xfj{zpnV<3ZRfw)mkWTa=C=lqVEsPNs5Z0$`|5__zC}K#^O; zHzvmAapbGgP9*qd90MiX*3#)4GSQ~v8d4cg$v32IL1H2IYF-3&Wu16wveb);KKKfi z<6ir4VDC%*VM>KKk*T~V#K9L#J~HtN2L#b93S2{V9d`>i!fvw-#WOVhAQga3$I;}i zmEy<h97nDjuw+NRyt#;cw?KL&#wM<Z7~SufwSz8)d9OJeMdr98VJ~0Pg|?KY3j#O? zyr9zqUd1%y{vsi-NoU+l*7$?Pq==Zgn{x~6X@PhGSBe;nC7Aof2@!0P{JjsgV8v7m z(V@$eXoFP3GT6K%_|D$AR_lx#87?|vCa5SkJFdk^HeUYQI{-(#CS0tRsV9iXQQfzi zy0*H8E7Z8cU@wNZ4GS6uY#_pMkYJh#>lv1<Syk>Nq!gqmIc{FXz#cC9dGC9h+q~K5 zM4|U70<Oh}c)EUkFwH(e`du?C(QPlg$;iH#S$y0I8?;d{*4AJ8N)ja1C)QyNdDbNO zPl5sK#iT3CYkORQF}bi`<Wn`#ir!K&)x5<8ieUNNowK<Fc6blX$hDfzjSg9pToI5* zdh#+!wW^%LNS>j0TT9`zWh76wx;#}jg30QMwZwd2l6ol@Vs!R3;D87Wicp-dv~tNI z=?Z58ltPKTp1R_(nwLJEWbZ+LwngdT_|uC%>j%U@5*TMY1((SSpW#GmmXDH6&cR)n zx<5b5YF7B@(&70C{rZ{9w!Az&JB>8fz?>3%lPe_1yqm<IO*6dDk_qi_MblJh?3;FK z(9vZl@nW|Yt<#^}H7<}MB^G`qqwu>j?-#wb9?7wZs^s>qH7^aQCAh;WV<*<G;ypH{ zF#a={>L`nF_6AlI%O`+U??`rLN0oiZTD1glB`2u6r-n{9lF64+l(z~+QOpU~qrB3g z%%;Sn=8OblIQ;~-#|SS<_?C{t^D)Yg3a75cYx^(ZZ+g<u<a`0+d<|BLD{ukK{uw+5 zR$q0DFvh@()vB;R0AgKnVdAe4%*I+_BU_nQ)>|tbTgb~`Y|Vo<oV((`sn&isvSk+` z&GJjlq=ykL^6o#JX6J@xdp~2LO~jg|pQSFew1tM>-Z8cR&WqKDVate0p(Oe8Bs60t z)^L?AAo&^+<EoPONae0$Uvk@aU#idrQiZxmQmS5(K>+ljjS;(b4+tR&@b$WVeqJ($ zMTiT`A_aB+{Ot;s&RXI<)-?1GN6E4rw3W?v)q#Gm*7gc>6xhU)a}BfK6_mf;aTNN| zwf#o!>Mo_KQL9aWmGj*bT;8n;m^gqCl<q6t(%(G0kqE`v%vqg}GpDWbNUr&?9W_Y1 z`UfS)dAhSIpOEQysVdLPm~M4&N4g%_dxbF}E4dK6_>3BmAg!o5kxUsEZEFF1+e<yi z0VSO<jB=Bs<p=W2<i@|O5;tmksPlsov;&yLK4`R#T}jJ*Vtdgk#c#S$xwn5;-)SQ! zXGXB%R8oS!mG4lS4;kWm=}-er=RdsOel3`OuU`ND&!rt#k`6(`%w2eyq-MrPik8u4 z-3Xm+1j%-vkn2<tWn}KHw^8y>GT+I!R4cUtvq{Q7Sva2t(Z&*^d1skU5z=0-UJ<Z< zE*z>rNex(9ED{(SlJ@pEiOg!{{7~GHQSRuvHK#NiKZ62d;9of~H)HE_S04S?E;|(j zT2!SxdixFYJofvt5AXZnp%0$7%Ny7EIsZBCNzU&il%rVnOZT>7fOt6*CeQcL1kK9| zLk6ujZo`LvQW*G=IQ07fbz1+<K1J;0tcmC)uwTGvS@gTLaS}W@)ZDIq7g@#N>qwN) z4q}GEw9T<yX-?hX_;!+8up#p7aE4A58QpT$Nxxd|=N2xlQ*GiUb2QKVr8#yV7Dfh! zofM)%Wn7|2(?=xDpAs>b{}8{|EtF6)N_&n4WOu2l%_H-#A1%<s`qhRS!HG)uH%Msl zx8Tz`>i9(kBsO}<>ux@^({^BQP|^n`3;s+04CNyN;(Vw~$!uk9nC}(D8Zy{Fub$Bw zmp@%IWBlU@A&o%UA(^-CQeuqd?%i37Kn9lQY!RUS8xqjxhgFMI0OM$#i)tlXDMh>t znGKNoYf901g5h5>v5x*5&nqU7^fo!T8j=#-@C5ujhAut|b6%*ujQGL#n=(&(G5qNg zA^U#?TF7)f=`|$Jt~Cu&H4(H05pr3!-xA<#Sw)NUNU(k;aMec`dJCMo4T<5(K3Z|v zbd<v06j+rO%!cUwHl^&ED;_BWP}yd4^4f-uq>*>>p8rD;mo^~_S>F&<(3M2zQ+5q_ zIUwux1v_-m2Jo9){1c&*3bNngK6{p*vs>mleaeP6SJDxsp}i=#k+)n-IB5P=E~8FP zX@EY)A5)>g;9)YY)Yz)TGc)^xR5sH%Nx%6CUqF32SEfkfDoH~hxh;Pf;ULyzeNnw` zt%LdC%vI;XdQz(kZx-!$D!X$Rk%Y6TtW#IPs%)oWtSWKbRnn}lL6I#|0XZ=l1(wri zzn<vae3cMafm-RxXsq#!Vj&!YrT7|aQn;S#UbY>ow4x%tX`fVF3#3~CKg+V7>l`{N zJ!FI++3%m6T&n8mdZ$-UT$J89+3YS&Mr`%ULEFbJ*||@>{JzU!DABe^0!UyHA&{ZP zw<-RW;j<OG+g@d3sZk_&gqn3IerkIgn(In>Q4|r%s=1F_j16P@Vcc--fbj~NWV&{! z(ZPd_^EFa_NP$z=l!D+<<=s=dNwz8i6&o4e$^=3jd2$(zc@0s*wWtTGkEq<P;^Vt< z->HQ7r(W*Mo~ybqM99=MW@%Eum`4Kt(+U3#`iU|@$VDklgDaKJ>#5x-`9OBD@g!#4 zJUX2|I8~(M_%tJ3rZlkr%vPQ20M{;T3}9j)00CCE0FD(5);}xHk%o+kk1duOpD_(Z zn4^i!bBnk@cDDAe{NO*x#3+e+hw%bFZ<^>hpSd$|gpzXAa>LqVtcWP#gUV|l)XRj( z@AY21m05Vh%DRYHEcna6Z|!H=F58#C_+b~UX7wr@gfGv7CYVCp9ypQ7hQH-cTN!mz zX-@B1>9}dO7%qbP8AcIJp5M3)9Jn!ecP#}dC0ANMSxk(^@`a6G+OHN&k7&w1ELrc< z=6VThMGCXK2iMxEOhxJw_BX=~VGji#H>gnJ#?J;~)Xg(VPEAFAZ60Gkgs_g=XO*Xg znI)_5HmThm8use3a=}-#1B7q<C5Ll^X7=lWCt%Us(}*wxZSz*Q7~iDTRj`DACuo2z zlszsFpje-^3ICO8XjQ4HITH!mY8m*^j7J0(hB2(d8=H{-gGs~LVi>*SIc5>vr+4i5 zxW*uJc~>j50dw}N55Ba@dw^_b;??;EzPUqr`y@2biLs5V9sNOeb6zmjFU>kE*<dUp zL<8k0uk_CYZNBC*MMp@^nMdgn+k%MBhq>Q%6#Ey+xs60lNYZ0-$z;#jeHrAx{f6Gc zFet<wziOuy=kq2kSzgYx3eNEld(Go7uqvF=Zx_wLcTnde!cIa$RZc?U|C$|OV6-Vg zDMGSCqIgl;mGV;bD3@e=$tC=HXxMW~HL4K^CEB)20|)aWw)4s5?Ys!}(6AvmH7Lx} zo&4<xVLPZXWoc=paq0hz)NRrCiN}PxpL<w*w!y{A203dSkY+vC6=^Wdx!dTYi~+Op zrZ8cXj26nN>NmtD&u}*%%+t;9=buEN$Y3riN?B+XWryj4rsA{)a~!ls%P>KI%XeEX zhf5iJ(7AU@cwG7iVkSN}=RwddU6;|jaekoI(tbE?m`!Ve&Sc!b)_rTQR?EKDOXYLW z)!0Puh`$a%*%U)1i&jz`#ZKRdUS&ixBAz>qDf}t6%#xx2(7}%<LaY`Kzjz(^+VOFz z8ys%W!cqp?WJ$bdLyGVYwcd2=O(L%HgMcauW$3wV;Qn^1GJo#G<PG)U0*Slqq_hgj z?DH*@MuOW)2Vouq0ea^nzLySG(m8aCtHGttBVQN{|4i!)hL;ygIySxM>i(*5y7$9i z;cOdK5ZyiH`hHgd)PsUCSCEkeivSw}d)y}suL3=Rca_!i00TqB{O<z}mYa_UdI;+& zrz8b?1Ob5sMzp|O$O8sO1|}ydrs=zOvFVdev{b<J?xN-8rJPpAStiH<0Y!k01ao2Y ztao!?_<Rv(Nkm2HNMRP903~imi6z5_o&ZHIXG!VkD8ld;&mt6FTpT0S8jHr>{5fK} zWH9LK1bx&Pw)(8_wD2V;@p&Zx#Yj_U^L6^t;Q5nT6b=x9CjS57ivm|B>zn0IgKK?$ z9W*5#k8ajn9y|u<G-x1WD6S-)lk&Iy0YXW<I%PO%j&xn#xf?zbBqT7h7;0CdXkSV= zsaWv%&>!@gQZN<>>9$brj7VCE(TBReRTxQE`@SWLi89Y0_RD`+H=)G=DlyXApCi9F z!zKhbO<VM(@-Si2uwj~!OIJ~h(faWv;b18GZ+D=;!{(3@_W?1LlD_v4cpBiN{kMYI zKnPLt9el|C&|_#<K~$|2%z^sxq7M$DF|iCQS0Y$fqJBKzIXFIoFsvtuL@BbdvSbRt z_^s<+p9O&SmUa)Y-K|4v)Ld{yUXo0+NYUr8iZN&2z_zxb?VyYv@6F>I4iA%tA7%^T z!b&Y}z)Cq-z(c9e0@?3Y6v;Yv`>Gt#6iO5Rmi0xXp~YGm_5%Sd^B)CZr1&?6rj*<} zcnl00>Kh<3JlVobGKfTWS9Gc-soq$@r$BW)&CKSN_*o~HNG~9P+oxjgEMg)DIeY}A zObC%$1_!B>54}+k73JN;f0hX2OJFnaqM!78oP?NSN{Q@k=uQ^d*r4j3nyi^fxhvSM zC~0XZ$*@H4WrJY1J4q`V2vPRmJR#Z~>wDANX5L5r7r(;?%)@Qn22FnrlH~%j>voV! zKS_N3X}<bd5<_JYn}%7wg_==nsgXs#q9Z?$&o4*Hn(*uaNK1uh;(L-B)@ABqKwEx* ze-yyov~)kZYCFOj08P4@gIKnSJYcIFUvMwzJCF?Lm6*GI90Fb)3!#-rHTuuOY<w5Y zd_XuNKmhIXTDp9j!)bduA^OxD9l?*iy7%$^aQy=M(1S@2y0QHpu$GTD#SK@=#}+k> zh;?F8x;%piRvFAaB$HB_TxK>5Ar$lALjl^FZQt>Y!n%Fs+#@;G9p$O>%WaQ#8HGbp zv+ujo)B7ANUo)l#7BaOf3_8(FIHb%#;X`3B5*0}#5i)?}i2~<Ds=bQ1<SKKBMSTYo z!LM|zPNXKsX@Y*k%=>sCR|7)98(i^;@dk#1HxYL1-ZKS;?gHNeOyS|~&=&4CnFak{ z4>6o4CwE`Fmm8lEEePw+ic_CSmgd7G=by*vgZUY#%>ty-d5~dq2*#|l(DG$FuwYsl zCBx(~PXXvBjuCwyL{E<GS%q#0e&U~NKF2O_d<ehmGB3n+H~d)FHdyhPc96-D2g*bC z!hg`G`$9E|iVOx3!#%f9tSoK3@8O*7YK*6$pBwb)HVtJO@UII2A*^+nCF3Bw=b#2m ziSS}eDpT#uP&33*_EpRA%!645dkWyZd4{%wKaW7R3`wg;j}*iQw`N+McJwRTCE$Xm z?ji&^9FfbvKjf6`NOy&yKM=6!Q2219%Nrnf3zh$^&+NV=+@Df|*4?!pEr@e=PXcaS zGm^k6D5EQK`<RPiu*{C&gEQCnCOie8UD-wVm4Oe`SL!u<xL=ZV@`H>N9`xMnr8K>F zYjri3!MeH$Iwxe^x7>l4i=7&TbYCQO%5TM0&;!%dptUrNh!Ol!?W~zM28pEhlR2*3 z;iM@f<L+4$E~4j>hezmBaBF0OwFexFV^(dvte9~CL;W_N>ZeFxkg!)QUr0W;eNneJ z*cQqA=;L!}<o_MMwYcq+H&Q54a3aFhCovc5xjI(T4ty?s)$EZ6n>+_7s)hCKhw9#( zq@I};jE0tL7~uAcfjt}e4O3Ef4lLdGf+eAl?b|*8PYHx*HaQKBJA9PnC!)Cd67x*x zKJs@i@W4`Ag0cJWccYM8KFpb{(<eUokRi1D0MY|nI3XJmvEnX#7Ds(iJ~4pG{0Ngs z@A4Tf0iioq=8&-}jDq&A4cA`|77ymX9!VkEy*e5D-_4?Qp_)`lHT57gu!qBi!HBZy zB~mO*fe_SxVqUwAvB6kkI)FqqHnE=BkTzQQhzh&?>c*^^aMbsnD1ppl9^A%gHGXsH zh^#lI@SsTAZ3;F6ilFG-Wc{X1G}grMFnEgEaMBukN#AVWYqx~P+*D!D=1ty*ZkGG- z*v)ulq{<sGOSVuR^7$f!&h4f_(BZ4M3Ee1Ivk)K#Y|&=tucF0gavHY`!+dhE=CiZ* z3CszoFm5NozLku#fnWzYz3eVnX)sH=?ms2gX?mIP)>xvD=SP}oXP-)!tq#jdQ}%80 z+`0vpPc_!AJB)LLcxt?OYdFXOmKf@rFxEzS-SK#>!FVw(%3+9}8z0W%wq3l!ZBY() z+JlMW+*V%!k1VZ$LLG!MiU3mrOaJL~Ghiy5yI=8`kgAJOVkAHYBIY3g4fO$lb0W65 z?J=}POt>|*_{RQ`_{Ja=7xdlMYl@SvnM|LEb+y^FrGsqE5RJ(j&U_D7tn+K$Tv4gE z@-bj;+n-<{5$0mmmGlrcQc$kqdaG?qgY{+2u$ckZ+UBZ%T26dzQ@awVddQ1K7wfx% z%10D|1y4?J5=jJ4hI1k@9ssz0q-pb&84P;+JEL;}TFaWyNjZDd4>E2hpOx<?ILdc% z7eUmU!G2bi*Y{U*AOanM_~bTZhzz9vbnwsnjA)(7lByK(Ldv<eYrR&UfJv)`%`yg1 zq@sGFRVp*fi5p^8Ou-CgZN!&mT#3%^gKZMM7N)!C^V!DC%R6<Z-tb?BZ2h&dM<p%8 zJy~y<eX+{g@e`1XF(hdB$ezVk4S6jkUWf?iSt#SO51*SL0Z>WZm8mH*@4&1vb3f|0 z^{N<azv^$1qE<+@NRedOyp}3&gB-ZR8HNbL0yF7s>kG`|s`9NLDL^$arbDt8P)uZW z%?BH>h3Kys=&?~fl%$$;RT1zfNF3buW-g0f0a-8kWf!u~Qtwd96)Qe;?usP4mnWjl z#S~FME0b(YJO=g+{pwN@6ry(vpI&j>n17UZWeRTR^`+=}D42qBS!xC<C|TONl}}~& z(vP7(`k`MqM>RZh78(WNS|LUXzL=vv`>Ra1|M4go!4%Fr7uFQnT<v$3QcMAi4aU4+ za!rOCDZ%*}9CyFkUMhE5{CF<#b3oDckgxwQspV?Hl~Ev;j=*oRwwQ&uX=^SXONA&9 zzvd}l1?G&N(;ZA~^XyMc@mOV<bc)mjve$N0ux2w#EL(gTy4CouMBAF+hHWz4v=!yu zuCdsaot8XozWwD|y_5fwFSTzvLH}*;2!@3qn(<;)G~hezo5=Z+NY6XUZ+ry5JHO^k z!SSDCMkoQFC!w2J!vOf_VO2%ECR5VV50Z#(CpbTSTUu(RptnM;0HZQ$B_FKxp<E-V z0Y|0U6=;}`Wl{@zEV?M)M$%qHn>nMefi)dcJuL~J@8ZFdZ$~N)*2jr`fii!y6)>Bv zk;1nrEEFT@M*xu@F%MpV#f8x1Drmq=Brr(D5m?ogj&IGpHkv=OZ}x{FbRq|F&Rj*4 zfH;h#mtFzRkEQtdo$Vq2&2m^Vqav9mgzDD(5ra2&6m(foUd^d1fu@RLlgCoUHTVPd z)=*srwkQv*Cz}GXqsl%w36WG?aMF1Ux5hSb!xF+!{DeDvL2v<orz$Q=l1TwQ&jPqA zGkpi0J=3MPAW8u9F#-h2n#RV<hVVcTBi|VDN^r?XImno=QcUXc!#{P;v921SDdM=k zlhrqvBE=F(Om4>&-pkAeoteIzw`hln2m5}NZ~b<s(H!FH#DGb&x(Sv?RSZcl14IO1 z3P8Q+EBCz2hyQV|>|%cpa`}u(Zuae7QsafO_AxGnTQ5dFWMv&iyMHe2Yb6On9=m<7 ze4~q|J&4XaZN}9+R?hYx*JB4y3}c6rzAxTD7}XTj!emf^3_5Y(2M<|aZEcuEY(hWn zdakeYz)5OoIZleAs-kUbXdpxRP0mmWOeP192w0n2_QdG250=%F1c(R*{%2f7mL9WC zp%AS2Cq}qZH&y3wdWD$iz!+%%9lm?`Fe9aV;{eAg?@o#X0S}#PpA6;B31eLpP$5S$ z&%qU##f}XmNA=`YF73Mdz;6&z)^Mjg;8<~D@cG&OT?Z5~bF=^CpJmm6BC8dxI#OsN zDCJHUH=G_!1^Cp4q+P+hkeZ1!JS975O0@=PO6`3l&#~L~`19dJ^<5GPR*97Qh-2O5 zfVk`ZpF8>n=iekA_>6jy;j;?ns@Tx-jPW3E58LAQBnlXNsxgw#@hPxWUD-AW7#HdU z^4HWNWQP9e4oAn97mP}-!tO~Jn_F;AH~y_YZlion+i-VguX78PeQ}kp6Q`LWIZ$0a z6DMjz;Xh4M$>vi!(RLMF%-wgFOZ7C!)@Y535)owo<7Y(m45Z1rp07$s_wiwL=1i%8 z7@+7^aQnMkra%+He{>M9j_%_$z)d6C)rAIx-ieElRDefn`M=M>DMp6}%XVp<eoGG; zZPO~(Tow(>VG3|4fxKC-JE3dDJlw-MqvB*00Ut;I6l_gn$TA^9L6-8X5>q63!C2jD z($J^-6NevFk<^q_!K(LYe+qo596PAc>Za2(*V}b*04qySDj#BkU9UEam2?LSV+HF^ zO{H`^D7B1=W=S@t1p37vf`OOEH;eP@r@^V|osaca3L9k%4$Z%TrYy87-6ry84aON% zlCS)`d|qfO%rD@rE(k9rk9A#HE`JI*ot(FZ836jkKi+WJxLF@-afNJ9%aY_fQwN;S zMNFE?Oz*s!H!CpB8dqTd`j;z%V(ONM%xu8bN$oO;Nmuk0Smb;0+kY^)>}9xSC`Z_O zRdViB$b$9$YCdsz$C|0{&AS5Nv$r(_hIL45^{a8>Q0F<2skNuKyjAzXej?h;`rUz) z_kW_p=z~SNSfO|u)t<!q1zTrGiyyv}N=oQo=vF{`1Edknw#@P^<bv^rwnUE)dwF8- zeO^YHyaE-q!WVV+<PJ0>ud!_Kcc{eh0n4blLg=}(cI&{A3WmflP}60exVSLz_lNBx zb0)_p0w_?E={rvJmH$T#WK+ogvuOPr*vvvLeri;3`-NI2*OB_lJw{E32A6SzEE_0r z-sHdFsjz&Y3n6|%sAP$DxqNy~DB8^NuDHvS<<`le`i^RjH^G6@;7R=#+SGNQniROo z{8Dqx^&Wp>PjkcZ26{vfZt<`Mn8gHXFj_+6Ar1uyu=b#(wD@|##{-S^G?UgiY-4Xo zkR!<D!_HuE*bIgahgEvW+!$WYoEoRZyRF|5Gupf#HsYoanf{^<`4`0o^1a<&We~qo z<Zz)q&^S+g4A2c;YGv(m_gXG910sO*6Ssu35cGA9#JzD)I>Psq$@>Do)@TG^ulgk| z391GC(Gn_>)hI;JiPJx<zWlc@wL-P=s%e$K!eb!E45g|O^>E6K>v>LY!|p*Ynui&u z+*j(e2-e#wugL@5G1DogD6&dZAeBW7bkI%V2VP%ybXcLdaAa`z5x%zTsg9Z3vBTM% z%!lzm=6tD{moi_o{lHEh%a!cb1F=k=Q~7pjt#a!(u~9U{r;@HuiHr7YZGUg!Xyb0` zx%!GWx2@MC&@WWnC;tX7HKfY>2)8(*XZ;?MJZN_&T$=+fg*GC?zqA&Nz5wNoA}=hK zd??aggfAJ(JJWRmr&f$0SkI^H8k*i?9YECV>)nb`qhuU|Jjm!oFc@s6He2F394SCV zuP^#g#}Kla1GakrjPka^(cIt<Yqt%`?p)Uwsed5|SDU9OT;1JtLV&)}&gZn@uH<G8 z*<jD*3GXX+;kN9XVQR|0OiiIBA12UjiY{s({T-oBof7W)G~D;$`0F|*q@Gq+{Up(= zOYc<c>o{cb(G(b_Ta5deDDA64iqzNWSCUYVgAdXwe#wW4eGt>7ZfH)^<tokTgTcPj zM1vL-f+u#0!jXl#f^iO?H^{>xJTQJuKw}V`C+`mhmsmHJ<!jAPB=z?Tkk?P#1)_p0 zUlm&xLFlDRp&Rf^?dK`m2`6m+XA`Jl>)IEVR12Sw(s7u(h1?IEL=x8>6n<}o8+#Qs z64ITZJAM1G@m=R?ibMb!M~8$L;78SprvZozJORF$4o`Q2(krEi;S-)mX1q*eGrUSe zw$gGza^G#5*GyBloX$Y1QTk#~at=Mkfs@Sh#PjVUqzH-I3`rz1fYNEB_e?I+#1Gk# zk7{Sc@{;Zk$Qj_g+xk6@ECibaExmry9>4?a4q+8Y&7ifG2SJi%AiI2X2``)|j%;Hg z>gpBscJjA?jN;Q=oDP_ZU`L$OW@iD8Dq1Q`p@9d_^6hC68b}w@E6ANqyMx$N<54EL z&AVpc*JlF7kss+T;OiZcrO{<05Yu}4oy6F8R|>&je7?W%@xFap<tqY|NPt+d$q_PX z`($`ijkxjRSHpJyo>;W6Dw9c%3Ip%to-!PI!!|Yq4-OA^3Afwv-;6^F!U~f;;a-uS z-JFWLBSm#6H0k(+{1f-d^z&VlfTEuV4mQ)-%{TrCFJ@;0(In<N#(q?>u?S}DRK_>F z1<HYkxehm=U8&Aurs4>_26P~jUN@k6a)thopHF01GaRR{5jP&uf(3Df5~Vzz=9>C$ z3@a-u*1WHu1R2ME2L}f`oem8n%`-wWVk)u(zHaBKz+XdsGP4W0i-XqEd4!Q!LCDQK zJ%Y7GkLb8}e{^bBjEsyD;4!KDcmEaTImea8l$MfjxPCk?meEiubvOEfFTc*Y4DD{A zRLADG>=Q_0BCzz3v@wMQt_Yt~&>tLc_Z7baYwC0L^whw!){#F+v7|7h(5a}X{+)R( z?{;i<(Vf7{MHg?k%>KQZR&aq4ARI`=ejtLKGnbi5Z!r72=QMPuN2&%0d0f&V?%a!I zNY2WF9TL&wpK{x<5qfPf_8~6xKePLvWfa!4HaG6(u2Eq52?iDq7CU!+NkAovJNo(o zpQ9y`(&QOcm8-Rp`p!G~gTo{7e_^d`l4_E6c67a;j}5yyHiZ?%G?c_)!3I+;PZlAP z#m(Tr)cC9>BHwWIU)|~liADNCABitkSa<kG|JjCT!<8a7HrA9iup<|*l-7K)TJ7KV z*W0$;NmMdtlg)=<{rPYgoHv(v%D&vm6e3!kGOzq7MZm_P5@-g?!`~Ti4P8(A>6us( zSgn^hEN~F9adEfTUr#Ro!xogiou@s{$jG<6t7AX?9=c7xjby~t{-mGO=L{S@jt&|( z@p@e1$;ikWvYhYpb5&DAckVnDX>{IvMH4cQK<cT=+8%h!7m2m)qoHH5@C!!=k&^Ko zR_yKf)6^WSyVK9C&yHhVEh{QR=4Fw5xqGW&D)<stJfbnZ(_3;%A;G4TH$#_wH;@dL z(_^K=WBTuY&ROwX^&XBrTfa98J4ytf|8=?mGBikn)|L$aTwA>LCBoG=xP4l8v6w53 z)a*%1=G+tVu+<JZryCv$Zlq+)#!$rJRT!o48C;D2S`ucI=(Rqbr&>1lVH%CcFY_b% zytmYo_VM9CArXvO_1O>uSCP&2yUcQU_MIUK=2=;Vq9R!e5=_K3bwB9mvd8G<36YS7 z{b)pbA#`ak`Sr7uoNoUnwzPl$c4vI9?B7XQcnc{5!0xQVNx|hr*b6PCclw|^hAYMu zD?tL3kJ$aktyd!7J!USg(`ZzpHl3G)7)S8}gGJ8H&u@=K`a~?=o}A45)8XVyW?b5{ z&Vd1-CaMVC7^WoVhLsk+(YCd2<a;hxtCvQlVbsONMR~Vvf+V@Et!+OnX|Qge*+*y4 z0~~tlXQ3WQ5Awf|lnSe;YmX32a$6>JKyhSQ9*v3*(I2?9@4o(SvKXUw%03b|AlwSL z7GkXX@uO5GI(hPTIPBU@=s1xa=K|8=HLP%-H`~Z>9A5x>`(1C!5#a@JchNl4#8BT3 z!JUUpRCT>s4Ful!3i=)w_^`TM8T!x3%fg)TJx{EOzWI&MC0}8Tz?4BJ4mN?Nu!4<z zN2{(gTGuo(Latc?3haQBVIk~(Jd5<_uQt=|z)z?)2>t|CR_)?}3VEtn@czHh4tz<d zy9C%An|Yg~oY;jAuDe`<tsYy>e$LNhY=Y0=NwDG#r<BRu9zSohRE<R>PyVvmG^}qp zr7TZYd4Bg(X6;Yaipg)%NS2E$2MuSSr#}PIGwizZdPWLbAeE@XRjCw>!d{1bt25x{ zS)dS?JqmE2d*%yy^P|0mdvJzhj*(tL{GGyelp3ESz+!nfWzbyt>uQwHWs-q~Wx3}> zE|s#St!;m2jC3DlzPu<qIDF~fqw#%{7r*N`*9>={g&21DZeY;EOhxV7Qf?0hM0%8j zUa)cmd<wnJ7Jp<|S(TY_5_l0SXlecX2wq%T+LvkDRt8rYXTAR|fjW7U|B08f#k{#d z53Lr#<ihDrt;sSGab4I15OJFyo?UUXFl$@)N*akCG6Rj>?Gfqo;SfTJKvJ2h>y0~i z`4LWpEWX`{oRuwLq8&*pe51S87cn)STom&4v6N-xPZt{(>xsHByzj=z$+`1^Dh%hc z(YUMRj|GR{+kGsYgL&czq2bjVamb5zsW(pFht>9e&})eBLfN(ZN{FIVD5&?G@2jOX zH#ZkbA(Lo+TPmfQ6_spu)jDSH^OXMq#nz{@O-`2>Zpt~JrW$q8l;uZzkY>C7>#`OI z#PIGi@;Qa*+fHh>nb})V5n-x2QW+n=xybEmztSKDkUX3sfYOwirzPM&4*GZnYfpEO zX8HclZG39#V?Lnuv&T44MFkaw<h|YR{4W!yQED=JdBdq?Lf^+me~WyOWDW7E1+&t6 zRwF+4ok5$kl}43v<ihD9@lB{G*mdt4v%P($DobH9`q7e%PQznsq4Z>f3lANr@1kGe zijy?tb5zGC3TPPG@O#$pyUTD$DM%{|AQA@M*x3?^_JT?U40dy&W_Oh3WkXmxqHl$( z+}&h@xf)>`@EQ$O$;)Q$T3XeOjbJch+pkP|nR9>tMwN{vsxi=5Mx49wzgRbRLCXtP zp7Vy;hH-V_ao{@3b<t(uqu(LoFn6A&Do~e|mrE||f-b3W5$faPV|K`P&|(~DaKPz+ z6%Q!gkVSrU;>g{?pj-P06OHWuplOhLT>SAyqm*0zX5~PMF|gWfb2|V_x+OZ5hXw)G zlTfsUcK0ik?q~fz-Xu3~+}J*d#mLoc1+GO0DoxE(Wn^H><zQ|vEhYSC%7w~=YxM={ z2(bSD%88c_!rx<N%Fd}6S@2BVjt6tBdtO>lUnbIMmJ<oM<b8s2Whuiz@a|r9U6+~> zh>x52S&tAgudKp>qG#(sjA_e%k_uGy$>s(PM0t^l!<nhAFGPqQDmmu`0!!=ah+$Dl z%7gUb0U<gj_i~a!uiAs|-C&^NV}0uP#k4Q-N~M}DBSS+Zv9Wl9QM~tHk;EW>BnEB9 zA~B^Lw7cgEy%3gT7lE39F3~NrK|Ox(ZIebiCjWao!n^xx6ICO<99om&XvRObc1|NS zMMODLQ`u;DGrrR##)J=s-+=ZZ@PFI{6%!rX|I}2|e9aiLcbuuZxi!^W7+#DN3Ho82 zFV}5KDE&94`*j?ctLlTONe5$uSdK()Sb_a->w_@5o2Muf(C0gmx|&9<6gE}a!%As^ zwCjp@Oi18*Fs_!%E(iBw-t(eCs)Xpb=6U(wdXmk^(}QfF(*;n+llECWoXmCFk1)hS zxTv5i7xI2rBIKD(mlGey{poW&IutZTgO2*@nJ^WH1G{mUc6(`3yCMeo;)}y!$>DR` zqio-FHX8dbU1sa-Jo-bU%C?P0d^~G@TU|r};mwOwrloU-F^4lx{L^DJfw-&7Q<F}S zI_=0pHZ@{;T6uAK$zor6?eaU?-C_6BpVk0S^+Q_lV1digqJ@8lzTlfduxCStILUYU zwEfWp32*Jpdb_j~StuqZCf<N2M{F(~@fe)XU(NTRDtNJn1-gSby8EaJi2cB_dS7I# z>aE)9GU7~)nZ}n?Rl!y%7ma2z<(>cdfg#@F``E;_9zd8Rk+HXiI_SolUE6q=MDX)E zMH^tkW`}`*fZ+MKCsBenT_lp!75v0OZz2jex18r9)XaTi7YQu$#kWB-n_(FPiE)zD z({ww`yBh5VVO3*el(>=78Z<pnc3AZ|uJ*zZ_Y63k)8YbcQq_E|4gP=^rE~<wU~Bf_ zXo32GMk(JjNLe|teyRiC!q(A#a3=Uw<7@;|Jar+@MIeB8W1+H!2UM*G@rYeejmv=` z1rTx_bpK~Go^HAIpPZJKr%!;Y&(B1CDgdP&NcnRxt!yGt;rvZ$5tNL>{F`6;6CMA~ zVl3W{o{@3Bl`f`~_T=hnG>5~+)>sfg`2(ULA?8&umj`E;7X_vn`zg#_vCrbO7$!(R z;=NoBGo_%Q!ms*>W&L$&uG?2!cK%XNBnk1+Q}nN)OCh8S>)^%jP_C+WJITm*;1cL< zy!7;bOLn{9T_7z2e^;mL>m>evsL6d#uHtIKtsV8dCz=_u^+0_^TmhiIC{U~P8eg}_ z$)(ONu0+6QGL?y2MkFsr1p540tDZsB`pa)Q1QPOtd(&g_ppGb~xp;4PHxf#;ga=C@ zTU32Lb3T7itUdrhsS1y={eSNQSQ-0SYALn1LAnc;b}WLk#57uB_h$;&f5pJPc%3gt zKRoSO=}8*|2wWA36jdr=h^y1DY$EYtEE*Q1?)zou^EDo3psews+Knd>3;fN^sJM=F z;3bkaBGzIdizweJ^tx{cl}R<F=6#`1K;cu!1<Uzkb-rUr_+Tu7xTa>U90)u)yOOrB z7$UL{jz|_eo$}!l`!2&3Qn>G@>mCa#2&{6~g196o54E@JE+Z`a3MT&g#a(OA<xRsS zBtC8m=gEEX9om0DQ_90-3lzKxMf_E#ea6Lm$wWv&XTLwjmXg!VtF6MVk4PT4zYG6k z6ZwF{wErSTm_?eJY|?If`_RN6WsheOGq!(nav^D<fvJ>78G!^e^+7zam3@mMCqgY- zip+`oRng6Um>dxp9Q?Vpv0*r6g@k7T2Nh=P=vew;01pT!y(>`SDE%<LY<B$bZXi#m z-VQa>n5e5GW&Qc#5b5CJf~s$zU)_o>4zuY1>R#iXo`0iP$V~#oNbCMYh%y<U>3ZJU z7z~3j>JpJEQ)_8$v-o^}vvn2(Sjs|m<^iN2!90;xSDJ4=BJ(u(EjdmACdR^}8X*5^ zUadX7k7tVz2Y7mWsxweTAmt<<59a%h!&chYS`E3OO?m77jEmAy5oY0m<<3*Or`G`y zfra(Bqs${~d+UhglDjpFR)Ha*%Qc%-SCF8AixUX(jSO^?gTL_Zs=xhrRqwpWsHd(x z6_3W=((}R{w0{Q)2st<UlZh0UY|?Ex0iw5#MtR|qWom})v+{LuXzT}rTZjRB1IAND z$G+gDBj9lYecrkefo^KIiH-%W_U27^{QP!;g=p*##=*8PwXQBzPfHDu`*(jg7MbD+ z7L!>R86&2w7X&pa{;>1&^EbH;K;&vkz{w$|Y$?m8BtLC+i$zTAl8^vQG&SKs0Pr1H zG~ppHp^4ASw>My_uT<5%H_jamwgor2`$$Ls&)Y0diIPyE!rN#6D%ZuLrE>3u_O>>e z_8sYQ6O9d+{v5RQnVCFECe_k+4>ESHKl+gt&-U>ASk_bLgv!MrF5BsQn4-nS)`uI5 zwcrhw7;VZqbTBSI@q(;BetdLvx>jqDO6lp@VsZEzySZ8qU3?zMLwYBcv6ma=$ozCL zHN7#3^0K#QZd8GU0Z?hShXb6_%wLCMA&0R!)tLAVfQ64F;(Op27c~K{-TAzf3Xq^6 zPA*E5X(Gyts%HdL5~EtOc+n)YiB>_c5~TGGJQqj&PhE8IkL_big;uR|gy&)cC^x&G zR&p=hIpJ)P{R*RP-9$MBYVq;!UZ9~fN@?vsyFq!?#bqoC`TSYUgFK?VOtw#E3}*Y= zfTi5TpJg%lm(oG;6ZjX9lU+HZwvvm>uEjnDcsjw;f@&B?ST@GvGX(<6XQ2IQ{cnFK zC&k*5aB|zp&wfuJs~lxDfC5(bcOgF??Z3{^3-DU|x*3drPOh(IbbNe-xImn})BmO9 zu-SaTSkz*i1183ru=g<zTY#PZp!w&|N&zC28-jqlpNvDt_XF4WQ)Skm$!%^``;JhU z#@x^(IVPvOS95Ug8ujaD_0<$pDIcES8r}Azcz(cx@YY*Ajs$ugGGN>vDm@*btd<KN z7%}74;>1;E)B}O!7~hK<8j|!;0hE_?w{V(zZ+~<^lEc==N_)I((|L-+fj3ctlOS?T zfx`i08<wN%TY2=pqt`nkmVVP;R?6cn`Ypbde@+**{Ma!P2Ctt<D~~|;(TBy+IGsjD z+?3!CN;o8vHKFySo~MR%ME9zB$B1>a-PJ@55TS1d)}+q`g^N^NmU@;$r*PjFMC)R- zW#)fDD%y?PbZjm#;at{uVoQmUq4gh4<yF(Dz)is2nl>ESckTGXm7>F>wenMlZ=HG$ zTC$(5U9sRHsn-A^ES1Nj-%Vpj+5Eu52H?t={8&sh2=175%mt0l|1FLb3WENEK!*`Q zlw^M~;jtryDVfK?A-)CL6|)T(*qkj$Q)TOeN@*67A6rMh)hZr-kgh~fbLsd1mnL1Z z*wQ1uyU=f>JwZKFi;i%BoG>;VZ7pb`Dkft-O6}gtpm7%6#vAG?jS#b+qGXNfx&O^1 zZk*UxGiqU~&+~NT2UiN;_HG%hryt$D>R5QS$R_i-Ctm${{&#M4Ga@-2AS1DUXsa6F z<d>+>9eSARAxwwpS2M-GZaFVpKYTA(I)~SaCoU_!+U21kq>*z3Pea5aiZ+F&^tT*~ zUO{ghF$}!acJXsrH4{BS`p3xsYvsJ(;e5V6F1o1EyR1kMy#!$q1d&9P=)L#eyQnKf z4-z#9V)YiCAbN}5>*~F;>UVsef8n_<m!I~Yd+wPtXU;kA*9?&)Z;2oS?$c0fess}J zTq2;`XCV_S2|Uvg24&w~48|rg;bba?Y2iYc5THa)Y5Z?EX<di_KnNb3tXGY>?7&)> zJ@jUlsElKnaN?MhtikZnMj^0n6=v1}VHP-)I?tuYL0(YYY7)l;p^yIf-w&SB(|9<- zIaZ}3=rE0)a+N?k(%HXinf=P5eC+kPs>mhZbbOZe`8<p%tk>j($-}xHR~{qy{e5zE zi_sSdbp(X?^RSaTNM@BZjU?j752;l{y4ODJ$5emoPwre%Rh5R)!{E;=wXq>g$Gmz` z5(%#FAFO+Z$xUN&n?mgQtumerI?}4BhQQ%^R-C~x@3Y?=da-6@2XcM{aL?v_Ox@f( zZNn3^UX{SVC`4d@S6(>!(fR(<a=lblG5@&G20dL>Q6@e@<@!n`{RCa&%0XU;R)U|} zH|@Wn;!Q8({z%51V0i--g1kITjf+|Ln17BPxE7)a9c0c`>@dRmRSU*m9=el}*F#KM zIZ(XRl6SR39VGGZdO3lH<zI#Ej2d-3bFhh-g4m%rKRwE#r<C%*)2EOUmbVr2#8&SS zC+{S&sjLDYtKnwJ9b3p`&6eH|Q!<aI1PdRv^lr-3vs*>Qcc9Nqs<8xoFN;0Xp`C{) zTuiGvpx<sOwx81*b)U)&Lr0~+%6%0jo$2~IhzIj&V(Rk-RypOM7DY>LO8)Z|D&yol zePYQjMTCbT{~r{(tA^auTnHTQ0iK<WHwUv3`G0Ro7gW*f<F$prKOu%aYC<1CR8^~* zT^5Dj#J%STA&QG7l`aN5=<yCnZz$glcz2KX#bcS1NGnZ1J&R~Qkw|vMoUh;;xh^+m zoyDlHuDG~-Bt9zBuxU=`aRtR(%KO6fcR7A-b6gp=N`gXX+N4U$6;>SN8>VvE{T)it z5iT5v35#Q3W*iCnZcZpw5S+<;<mc$_VUIPTWd|iYIc^oH<Qp?(Rj$tC%khUf&SY;p zG&BZ{p6L-SItcyB1hWzUcx7vvKY0DcL?hMLm?Wl62lr~(;{iq5AIOSeBHmG<dr?cS zP-pCG!2OE<>MW<J8RP*iM&^aX;ff~DtzThxyHI;0PzhfWzeU6dQpz}|HqF;OKKP|s z=YsQs7#Q{G3dW-^`N@3g#=_*v_%dDZ;#`C{<%A=?I1)*hB`1SrHi8}aAh6|^=X<@_ zti>9B0;H{Wwa1esZYH^5cPD6uY(E%FOOI^LiFGp8C=a2SCWwFRcm@r0P>K|vJG^5% z|K6@5TTDXM%BVYjJXiK2oIvsFL|}wvy~)7`4vFeWree**^d1=)_D+YQ1WOurl@}sQ zVp|M;Bp(3}!}P5%IZuJN<Hz6Z7{-8IOS&V>pnIRe9~p-b(kN8ZD6HH{Ad2$@WSxVS zEF)zQoR>w}#$OBO!%g`bN<T6iU#-PnI%PAeg$<!Hy`;m1V+>(`=zJ6Wyt73m=V_5t zQ*|{(*|#%P5t-~qY7q%qco3#+Y?%@HRPfa`m|rA5hm_f`=U##|+JgU~^pMyyuvW{< z%YWTFtA||JrqGf`)Te-uc$waCEH_3G*@@`)(rZBdG-sGcE`{CAA|pF)^P#ivm1-gp z;aQ%4*ZJA0?-NSAE#XiLZp8?&AV@3t2r=V3<eq$aU|{g}=(o7MW|#d`L%v?3X}@$2 zy2Ph;qn2`0LYr(e&>Sgdh3fIM*)KeAh7^a@>T~&59{gdzel=dB02w?ko!NB|PIJzm z0$mF+sQfh2U`c#0mC&Df@-eQU`RzhL-wV~)B6~?Bc{{#L;llBsu?a<b>+q?D5J$ZF zEPH11x~n2U?nY~&QH!12#N7O2FX$k8_FUtPMOhHyMU#RFp7Lb0I=$vgt|yXBr>z)& z5j++gqt1?9q2Qf>==jJwoto@@v?$ai2iN3dfh^3;H7Y2n_H*gKjLHVP8I!Zuks334 zw&qo_M>sm`&R}YcI$8Vn_Wp$GPj)Uriu?Rpt{+Aex5uuDLG*=u7dKNS^o_s!TJSYo zm2Djq|E%XB;RvCytgu4%b2}@s;20Nk?wJ<c>4|f0=|JL$QRd@RWxZZO;?I)fWvtah z7O(yM#H#2e-)N=qm@l1zG}NL<6AkkveM`hlqKc_X*VVOHaO<=i9oR>n#p8U)i`OE8 zFcslsZJGs575hT<Q~}*1CtmUu=Hu@#o)sIm=IALwwCJMPMIt$z()hy%hl~1!zg_|& z?8L=HudCCD=M6P(f+H<fM0?=%HMCHt)=B)ops9R~lyGMk{=oQitBG9te`7N?raLk* z0jpuMyo7?-2oDn*v(3Uv27D6#y$q4npNRxHL02paqi@=GilZuPwGw<->%Y34d!@(3 z+!*K)38P<uzwBD+nzpX2b=}#9Kc+u=GCT8<86ioJa_yI~Cf^8R$dS$9nbq7x5Q)7r zQ}?SHGMW$**NX*=j>m4<bQ*{)>C$w=+Kq&J2xu1FKHh&>e0v&J&{QrDf&_6`_DcWl zfUTlrQ++*%?qHd4c<vxgBx6T315CAGg7(K6Xjkx=I=#mb-YcmdzE`nE-|3EYb<;fc zO4OaF3{fc7d-WCiKNH1$XyS7}^{aRyd;A6irE7?r@kSTMC$Lg&KSO@z(NJgAJ7XiD zqV_(ETpC-BZG1K^1-)qI=7FLr)uE!e-ZaSbjiu;Op!9@{!sOD2Pz40=5BzvY<uJ7( zTmdQ-*3dWl>OBMY|0J6V>Txp_-yE+?E4`MGcpzXi`}e<SzNOl)$tPuK>z{Bw=6lmH zSdd%^^d%Fp(J|4s^>b@KWRD{)?FVKukbeEd2l-QRcY2X0GfVFC|Jbq3$?tGy+RB)P zQp203y<$#K#_jJcov~q|5e?TOhcJmsiq#WkO~H{lY&4Y7NsIx>UkE)>HqJbVB4u33 z*m}8Ge#pPZhDh0Uq=rmr&mxK5tMy0xP|=he-EZGkusbA(h_Sb^u_8c6O_l;W0GQzH z%F1AYN04AVR_*y;XlCvYJc525V&ggSf3bL|Uq|58HNmc_Ge0v^aASfcaK_2TmQ5~$ zO{F}(!wBg4{!^<zpDcb*NDPKp=0g?yO1a)Uzr!^u`?dxqPv$Erh4FlYw{!mYN0Oo8 z*&gh8X1h`^zVHAd1h~77wtVQI1R?Txoo4YE$?rdJ!2P)S2a0iL<f$Sb$W24``wB!& zoK`IM+tCzPC_zPqReS>c{`U5E7fkwu%G>(>P^D~(M0|*eMUAZL23#1Y1Gv8@lT#)% zZjffLu^!JzdHG}t8Qt0Qs-HE%X24}(&T)v>a!n+vKh)#56bpsF0aP~PR9Cw#UrgVR zg)=U122HfW1`iX>$?3m_52kQ?MZvfB(?A~JIkA6HbO%Ss_d#~Q9Ww6g1y_C;h?3MB zGL&s0`%1EF(Frht2K?6kOK^A?#wF2FCEh}eewhyvFJll(uCu8`t$<9rU0UPp&ynru z4mKocY396e+Io;7$G6Rnn?;#)Dcud)eCTJ#J@B0Y9x*mO4P?Pz#!ntSd5DXvq^Bp4 zluQpX;RfPG9*wOXw*?K{ki85A)LD2f)}ba4|I8xYi5lqOahFrQl9tw6j%XrYmQ-ou z$69pLf;(!ee**!m#<fFR=uBS@3L1-kdy?8I#UV=M5g5ijy=AdIgd~#6Hfvc$eaYIW zEe4}Lc&gz~hG#;O7_@lICt*+&egOf-Lgy#3fq|&Wd<xidFJ+e||E@i*`;EkfOwK`n zt&9GI_@C`edD2H?g=blah4!1Zt#qr___v@=-+}#;c%jLBOwU__3Vo;$N%>xt=+qlX z=MA2JgRiHjr+15rijvKzbawiazJ4|6`&NeaixrfSh9kJBMdo(;hK4?y#~_q~p%kU( zho|;Y-(nax`a%A;$>wZOjR<Gs%u9TOEmsFleEj~aq=*R)BfK)6^N<EGUqExV;lDxu zE~(qu+T-76Q3U-ELZ&l+4jNJF6hZr3iqhbim9u5sUTY4`kVOooV;-=|W2)(ZSQkyR zbIfoQv(RK~U6Y@WGi0H1%mX5#-qqHpNjj1oaYS+ae0w_3IVB;pA9fAnK4xLCYarF) zce^i+EJ>z|`A*Nw%@q|0+6$!c*v$$RYJSv~m5(Qi!vie2cTsH)fd6*2ujPodn(Tt1 zMb@%5U0j+CLM64e7$8`XZ+aOe_2C1-b2c`%d`n`<xE6r+$)srO&s}(+2MowG9D%BJ z<^_RIolalH`T!%*X!TtI81Y~nl3(fgkk{4s(8bxc6494ux~_;PH}vSj)C+X*{a68r z|E*73Kiw`}-C7^e;+K~hRaDiKMQJ3%I5kb<0Xh4L0&m*;(1}(;0atIj=_K?K!x4>O zq5pB;_mMD}>^iSww|Y86XLMU!GBuFQ!=Bx<pEkAa;9N#ANSTPd1{u8FS(<S(K2V(X zeXlr8OG~TsKF*ejY+dP&w*<R*mfXNaKKJx#WILa#^bf>!%-Qk?=SmW1Q9it+M3#wo z=r+WI-maR4EdE)h*=G6EQ5_tJeg|QqXb(7WvFJ+5h-MsP3_-7_hFxDBY`O&uX4t=S zcXuc5Sc~APg_kELvqM&TfztfRqHJ3@6yAmHCSa)EzdNhwpHYd6^gLd30u}4=hN1KJ z`G($ANoi>ewL*>Bq+|}rO2mcZ?ns{|RBr+3G-0sIrFw^F98Dw{Q52W0A-Eg6yJKT1 zAS<I3_2TEO-x=N<b-{t$^%S{tq-{S>`|0dzZ6qUKlZSRg@nKL7wx5s)@n27UsUsy7 zR9uFPxcZZrl$8DZ_wUci+>n(F$AtH@X8oL~_W#68<9NuFyI@VZB>(M}n+J^-E{%(M zgQ*hg>J%oL<FrR$m9DO?0%i7j_OticNZBS&_5PjI&tu%v6)1FkRw}GfG3Tg~bN$D| ztMxgyT^Zv3P4I#O+(QqY2}fE2EI1rqYPu}|R|J|x{lkK$y0$IO(HG={ltHBUtqXqi zCD1xEk&x@=Qq$wLO9e6H>+|<CK`o!IuYKO93I%BKLRS30)mqS0P<(ybL$UFP6en|! zd<R||`7Uq2Gw-<F-om19duQi0JNZb%LvoZ^J3-FoYbTpInMO~b9Q8iWz_b2PR@|uF zLb<$zf|`bJd43b@(saS#cOh{R&Q`3!lb?kuP@p<d1|rA4XCzL?M?OH#+k=f(;y}c; zkm$W74b)lf_sS9@;1YwQjQ!zo@$04}uOt1|IroMBv57GVEy4CyKMfw{7kW|Z1hNE` zy-!4e_so0zi@k?oYDvWiCV`E!R_`<Hv)x&h47-K+!Qd3f@?!cW2aR(_Cnu+avF+yY zRW?B0Jp0hqwMMTRYu*1Gg?ZyUZ}(%_Htb5lKMQ`GTy)LmGQrmh`>AcdUf03Jp2x3@ zp4uoGLhPD0#m$sSm`zqLm(Zel%)5oc1YpG>3I@-O0_ZQa6cG0){m5bc(RZhh1isfi z(=#&=xwv8k2r>^5orwIr^xUM<;4iNhzE`ik0?Pw1qTAD{B8TN;gbN`R9(KE2H7++z zR3t~Z6r77&TU)MUm9>*8?n1QRgijx`>z4(F+G0}~I&~;C&Zp~R>WvDTDyuRDH`;F4 zi+KvAHFIUi39fg=KDpA;)_zeE*w|&kpH*0hH#RoLZzI)(?Q{j#?E`uqX1w&o7de!e zEJNTe4wio>Taq5hl^eAmQNhHK=%S*cb!OAxU>d9~fHg_JWgtz&axygL(c(<AMy-hX zEU8BM5tiC-D+N!Gh-}!r9z+@o=3Sky@$JftO-wAz{`(iE!JfMxaSS~=a^kU_<{vHA zop~LN0%_Cs8&fwE4)2iU-q4xqQF(n?_s{u^`)p6+?pcUWoGnnW`|Ik2ft)_q=o#M~ zJUpzdBev@F+(4#_`wTH{uAzo}N_4Vw=EAe`6zBHrc(U<~o|B|WB;&K-4zoCt$NglI zXO7R-BVE?bO#rN0WhiomllnKrgfh9-fvq=<o1+Y_y8i0AJwzd$k72+2>;9nmR;0+u zVdff;KsSq(S+P;U9(*`f;zwpZQFQ$8iA2|d<MyDH8Q`cNzH@^J>FLk%<TBFl$g1DS zdaQ!dCGRRV_II!2dA}>d8T*>U4zir5PfNE7t=o>FHUexwse2*FwcjRwha6nrJbcV_ zJa;fx3!7a{dR4ilbAtXVD)iria&+hVT&wBui$y*pCO!0`Z1?YH5;;~+1K#i4ey!*L z<0{$7lMRaLJ4aLvmIEoi#bj`p?f_0J3ywK7;&<}y37fcd*)RNl;d8LqDYWn}=IfMz zT@r4R4)6DlbsRu4lG~em#uo=ZEqIL6#{ZeOwNakA)V$4CCs!9&Y{Y&Ic)S|Gw6r2l zxAd5vhBE?AiQ9Ec#b&nhGa%6LPKq+P7Sy<r!a$d3IrNhKNd*pk0XfdYY3MyCNePUb z*3PQ^=R;Oz=Jf@zz6|)OU)=E{fK12IYE~h!h(StDmf^qO=q{eq85+~aZ9I^b5?*p~ zE~^8mU+!d=!Ca+f9&{0!A<t#e{m+E+(_cSN1Tzo_{{HROKMi#E%<OF4a~ql{ghBO; zlBQ;Wb#YU&)eKRb#1UKZ{Qh$)LQuJAb&;du@h7~bjz+X|L>%#+CLgq|uH7!LyE}J+ z)M8>=e)<~8`Z3qwd~Xgcgg2PL{qyzds^JW6joxID8N?Vrx)7l$wVsNudEdl&?NHYZ zBlPFp?)%P%jgG3Q3LF-Q6@g_airP}sFO&s=Vc|b(!=g8yLgfD0;Y2AhCW(n4m6I$j zz?eH_*zG>Ceu9@ra|7@kU#}_Cq@u3g-k{#yPzfTJ8|igVdbI*q1FzM;WX*Rs{v|&< zKgXOL?Ru;2_Lnr|4lD5!U}kHcAF4>pOwNQ3C=f2TbKvHgT%In$X7HPVx2!SFpqKU6 zZ!Vq|ppcq3t1`N-ajaR}DmeIav?{U@%gEI4kSb3Uxrlz_tCrgZ<jD=&Yts6Oxi)-Q zZyRB!x0v<Xc`cakEkB$T3vpT<P71JTIP6wU45a(t1zLH*vE>-J?DgH8^$|F)ub_%# zyCc88gIw^WWx|WP5r0!((&IIV5*tp(wfT~hljDg`UKx=bu;t0Osh8C65s9h=|4h>D z_516ZafuS!^g&(%Y(B)%j2o8H_HB9n-V6$N#I5=@*}|#z*SY;EQ~tN>{zmUTU*du5 zmZGR4+7CMH{etZ0yx3%;$swDovITBst-W@X8rY}pSEV4B+_95bKXgCbfoBjDn5Qrd z2wvYJk88mK^L24^+e)`}j_o#SmA^Y=@VE`3u;{>tSgz$``SrQ_d7%KYX6GIB7#Iq` zZ}ICtF`PjNQK}ctr1mZjNq{P$FwJA@Cen0URkHLlSxVuJ7N&1!nK)#40V9{??kFSa z3B)DMgRtJpjwZ2r02%8ra_6$Bz&DU4UQ!=6C5<}xgo}&tZhQL<*ZT~r0FcS#sj3r! zVni1M(Vi{V$2-q|=lry7BoXHLGfNYX9v#t)mn@va#IIXsCP%+k8s6{2Sy_^^9teDo z<!<JC)R7Mmux+mN{uHrId;XLs00hZ8{u_|I<U=Pj+S`W3;1lMHpjmk3=}Glk>3t6m zP-d;I*>1O+&k)7+ellFfpoQv^>GtqEAN*(Pd*%g(s+yAjMgpU<{r~J$9fzJei!4iS zZsui}>EB&WC@Cw)RZ<C31l^w7-#l<OTadW_1mw_`ZlS@^DcGkz@jM=$2{=<&XsKY^ z|GDleG+k}au)Vcq6rNRT5^MUsO0VWm`VV|rP#LH$n(ZcU_DdeSzJ#VU9zON@0IRs7 zU~d3TH@16udBxG600M#ZB=~1O!zi?M@5d(ws>BkFva2-rdBdBV8}{!enr1~s6qCn; zBTz3;4ORvryrFC~y=kT*%cjJ_{QQ8P@97H=m10x9B^0|L67jnh!o>`dW2mcjSVHwa z9h;cEhkrKTk{m@BX;oeRvG>2yKI`KfRPGF8T96_X?fZ}_)ZMzo{ZaLWr39B8v9+b8 zY4hb+$<*@GcV;6A&sO&DvThIBqQ4EU8-uRyv{P92rT+Xgz?^OXxDXAUxHw@KlITuN zZEcaOlAEik@PvZ1Vel9iz3&c>+r~c#IbP`P5pGRU<j`BEIO0L*F}t;um638>kX{_q z_|#PU{4IiEDm0QN|Bx7Uann5Av@<%xAmG(viJt`XGp@?=ymY_hbh0=f?{xq4s^7nP zH521+dB?X;%cI3E!$dD9jYmDY!>SyHmN&i6ca7HvGwxtgKLHHNdfHP^QU;=jQV(eQ z=nr+$5af-Yn!0*tx@V#ucWkWr7<>$C-fNq%u&5}q-KfkT*>`esQkn#=6b7%`IrBI` zL3u=Ze=mR!SK~D=7#BIOe|#MP12ML>wcQbHzTrr5-}kL`sp@`H>NsL{20$g=l4_V- z+(`)YOOHmqvsPR#<$v)j-iJ9!8nUvo!!SF}v#snQmMbuvlUrlf7Vji@3wNhaN$)4^ z`07UA3tkR~_aP2T0l=IPn9j6dU9xNH>+36*riJuea`;9kc8%k`5-Xek031jk%4+BH zKP}L&$XzodkCb^KE(^>reO~YP{^`W#OGx)QApA<_NwID=NAjlFN*a3B2Ai9ci-o8N z1nj3;=Y97@*A6}61dNLc3L+X$j(SN?n2>s&r>f&4$EzL0&DZ?BAI|c`=?n<j^_zl< zg}O}?L_tq|FZn@F<>>ZQNJFZst1HYivWo=e9zv_V1+DGu%vub%O&c!_xVwNuv`Bv1 z{RWJG@@)rAv!PyzpeY@rW}>F=4XfJ63L6|<$2b>4@oQ`muM-x~BrC3$w33FtKEu^% ziGP10r}vM<V&U$u=7=CdF$17a<!lTYglBPs0d71UXZS_(TG{+~jbrCvsg0coo2ly8 z)WQJE#`d-`*sogC{Vu7j{xR8dXw)3!HhQ0zJFgFvS@8ELKUJEm3c9&15--KTC7*w- zp8j(*w_khmioqvlH0iBB*GAhC_x)!yU(M}L4x9G=Qdb!6N#xL;3P8gGebawC{?*6N zwi_9WdA1zERd%(upf9JMjt6XBZFiyBUmU;;3f(%F5fTj1o!>hVh73LzkQwA(5}UnQ zPnEiFc=;gQ-tk*aP}c;2`0%;$g?Bu0a&pR)bN!|%8x<-p1qT=`d%rfI>?;enI3MQ0 z7xvA~2T~22Z+7=5@1a?j({9DdDr*W6kAue`0lAjU!8vhp$Qoi1aa>0C_UR;e=)qg* zwm;QIO+)h$G*LDLs;6M0r<i4<O7k*2L;dRFBr06D1<vXhZlbEHs>&RMQinf80=wHk zuee`QMf%MFsOdjpFoq8{VsSn5{p)Q_RaFU%#{(ieOE88^*r%VP+a-75Ae1hfpP&B< z^M=x!16Q@PD}Ecxp;Kcatm_-6mdL5Cb_Ix5^Tx(TR^Laij@Zn!1Qmc#Ia~9;6V$G^ zO9LmG<Z{y#pe^&h=b~%JNSB1C7v&`QXZ!x~!kkRL96FUAm%v$xj89H}J>kH(J5-oK zDJUo~F1g!Mw?T%J)o*eViT<{k>H#6A?fC3$A8=ytUPvq5JF0sZGB{*4{&RVQ_~*c$ zsQ2V5h<N~=2CDgso?@nVoE?-*a*{yJ0Oh+6>Cn%YmzSQ_*4EV{X^-`RNu*5WB<Tb? zB092bYOsNZff)qJx%;50_77B+Kjv*Y0vc}Cd60`GiDiYa^GP(c6=Z)8-zW1wva1$Z zCB#GdYs7PMdYTECK;Wv|KgToM&Q#mtkIX&3>zc0Gh63_AQN(ch^~(Bsn^oB>()O=+ z-cRKu)zt-~XkP|Ki{E-&ZH*PI4b45KGGB#{UES^9-EfVMj}I7?Y4pJCISH12!7ry0 zg9f2eB1*A$mdGQr`US9Ex^0cJjxQ_>nrPC0JwqaOhk+qT*~WVvwY9zDYVIqpxppEY zBWp3M$Z@$?vxhkXv!SM@R#exI9?4VK*Qs(^rLBANWFmRG$~EbIx{jt24^Bu(2oQRR z&>zqyUA_S*5a6VRy!U89Kf}G(`*UcsVi?5eeKri;kgFdR0q#~_QGsQ8v35+T4l4V? z!Xl1GD{`QYHqLbqXV>#O*-Te{S5;B@QC^OUL?TNy*n`OTK!p@=J(ZP<8)e2qUMG`< zKnmZ>te1p{@2~?YJ=bysey*;rp8e|=_Op0PMXytoAMod3`T#jwS6BBBWLW^e4W;1H zGsza=g95{`@Y2+rn#VzOW)~LHVqhRyGq4Y;!2^IOt#w{M09L$o9~VqXLBy|ZXMU&o zuCh%S>`az9)anpPJ1Tmq{JC40PeZSA%yC4yv$i~C9MY0_n8J=nDNn1AYC`Zbrl)`4 zg|mFIo9Y@bW{|oA#uvm>60Yv{gxY>jr?iX2vi0S^+PpZJ(q?>bKE)_nTgnybt)Ub_ zs6@Jd8lkUUsVZ@@P)Kj)-+A3MPAs7D%Liq#u#i4{^DO=iQ``jrP`Sm$_Zys6c{zr~ zuw-Ng=fCVcJWm!eMGZhfmzb<P|0b7c`cs+p`fA4B@#<{X*<4muVQ53KYo9Xj17X^A zn{`RlJt_73ci=iwz7e}Wxlxl@o+&=86Claa86qOWk`xF5m(%GN+4c1_{r&ye0xu*; z+vOXzXIWDEjf{+l7krNK2^hp)drCo?gSh$%)FUVK{pmnD3=Baa#dhQlQ+FcMlKO29 zaa=dk8U^vU)YQK_eSIwv6kM}El%~Ncseyrkd5cOcu@VZs5()ws8eW@?S4~RQxs5=C zcJ*z@)%kw2_w6;7ig#WN@JuHdU?Vno4p5Y$B7FAV@zs59JhbH8Oy&H?X#<ZFv^x6w z*q0B5q8P+w_P=v1|NR^fW2B4Sri;a9jKv1Um)A;#96#;cG&@pROw`mLf#7+u1?_rM z6y6AK!MJn0ZN)IYyS?$quBLFS_x<R;c>OKc61*Wt8So5{Se?J4qom7+7ju~-d3xDH z(>gb@SXsJhX^15U5l}uDBE^$j^gMtP7K~{n83^K`)fG!Akpk?LtLcJyPu#=dU^(R2 z<y;n`;MY@SJ@G|w!H1;9fGFVA56%~3%({KxEl3|fU-tphwRMWp$_Ag6*-1^S%mX|; z{EXV!Ny-c7$~-K9@dKngizU$T+cf$Qza_gL%B;q&FCqYOG^0P?QPv{SLk5nWzoQfJ zTi(6lYQ8=f^{xZZ`hzHhfGfqo2&Y{eH&_)9Lr{U8KTl{~9wtsqOf3DT)9?ZcJ;98e zFLA!UICKYfzJ=CZ+XIirjjf&FiEWI*<0_GQuc&5Em^!C=Oz$eUpkRde`QDP~^L}uL zjJ~~z%gGuD9)|0^&+UQ(B>-bTYU+3<7f@nJ4Ig`Mq8ZBG`zDVs<|jLGH<MYexf*Xl z0hV}!%OPjvvcg=IuT3d!#M&A;{|n4Trx!n}sxW{lfcX_26^yEe!!<NDTUsSi%QW!L z_ZIHv^u-!ZVr0Pm3D=lnw<{#s=7aPuC4zC&Ru526;BZup83tYU9>AdV=9BVnlCg7e z7<#^RMf81N3KDU}yNafdtee~0wk;}ZtY>`0{ROR`EBFsL9(oH-l6BFlwCIFUx`4M} z=g~HnzA-O(y`!1O#$(+C(xVlsi<6ONYOs!^w6)owdR!W?Y&((Xeo?h7>YPbR?Bub% ztEI{P#Z?+_m|_MBCF6dsm*<LedlXLWl9xneQQBHs26Q4MK7!+e^n{>V4s=076auV| z+Cp<y#=o|OdscaK^YVB^MT5F0nWE0lKe~Z|HMey*m<%W`9vIa3apY>PZ*_=Z6iSB` z4d7Oa3yw^<(y0|x{btrrH2wPaDNA^u3GZi>=OI2~(UN6h%K5=#eOrkO=Dy2+yQS!( z*M))1*^UWnMIKOk@Lx!m(}6uAG!%1k*G;2noB_SgkW%}oZHm4By}Z1knH#yjFLG=y zGjpUeJ6tl|=Jyj{-+)H0J$cvtO&OC3&I=zgA=)SorHZ?p7JJUM#9q^{y{lFKO4Ksp z&(-*-R*pQs_L{0ZCu4a_)-L&=)`#G2PI(r~SPD{d>7)XV3(hi#JjQN?L?Pzg>ZLu# z8Tg&J@id~)jLjEagqMzy|Nbqab~-u~E@)2ex=q^r=Ac<oNU7~D|B~QBP1xCaIF=?N zIDkj^Q8QFBeRO6hAV58PXd`WJ&u-@->=8D)m0^W0Y6sp`Waclpm2JSp_2P5#h$;~j z)sY|h&w(G!wJhbsD<sEdVuiiU!E<d?P*BYu_cPB?4k+F>&?G0oLQCl<kRbZ=9~#te zhSpndKq<20h6%k}(3M~N_!B5r0x3o0D{Jh&BE0$wMrC0M3H%)lQN~6_s6l9GUmuYk znXrZWDku!5fw&St|M-3xC3Xsfb~2ltMrD7js>aU_?R8Mb`SF317~|haRs*-3M__<+ zM&J)rJKFZkT8t!i^ObZbCOE(1=Ojcf*t>(Ds;YLCe*v>RdA{(3JVL1kxUJpgqXf2& z{qtQZSy?O}G5xvA<<YCQMJ#)--T}Xv6!*8`S&uUYjSV3Iz(*Xy5Gsk_QmmP=t0zw~ zWV46Rfd9hAlmdoP%3g1YB@<J`V=d@Syz2ClDPHc2c<P_Of6+yY-a{19Dcai1i>qO6 zFk!|=m6iN$`{!+|PGdRRkSSVltU;@YF@x)Iyqqy47Cgd4FB&eWce{~I<`n`i2XX$@ zd}mQvROH%_Z7c{1ypJAYEFF4S;Z~V=^Y!wS>qtI}Z#g<5rWa3_Whc+JjRAv~M@2=| zI5j*yJX3M+^oYRjz}_2(s984)aAamBjnL>fDQ#%@67m|=xx)EdT8i&(+q<M+Rp=qm zsm+d#fqoZP*N~u=$HF4+ZJRFR)W%9L&8-I}`{`bVNIr;&co!xfZfs^o9uX1YQbz&C zL&5!Yx>Kg6(YDCm^CQXYY5>s$O`+-%xjX$zxl06w9qRBMFOi%AEYHY`Y}SWv_cug| zqoD->y0u6!B_-t%0c>b^7B#w4cgDMUE`4LRxWe`L;MAw-6WGaWYhU(>rnmK-^u;=_ zcUZXNfj2fsHZ|QIyyMzU!wHeZZahGR+6n3uV>-}kTjwd3d<;)dQWR8JQC1}b+d{1l zLB7hvckkYP^S-A19P&56tgK>vV+>rBwenrq)oa6qg_0IGMDpP3#=^=fm?gZbUHiCO z`4he5WxgU7inNkqz6$t@;UZOJCoL<FYrVckjf;>IcKi%H%%%6;P3$0Az@LCK2N7`C zWHt-CdIlfX_8^^N(ScjU>yf*$HhM+QE8#SmGL6^I;w6OBLcjJJJMw%Ubqep{4hF8l zHcx>t5_#PeFE1~TjZVFE?6q|2^*Ef-BfW&q`~rdEL*F{P12aAw9CD@0aiT(r`H&Z@ zq4A0{L)HlLfHg_#Sv(REa?Ic(vri3%^>@+jZMIUz;CZwn3+b7cC<wL=kk=rf_^_^} zPZw%v1yf0(qwg;%IxsXi^LxO~jo0`)<PmoUr)nl#mGmLTMje4%9B{;vs;YmRqo1(J zIk~x>&f!uFeEb0}1}k^|@+E5i#0%PJ7mf8HkHkm{?e!3TlyM6#YHFY&+v&F=U#d`~ zMB5AJA$Mcra^@GTSBJ2_9X|x{(9{ZSZ_H(EAJu9VNh*<AB!~JmmCmDT!q}4(m7f1o zA=8wT{LquB!U_4V6AV{V|5@nr4Heu8M{<N76x2yjO6wl8UhD3mhb@Hh06JJgH@#%A z=v4a{8&x9_qqls~lRohAs|ozBay<Eu6I$3aHh^v@ouQiC{jJ3cst$$yO{!#}#b~9Y z1HW`<$~83iui{`#a=%y}vXiqNZNt88B!}yW`K!k{!8S{sz%X__16eL%1-mzJHkgz! zgld%W!ta^gQcYV2AzA<cR|UQKRE751M6>Au@H+)ny7_AMtl>@tI-I_4t4F5a^_2b} d?i)N{z-oFBU4_ln3$9Z{k(2)Lx>(X6@PE0t%~${c literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/user.png b/src/main/resources/com/unicenta/images/user.png new file mode 100644 index 0000000000000000000000000000000000000000..05ed9d23377ca7b7e592e0471cbd9a9edbae0d1f GIT binary patch literal 675 zcmV;U0$lxxP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyA9O`nbVF}&d2(rIXmkKlPgy}sR9PTKQbk1|Oi4pUPE$o7-r0+3 z0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK0nkZAK~z{r)s|gO z!axwm2T$M;dIVm5;|LtVBX9%p1RS9cDDf+NiTHrfs3?!TgQTe8TUeuDRM2t8U^Lkl zw%RsvlV8*9&iwb^+1<7QaM~*G8l`LyVF(0PKhqKK>6#`sVQr=9R8l?u@+}CLZvras zXbF#Tj3@14roqKb5V!=6;VQY@%2OT6Q&dEEd3KUJe-#8OBHTA{_JZI9*BzWbBRIiz z1ICj8;|Ue<U<pbS9ZC~a#Dh&(9BWV<3j&wGF&-R4UelAuAR!2}fyX?05q)i{!h;5d z2b~ZE&f$CR^XSQ4-_id@Fh5*}<B>_=oY+$D$D`PfcoSITS1mu(DH$yY+v??qVVfL> z$1*q2;ph%6$qh_f13YG*r)c7^ABEfi7joE_%gTMr^P-DaBiqv;+d~E9Dr9@6LLO@` zII5X$3Nl?(<h!JquCAEF+9~TQq&pg<JLnLT;;RmGcn*syq}mZkwb3Ucaut#-1ClND z2}3q;aEst4l7syl1V51s>|G=HiDY26iQp%afgKaUPb340h7O4a`h>-IA<@ua`$`b# zF@he_=5@SP55iWxN}xxuw!%MSycU9ZEk+mw{t?z-t&r6>-~;r5j2k|pw7CEP002ov JPDHLkV1k#=4_5#H literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/user_sml.png b/src/main/resources/com/unicenta/images/user_sml.png new file mode 100644 index 0000000000000000000000000000000000000000..7dcb34dc367c325125f532cb98c73cd1fce00069 GIT binary patch literal 582 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP(r@M zHKN2hzo4=xGd-h(A;>?{(I+HQ!7a$uRl+0`%DRpH*v?o6OkDUj0O{Irtt#G+J& zfW*wa5<NfH5QQ>hJyShH1A{L`3qcO^ba4#v@IE`)+mFdnpe@_xpv*z#GuQ6Q9GrbZ z@E6+)&Ik=I#RVs_9bGtBroR!L%gN{(H(7v#r72ZBDM#j+;$?2_pK5bo?tlIM)vK@r z{x&r&JKnH}JT1_5H~IOUr;pF?uTJ^(E8&SN)?a8WFlfFN)O<_G_QE&wm3k5(;x8C) z-(O&q9x!t;J0s62W45P~RRRYVm|R_8;>yqTrGf8zp3t)e%#8UL%fEL$77#hk#%_LL z#=T?py@xzn4{01poRfS!_tKr|ZCh6DFDhb|{p8%;%(N@Fu+GCOFxfHh!Nm_b@sE|Z zOniI)HqVRu`MKNj8K2&e-2PrGrHYMR_Qy)4%a>zI*aGyTm+a=b6kD?J;PWfICS{l3 zRn%NxFLr0oLhU6VSKnTxaP^|%RmYPY;>tJECgdzmX-W3lBB2tcA$d?C&!}TIh)y%; zkOa~XUb(iPPM^Z{^iEgCWXCO?lWu(EJMs3BXZz>l9Lo<Lw0Fu@dM)Er!=yILSzhE% SRv0jn7(8A5T-G@yGywp7=I18> literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/users.png b/src/main/resources/com/unicenta/images/users.png new file mode 100644 index 0000000000000000000000000000000000000000..d9194e60c4a236724426e44ac156f586763babbd GIT binary patch literal 742 zcmV<C0vY{@P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyA9O`nbVF}&d2(rIXmkKlPgy}sR9PTKQbk1|Oi4pUPE$o7-r0+3 z0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK0uxC@K~z{r?Uh+l z!axv)`v^ILN8kuKN{-+W<|cVi%N3)zAZi&c*SEZ@B`%1f!l0H*xwYL0LYRbvA@Rws z`l_a8{{Fj}$qWGh5w-*SUjp{OBpe_%;4#nrN$h>vu=j}}*y;AL`(eWF2S$)duZf*^ z0Xy#)L5fGQ{U%`h4I@agfvr~ywq7v;E4?FN=gk+7z!1E2i?h4?Y!EJiUGSWdegmxv z8&4V7coI!g{PMZr`lCVE1U6C6dHvDqSZ8fQyRmw2z}kaHU<VR-z7;<j*`-k*rL_mq zrQ@84TT`gJR16gg^>!kURgLNU9tw3k(1-JQEihK3NsBB9W<?GIqpnMzUz88$vqp)0 z&4GLkHE?}i`I?B~5pWdCRRlf!4J=nh44;4omhKRASiJQ=NK1EC3?KDo!NLt{QdEv} z;l}IX74m}SDiU%P>=Q1ez5zU!tGEGPZlJ#L3+Asa0{fsy+TIV){B?#jqDhPwbneQ8 zxhsc|1V-S$N>14Tr)>Y`IA!&md9LNlTFyx%W-kqxz4Qp|K+?Ef;77xAof^(bpowhB zg=`4}XkWK%NrY(p*SPN;nYl1w<^n^RJ|70AmxevGW9rO-sWTi9N4q{uo?;?scQ8>z zNCK?}#!rS|`~(w0s{u|LJC+0vi2pCWuV%)MEf_t*fnbk;V&u?-kwb@&1jdB5oYT01 Y-~Pa?wz}*5jsO4v07*qoM6N<$f-wC!@c;k- literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/utilities.png b/src/main/resources/com/unicenta/images/utilities.png new file mode 100644 index 0000000000000000000000000000000000000000..38d0ed1d11b969872ba18f27c8a23c41c96300c4 GIT binary patch literal 1054 zcmV+(1mXLMP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyA9O`nbVF}&d2(rIXmkKlPgy}sR9PTKQbk1|Oi4pUPE$o7-r0+3 z0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)>H;LN@>a14~InK~z{r?Ud(h z6j2n#^F=`g9aK<JLB)cKI#yIvqJoMw_O6RvR9q`6C>GGa#ol}Gy`n-w%C>CZl_aE> z>$%1k@4ifS$4&fZ;K!Tu-aF@=oy<%|#{a(*cc8AW&Uxzl4`NP!t0$eCh8*L>*B^BJ zH_)c79BESKV+gTj{=KQTw$?cEB~FsV(3nqMqNb+Cp^R*j*eOw6U2Pot94Ey=Tuba^ zWFW*LO$R>3Ns%m|s;bJ^|0zbyzK@CQg=TCO;7uH$OlsVdB%rdg(%AhWM!Phe&=T7P zbmPwVQDUqDDk>_B9axiWe-|Yk-q+wSFE4kp0i#0?mBwudl2{ek`Zh|6Ex6X%{5Hbp z{5hOMq^Y#Dw4sDDvq`e)O@zwI%ChtVn9JOVwG9@me;pwPdlC=lkW?mRUWWjM)vtHF zijdCQS7B1%$2C5jgOZupyhda7%P<ue7dt^i;3~{XRzgckN=mE`=K{*8n^wFClVmxx zWEpf(QIWx;V(Ie`NtQs%qD?;ex`~a7#kkg4^ejY@h0u}(PeWWT_18`|Vv}S(v`!Z0 zB=epGNir9jvHgzg8`(TZ5Rb=yJ?*m}2T3vuS~3$_k@n%qjImhEnDHn`(;o#AnD#J0 zl4vyA^uyNNW|2t5ocbU@%oL5u(28(4{O?L2+%f6CpA-}C`AKI2=0c%R%a;fSgXZ|V zeqzR1FcxzX>~Faefk40<bElA)(E#BN9+^?M6B!AufUo%_3JVL(5eOZAs~*4K|Lgtc z(S%kEyX7Ov(3?JD;7`AV&*w9TAVk4s<ipH*@C_eH20`l}=kH5+y<T(Rbss6XjMbaO z^8>DXssFXc^uwG2dG<@V-ELDE`y#~S@g)7M@_L`EUQ+bNwWQY-FEPkXUBcyZ9c8mH z+4`n)>7JK8B<TSy=?;zjrc1C{8nD^c;p$(*`@3E8P*(x3b-Cy!NkKtD;}ZG#`A%ts zKAO(g6X9m(3vOaMS<n%4$j(g2&dtru(oN|ct~_~pd1i<6E|RoA=OP8KC*&LF-3^;j z#@U?1l@~c?yR$B8tI-D9GM_i+<m6<v#NjFfd1mV~1;n&ET~ABq+sew$&Ne_MNVx4k Y0X3Obl^Q>%S^xk507*qoM6N<$f=P+x;{X5v literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/viewmag+.png b/src/main/resources/com/unicenta/images/viewmag+.png new file mode 100644 index 0000000000000000000000000000000000000000..7547acf49a2a564d004491009ad9e2a46af8389d GIT binary patch literal 649 zcmV;40(Sk0P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyA9O`nbVF}&d2(rIXmkKlPgy}sR9PTKQbk1|Oi4pUPE$o7-r0+3 z0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK0k%m*K~zXf&6HVE z!axv)`v@E%N5~O8LXN-@I6`iaBjiCX6+slxazPds<Sp+?5m{UStx=HzRBT(KMUo*i z5MNBy_mIio{Y_0~2H;;j6;z>uF+%sD(R(EP9LwV<l*cw)e4>!@*rc2?zv%2;f%6ZG zz=b$_kI5w`BNa~H7=a-%gC(V*0;M5?lM()j($JVKDGn?s4lsZMjZc4Qai9sZ-#s+1 zB;SuhzK;TQZdT&F?ak+UHXOgA0A3)@BjkEfM{@YA!qE##;03ap!{?MEICzQ?=%YYl z-Nh2OMDFhgPX^U9Uk~Qg>@%G}AB&&ReP(cdCW74u6ZRg_gZ#wsiM>aCcAsolhin%; zgb@Vx$#itcbkIY(?c2u^W4f(Cx?SM<Ov-ldH3B8@yGUMRIn&y{i$LlYCGY}yjqA!t zwoFL2PyjCw=MlDUl<C4InhGSE7|3SBdx32>BEo#4IpbE1*JBW`V*rfC4MP9H5@c=q z7I2Q%Z4=gQ`~wU&u2u1#TdNtcR>Kh3R3mBrt6r^Yuv)bVoD-9Bi(fCWautQ;%M`%~ j^kLDvK^fO>@h;96H_3aMe;M!^00000NkvXXu0mjfd-n!G literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/viewmag-.png b/src/main/resources/com/unicenta/images/viewmag-.png new file mode 100644 index 0000000000000000000000000000000000000000..a0c6907708158d06d0f21d1ee96b07c7c414d677 GIT binary patch literal 587 zcmV-R0<`^!P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUyA9O`nbVF}&d2(rIXmkKlPgy}sR9PTKQbk1|Oi4pUPE$o7-r0+3 z0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK0eDG7K~zXf&D2{? z!ax)T;Ijml&?R&!T|$@8C3FW}LLZcX1VjM|AaWCtx4tW3B;W;*42T2}@pwXGq~%g5 zHF1*fVUjcFpG;;3;9ra?icm#`s5TPKeeU;Inafa_Gr0Z2ttxY!>V(~c$}<6OJ`I9< zDbEz=kkV9y>km%QC4F;9aUwu*!l5+9gA^y)`jEodfWjC(B3VOnBN=id^boTKWQPo{ z-qBOpp=^d^1|nR(q31G#s2Py%D+F!w6s+zn-PdS6xAov=K#HpbZT5emDXy*bSp;0X z>X7WAh4YJ9tw{FN^?edu6%t*va1*exPrRc-yn`08w(TA}B*xkT#M=3lK8t1NFA~8& zV3^xFd-g%}3ID*-ml0{{5NV;OP9KHegAF$Y2shC~Ykt*GLxE5OJ;12PhIbTXIs_RW zfWygyxc$xr>KX*<=mMiP4$Xg}{WS^vHAZkpI@Rs}y}<Fk3`ciS!U@_KG}owR>9$x8 Z=Nq*?*sSP*9{~UW002ovPDHLkV1m(7>UsbG literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/voucher.png b/src/main/resources/com/unicenta/images/voucher.png new file mode 100644 index 0000000000000000000000000000000000000000..ca87493b6b2cad7521c3fe1f681c1a87b548f783 GIT binary patch literal 777 zcmV+k1NQuhP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004XF*Lt006O% z3;baP0000)bVXQnLvL_-a%pF1bO1wgWnpw_c4Z(#Z*6UFZgU_(baZlQVs&(BZ*Cw? zZ*DC^Z*6U5a${*>Y#>f=AVg(yX?9_BX?A6Ed)=_00000QbVXQnQ*UN;cVTj608n9R zZgehAMN}YmGcGkQF)%Rna-jeK0!m3lK~z{r?U&C_6HySyUyM;B@wfOpUObq1@ZiCV zqT<j0&ws(hG|`Ayi9l2g$fZ#t)&|<x!Y<3cTIi2JO|cxtnbp~DcjvW-ZNsHaKKq)P zc{AV6zMZy84PJu|U<aPe7a`1Jv`IYrT!b(W(I)W#?GpFVPI%3yjokuy1FxgFN8;XG z5hU)SJ<J`n5sEiRL1g2=@H&D%iQ8zGxHVe@33c<6hF+1i9GG8e<@@4RKv%aq=2tgR zK(BBd2ej5uDwUvIE<>$WgL=K*F~7P#qoEhf<ZLhr__ncatf8)b)DVY-<s9Vmd9W<Y z6YwI}$~V4R_BzmLG@#jRLiNvXq?Wq+K|>rSfBf_XB$k{=uB2V{1=#gw#ILTr*AN%( zfGH1mK=P~0(=Nn?1(@=%0LiZ|Ot}z;iFE50Jj<*_a*bK7TkyTM6Y;A{*nx`%Ov28i zXy)ru`yqV3?7}(p6E6#!ZHKV3vkPa@PMrCV;$U`!R}KuX!;>xqna=)u3ZyxZt!%?7 zjF(WS(ZQI4PGXG23A8g$7tM1ZRoa5%?_4-0pvVzM3MAW6fg@-m(uMX8%-S3NB&0() zG_me+ID}$H+?59r-GYU+UtTdD#X$kVItSjagF1wPoj8d8ZY0tx{v;#;93K=Q<=B@* z0sB!!T!N#R1aQ8ffYj#iNF7B2yh}`ynF1s-HcaIlNUgeU`GVgCkveZk0A2QqaS}k6 zz2Y?spf~+w4D*}t3wH|Yr_cLo+^xVX`~>}A@TX|d0qnqE##)Tf%YdTL00000NkvXX Hu0mjfc|c)^ literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/wallet.png b/src/main/resources/com/unicenta/images/wallet.png new file mode 100644 index 0000000000000000000000000000000000000000..71e6986a1c0683f797c6c242e2477cfe27228d5e GIT binary patch literal 695 zcmV;o0!aOdP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004XF*Lt006O% z3;baP0000QbVXQnQ*UN;cVTj608n9RZgehAMN}YmGcGkQF)%Rna-jeK0!T?jK~zXf zz0+4{Q*jgq@c)AoocN$Pg9}s?6~zhGfr=uc-~tszMNv_3fr_G{-~tr|7r3wv9Cg&K zbyn-Bi#mFHvzn&OXp{6cFQ4ZGul#dzn>2ke@XI~tyGgzqZlcuxcmQx*aMpsI7tWcr zkj_#joiSsuBwh1qBL;TL#!1Sg6Qwao$4jHoB^4a|9mUZs9r+anJNz?};t*v?1qXjb zP?rOA&d&al2=<lKq}WRt<AQiRo|BmOe6NADo3eCveXE9UC+#{e*g+Xn+rL(WZOg*e zFJV}=&@6Gm=Fed;wW&CaOg0vWpxf{%1h(GBI?A|!kBNEh#}MkW=0gy6R=*EIl7FXF z^qQ4KttbkDEiVex+p>27==j5zQl?w-HUOp;7Y4AXuqrDH-&Db}fMzb>BbzU%d9N#x z$=p|!(9NNJwuTFMpY<}8n)$*HX$EEKOn>f&B=5nr0za6VT2KKt<yrkrep&&`B$_2I zn@BlR6Q1}mK7(<Oeb9}io#ogV^T?ODCwxrIqaT)|E~Dt2oskd9F+vzlyM+sQ9(Lag zHI$yDA@{sUXE2@D4a)aI#{~oPJz#3UT@U(asoxzBEPZK~xS-E%H<;>u%MGa)Wm3;P zH*`H{m%8V<z_{Sw-0h|dmaaEkkh)MNb*4<}blnLH7x3JXs1DbhVD0}hP17NN(+%0% zT{Xc}TY749B~@$6bggKYT3#-L)Pgcy;^GX$a5TSE2G%S$Ra45OCb<Tr#up9f8qwa6 dZ=cnB{s59>k5Sll;vfJ3002ovPDHLkV1l&}IxzqM literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/window.logo.png b/src/main/resources/com/unicenta/images/window.logo.png new file mode 100644 index 0000000000000000000000000000000000000000..bb8344a23d83a46daaed9aad7f01b72526822bcb GIT binary patch literal 1067 zcmV+`1l0S9P)<h;3K|Lk000e1NJLTq001Tc001Tk0ssI2CtrT~00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy8gxZibW?9;ba!ELWdKlNX>N2bPDNB8b~7$DE-^7j^FlWO00V<b zL_t(oN5z(DQ`%4zhTH$%MJp;$L@jE^Q4y`Xt)=b`Ql+RMAjqx=S_KqTk{c3c`eJ|t zgoFrVnSA5k_c{ALZwrOOn^*n;`O3dHFW|9U;el`&ntNn8j#DhqERtfl<G=ZNAJN;X z54*W{meSX0%^8lUpFt8#u`s2XpFHx8;(i1Oq<Kt-HTUI^nsC!54?X6h`$QI~ZPadz zA$b|D6cScj&KWR3>fNW-!X%bq^UqwN^96r0zi>+UlNuZ4OG;s-kQ)&O5~{tNEzU5k ze9Z1?&Kx9s*v%o*D9%zy!WPyeOqOmgMP-vNGOW%{fjWIc=j$0NpG$e~o}G9k+=zn) zb<Rhg+gpo7)z2*~MWSafAc?P_!cobfT4PL&R4wwz;q2(@nVgzw5sB-!6xY2+eca7m zKUBF|g`_A-qtmN;wW)NvbtDwf%5c=^rp0PiNbBA{T-@B=X$ub`@NW1isi>)nrhr5i z`v-@*dNlX<5A8xi$9q$BbjeTZAmfPyT%4U>Y$Fd+7#+wcn!D1bf|q<$9mlTrBB6%K zERL;!L~j6jbCYa462l8fd!jT21?1P!@lI85J})<wm0J`_vp}weOARU@Q9J6-dgX%h zHxl<n<Z`)!1f+hzpwacq3n)Kv^@OYxt$-XF8AXS@<e8T<B6?Ru;%(s%3dpH%vnZcT zCM&0)_<zS$u{D2}hpm9z*xCWo9|$Uzl)Hd61;}8!G=KzTAQ%GDyt*!@p!k3NL2<ZK z<$Xdx5{Bu~=(K(P?d_9zwwOrqWUm_QE9O-=>TK%(!Yd7==UQm@Dr7R5`qZt~4;ly& zrm*5TiY_Fw?0ZWNTcCIks(qr7OE|i^zS#<izl#lxUkvb=h}CM5c%}7&L!f$2ye(3J z9Cy((-r9iGS-0YeODqN$3#a}-i&X50l|rraUW(PxFhC-&Hv56Hm9kKvX>xgaC1GpB zr7|3es<nNHuxWZWnMyV3ZYUHUFbsFAwXutMqbpK-Y&v~AHZch*++F&<a&{hTG=Wj! zCtlx}(S*aDsvb0(M9s^r&R{r?-FVlag%5*bW^QqN$6`M?#QM4a$G*0)Wi(AA_xyoz zqv<?$Asv#Ywsn?eQA+cR%Xm<E>6#BV{aV{V-8B>crjQjOIE}obxSTFGymYxek!UoV lRrdHOLpI}t?3w?7{09k;r68%i044wc002ovPDHLkV1kO6<naIi literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/images/yast_printer.png b/src/main/resources/com/unicenta/images/yast_printer.png new file mode 100644 index 0000000000000000000000000000000000000000..c1f30d9866708078af706f1bc1f504eb084868cc GIT binary patch literal 634 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP{O6e zHKN2hzo4=xGd-h(!MP|ku_UuBRlzwwH#a}8Si!NRq$o3~v?Mb>Pr)xgPZuPfT9llb zm;>Z0xTF?kmVq@CSKr;R0BD{R$h_eEw370~qEv=}#LT=BJwMkFg)(D3Q$0figD*u3 zfv#`zba4#v@ZLJ*wii>NNZa*2q0{Y}`Y$YgGcQ3dQO_sv2wzB0O5dUzOTRDENMhHT zdBP<yXX~|l&X;9!wkQ92n0&hE|9vTutqQYl`?Kq0+nfEr{ea<{&d1+Z&$&6IH?z!F zThV9sc5A~osjc4^iSIZZn;WIgxOVDKrgsJ5v!4Yy6ld;hu)cG3*+zj25i|53@RbV( z&re@ycU<6>dS^_>x0{;5vr{|u?$ji3TxPvkm;21iJZ68g(lYLCRqO5vlySyX%@C5S zjA=T5fb**6vX);#t1suAU>9FMgX_6|7UO*Txdq>PG#^epuKI&#PQkAhYgRwG!sQ1p z+6u`f9{$+8;PO=Cy4<EuJN6y^HuuZ);F$`E_5ast2`i>A3!L|0{|ckRDa&o#lp+G; zxGjx)Ke2G%(6n7D2-GXwRPeMXSSt08<oWFrKfd48zPsl9$GJ~5`F67$dk|LmLS>)$ zzV-90P9A(0!Nttj+W6D`i0r$p$?v&Od>7<<-y(SD;X1RO^BQ9K|9j>f6t}C+QaSVE S(Me#OF?hQAxvX<aXaWEMW(O(& literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/pos/config/Bundle.properties b/src/main/resources/com/unicenta/pos/config/Bundle.properties new file mode 100644 index 0000000..6e8a2c6 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/config/Bundle.properties @@ -0,0 +1,25 @@ +# To change this license header, choose License Headers in Project Properties. +# To change this template file, choose Tools | Templates +# and open the template in the editor. + +label.ticketheader1=Header 1 +label.ticketheader2=Header 2 +label.ticketheader3=Header 3 +label.ticketheader4=Header 4 +label.ticketheader5=Header 5 +label.ticketheader6=Header 6 +label.ticketfooter1=Footer 1 +label.ticketfooter2=Footer 2 +label.ticketfooter3=Footer 3 +label.ticketfooter4=Footer 4 +label.ticketfooter5=Footer 5 +label.ticketfooter6=Footer 6 +# To change this license header, choose License Headers in Project Properties. +# To change this template file, choose Tools | Templates +# and open the template in the editor. +label.tktheader1=Header 1 +label.tktheader2=Header 2 +label.tktheader3=Header 3 +label.tktheader4=Header 4 +label.tktheader5=Header 5 +label.tktheader6=Header 6 diff --git a/src/main/resources/com/unicenta/pos/customers/Bundle.properties b/src/main/resources/com/unicenta/pos/customers/Bundle.properties new file mode 100644 index 0000000..9c41ba4 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/customers/Bundle.properties @@ -0,0 +1,4 @@ +# To change this license header, choose License Headers in Project Properties. +# To change this template file, choose Tools | Templates +# and open the template in the editor. + diff --git a/src/main/resources/com/unicenta/pos/scripts/Derby-create.sql b/src/main/resources/com/unicenta/pos/scripts/Derby-create.sql new file mode 100644 index 0000000..89b610f --- /dev/null +++ b/src/main/resources/com/unicenta/pos/scripts/Derby-create.sql @@ -0,0 +1,699 @@ + +CREATE TABLE applications ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + version varchar(255) NOT NULL, + instdate timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP , + PRIMARY KEY (id) +); + +CREATE TABLE attribute ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE attributeinstance ( + id varchar(255) NOT NULL, + attributesetinstance_id varchar(255) NOT NULL, + attribute_id varchar(255) NOT NULL, + value varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE attributeset ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE attributesetinstance ( + id varchar(255) NOT NULL, + attributeset_id varchar(255) NOT NULL, + description varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE attributeuse ( + id varchar(255) NOT NULL, + attributeset_id varchar(255) NOT NULL, + attribute_id varchar(255) NOT NULL, + lineno smallint default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE attributevalue ( + id varchar(255) NOT NULL, + attribute_id varchar(255) NOT NULL, + value varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE breaks ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + visible smallint NOT NULL default 1 , + notes varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE categories ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + parentid varchar(255) default NULL, + image blob default NULL, + texttip varchar(255) default NULL, + catshowname smallint NOT NULL default 1 , + catorder varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE closedcash ( + money varchar(255) NOT NULL, + host varchar(255) NOT NULL, + hostsequence smallint NOT NULL, + datestart timestamp NOT NULL, + dateend timestamp default NULL, + nosales smallint NOT NULL default 0 , + PRIMARY KEY (money) +); + +CREATE TABLE csvimport ( + id varchar(255) NOT NULL, + rownumber varchar(255) default NULL, + csverror varchar(255) default NULL, + reference varchar(255) default NULL, + code varchar(255) default NULL, + name varchar(255) default NULL, + pricebuy double default NULL, + pricesell double default NULL, + previousbuy double default NULL, + previoussell double default NULL, + category varchar(255) default NULL, + tax varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE customers ( + id varchar(255) NOT NULL, + searchkey varchar(255) NOT NULL, + taxid varchar(255) default NULL, + name varchar(255) NOT NULL, + taxcategory varchar(255) default NULL, + card varchar(255) default NULL, + maxdebt double NOT NULL default 0 , + address varchar(255) default NULL, + address2 varchar(255) default NULL, + postal varchar(255) default NULL, + city varchar(255) default NULL, + region varchar(255) default NULL, + country varchar(255) default NULL, + firstname varchar(255) default NULL, + lastname varchar(255) default NULL, + email varchar(255) default NULL, + phone varchar(255) default NULL, + phone2 varchar(255) default NULL, + fax varchar(255) default NULL, + notes varchar(255) default NULL, + visible smallint NOT NULL default 1 , + curdate timestamp default NULL, + curdebt double default 0 , + image blob default NULL, + isvip smallint NOT NULL default 0 , + discount double default 0 , + memodate timestamp default CURRENT_TIMESTAMP , + PRIMARY KEY (id) +); + +CREATE TABLE draweropened ( + opendate timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP , + name varchar(255) default NULL, + ticketid varchar(255) default NULL +); + +CREATE TABLE floors ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + image blob default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE leaves ( + id varchar(255) NOT NULL, + pplid varchar(255) NOT NULL, + name varchar(255) NOT NULL, + startdate timestamp NOT NULL, + enddate timestamp NOT NULL, + notes varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE lineremoved ( + removeddate timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP , + name varchar(255) default NULL, + ticketid varchar(255) default NULL, + productid varchar(255) default NULL, + productname varchar(255) default NULL, + units double NOT NULL +); + +CREATE TABLE locations ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + address varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE moorers ( + vesselname varchar(255) default NULL, + size smallint default NULL, + days smallint default NULL, + power smallint NOT NULL default 0 +); + +CREATE TABLE orders ( + id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY(Start with 1, Increment by 1), + orderid varchar(50) DEFAULT NULL, + qty smallint DEFAULT 1 , + details varchar(255) DEFAULT NULL, + attributes varchar(255) DEFAULT NULL, + notes varchar(255) DEFAULT NULL, + ticketid varchar(50) DEFAULT NULL, + ordertime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP , + displayid smallint DEFAULT 1 , + auxiliary smallint DEFAULT NULL, + completetime timestamp DEFAULT NULL +); + +CREATE TABLE payments ( + id varchar(255) NOT NULL, + receipt varchar(255) NOT NULL, + payment varchar(255) NOT NULL, + total double NOT NULL default 0 , + tip double default 0 , + transid varchar(255) default NULL, + isprocessed smallint default 0 , + returnmsg blob default NULL, + notes varchar(255) default NULL, + tendered double default NULL, + cardname varchar(255) default NULL, + voucher varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE people ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + apppassword varchar(255) default NULL, + card varchar(255) default NULL, + role varchar(255) NOT NULL, + visible smallint NOT NULL, + image blob default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE pickup_number ( + id smallint NOT NULL default 0 +); + +CREATE TABLE places ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + seats varchar(6) NOT NULL DEFAULT '1' , + x smallint NOT NULL, + y smallint NOT NULL, + floor varchar(255) NOT NULL, + customer varchar(255) default NULL, + waiter varchar(255) default NULL, + ticketid varchar(255) default NULL, + tablemoved smallint NOT NULL default 0 , + width smallint NOT NULL, + height smallint NOT NULL, + guests smallint DEFAULT 0, + occupied timestamp DEFAULT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE products ( + id varchar(255) NOT NULL, + reference varchar(255) NOT NULL, + code varchar(255) NOT NULL, + codetype varchar(255) default NULL, + name varchar(255) NOT NULL, + pricebuy double NOT NULL default 0 , + pricesell double NOT NULL default 0 , + category varchar(255) NOT NULL, + taxcat varchar(255) NOT NULL, + attributeset_id varchar(255) default NULL, + stockcost double NOT NULL default 0 , + stockvolume double NOT NULL default 0 , + image blob default NULL, + iscom smallint NOT NULL default 0 , + isscale smallint NOT NULL default 0 , + isconstant smallint NOT NULL default 0 , + printkb smallint NOT NULL default 0 , + sendstatus smallint NOT NULL default 0 , + isservice smallint NOT NULL default 0 , + attributes blob default NULL, + display varchar(255) default NULL, + isvprice smallint NOT NULL default 0 , + isverpatrib smallint NOT NULL default 0 , + texttip varchar(255) default NULL, + warranty smallint NOT NULL default 0 , + stockunits double NOT NULL default 0 , + printto varchar(255) default '1' , + supplier varchar(255) default NULL, + uom varchar(255) default '0' , + memodate timestamp default '2018-01-01 00:00:01' , + PRIMARY KEY (id) +); + +CREATE TABLE products_bundle ( + id varchar(255) NOT NULL, + product VARCHAR(255) NOT NULL, + product_bundle VARCHAR(255) NOT NULL, + quantity DOUBLE NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE products_cat ( + product varchar(255) NOT NULL, + catorder smallint default NULL, + PRIMARY KEY (product) +); + +CREATE TABLE products_com ( + id varchar(255) NOT NULL, + product varchar(255) NOT NULL, + product2 varchar(255) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE receipts ( + id varchar(255) NOT NULL, + money varchar(255) NOT NULL, + datenew timestamp NOT NULL, + attributes blob default NULL, + person varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE reservation_customers ( + id varchar(255) NOT NULL, + customer varchar(255) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE reservations ( + id varchar(255) NOT NULL, + created timestamp NOT NULL, + datenew timestamp NOT NULL default '2018-01-01 00:00:00' , + title varchar(255) NOT NULL, + chairs smallint NOT NULL, + isdone smallint NOT NULL, + description varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE resources ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + restype smallint NOT NULL, + content blob default NULL, + version varchar(10) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE roles ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + permissions blob default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE sharedtickets ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + content blob default NULL, + appuser varchar(255) default NULL, + pickupid smallint NOT NULL default 0 , + locked varchar(20) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE shift_breaks ( + id varchar(255) NOT NULL, + shiftid varchar(255) NOT NULL, + breakid varchar(255) NOT NULL, + starttime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP , + endtime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP , + PRIMARY KEY (id) +); + +CREATE TABLE shifts ( + id varchar(255) NOT NULL, + startshift timestamp NOT NULL, + endshift timestamp default NULL, + pplid varchar(255) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE stockcurrent ( + location varchar(255) NOT NULL, + product varchar(255) NOT NULL, + attributesetinstance_id varchar(255) default NULL, + units double NOT NULL +); + +CREATE TABLE stockdiary ( + id varchar(255) NOT NULL, + datenew timestamp NOT NULL, + reason smallint NOT NULL, + location varchar(255) NOT NULL, + product varchar(255) NOT NULL, + attributesetinstance_id varchar(255) default NULL, + units double NOT NULL, + price double NOT NULL, + appuser varchar(255) default NULL, + supplier varchar(255) default NULL, + supplierdoc varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE stocklevel ( + id varchar(255) NOT NULL, + location varchar(255) NOT NULL, + product varchar(255) NOT NULL, + stocksecurity double default NULL, + stockmaximum double default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE suppliers ( + id varchar(255) NOT NULL, + searchkey varchar(255) NOT NULL, + taxid varchar(255) default NULL, + name varchar(255) NOT NULL, + maxdebt double NOT NULL default 0 , + address varchar(255) default NULL, + address2 varchar(255) default NULL, + postal varchar(255) default NULL, + city varchar(255) default NULL, + region varchar(255) default NULL, + country varchar(255) default NULL, + firstname varchar(255) default NULL, + lastname varchar(255) default NULL, + email varchar(255) default NULL, + phone varchar(255) default NULL, + phone2 varchar(255) default NULL, + fax varchar(255) default NULL, + notes varchar(255) default NULL, + visible smallint NOT NULL default 1 , + curdate timestamp default NULL, + curdebt double default 0 , + vatid varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE taxcategories ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE taxcustcategories ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE taxes ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + category varchar(255) NOT NULL, + custcategory varchar(255) default NULL, + parentid varchar(255) default NULL, + rate double NOT NULL default 0 , + ratecascade smallint NOT NULL default 0 , + rateorder smallint default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE taxlines ( + id varchar(255) NOT NULL, + receipt varchar(255) NOT NULL, + taxid varchar(255) NOT NULL, + base double NOT NULL default 0 , + amount double NOT NULL default 0 , + PRIMARY KEY (id) +); + +CREATE TABLE taxsuppcategories ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE thirdparties ( + id varchar(255) NOT NULL, + cif varchar(255) NOT NULL, + name varchar(255) NOT NULL, + address varchar(255) default NULL, + contactcomm varchar(255) default NULL, + contactfact varchar(255) default NULL, + payrule varchar(255) default NULL, + faxnumber varchar(255) default NULL, + phonenumber varchar(255) default NULL, + mobilenumber varchar(255) default NULL, + email varchar(255) default NULL, + webpage varchar(255) default NULL, + notes varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE ticketlines ( + ticket varchar(255) NOT NULL, + line smallint NOT NULL, + product varchar(255) default NULL, + attributesetinstance_id varchar(255) default NULL, + units double NOT NULL, + price double NOT NULL, + taxid varchar(255) NOT NULL, + attributes blob default NULL, + PRIMARY KEY (ticket , line) +); + +CREATE TABLE tickets ( + id varchar(255) NOT NULL, + tickettype smallint NOT NULL default 0 , + ticketid smallint NOT NULL, + person varchar(255) NOT NULL, + customer varchar(255) default NULL, + status smallint NOT NULL default 0 , + PRIMARY KEY (id) +); + +CREATE TABLE ticketsnum ( + id smallint NOT NULL +); + +CREATE TABLE ticketsnum_payment ( + id smallint NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE ticketsnum_refund ( + id smallint NOT NULL +); + +CREATE TABLE uom ( + id VARCHAR(255) NOT NULL, + name VARCHAR(255) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE vouchers ( + id VARCHAR(100) NOT NULL, + voucher_number VARCHAR(100) DEFAULT NULL, + customer VARCHAR(100) DEFAULT NULL, + amount DOUBLE DEFAULT NULL, + status CHAR(1) DEFAULT 'A' , + PRIMARY KEY (id) +); + +-- ADD roles +INSERT INTO roles(id, name, permissions) VALUES('0', 'Administrator role', $FILE{/com/unicenta/pos/templates/Role.Administrator.xml} ); +INSERT INTO roles(id, name, permissions) VALUES('1', 'Manager role', $FILE{/com/unicenta/pos/templates/Role.Manager.xml} ); +INSERT INTO roles(id, name, permissions) VALUES('2', 'Employee role', $FILE{/com/unicenta/pos/templates/Role.Employee.xml} ); +INSERT INTO roles(id, name, permissions) VALUES('3', 'Guest role', $FILE{/com/unicenta/pos/templates/Role.Guest.xml} ); + +-- ADD people +INSERT INTO people(id, name, apppassword, role, visible, image) VALUES ('0', 'Administrator', NULL, '0', 1, NULL); +INSERT INTO people(id, name, apppassword, role, visible, image) VALUES ('1', 'Manager', NULL, '1', 1, NULL); +INSERT INTO people(id, name, apppassword, role, visible, image) VALUES ('2', 'Employee', NULL, '2', 1, NULL); +INSERT INTO people(id, name, apppassword, role, visible, image) VALUES ('3', 'Guest', NULL, '3', 1, NULL); + +-- ADD resources -- +-- SYSTEM +INSERT INTO resources(id, name, restype, content) VALUES('00', 'Menu.Root', 0, $FILE{/com/unicenta/pos/templates/Menu.Root.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('02', 'Cash.Close', 0, $FILE{/com/unicenta/pos/templates/Cash.Close.xml}); +INSERT INTO resources(ID, name, restype, content) VALUES('03', 'Customer.Created', 0, $FILE{/com/unicenta/pos/templates/customer.created.xml}); +INSERT INTO resources(ID, name, restype, content) VALUES('04', 'Customer.Deleted', 0, $FILE{/com/unicenta/pos/templates/customer.deleted.xml}); +INSERT INTO resources(ID, name, restype, content) VALUES('05', 'Customer.Updated', 0, $FILE{/com/unicenta/pos/templates/customer.updated.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('06', 'payment.cash', 0, $FILE{/com/unicenta/pos/templates/payment.cash.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('07', 'Ticket.Buttons', 0, $FILE{/com/unicenta/pos/templates/Ticket.Buttons.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('08', 'Ticket.Close', 0, $FILE{/com/unicenta/pos/templates/Ticket.Close.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('09', 'Ticket.Line', 0, $FILE{/com/unicenta/pos/templates/Ticket.Line.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('10', 'Window.Title', 0, $FILE{/com/unicenta/pos/templates/Window.Title.txt}); + +-- IMAGES +INSERT INTO resources(id, name, restype, content) VALUES('11', 'img.001', 1, $FILE{/com/unicenta/images/.01.png}); +INSERT INTO resources(id, name, restype, content) VALUES('12', 'img.002', 1, $FILE{/com/unicenta/images/.02.png}); +INSERT INTO resources(id, name, restype, content) VALUES('13', 'img.005', 1, $FILE{/com/unicenta/images/.05.png}); +INSERT INTO resources(id, name, restype, content) VALUES('14', 'img.010', 1, $FILE{/com/unicenta/images/.10.png}); +INSERT INTO resources(id, name, restype, content) VALUES('15', 'img.020', 1, $FILE{/com/unicenta/images/.20.png}); +INSERT INTO resources(id, name, restype, content) VALUES('16', 'img.025', 1, $FILE{/com/unicenta/images/.25.png}); +INSERT INTO resources(id, name, restype, content) VALUES('17', 'img.050', 1, $FILE{/com/unicenta/images/.50.png}); +INSERT INTO resources(id, name, restype, content) VALUES('18', 'img.1', 1, $FILE{/com/unicenta/images/1.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('19', 'img.2', 1, $FILE{/com/unicenta/images/2.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('20', 'img.5', 1, $FILE{/com/unicenta/images/5.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('21', 'img.10', 1, $FILE{/com/unicenta/images/10.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('22', 'img.20', 1, $FILE{/com/unicenta/images/20.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('23', 'img.50', 1, $FILE{/com/unicenta/images/50.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('24', 'img.100', 1, $FILE{/com/unicenta/images/100.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('25', 'img.200', 1, $FILE{/com/unicenta/images/200.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('26', 'img.500', 1, $FILE{/com/unicenta/images/500.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('27', 'img.1000', 1, $FILE{/com/unicenta/images/1000.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('28', 'img.cash', 1, $FILE{/com/unicenta/images/cash.png}); +INSERT INTO resources(id, name, restype, content) VALUES('29', 'img.cashdrawer', 1, $FILE{/com/unicenta/images/cashdrawer.png}); +INSERT INTO resources(id, name, restype, content) VALUES('30', 'img.discount', 1, $FILE{/com/unicenta/images/discount.png}); +INSERT INTO resources(id, name, restype, content) VALUES('31', 'img.discount_b', 1, $FILE{/com/unicenta/images/discount_b.png}); +INSERT INTO resources(id, name, restype, content) VALUES('32', 'img.heart', 1, $FILE{/com/unicenta/images/heart.png}); +INSERT INTO resources(id, name, restype, content) VALUES('33', 'img.keyboard_48', 1, $FILE{/com/unicenta/images/keyboard_48.png}); +INSERT INTO resources(id, name, restype, content) VALUES('34', 'img.kit_print', 1, $FILE{/com/unicenta/images/kit_print.png}); +INSERT INTO resources(id, name, restype, content) VALUES('35', 'img.no_photo', 1, $FILE{/com/unicenta/images/no_photo.png}); +INSERT INTO resources(id, name, restype, content) VALUES('36', 'img.refundit', 1, $FILE{/com/unicenta/images/refundit.png}); +INSERT INTO resources(id, name, restype, content) VALUES('37', 'img.run_script', 1, $FILE{/com/unicenta/images/run_script.png}); +INSERT INTO resources(id, name, restype, content) VALUES('38', 'img.ticket_print', 1, $FILE{/com/unicenta/images/ticket_print.png}); +INSERT INTO resources(id, name, restype, content) VALUES('40', 'Printer.Ticket.Logo', 1, $FILE{/com/unicenta/images/printer.ticket.logo.jpg}); + +-- PRINTER +INSERT INTO resources(id, name, restype, content) VALUES('41', 'Printer.CloseCash.Preview', 0, $FILE{/com/unicenta/pos/templates/Printer.CloseCash.Preview.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('42', 'Printer.CloseCash', 0, $FILE{/com/unicenta/pos/templates/Printer.CloseCash.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('43', 'Printer.CustomerPaid', 0, $FILE{/com/unicenta/pos/templates/Printer.CustomerPaid.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('44', 'Printer.CustomerPaid2', 0, $FILE{/com/unicenta/pos/templates/Printer.CustomerPaid2.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('45', 'Printer.FiscalTicket', 0, $FILE{/com/unicenta/pos/templates/Printer.FiscalTicket.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('46', 'Printer.Inventory', 0, $FILE{/com/unicenta/pos/templates/Printer.Inventory.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('47', 'Printer.OpenDrawer', 0, $FILE{/com/unicenta/pos/templates/Printer.OpenDrawer.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('48', 'Printer.PartialCash', 0, $FILE{/com/unicenta/pos/templates/Printer.PartialCash.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('49', 'Printer.PrintLastTicket', 0, $FILE{/com/unicenta/pos/templates/Printer.PrintLastTicket.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('50', 'Printer.Product', 0, $FILE{/com/unicenta/pos/templates/Printer.Product.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('52', 'Printer.ReprintTicket', 0, $FILE{/com/unicenta/pos/templates/Printer.ReprintTicket.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('53', 'Printer.Start', 0, $FILE{/com/unicenta/pos/templates/Printer.Start.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('54', 'Printer.Ticket.P1', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P1.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('55', 'Printer.Ticket.P2', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P2.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('56', 'Printer.Ticket.P3', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P3.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('57', 'Printer.Ticket.P4', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P4.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('58', 'Printer.Ticket.P5', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P5.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('59', 'Printer.Ticket.P6', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P6.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('60', 'Printer.Ticket', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('61', 'Printer.Ticket2', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket2.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('62', 'Printer.TicketClose', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketClose.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('63', 'Printer.TicketLine', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketLine.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('64', 'Printer.TicketNew', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketLine.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('65', 'Printer.TicketPreview', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketPreview.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('66', 'Printer.Ticket_A4', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket_A4.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('67', 'Printer.TicketPreview_A4', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketPreview_A4.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('68', 'Printer.TicketRemote', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketRemote.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('69', 'Printer.TicketTotal', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketTotal.xml}); + +-- SCRIPTS +INSERT INTO resources(id, name, restype, content) VALUES('70', 'script.Keyboard', 0, $FILE{/com/unicenta/pos/templates/script.Keyboard.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('71', 'script.Linediscount', 0, $FILE{/com/unicenta/pos/templates/script.Linediscount.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('73', 'script.SendOrder', 0, $FILE{/com/unicenta/pos/templates/script.SendOrder.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('74', 'script.Totaldiscount', 0, $FILE{/com/unicenta/pos/templates/script.Totaldiscount.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('75', 'script.multibuy', 0, $FILE{/com/unicenta/pos/templates/script.multibuy.txt}); + +-- ADD CATEGORIES +INSERT INTO categories(id, name) VALUES ('000', 'Category Standard'); + +-- ADD TAXCATEGORIES +/* 002 added 31/01/2017 00:00:00. */ +INSERT INTO taxcategories(id, name) VALUES ('000', 'Tax Exempt'); +INSERT INTO taxcategories(id, name) VALUES ('001', 'Tax Standard'); +INSERT INTO taxcategories(id, name) VALUES ('002', 'Tax Other'); + +-- ADD TAXES +/* 002 added 31/01/2017 00:00:00. */ +INSERT INTO taxes(id, name, category, custcategory, parentid, rate, ratecascade, rateorder) VALUES ('000', 'Tax Exempt', '000', NULL, NULL, 0, 0, NULL); +INSERT INTO taxes(id, name, category, custcategory, parentid, rate, ratecascade, rateorder) VALUES ('001', 'Tax Standard', '001', NULL, NULL, 0.20, 0, NULL); +INSERT INTO taxes(id, name, category, custcategory, parentid, rate, ratecascade, rateorder) VALUES ('002', 'Tax Other', '002', NULL, NULL, 0, 0, NULL); + +-- ADD PRODUCTS +INSERT INTO products(id, reference, code, name, category, taxcat, isservice, display, printto) +VALUES ('xxx999_999xxx_x9x9x9', 'xxx999', 'xxx999', 'Free Line entry', '000', '001', 1, '<html><center>Free Line entry', '1'); +INSERT INTO products(id, reference, code, name, category, taxcat, isservice, display, printto) +VALUES ('xxx998_998xxx_x8x8x8', 'xxx998', 'xxx998', 'Service Charge', '000', '001', 1, '<html><center>Service Charge', '1'); + +-- ADD PRODUCTS_CAT +INSERT INTO products_cat(product) VALUES ('xxx999_999xxx_x9x9x9'); +INSERT INTO products_cat(product) VALUES ('xxx998_998xxx_x8x8x8'); + +-- ADD LOCATION +INSERT INTO locations(id, name, address) VALUES ('0','Location 1','Local'); + +-- ADD SUPPLIERS +INSERT INTO suppliers(id, searchkey, name) VALUES ('0','unicenta','unicenta'); + +-- ADD UOM +INSERT INTO uom(id, name) VALUES ('0','Each'); + +-- ADD FLOORS +INSERT INTO floors(id, name, image) VALUES ('0', 'Restaurant floor', $FILE{/com/unicenta/images/paperboard960_600.png}); + +-- ADD PLACES +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('1', 'Table 1', 100, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('2', 'Table 2', 250, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('3', 'Table 3', 400, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('4', 'Table 4', 550, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('5', 'Table 5', 700, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('6', 'Table 6', 850, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('7', 'Table 7', 100, 150, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('8', 'Table 8', 250, 150, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('9', 'Table 9', 400, 150, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('10', 'Table 10', 550, 150, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('11', 'Table 11', 700, 150, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('12', 'Table 12', 850, 150, '0', '1', 90, 45); + +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('13', 'Table 13', 100, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('14', 'Table 14', 250, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('15', 'Table 15', 400, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('16', 'Table 16', 550, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('17', 'Table 17', 700, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('18', 'Table 18', 850, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('19', 'Table 19', 100, 350, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('20', 'Table 20', 250, 350, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('21', 'Table 21', 400, 350, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('22', 'Table 22', 550, 350, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('23', 'Table 23', 700, 350, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('24', 'Table 24', 850, 350, '0', '1', 90, 45); + +-- ADD SHIFTS +INSERT INTO shifts(id, startshift, endshift, pplid) VALUES ('0', '2018-01-01 00:00:00.001', '2018-01-01 00:00:00.002','0'); + +-- ADD BREAKS +INSERT INTO breaks(id, name, visible, notes) VALUES ('0', 'Lunch Break', 1, NULL); +INSERT INTO breaks(id, name, visible, notes) VALUES ('1', 'Tea Break', 1, NULL); +INSERT INTO breaks(id, name, visible, notes) VALUES ('2', 'Mid Break', 1, NULL); + +-- ADD SHIFT_BREAKS +INSERT INTO shift_breaks(id, shiftid, breakid, starttime, endtime) VALUES ('0', '0', '0', '2018-01-01 00:00:00.003', '2018-01-01 00:00:00.004'); + +-- ADD SEQUENCES +INSERT INTO pickup_number VALUES(1); +INSERT INTO ticketsnum VALUES(1); +INSERT INTO ticketsnum_refund VALUES(1); +INSERT INTO ticketsnum_payment VALUES(1); + +-- ADD APPLICATION VERSION +INSERT INTO applications(id, name, version) VALUES($APP_ID{}, $APP_NAME{}, $APP_VERSION{}); diff --git a/src/main/resources/com/unicenta/pos/scripts/MariaDB-create.sql b/src/main/resources/com/unicenta/pos/scripts/MariaDB-create.sql new file mode 100644 index 0000000..76e76f6 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/scripts/MariaDB-create.sql @@ -0,0 +1,1003 @@ +-- uniCenta oPOS - Touch Friendly Point Of Sale +-- Copyright (c) 2009-2018 uniCenta +-- https://unicenta.com +-- +-- This file is part of uniCenta oPOS. +-- +-- uniCenta oPOS is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- uniCenta oPOS is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +/* + * Script created by Jack, uniCenta 23/01/2018 08:00:00 + * + * Creating for version unicentaopos45. Jan 2018 +*/ + +/* Header line. Object: applications. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `applications` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `version` varchar(255) NOT NULL, + `instdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: attribute. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `attribute` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: attributeinstance. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `attributeinstance` ( + `id` varchar(255) NOT NULL, + `attributesetinstance_id` varchar(255) NOT NULL, + `attribute_id` varchar(255) NOT NULL, + `value` varchar(255) default NULL, + KEY `attinst_att` ( `attribute_id` ), + KEY `attinst_set` ( `attributesetinstance_id` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: attributeset. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `attributeset` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: attributesetinstance. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `attributesetinstance` ( + `id` varchar(255) NOT NULL, + `attributeset_id` varchar(255) NOT NULL, + `description` varchar(255) default NULL, + KEY `attsetinst_set` ( `attributeset_id` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: attributeuse. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `attributeuse` ( + `id` varchar(255) NOT NULL, + `attributeset_id` varchar(255) NOT NULL, + `attribute_id` varchar(255) NOT NULL, + `lineno` int(11) default NULL, + KEY `attuse_att` ( `attribute_id` ), + UNIQUE INDEX `attuse_line` ( `attributeset_id`, `lineno` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: attributevalue. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `attributevalue` ( + `id` varchar(255) NOT NULL, + `attribute_id` varchar(255) NOT NULL, + `value` varchar(255) default NULL, + KEY `attval_att` ( `attribute_id` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: breaks. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `breaks` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `visible` tinyint(1) NOT NULL default '1', + `notes` varchar(255) default NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: categories. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `categories` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `parentid` varchar(255) default NULL, + `image` mediumblob default NULL, + `texttip` varchar(255) default NULL, + `catshowname` smallint(6) NOT NULL default '1', + `catorder` varchar(255) default NULL, + KEY `categories_fk_1` ( `parentid` ), + UNIQUE INDEX `categories_name_inx` ( `name` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: closedcash. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `closedcash` ( + `money` varchar(255) NOT NULL, + `host` varchar(255) NOT NULL, + `hostsequence` int(11) NOT NULL, + `datestart` datetime NOT NULL, + `dateend` datetime default NULL, + `nosales` int(11) NOT NULL default '0', + KEY `closedcash_inx_1` ( `datestart` ), + UNIQUE INDEX `closedcash_inx_seq` ( `host`, `hostsequence` ), + PRIMARY KEY ( `money` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: csvimport. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `csvimport` ( + `id` varchar(255) NOT NULL, + `rownumber` varchar(255) default NULL, + `csverror` varchar(255) default NULL, + `reference` varchar(255) default NULL, + `code` varchar(255) default NULL, + `name` varchar(255) default NULL, + `pricebuy` double default NULL, + `pricesell` double default NULL, + `previousbuy` double default NULL, + `previoussell` double default NULL, + `category` varchar(255) default NULL, + `tax` varchar(255) default NULL, + `searchkey` varchar(255) default NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: customers. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `customers` ( + `id` varchar(255) NOT NULL, + `searchkey` varchar(255) NOT NULL, + `taxid` varchar(255) default NULL, + `name` varchar(255) NOT NULL, + `taxcategory` varchar(255) default NULL, + `card` varchar(255) default NULL, + `maxdebt` double NOT NULL default '0', + `address` varchar(255) default NULL, + `address2` varchar(255) default NULL, + `postal` varchar(255) default NULL, + `city` varchar(255) default NULL, + `region` varchar(255) default NULL, + `country` varchar(255) default NULL, + `firstname` varchar(255) default NULL, + `lastname` varchar(255) default NULL, + `email` varchar(255) default NULL, + `phone` varchar(255) default NULL, + `phone2` varchar(255) default NULL, + `fax` varchar(255) default NULL, + `notes` varchar(255) default NULL, + `visible` bit(1) NOT NULL default b'1', + `curdate` datetime default NULL, + `curdebt` double default '0', + `image` mediumblob default NULL, + `isvip` bit(1) NOT NULL default b'0', + `discount` double default '0', + `memodate` datetime default '2000-01-01 00:00:01', + KEY `customers_card_inx` ( `card` ), + KEY `customers_name_inx` ( `name` ), + UNIQUE INDEX `customers_skey_inx` ( `searchkey` ), + KEY `customers_taxcat` ( `taxcategory` ), + KEY `customers_taxid_inx` ( `taxid` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: draweropened. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `draweropened` ( + `opendate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `name` varchar(255) default NULL, + `ticketid` varchar(255) default NULL +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: floors. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `floors` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `image` mediumblob default NULL, + UNIQUE INDEX `floors_name_inx` ( `name` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: leaves. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `leaves` ( + `id` varchar(255) NOT NULL, + `pplid` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `startdate` datetime NOT NULL, + `enddate` datetime NOT NULL, + `notes` varchar(255) default NULL, + KEY `leaves_pplid` ( `pplid` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: lineremoved. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `lineremoved` ( + `removeddate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `name` varchar(255) default NULL, + `ticketid` varchar(255) default NULL, + `productid` varchar(255) default NULL, + `productname` varchar(255) default NULL, + `units` double NOT NULL +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: locations. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `locations` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `address` varchar(255) default NULL, + UNIQUE INDEX `locations_name_inx` ( `name` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: moorers. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `moorers` ( + `vesselname` varchar(255) default NULL, + `size` int(11) default NULL, + `days` int(11) default NULL, + `power` bit(1) NOT NULL default b'0' +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +CREATE TABLE IF NOT EXISTS `orders` ( + `id` MEDIUMINT NOT NULL AUTO_INCREMENT, + `orderid` varchar(50) DEFAULT NULL, + `qty` int(11) DEFAULT '1', + `details` varchar(255) DEFAULT NULL, + `attributes` varchar(255) DEFAULT NULL, + `notes` varchar(255) DEFAULT NULL, + `ticketid` varchar(50) DEFAULT NULL, + `ordertime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `displayid` int(11) DEFAULT '1', + `auxiliary` int(11) DEFAULT NULL, + `completetime` timestamp NULL, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: payments. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `payments` ( + `id` varchar(255) NOT NULL, + `receipt` varchar(255) NOT NULL, + `payment` varchar(255) NOT NULL, + `total` double NOT NULL default '0', + `tip` double default '0', + `transid` varchar(255) default NULL, + `isprocessed` bit(1) default b'0', + `returnmsg` mediumblob default NULL, + `notes` varchar(255) default NULL, + `tendered` double default NULL, + `cardname` varchar(255) default NULL, + `voucher` varchar(255) default NULL, + KEY `payments_fk_receipt` ( `receipt` ), + KEY `payments_inx_1` ( `payment` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: people. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `people` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `apppassword` varchar(255) default NULL, + `card` varchar(255) default NULL, + `role` varchar(255) NOT NULL, + `visible` bit(1) NOT NULL, + `image` mediumblob default NULL, + KEY `people_card_inx` ( `card` ), + KEY `people_fk_1` ( `role` ), + UNIQUE INDEX `people_name_inx` ( `name` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: pickup_number. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `pickup_number` ( + `id` int(11) NOT NULL default '0' +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: places. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `places` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `seats` varchar(6) NOT NULL DEFAULT '1', + `x` int(11) NOT NULL, + `y` int(11) NOT NULL, + `floor` varchar(255) NOT NULL, + `customer` varchar(255) default NULL, + `waiter` varchar(255) default NULL, + `ticketid` varchar(255) default NULL, + `tablemoved` smallint(6) NOT NULL default '0', + `width` int(11) NOT NULL, + `height` int(11) NOT NULL, + `guests` int(11) DEFAULT 0, + `occupied` datetime DEFAULT NULL, + UNIQUE INDEX `places_name_inx` ( `name` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: products. Script date: 02/04/2016 10:53:00. */ +CREATE TABLE `products` ( + `id` varchar(255) NOT NULL, + `reference` varchar(255) NOT NULL, + `code` varchar(255) NOT NULL, + `codetype` varchar(255) default NULL, + `name` varchar(255) NOT NULL, + `pricebuy` double NOT NULL default '0', + `pricesell` double NOT NULL default '0', + `category` varchar(255) NOT NULL, + `taxcat` varchar(255) NOT NULL, + `attributeset_id` varchar(255) default NULL, + `stockcost` double NOT NULL default '0', + `stockvolume` double NOT NULL default '0', + `image` mediumblob default NULL, + `iscom` bit(1) NOT NULL default b'0', + `isscale` bit(1) NOT NULL default b'0', + `isconstant` bit(1) NOT NULL default b'0', + `printkb` bit(1) NOT NULL default b'0', + `sendstatus` bit(1) NOT NULL default b'0', + `isservice` bit(1) NOT NULL default b'0', + `attributes` mediumblob default NULL, + `display` varchar(255) default NULL, + `isvprice` smallint(6) NOT NULL default '0', + `isverpatrib` smallint(6) NOT NULL default '0', + `texttip` varchar(255) default NULL, + `warranty` smallint(6) NOT NULL default '0', + `stockunits` double NOT NULL default '0', + `printto` varchar(255) default '1', + `supplier` varchar(255) default NULL, + `uom` varchar(255) default '0', + `memodate` datetime default '2018-01-01 00:00:01', + + PRIMARY KEY ( `id` ), + KEY `products_attrset_fx` ( `attributeset_id` ), + KEY `products_fk_1` ( `category` ), + UNIQUE INDEX `products_inx_0` ( `reference` ), + UNIQUE INDEX `products_inx_1` ( `code` ), + INDEX `products_name_inx` ( `name` ), + KEY `products_taxcat_fk` ( `taxcat` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8; + +/* Header line. Object: products_cat. Script date: 11/05/2016 05:25:00. */ +CREATE TABLE `products_bundle` ( + `id` varchar(255) NOT NULL, + `product` VARCHAR(255) NOT NULL, + `product_bundle` VARCHAR(255) NOT NULL, + `quantity` DOUBLE NOT NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `pbundle_inx_prod` ( `product` , `product_bundle` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8; + +/* Header line. Object: products_cat. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `products_cat` ( + `product` varchar(255) NOT NULL, + `catorder` int(11) default NULL, + PRIMARY KEY ( `product` ), + KEY `products_cat_inx_1` ( `catorder` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: products_com. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `products_com` ( + `id` varchar(255) NOT NULL, + `product` varchar(255) NOT NULL, + `product2` varchar(255) NOT NULL, + UNIQUE INDEX `pcom_inx_prod` ( `product`, `product2` ), + PRIMARY KEY ( `id` ), + KEY `products_com_fk_2` ( `product2` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: receipts. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `receipts` ( + `id` varchar(255) NOT NULL, + `money` varchar(255) NOT NULL, + `datenew` datetime NOT NULL, + `attributes` mediumblob default NULL, + `person` varchar(255) default NULL, + PRIMARY KEY ( `id` ), + KEY `receipts_fk_money` ( `money` ), + KEY `receipts_inx_1` ( `datenew` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: reservation_customers. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `reservation_customers` ( + `id` varchar(255) NOT NULL, + `customer` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ), + KEY `res_cust_fk_2` ( `customer` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8; + +/* Header line. Object: reservations. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `reservations` ( + `id` varchar(255) NOT NULL, + `created` datetime NOT NULL, + `datenew` datetime NOT NULL default '2018-01-01 00:00:00', + `title` varchar(255) NOT NULL, + `chairs` int(11) NOT NULL, + `isdone` bit(1) NOT NULL, + `description` varchar(255) default NULL, + PRIMARY KEY ( `id` ), + KEY `reservations_inx_1` ( `datenew` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: resources. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `resources` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `restype` int(11) NOT NULL, + `content` mediumblob default NULL, + `version` varchar(10) default NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `resources_name_inx` ( `name` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: roles. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `roles` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `permissions` mediumblob default NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `roles_name_inx` ( `name` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: sharedtickets. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `sharedtickets` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `content` mediumblob default NULL, + `appuser` varchar(255) default NULL, + `pickupid` int(11) NOT NULL default '0', + `locked` varchar(20) default NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8; + +/* Header line. Object: shift_breaks. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `shift_breaks` ( + `id` varchar(255) NOT NULL, + `shiftid` varchar(255) NOT NULL, + `breakid` varchar(255) NOT NULL, + `starttime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `endtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY ( `id` ), + KEY `shift_breaks_breakid` ( `breakid` ), + KEY `shift_breaks_shiftid` ( `shiftid` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: shifts. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `shifts` ( + `id` varchar(255) NOT NULL, + `startshift` datetime NOT NULL, + `endshift` datetime default NULL, + `pplid` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: stockcurrent. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `stockcurrent` ( + `location` varchar(255) NOT NULL, + `product` varchar(255) NOT NULL, + `attributesetinstance_id` varchar(255) default NULL, + `units` double NOT NULL, + KEY `stockcurrent_attsetinst` ( `attributesetinstance_id` ), + KEY `stockcurrent_fk_1` ( `product` ), + UNIQUE INDEX `stockcurrent_inx` ( `location`, `product`, `attributesetinstance_id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: stockdiary. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `stockdiary` ( + `id` varchar(255) NOT NULL, + `datenew` datetime NOT NULL, + `reason` int(11) NOT NULL, + `location` varchar(255) NOT NULL, + `product` varchar(255) NOT NULL, + `attributesetinstance_id` varchar(255) default NULL, + `units` double NOT NULL, + `price` double NOT NULL, + `appuser` varchar(255) default NULL, + `supplier` varchar(255) default NULL, + `supplierdoc` varchar(255) default NULL, + PRIMARY KEY ( `id` ), + KEY `stockdiary_attsetinst` ( `attributesetinstance_id` ), + KEY `stockdiary_fk_1` ( `product` ), + KEY `stockdiary_fk_2` ( `location` ), + KEY `stockdiary_inx_1` ( `datenew` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: stocklevel. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `stocklevel` ( + `id` varchar(255) NOT NULL, + `location` varchar(255) NOT NULL, + `product` varchar(255) NOT NULL, + `stocksecurity` double default NULL, + `stockmaximum` double default NULL, + PRIMARY KEY ( `id` ), + KEY `stocklevel_location` ( `location` ), + KEY `stocklevel_product` ( `product` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: suppliers. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `suppliers` ( + `id` varchar(255) NOT NULL, + `searchkey` varchar(255) NOT NULL, + `taxid` varchar(255) default NULL, + `name` varchar(255) NOT NULL, + `maxdebt` double NOT NULL default '0', + `address` varchar(255) default NULL, + `address2` varchar(255) default NULL, + `postal` varchar(255) default NULL, + `city` varchar(255) default NULL, + `region` varchar(255) default NULL, + `country` varchar(255) default NULL, + `firstname` varchar(255) default NULL, + `lastname` varchar(255) default NULL, + `email` varchar(255) default NULL, + `phone` varchar(255) default NULL, + `phone2` varchar(255) default NULL, + `fax` varchar(255) default NULL, + `notes` varchar(255) default NULL, + `visible` bit(1) NOT NULL default b'1', + `curdate` datetime default NULL, + `curdebt` double default '0', + `vatid` varchar(255) default NULL, + PRIMARY KEY ( `id` ), + KEY `suppliers_name_inx` ( `name` ), + UNIQUE INDEX `suppliers_skey_inx` ( `searchkey` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8; + +/* Header line. Object: taxcategories. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `taxcategories` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `taxcat_name_inx` ( `name` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8; + +/* Header line. Object: taxcustcategories. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `taxcustcategories` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `taxcustcat_name_inx` ( `name` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: taxes. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `taxes` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `category` varchar(255) NOT NULL, + `custcategory` varchar(255) default NULL, + `parentid` varchar(255) default NULL, + `rate` double NOT NULL default '0', + `ratecascade` bit(1) NOT NULL default b'0', + `rateorder` int(11) default NULL, + PRIMARY KEY ( `id` ), + KEY `taxes_cat_fk` ( `category` ), + KEY `taxes_custcat_fk` ( `custcategory` ), + UNIQUE INDEX `taxes_name_inx` ( `name` ), + KEY `taxes_taxes_fk` ( `parentid` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: taxlines. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `taxlines` ( + `id` varchar(255) NOT NULL, + `receipt` varchar(255) NOT NULL, + `taxid` varchar(255) NOT NULL, + `base` double NOT NULL default '0', + `amount` double NOT NULL default '0', + PRIMARY KEY ( `id` ), + KEY `taxlines_receipt` ( `receipt` ), + KEY `taxlines_tax` ( `taxid` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8; + +/* Header line. Object: taxsuppcategories. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `taxsuppcategories` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8; + +/* Header line. Object: thirdparties. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `thirdparties` ( + `id` varchar(255) NOT NULL, + `cif` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `address` varchar(255) default NULL, + `contactcomm` varchar(255) default NULL, + `contactfact` varchar(255) default NULL, + `payrule` varchar(255) default NULL, + `faxnumber` varchar(255) default NULL, + `phonenumber` varchar(255) default NULL, + `mobilenumber` varchar(255) default NULL, + `email` varchar(255) default NULL, + `webpage` varchar(255) default NULL, + `notes` varchar(255) default NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `thirdparties_cif_inx` ( `cif` ), + UNIQUE INDEX `thirdparties_name_inx` ( `name` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: ticketlines. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `ticketlines` ( + `ticket` varchar(255) NOT NULL, + `line` int(11) NOT NULL, + `product` varchar(255) default NULL, + `attributesetinstance_id` varchar(255) default NULL, + `units` double NOT NULL, + `price` double NOT NULL, + `taxid` varchar(255) NOT NULL, + `attributes` mediumblob default NULL, + PRIMARY KEY ( `ticket`, `line` ), + KEY `ticketlines_attsetinst` ( `attributesetinstance_id` ), + KEY `ticketlines_fk_2` ( `product` ), + KEY `ticketlines_fk_3` ( `taxid` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8; + +/* Header line. Object: tickets. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `tickets` ( + `id` varchar(255) NOT NULL, + `tickettype` int(11) NOT NULL default '0', + `ticketid` int(11) NOT NULL, + `person` varchar(255) NOT NULL, + `customer` varchar(255) default NULL, + `status` int(11) NOT NULL default '0', + PRIMARY KEY ( `id` ), + KEY `tickets_customers_fk` ( `customer` ), + KEY `tickets_fk_2` ( `person` ), + KEY `tickets_ticketid` ( `tickettype`, `ticketid` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8; + +/* Header line. Object: ticketsnum. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `ticketsnum` ( + `id` int(11) NOT NULL +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: ticketsnum_payment. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `ticketsnum_payment` ( + `id` int(11) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: ticketsnum_refund. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `ticketsnum_refund` ( + `id` int(11) NOT NULL +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: uom. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `uom` ( + `id` VARCHAR(255) NOT NULL, + `name` VARCHAR(255) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +/* Header line. Object: vouchers. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `vouchers` ( + `id` VARCHAR(100) NOT NULL, + `voucher_number` VARCHAR(100) DEFAULT NULL, + `customer` VARCHAR(100) DEFAULT NULL, + `amount` DOUBLE DEFAULT NULL, + `status` CHAR(1) DEFAULT 'A', + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ; + +-- Update foreign keys of attributeinstance +ALTER TABLE `attributeinstance` ADD CONSTRAINT `attinst_att` + FOREIGN KEY ( `attribute_id` ) REFERENCES `attribute` ( `id` ); + +ALTER TABLE `attributeinstance` ADD CONSTRAINT `attinst_set` + FOREIGN KEY ( `attributesetinstance_id` ) REFERENCES `attributesetinstance` ( `id` ) ON DELETE CASCADE; + +-- Update foreign keys of attributesetinstance +ALTER TABLE `attributesetinstance` ADD CONSTRAINT `attsetinst_set` + FOREIGN KEY ( `attributeset_id` ) REFERENCES `attributeset` ( `id` ) ON DELETE CASCADE; + +-- Update foreign keys of attributeuse +ALTER TABLE `attributeuse` ADD CONSTRAINT `attuse_att` + FOREIGN KEY ( `attribute_id` ) REFERENCES `attribute` ( `id` ); + +ALTER TABLE `attributeuse` ADD CONSTRAINT `attuse_set` + FOREIGN KEY ( `attributeset_id` ) REFERENCES `attributeset` ( `id` ) ON DELETE CASCADE; + +-- Update foreign keys of attributevalue +ALTER TABLE `attributevalue` ADD CONSTRAINT `attval_att` + FOREIGN KEY ( `attribute_id` ) REFERENCES `attribute` ( `id` ) ON DELETE CASCADE; + +-- Update foreign keys of categories +ALTER TABLE `categories` ADD CONSTRAINT `categories_fk_1` + FOREIGN KEY ( `parentid` ) REFERENCES `categories` ( `id` ); + +-- Update foreign keys of customers + ALTER TABLE `customers` ADD CONSTRAINT `customers_taxcat` + FOREIGN KEY ( `taxcategory` ) REFERENCES `taxcustcategories` ( `id` ); + +-- Update foreign keys of leaves +ALTER TABLE `leaves` ADD CONSTRAINT `leaves_pplid` + FOREIGN KEY ( `pplid` ) REFERENCES `people` ( `id` ); + +-- Update foreign keys of payments +ALTER TABLE `payments` ADD CONSTRAINT `payments_fk_receipt` + FOREIGN KEY ( `receipt` ) REFERENCES `receipts` ( `id` ); + +-- Update foreign keys of people +ALTER TABLE `people` ADD CONSTRAINT `people_fk_1` + FOREIGN KEY ( `role` ) REFERENCES `roles` ( `id` ); + +-- Update foreign keys of products +ALTER TABLE `products` ADD CONSTRAINT `products_attrset_fk` + FOREIGN KEY ( `attributeset_id` ) REFERENCES `attributeset` ( `id` ); + +ALTER TABLE `products` ADD CONSTRAINT `products_fk_1` + FOREIGN KEY ( `category` ) REFERENCES `categories` ( `id` ); + +ALTER TABLE `products` ADD CONSTRAINT `products_taxcat_fk` + FOREIGN KEY ( `taxcat` ) REFERENCES `taxcategories` ( `id` ); + +-- Update foreign keys of product_bundle +ALTER TABLE `products_bundle` ADD CONSTRAINT `products_bundle_fk_1` + FOREIGN KEY ( `product` ) REFERENCES `products`( `id` ); + +ALTER TABLE `products_bundle` ADD CONSTRAINT `products_bundle_fk_2` + FOREIGN KEY ( `product_bundle` ) REFERENCES `products`( `id` ); + +-- Update foreign keys of products_cat +ALTER TABLE `products_cat` ADD CONSTRAINT `products_cat_fk_1` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +-- Update foreign keys of products_com +ALTER TABLE `products_com` ADD CONSTRAINT `products_com_fk_1` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +ALTER TABLE `products_com` ADD CONSTRAINT `products_com_fk_2` + FOREIGN KEY ( `product2` ) REFERENCES `products` ( `id` ); + +-- Update foreign keys of receipts +ALTER TABLE `receipts` ADD CONSTRAINT `receipts_fk_money` + FOREIGN KEY ( `money` ) REFERENCES `closedcash` ( `money` ); + +-- Update foreign keys of reservation_customers +ALTER TABLE `reservation_customers` ADD CONSTRAINT `res_cust_fk_1` + FOREIGN KEY ( `id` ) REFERENCES `reservations` ( `id` ); + +ALTER TABLE `reservation_customers` ADD CONSTRAINT `res_cust_fk_2` + FOREIGN KEY ( `customer` ) REFERENCES `customers` ( `id` ); + +-- Update foreign keys of shift_breaks +ALTER TABLE `shift_breaks` ADD CONSTRAINT `shift_breaks_breakid` + FOREIGN KEY ( `breakid` ) REFERENCES `breaks` ( `id` ); + +ALTER TABLE `shift_breaks` ADD CONSTRAINT `shift_breaks_shiftid` + FOREIGN KEY ( `shiftid` ) REFERENCES `shifts` ( `id` ); + +-- Update foreign keys of stockcurrent +ALTER TABLE `stockcurrent` ADD CONSTRAINT `stockcurrent_attsetinst` + FOREIGN KEY ( `attributesetinstance_id` ) REFERENCES `attributesetinstance` ( `id` ); + +ALTER TABLE `stockcurrent` ADD CONSTRAINT `stockcurrent_fk_1` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +ALTER TABLE `stockcurrent` ADD CONSTRAINT `stockcurrent_fk_2` + FOREIGN KEY ( `location` ) REFERENCES `locations` ( `id` ); + +-- Update foreign keys of stockdiary +ALTER TABLE `stockdiary` ADD CONSTRAINT `stockdiary_attsetinst` + FOREIGN KEY ( `attributesetinstance_id` ) REFERENCES `attributesetinstance` ( `id` ); + +ALTER TABLE `stockdiary` ADD CONSTRAINT `stockdiary_fk_1` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +ALTER TABLE `stockdiary` ADD CONSTRAINT `stockdiary_fk_2` + FOREIGN KEY ( `location` ) REFERENCES `locations` ( `id` ); + +-- Update foreign keys of stocklevel +ALTER TABLE `stocklevel` ADD CONSTRAINT `stocklevel_location` + FOREIGN KEY ( `location` ) REFERENCES `locations` ( `id` ); + +ALTER TABLE `stocklevel` ADD CONSTRAINT `stocklevel_product` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +-- Update foreign keys of taxes +ALTER TABLE `taxes` ADD CONSTRAINT `taxes_cat_fk` + FOREIGN KEY ( `category` ) REFERENCES `taxcategories` ( `id` ); + +ALTER TABLE `taxes` ADD CONSTRAINT `taxes_custcat_fk` + FOREIGN KEY ( `custcategory` ) REFERENCES `taxcustcategories` ( `id` ); + +ALTER TABLE `taxes` ADD CONSTRAINT `taxes_taxes_fk` + FOREIGN KEY ( `parentid` ) REFERENCES `taxes` ( `id` ); + +-- Update foreign keys of taxlines +ALTER TABLE `taxlines` ADD CONSTRAINT `taxlines_receipt` + FOREIGN KEY ( `receipt` ) REFERENCES `receipts` ( `id` ); + +ALTER TABLE `taxlines` ADD CONSTRAINT `taxlines_tax` + FOREIGN KEY ( `taxid` ) REFERENCES `taxes` ( `id` ); + +-- Update foreign keys of ticketlines +ALTER TABLE `ticketlines` ADD CONSTRAINT `ticketlines_attsetinst` + FOREIGN KEY ( `attributesetinstance_id` ) REFERENCES `attributesetinstance` ( `id` ); + +ALTER TABLE `ticketlines` ADD CONSTRAINT `ticketlines_fk_2` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +ALTER TABLE `ticketlines` ADD CONSTRAINT `ticketlines_fk_3` + FOREIGN KEY ( `taxid` ) REFERENCES `taxes` ( `id` ); + +ALTER TABLE `ticketlines` ADD CONSTRAINT `ticketlines_fk_ticket` + FOREIGN KEY ( `ticket` ) REFERENCES `tickets` ( `id` ); + +-- Update foreign keys of tickets +ALTER TABLE `tickets` ADD CONSTRAINT `tickets_customers_fk` + FOREIGN KEY ( `customer` ) REFERENCES `customers` ( `id` ); + +ALTER TABLE `tickets` ADD CONSTRAINT `tickets_fk_2` + FOREIGN KEY ( `person` ) REFERENCES `people` ( `id` ); + +ALTER TABLE `tickets` ADD CONSTRAINT `tickets_fk_id` + FOREIGN KEY ( `id` ) REFERENCES `receipts` ( `id` ); + +-- ***************************************************************************** + +-- ADD roles +INSERT INTO roles(id, name, permissions) VALUES('0', 'Administrator role', $FILE{/com/unicenta/pos/templates/Role.Administrator.xml} ); +INSERT INTO roles(id, name, permissions) VALUES('1', 'Manager role', $FILE{/com/unicenta/pos/templates/Role.Manager.xml} ); +INSERT INTO roles(id, name, permissions) VALUES('2', 'Employee role', $FILE{/com/unicenta/pos/templates/Role.Employee.xml} ); +INSERT INTO roles(id, name, permissions) VALUES('3', 'Guest role', $FILE{/com/unicenta/pos/templates/Role.Guest.xml} ); + +-- ADD people +INSERT INTO people(id, name, apppassword, role, visible, image) VALUES ('0', 'Administrator', NULL, '0', TRUE, NULL); +INSERT INTO people(id, name, apppassword, role, visible, image) VALUES ('1', 'Manager', NULL, '1', TRUE, NULL); +INSERT INTO people(id, name, apppassword, role, visible, image) VALUES ('2', 'Employee', NULL, '2', TRUE, NULL); +INSERT INTO people(id, name, apppassword, role, visible, image) VALUES ('3', 'Guest', NULL, '3', TRUE, NULL); + +-- ADD resources -- +-- SYSTEM +INSERT INTO resources(id, name, restype, content) VALUES('00', 'Menu.Root', 0, $FILE{/com/unicenta/pos/templates/Menu.Root.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('02', 'Cash.Close', 0, $FILE{/com/unicenta/pos/templates/Cash.Close.xml}); +INSERT INTO resources(ID, name, restype, content) VALUES('03', 'Customer.Created', 0, $FILE{/com/unicenta/pos/templates/customer.created.xml}); +INSERT INTO resources(ID, name, restype, content) VALUES('04', 'Customer.Deleted', 0, $FILE{/com/unicenta/pos/templates/customer.deleted.xml}); +INSERT INTO resources(ID, name, restype, content) VALUES('05', 'Customer.Updated', 0, $FILE{/com/unicenta/pos/templates/customer.updated.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('06', 'payment.cash', 0, $FILE{/com/unicenta/pos/templates/payment.cash.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('07', 'Ticket.Buttons', 0, $FILE{/com/unicenta/pos/templates/Ticket.Buttons.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('08', 'Ticket.Close', 0, $FILE{/com/unicenta/pos/templates/Ticket.Close.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('09', 'Ticket.Line', 0, $FILE{/com/unicenta/pos/templates/Ticket.Line.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('10', 'Window.Title', 0, $FILE{/com/unicenta/pos/templates/Window.Title.txt}); + +-- IMAGES +INSERT INTO resources(id, name, restype, content) VALUES('11', 'img.001', 1, $FILE{/com/unicenta/images/.01.png}); +INSERT INTO resources(id, name, restype, content) VALUES('12', 'img.002', 1, $FILE{/com/unicenta/images/.02.png}); +INSERT INTO resources(id, name, restype, content) VALUES('13', 'img.005', 1, $FILE{/com/unicenta/images/.05.png}); +INSERT INTO resources(id, name, restype, content) VALUES('14', 'img.010', 1, $FILE{/com/unicenta/images/.10.png}); +INSERT INTO resources(id, name, restype, content) VALUES('15', 'img.020', 1, $FILE{/com/unicenta/images/.20.png}); +INSERT INTO resources(id, name, restype, content) VALUES('16', 'img.025', 1, $FILE{/com/unicenta/images/.25.png}); +INSERT INTO resources(id, name, restype, content) VALUES('17', 'img.050', 1, $FILE{/com/unicenta/images/.50.png}); +INSERT INTO resources(id, name, restype, content) VALUES('18', 'img.1', 1, $FILE{/com/unicenta/images/1.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('19', 'img.2', 1, $FILE{/com/unicenta/images/2.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('20', 'img.5', 1, $FILE{/com/unicenta/images/5.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('21', 'img.10', 1, $FILE{/com/unicenta/images/10.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('22', 'img.20', 1, $FILE{/com/unicenta/images/20.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('23', 'img.50', 1, $FILE{/com/unicenta/images/50.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('24', 'img.100', 1, $FILE{/com/unicenta/images/100.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('25', 'img.200', 1, $FILE{/com/unicenta/images/200.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('26', 'img.500', 1, $FILE{/com/unicenta/images/500.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('27', 'img.1000', 1, $FILE{/com/unicenta/images/1000.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('28', 'img.cash', 1, $FILE{/com/unicenta/images/cash.png}); +INSERT INTO resources(id, name, restype, content) VALUES('29', 'img.cashdrawer', 1, $FILE{/com/unicenta/images/cashdrawer.png}); +INSERT INTO resources(id, name, restype, content) VALUES('30', 'img.discount', 1, $FILE{/com/unicenta/images/discount.png}); +INSERT INTO resources(id, name, restype, content) VALUES('31', 'img.discount_b', 1, $FILE{/com/unicenta/images/discount_b.png}); +INSERT INTO resources(id, name, restype, content) VALUES('32', 'img.heart', 1, $FILE{/com/unicenta/images/heart.png}); +INSERT INTO resources(id, name, restype, content) VALUES('33', 'img.keyboard_48', 1, $FILE{/com/unicenta/images/keyboard_48.png}); +INSERT INTO resources(id, name, restype, content) VALUES('34', 'img.kit_print', 1, $FILE{/com/unicenta/images/kit_print.png}); +INSERT INTO resources(id, name, restype, content) VALUES('35', 'img.no_photo', 1, $FILE{/com/unicenta/images/no_photo.png}); +INSERT INTO resources(id, name, restype, content) VALUES('36', 'img.refundit', 1, $FILE{/com/unicenta/images/refundit.png}); +INSERT INTO resources(id, name, restype, content) VALUES('37', 'img.run_script', 1, $FILE{/com/unicenta/images/run_script.png}); +INSERT INTO resources(id, name, restype, content) VALUES('38', 'img.ticket_print', 1, $FILE{/com/unicenta/images/ticket_print.png}); +INSERT INTO resources(id, name, restype, content) VALUES('39', 'Printer.Ticket.Logo', 1, $FILE{/com/unicenta/images/printer.ticket.logo.jpg}); + +-- PRINTER +INSERT INTO resources(id, name, restype, content) VALUES('41', 'Printer.CloseCash.Preview', 0, $FILE{/com/unicenta/pos/templates/Printer.CloseCash.Preview.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('42', 'Printer.CloseCash', 0, $FILE{/com/unicenta/pos/templates/Printer.CloseCash.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('43', 'Printer.CustomerPaid', 0, $FILE{/com/unicenta/pos/templates/Printer.CustomerPaid.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('44', 'Printer.CustomerPaid2', 0, $FILE{/com/unicenta/pos/templates/Printer.CustomerPaid2.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('45', 'Printer.FiscalTicket', 0, $FILE{/com/unicenta/pos/templates/Printer.FiscalTicket.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('46', 'Printer.Inventory', 0, $FILE{/com/unicenta/pos/templates/Printer.Inventory.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('47', 'Printer.OpenDrawer', 0, $FILE{/com/unicenta/pos/templates/Printer.OpenDrawer.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('48', 'Printer.PartialCash', 0, $FILE{/com/unicenta/pos/templates/Printer.PartialCash.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('49', 'Printer.PrintLastTicket', 0, $FILE{/com/unicenta/pos/templates/Printer.PrintLastTicket.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('50', 'Printer.Product', 0, $FILE{/com/unicenta/pos/templates/Printer.Product.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('52', 'Printer.ReprintTicket', 0, $FILE{/com/unicenta/pos/templates/Printer.ReprintTicket.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('53', 'Printer.Start', 0, $FILE{/com/unicenta/pos/templates/Printer.Start.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('54', 'Printer.Ticket.P1', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P1.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('55', 'Printer.Ticket.P2', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P2.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('56', 'Printer.Ticket.P3', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P3.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('57', 'Printer.Ticket.P4', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P4.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('58', 'Printer.Ticket.P5', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P5.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('59', 'Printer.Ticket.P6', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P6.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('60', 'Printer.Ticket', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('61', 'Printer.Ticket2', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket2.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('62', 'Printer.TicketClose', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketClose.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('63', 'Printer.TicketLine', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketLine.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('64', 'Printer.TicketNew', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketLine.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('65', 'Printer.TicketPreview', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketPreview.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('66', 'Printer.Ticket_A4', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket_A4.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('67', 'Printer.TicketPreview_A4', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketPreview_A4.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('68', 'Printer.TicketRemote', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketRemote.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('69', 'Printer.TicketTotal', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketTotal.xml}); + +-- SCRIPTS +INSERT INTO resources(id, name, restype, content) VALUES('70', 'script.Keyboard', 0, $FILE{/com/unicenta/pos/templates/script.Keyboard.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('71', 'script.Linediscount', 0, $FILE{/com/unicenta/pos/templates/script.Linediscount.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('72', 'script.SendOrder', 0, $FILE{/com/unicenta/pos/templates/script.SendOrder.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('73', 'script.Totaldiscount', 0, $FILE{/com/unicenta/pos/templates/script.Totaldiscount.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('74', 'script.multibuy', 0, $FILE{/com/unicenta/pos/templates/script.multibuy.txt}); + +-- ADD CATEGORIES +INSERT INTO categories(id, name) VALUES ('000', 'Category Standard'); + +-- ADD TAXCATEGORIES +/* 002 added 31/01/2017 00:00:00. */ +INSERT INTO taxcategories(id, name) VALUES ('000', 'Tax Exempt'); +INSERT INTO taxcategories(id, name) VALUES ('001', 'Tax Standard'); +INSERT INTO taxcategories(id, name) VALUES ('002', 'Tax Other'); + +-- ADD TAXES +/* 002 added 31/01/2017 00:00:00. */ +INSERT INTO taxes(id, name, category, custcategory, parentid, rate, ratecascade, rateorder) VALUES ('000', 'Tax Exempt', '000', NULL, NULL, 0, FALSE, NULL); +INSERT INTO taxes(id, name, category, custcategory, parentid, rate, ratecascade, rateorder) VALUES ('001', 'Tax Standard', '001', NULL, NULL, 0.20, FALSE, NULL); +INSERT INTO taxes(id, name, category, custcategory, parentid, rate, ratecascade, rateorder) VALUES ('002', 'Tax Other', '002', NULL, NULL, 0, FALSE, NULL); + +-- ADD PRODUCTS +INSERT INTO products(id, reference, code, name, category, taxcat, isservice, display, printto) +VALUES ('xxx999_999xxx_x9x9x9', 'xxx999', 'xxx999', 'Free Line entry', '000', '001', 1, '<html><center>Free Line entry', '1'); +INSERT INTO products(id, reference, code, name, category, taxcat, isservice, display, printto) +VALUES ('xxx998_998xxx_x8x8x8', 'xxx998', 'xxx998', 'Service Charge', '000', '001', 1, '<html><center>Service Charge', '1'); + +-- ADD PRODUCTS_CAT +INSERT INTO products_cat(product) VALUES ('xxx999_999xxx_x9x9x9'); +INSERT INTO products_cat(product) VALUES ('xxx998_998xxx_x8x8x8'); + +-- ADD LOCATION +INSERT INTO locations(id, name, address) VALUES ('0','Location 1','Local'); + +-- ADD SUPPLIERS +INSERT INTO suppliers(id, searchkey, name) VALUES ('0','uniCenta','uniCenta'); + +-- ADD UOM +INSERT INTO uom(id, name) VALUES ('0','Each'); + +-- ADD FLOORS +INSERT INTO floors(id, name, image) VALUES ('0', 'Restaurant floor', $FILE{/com/unicenta/images/paperboard960_600.png}); + +-- ADD PLACES +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('1', 'Table 1', 100, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('2', 'Table 2', 250, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('3', 'Table 3', 400, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('4', 'Table 4', 550, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('5', 'Table 5', 700, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('6', 'Table 6', 850, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('7', 'Table 7', 100, 150, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('8', 'Table 8', 250, 150, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('9', 'Table 9', 400, 150, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('10', 'Table 10', 550, 150, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('11', 'Table 11', 700, 150, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('12', 'Table 12', 850, 150, '0', '1', 90, 45); + +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('13', 'Table 13', 100, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('14', 'Table 14', 250, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('15', 'Table 15', 400, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('16', 'Table 16', 550, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('17', 'Table 17', 700, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('18', 'Table 18', 850, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('19', 'Table 19', 100, 350, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('20', 'Table 20', 250, 350, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('21', 'Table 21', 400, 350, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('22', 'Table 22', 550, 350, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('23', 'Table 23', 700, 350, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('24', 'Table 24', 850, 350, '0', '1', 90, 45); + +-- ADD SHIFTS +INSERT INTO shifts(id, startshift, endshift, pplid) VALUES ('0', '2018-01-01 00:00:00.001', '2018-01-01 00:00:00.002','0'); + +-- ADD BREAKS +INSERT INTO breaks(id, name, visible, notes) VALUES ('0', 'Lunch Break', TRUE, NULL); +INSERT INTO breaks(id, name, visible, notes) VALUES ('1', 'Tea Break', TRUE, NULL); +INSERT INTO breaks(id, name, visible, notes) VALUES ('2', 'Mid Break', TRUE, NULL); + +-- ADD SHIFT_BREAKS +INSERT INTO shift_breaks(id, shiftid, breakid, starttime, endtime) VALUES ('0', '0', '0', '2018-01-01 00:00:00.003', '2018-01-01 00:00:00.004'); + +-- ADD SEQUENCES +INSERT INTO pickup_number VALUES(1); +INSERT INTO ticketsnum VALUES(1); +INSERT INTO ticketsnum_refund VALUES(1); +INSERT INTO ticketsnum_payment VALUES(1); + +-- ADD APPLICATION VERSION +INSERT INTO applications(id, name, version) VALUES($APP_ID{}, $APP_NAME{}, $APP_VERSION{}); \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/scripts/MariaDB-upgrade_master.sql b/src/main/resources/com/unicenta/pos/scripts/MariaDB-upgrade_master.sql new file mode 100644 index 0000000..c6ee72d --- /dev/null +++ b/src/main/resources/com/unicenta/pos/scripts/MariaDB-upgrade_master.sql @@ -0,0 +1,61 @@ +-- CLEAR THE DECKS +DELETE FROM sharedtickets; + +-- Switch OFF table foreign key relationships +set foreign_key_checks = 0; + +-- RECREATE applications table +DROP TABLE `applications`; +CREATE TABLE IF NOT EXISTS `applications` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `version` varchar(255) NOT NULL, + `instdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + + +-- SYSTEM +DELETE FROM resources WHERE name = 'script.posapps'; + + +DELETE FROM resources WHERE id = '0'; +DELETE FROM resources WHERE id = '00'; +INSERT INTO resources(id, name, restype, content) VALUES('00', 'Menu.Root', 0, $FILE{/com/unicenta/pos/templates/Menu.Root.txt}); + +UPDATE resources SET content = $FILE{/com/unicenta/pos/templates/Ticket.Buttons.xml} WHERE name = 'Ticket.Buttons'; +COMMIT; + +UPDATE resources SET content = $FILE{/com/unicenta/pos/templates/Printer.Ticket.xml} WHERE name = 'Printer.Ticket'; +COMMIT; + +UPDATE resources SET content = $FILE{/com/unicenta/pos/templates/Ticket.Close.xml} WHERE name = 'Ticket.Close'; +COMMIT; + +UPDATE resources SET content = $FILE{/com/unicenta/pos/templates/Cash.Close.xml} WHERE name = 'Cash.Close'; +COMMIT; + +UPDATE resources SET content = $FILE{/com/unicenta/pos/templates/customer.created.xml} WHERE name = 'Customer.Created'; +COMMIT; + +UPDATE resources SET content = $FILE{/com/unicenta/pos/templates/customer.deleted.xml} WHERE name = 'Customer.Deleted'; +COMMIT; + +UPDATE resources SET content = $FILE{/com/unicenta/pos/templates/customer.updated.xml} WHERE name = 'Customer.Updated'; +COMMIT; + +-- ROLES +DELETE FROM roles WHERE id = '0'; +INSERT INTO roles(id, name, permissions) VALUES('0', 'Administrator role', $FILE{/com/unicenta/pos/templates/Role.Administrator.xml} ); +DELETE FROM roles WHERE id = '1'; +INSERT INTO roles(id, name, permissions) VALUES('1', 'Manager role', $FILE{/com/unicenta/pos/templates/Role.Manager.xml} ); +DELETE FROM roles WHERE id = '2'; +INSERT INTO roles(id, name, permissions) VALUES('2', 'Employee role', $FILE{/com/unicenta/pos/templates/Role.Employee.xml} ); + + +-- Switch ON table foreign key relationships +set foreign_key_checks = 1; + +INSERT INTO applications(id, name, version) VALUES($APP_ID{}, $APP_NAME{}, $APP_VERSION{}); + +COMMIT; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/scripts/MySQL-FKeys.sql b/src/main/resources/com/unicenta/pos/scripts/MySQL-FKeys.sql new file mode 100644 index 0000000..40ac764 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/scripts/MySQL-FKeys.sql @@ -0,0 +1,191 @@ +-- uniCenta oPOS - Touch Friendly Point Of Sale +-- Copyright (c) 2009-2017 uniCenta +-- https://unicenta.com +-- +-- This file is part of uniCenta oPOS. +-- +-- uniCenta oPOS is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- uniCenta oPOS is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +/* + * Script created by Jack, uniCenta 07/08/2016 08:00:00 + * Modified 10 Sept 2017 + * Called by Transfer for v4.4 after data complete +*/ + +-- ---------------------------- +-- FOREIGN KEYS AND CONSTRAINTS +-- ---------------------------- +set foreign_key_checks = 1; +set foreign_key_checks = 0; + +-- Update foreign keys of attributeinstance +ALTER TABLE `attributeinstance` ADD CONSTRAINT `attinst_att` + FOREIGN KEY ( `attribute_id` ) REFERENCES `attribute` ( `id` ); + +ALTER TABLE `attributeinstance` ADD CONSTRAINT `attinst_set` + FOREIGN KEY ( `attributesetinstance_id` ) REFERENCES `attributesetinstance` ( `id` ) ON DELETE CASCADE; + +-- Update foreign keys of attributesetinstance +ALTER TABLE `attributesetinstance` ADD CONSTRAINT `attsetinst_set` + FOREIGN KEY ( `attributeset_id` ) REFERENCES `attributeset` ( `id` ) ON DELETE CASCADE; + +-- Update foreign keys of attributeuse +ALTER TABLE `attributeuse` ADD CONSTRAINT `attuse_att` + FOREIGN KEY ( `attribute_id` ) REFERENCES `attribute` ( `id` ); + +ALTER TABLE `attributeuse` ADD CONSTRAINT `attuse_set` + FOREIGN KEY ( `attributeset_id` ) REFERENCES `attributeset` ( `id` ) ON DELETE CASCADE; + +-- Update foreign keys of attributevalue +ALTER TABLE `attributevalue` ADD CONSTRAINT `attval_att` + FOREIGN KEY ( `attribute_id` ) REFERENCES `attribute` ( `id` ) ON DELETE CASCADE; + +-- Update foreign keys of categories +ALTER TABLE `categories` ADD CONSTRAINT `categories_fk_1` + FOREIGN KEY ( `parentid` ) REFERENCES `categories` ( `id` ); + +-- Update foreign keys of customers +ALTER TABLE `customers` ADD CONSTRAINT `customers_taxcat` + FOREIGN KEY ( `taxcategory` ) REFERENCES `taxcustcategories` ( `id` ); + +-- Update foreign keys of leaves +ALTER TABLE `leaves` ADD CONSTRAINT `leaves_pplid` + FOREIGN KEY ( `pplid` ) REFERENCES `people` ( `id` ); + +-- Update foreign keys of payments +ALTER TABLE `payments` ADD CONSTRAINT `payments_fk_receipt` + FOREIGN KEY ( `receipt` ) REFERENCES `receipts` ( `id` ); + +-- Update foreign keys of people +ALTER TABLE `people` ADD CONSTRAINT `people_fk_1` + FOREIGN KEY ( `role` ) REFERENCES `roles` ( `id` ); + +-- Update Indeces of products +ALTER TABLE `products` ADD UNIQUE INDEX `products_inx_0` ( `reference` ); +ALTER TABLE `products` ADD UNIQUE INDEX `products_inx_1` ( `code` ); +ALTER TABLE `products` ADD INDEX `products_name_inx` ( `name` ); +-- Update foreign keys of products +ALTER TABLE `products` ADD CONSTRAINT `products_attrset_fk` + FOREIGN KEY ( `attributeset_id` ) REFERENCES `attributeset` ( `id` ); +ALTER TABLE `products` ADD CONSTRAINT `products_fk_1` + FOREIGN KEY ( `category` ) REFERENCES `categories` ( `id` ); +ALTER TABLE `products` ADD CONSTRAINT `products_taxcat_fk` + FOREIGN KEY ( `taxcat` ) REFERENCES `taxcategories` ( `id` ); + +-- Update foreign keys of product_bundle +ALTER TABLE `products_bundle` ADD CONSTRAINT `products_bundle_fk_1` + FOREIGN KEY ( `product` ) REFERENCES `products`( `id` ); + +ALTER TABLE `products_bundle` ADD CONSTRAINT `products_bundle_fk_2` + FOREIGN KEY ( `product_bundle` ) REFERENCES `products`( `id` ); + +-- Update foreign keys of products_cat +ALTER TABLE `products_cat` ADD CONSTRAINT `products_cat_fk_1` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +-- Update foreign keys of products_com +ALTER TABLE `products_com` ADD CONSTRAINT `products_com_fk_1` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +ALTER TABLE `products_com` ADD CONSTRAINT `products_com_fk_2` + FOREIGN KEY ( `product2` ) REFERENCES `products` ( `id` ); + +-- Update foreign keys of receipts +ALTER TABLE `receipts` ADD CONSTRAINT `receipts_fk_money` + FOREIGN KEY ( `money` ) REFERENCES `closedcash` ( `money` ); + +-- Update foreign keys of reservation_customers +ALTER TABLE `reservation_customers` ADD CONSTRAINT `res_cust_fk_1` + FOREIGN KEY ( `id` ) REFERENCES `reservations` ( `id` ); + +ALTER TABLE `reservation_customers` ADD CONSTRAINT `res_cust_fk_2` + FOREIGN KEY ( `customer` ) REFERENCES `customers` ( `id` ); + +-- Update foreign keys of shift_breaks +ALTER TABLE `shift_breaks` ADD CONSTRAINT `shift_breaks_breakid` + FOREIGN KEY ( `breakid` ) REFERENCES `breaks` ( `id` ); + +ALTER TABLE `shift_breaks` ADD CONSTRAINT `shift_breaks_shiftid` + FOREIGN KEY ( `shiftid` ) REFERENCES `shifts` ( `id` ); + +-- Update foreign keys of stockcurrent +ALTER TABLE `stockcurrent` ADD CONSTRAINT `stockcurrent_attsetinst` + FOREIGN KEY ( `attributesetinstance_id` ) REFERENCES `attributesetinstance` ( `id` ); + +ALTER TABLE `stockcurrent` ADD CONSTRAINT `stockcurrent_fk_1` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +ALTER TABLE `stockcurrent` ADD CONSTRAINT `stockcurrent_fk_2` + FOREIGN KEY ( `location` ) REFERENCES `locations` ( `id` ); + +-- Update foreign keys of stockdiary +ALTER TABLE `stockdiary` ADD CONSTRAINT `stockdiary_attsetinst` + FOREIGN KEY ( `attributesetinstance_id` ) REFERENCES `attributesetinstance` ( `id` ); + +ALTER TABLE `stockdiary` ADD CONSTRAINT `stockdiary_fk_1` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +ALTER TABLE `stockdiary` ADD CONSTRAINT `stockdiary_fk_2` + FOREIGN KEY ( `location` ) REFERENCES `locations` ( `id` ); + +-- Update foreign keys of stocklevel +ALTER TABLE `stocklevel` ADD CONSTRAINT `stocklevel_location` + FOREIGN KEY ( `location` ) REFERENCES `locations` ( `id` ); + +ALTER TABLE `stocklevel` ADD CONSTRAINT `stocklevel_product` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +-- Update foreign keys of taxes +ALTER TABLE `taxes` ADD CONSTRAINT `taxes_cat_fk` + FOREIGN KEY ( `category` ) REFERENCES `taxcategories` ( `id` ); + +ALTER TABLE `taxes` ADD CONSTRAINT `taxes_custcat_fk` + FOREIGN KEY ( `custcategory` ) REFERENCES `taxcustcategories` ( `id` ); + +ALTER TABLE `taxes` ADD CONSTRAINT `taxes_taxes_fk` + FOREIGN KEY ( `parentid` ) REFERENCES `taxes` ( `id` ); + +-- Update foreign keys of taxlines +ALTER TABLE `taxlines` ADD CONSTRAINT `taxlines_receipt` + FOREIGN KEY ( `receipt` ) REFERENCES `receipts` ( `id` ); + +ALTER TABLE `taxlines` ADD CONSTRAINT `taxlines_tax` + FOREIGN KEY ( `taxid` ) REFERENCES `taxes` ( `id` ); + +-- Update foreign keys of ticketlines +ALTER TABLE `ticketlines` ADD CONSTRAINT `ticketlines_attsetinst` + FOREIGN KEY ( `attributesetinstance_id` ) REFERENCES `attributesetinstance` ( `id` ); + +ALTER TABLE `ticketlines` ADD CONSTRAINT `ticketlines_fk_2` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +ALTER TABLE `ticketlines` ADD CONSTRAINT `ticketlines_fk_3` + FOREIGN KEY ( `taxid` ) REFERENCES `taxes` ( `id` ); + +ALTER TABLE `ticketlines` ADD CONSTRAINT `ticketlines_fk_ticket` + FOREIGN KEY ( `ticket` ) REFERENCES `tickets` ( `id` ); + +-- Update foreign keys of tickets +ALTER TABLE `tickets` ADD CONSTRAINT `tickets_customers_fk` + FOREIGN KEY ( `customer` ) REFERENCES `customers` ( `id` ); + +ALTER TABLE `tickets` ADD CONSTRAINT `tickets_fk_2` + FOREIGN KEY ( `person` ) REFERENCES `people` ( `id` ); + +ALTER TABLE `tickets` ADD CONSTRAINT `tickets_fk_id` + FOREIGN KEY ( `id` ) REFERENCES `receipts` ( `id` ); + +set foreign_key_checks = 1; + +-- ***************************************************************************** diff --git a/src/main/resources/com/unicenta/pos/scripts/MySQL-check-tables.sql b/src/main/resources/com/unicenta/pos/scripts/MySQL-check-tables.sql new file mode 100644 index 0000000..cc3c10a --- /dev/null +++ b/src/main/resources/com/unicenta/pos/scripts/MySQL-check-tables.sql @@ -0,0 +1,818 @@ +-- uniCenta oPOS is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- uniCenta oPOS is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +/* + * Script created by Jack, uniCenta 23/07/2016 08:00:00 + * + * Check DB tables. +*/ + +/* Header line. Object: applications. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE `applications` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `version` varchar(255) NOT NULL, + `instdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: attribute. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `attribute` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: attributeinstance. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `attributeinstance` ( + `id` varchar(255) NOT NULL, + `attributesetinstance_id` varchar(255) NOT NULL, + `attribute_id` varchar(255) NOT NULL, + `value` varchar(255) default NULL, + KEY `attinst_att` ( `attribute_id` ), + KEY `attinst_set` ( `attributesetinstance_id` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: attributeset. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `attributeset` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: attributesetinstance. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `attributesetinstance` ( + `id` varchar(255) NOT NULL, + `attributeset_id` varchar(255) NOT NULL, + `description` varchar(255) default NULL, + KEY `attsetinst_set` ( `attributeset_id` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: attributeuse. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `attributeuse` ( + `id` varchar(255) NOT NULL, + `attributeset_id` varchar(255) NOT NULL, + `attribute_id` varchar(255) NOT NULL, + `lineno` int(11) default NULL, + KEY `attuse_att` ( `attribute_id` ), + UNIQUE INDEX `attuse_line` ( `attributeset_id`, `lineno` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: attributevalue. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `attributevalue` ( + `id` varchar(255) NOT NULL, + `attribute_id` varchar(255) NOT NULL, + `value` varchar(255) default NULL, + KEY `attval_att` ( `attribute_id` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: breaks. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `breaks` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `visible` tinyint(1) NOT NULL default '1', + `notes` varchar(255) default NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: categories. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `categories` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `parentid` varchar(255) default NULL, + `image` mediumblob default NULL, + `texttip` varchar(255) default NULL, + `catshowname` smallint(6) NOT NULL default '1', + `catorder` varchar(255) default NULL, + KEY `categories_fk_1` ( `parentid` ), + UNIQUE INDEX `categories_name_inx` ( `name` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: closedcash. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `closedcash` ( + `money` varchar(255) NOT NULL, + `host` varchar(255) NOT NULL, + `hostsequence` int(11) NOT NULL, + `datestart` datetime NOT NULL, + `dateend` datetime default NULL, + `nosales` int(11) NOT NULL default '0', + KEY `closedcash_inx_1` ( `datestart` ), + UNIQUE INDEX `closedcash_inx_seq` ( `host`, `hostsequence` ), + PRIMARY KEY ( `money` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: csvimport. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `csvimport` ( + `id` varchar(255) NOT NULL, + `rownumber` varchar(255) default NULL, + `csverror` varchar(255) default NULL, + `reference` varchar(255) default NULL, + `code` varchar(255) default NULL, + `name` varchar(255) default NULL, + `pricebuy` double default NULL, + `pricesell` double default NULL, + `previousbuy` double default NULL, + `previoussell` double default NULL, + `category` varchar(255) default NULL, + `tax` varchar(255) default NULL, + `searchkey` varchar(255) default NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: customers. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `customers` ( + `id` varchar(255) NOT NULL, + `searchkey` varchar(255) NOT NULL, + `taxid` varchar(255) default NULL, + `name` varchar(255) NOT NULL, + `taxcategory` varchar(255) default NULL, + `card` varchar(255) default NULL, + `maxdebt` double NOT NULL default '0', + `address` varchar(255) default NULL, + `address2` varchar(255) default NULL, + `postal` varchar(255) default NULL, + `city` varchar(255) default NULL, + `region` varchar(255) default NULL, + `country` varchar(255) default NULL, + `firstname` varchar(255) default NULL, + `lastname` varchar(255) default NULL, + `email` varchar(255) default NULL, + `phone` varchar(255) default NULL, + `phone2` varchar(255) default NULL, + `fax` varchar(255) default NULL, + `notes` varchar(255) default NULL, + `visible` bit(1) NOT NULL default b'1', + `curdate` datetime default NULL, + `curdebt` double default '0', + `image` mediumblob default NULL, + `isvip` bit(1) NOT NULL default b'0', + `discount` double default '0', + `memodate` datetime default '1900-01-01 00:00:01', + KEY `customers_card_inx` ( `card` ), + KEY `customers_name_inx` ( `name` ), + UNIQUE INDEX `customers_skey_inx` ( `searchkey` ), + KEY `customers_taxcat` ( `taxcategory` ), + KEY `customers_taxid_inx` ( `taxid` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: draweropened. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `draweropened` ( + `opendate` timestamp NOT NULL, + `name` varchar(255) default NULL, + `ticketid` varchar(255) default NULL +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: floors. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `floors` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `image` mediumblob default NULL, + UNIQUE INDEX `floors_name_inx` ( `name` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: leaves. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `leaves` ( + `id` varchar(255) NOT NULL, + `pplid` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `startdate` datetime NOT NULL, + `enddate` datetime NOT NULL, + `notes` varchar(255) default NULL, + KEY `leaves_pplid` ( `pplid` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: lineremoved. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `lineremoved` ( + `removeddate` timestamp NOT NULL, + `name` varchar(255) default NULL, + `ticketid` varchar(255) default NULL, + `productid` varchar(255) default NULL, + `productname` varchar(255) default NULL, + `units` double NOT NULL +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: locations. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `locations` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `address` varchar(255) default NULL, + UNIQUE INDEX `locations_name_inx` ( `name` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: moorers. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `moorers` ( + `vesselname` varchar(255) default NULL, + `size` int(11) default NULL, + `days` int(11) default NULL, + `power` bit(1) NOT NULL default b'0' +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: orders. Script date: 01/01/2017 00:00:01. */ +CREATE TABLE IF NOT EXISTS `orders` ( + `id` int(11) NOT NULL, + `orderid` varchar(50) DEFAULT NULL, + `qty` int(11) DEFAULT '1', + `details` varchar(255) DEFAULT NULL, + `attributes` varchar(255) DEFAULT NULL, + `notes` varchar(255) DEFAULT NULL, + `ticketid` varchar(50) DEFAULT NULL, + `ordertime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `displayid` int(11) DEFAULT '1', + `auxiliary` int(11) DEFAULT NULL, + `completetime` timestamp, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: payments. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `payments` ( + `id` varchar(255) NOT NULL, + `receipt` varchar(255) NOT NULL, + `payment` varchar(255) NOT NULL, + `total` double NOT NULL default '0', + `tip` double default '0', + `transid` varchar(255) default NULL, + `isprocessed` bit(1) default b'0', + `returnmsg` mediumblob default NULL, + `notes` varchar(255) default NULL, + `tendered` double default NULL, + `cardname` varchar(255) default NULL, + `voucher` varchar(255) default NULL, + KEY `payments_fk_receipt` ( `receipt` ), + KEY `payments_inx_1` ( `payment` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: people. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `people` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `apppassword` varchar(255) default NULL, + `card` varchar(255) default NULL, + `role` varchar(255) NOT NULL, + `visible` bit(1) NOT NULL, + `image` mediumblob default NULL, + KEY `people_card_inx` ( `card` ), + KEY `people_fk_1` ( `role` ), + UNIQUE INDEX `people_name_inx` ( `name` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: pickup_number. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `pickup_number` ( + `id` int(11) NOT NULL default '0' +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: places. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `places` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `x` int(11) NOT NULL, + `y` int(11) NOT NULL, + `floor` varchar(255) NOT NULL, + `customer` varchar(255) default NULL, + `waiter` varchar(255) default NULL, + `ticketid` varchar(255) default NULL, + `tablemoved` smallint(6) NOT NULL default '0', + UNIQUE INDEX `places_name_inx` ( `name` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: products. Script date: 02/04/2016 10:53:00. */ +CREATE TABLE IF NOT EXISTS `products` ( + `id` varchar(255) NOT NULL, + `reference` varchar(255) NOT NULL, + `code` varchar(255) NOT NULL, + `codetype` varchar(255) default NULL, + `name` varchar(255) NOT NULL, + `pricebuy` double NOT NULL default '0', + `pricesell` double NOT NULL default '0', + `category` varchar(255) NOT NULL, + `taxcat` varchar(255) NOT NULL, + `attributeset_id` varchar(255) default NULL, + `stockcost` double NOT NULL default '0', + `stockvolume` double NOT NULL default '0', + `image` mediumblob default NULL, + `iscom` bit(1) NOT NULL default b'0', + `isscale` bit(1) NOT NULL default b'0', + `isconstant` bit(1) NOT NULL default b'0', + `printkb` bit(1) NOT NULL default b'0', + `sendstatus` bit(1) NOT NULL default b'0', + `isservice` bit(1) NOT NULL default b'0', + `attributes` mediumblob default NULL, + `display` varchar(255) default NULL, + `isvprice` smallint(6) NOT NULL default '0', + `isverpatrib` smallint(6) NOT NULL default '0', + `texttip` varchar(255) default NULL, + `warranty` smallint(6) NOT NULL default '0', + `stockunits` double NOT NULL default '0', + `printto` varchar(255) default '1', + `supplier` varchar(255) default NULL, + `uom` varchar(255) default '0', + `memodate` datetime default '1900-01-01 00:00:01', + + PRIMARY KEY ( `id` ), + KEY `products_attrset_fx` ( `attributeset_id` ), + KEY `products_fk_1` ( `category` ), + UNIQUE INDEX `products_inx_0` ( `reference` ), + UNIQUE INDEX `products_inx_1` ( `code` ), + INDEX `products_name_inx` ( `name` ), + KEY `products_taxcat_fk` ( `taxcat` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: products_cat. Script date: 11/05/2016 05:25:00. */ +CREATE TABLE IF NOT EXISTS `products_bundle` ( + `id` varchar(255) NOT NULL, + `product` VARCHAR(255) NOT NULL, + `product_bundle` VARCHAR(255) NOT NULL, + `quantity` DOUBLE NOT NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `pbundle_inx_prod` ( `product` , `product_bundle` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: products_cat. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `products_cat` ( + `product` varchar(255) NOT NULL, + `catorder` int(11) default NULL, + PRIMARY KEY ( `product` ), + KEY `products_cat_inx_1` ( `catorder` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: products_com. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `products_com` ( + `id` varchar(255) NOT NULL, + `product` varchar(255) NOT NULL, + `product2` varchar(255) NOT NULL, + UNIQUE INDEX `pcom_inx_prod` ( `product`, `product2` ), + PRIMARY KEY ( `id` ), + KEY `products_com_fk_2` ( `product2` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: receipts. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `receipts` ( + `id` varchar(255) NOT NULL, + `money` varchar(255) NOT NULL, + `datenew` datetime NOT NULL, + `attributes` mediumblob default NULL, + `person` varchar(255) default NULL, + PRIMARY KEY ( `id` ), + KEY `receipts_fk_money` ( `money` ), + KEY `receipts_inx_1` ( `datenew` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: reservation_customers. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `reservation_customers` ( + `id` varchar(255) NOT NULL, + `customer` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ), + KEY `res_cust_fk_2` ( `customer` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: reservations. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `reservations` ( + `id` varchar(255) NOT NULL, + `created` datetime NOT NULL, + `datenew` datetime NOT NULL default '2016-01-01 00:00:00', + `title` varchar(255) NOT NULL, + `chairs` int(11) NOT NULL, + `isdone` bit(1) NOT NULL, + `description` varchar(255) default NULL, + PRIMARY KEY ( `id` ), + KEY `reservations_inx_1` ( `datenew` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: resources. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `resources` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `restype` int(11) NOT NULL, + `content` mediumblob default NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `resources_name_inx` ( `name` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: roles. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `roles` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `permissions` mediumblob default NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `roles_name_inx` ( `name` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: sharedtickets. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `sharedtickets` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `content` mediumblob default NULL, + `appuser` varchar(255) default NULL, + `pickupid` int(11) NOT NULL default '0', + `locked` varchar(20) default NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: shift_breaks. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `shift_breaks` ( + `id` varchar(255) NOT NULL, + `shiftid` varchar(255) NOT NULL, + `breakid` varchar(255) NOT NULL, + `starttime` timestamp NOT NULL, + `endtime` timestamp NOT NULL, + PRIMARY KEY ( `id` ), + KEY `shift_breaks_breakid` ( `breakid` ), + KEY `shift_breaks_shiftid` ( `shiftid` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: shifts. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `shifts` ( + `id` varchar(255) NOT NULL, + `startshift` datetime NOT NULL, + `endshift` datetime default NULL, + `pplid` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: stockcurrent. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `stockcurrent` ( + `location` varchar(255) NOT NULL, + `product` varchar(255) NOT NULL, + `attributesetinstance_id` varchar(255) default NULL, + `units` double NOT NULL, + KEY `stockcurrent_attsetinst` ( `attributesetinstance_id` ), + KEY `stockcurrent_fk_1` ( `product` ), + UNIQUE INDEX `stockcurrent_inx` ( `location`, `product`, `attributesetinstance_id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: stockdiary. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `stockdiary` ( + `id` varchar(255) NOT NULL, + `datenew` datetime NOT NULL, + `reason` int(11) NOT NULL, + `location` varchar(255) NOT NULL, + `product` varchar(255) NOT NULL, + `attributesetinstance_id` varchar(255) default NULL, + `units` double NOT NULL, + `price` double NOT NULL, + `appuser` varchar(255) default NULL, + `supplier` varchar(255) default NULL, + `supplierdoc` varchar(255) default NULL, + PRIMARY KEY ( `id` ), + KEY `stockdiary_attsetinst` ( `attributesetinstance_id` ), + KEY `stockdiary_fk_1` ( `product` ), + KEY `stockdiary_fk_2` ( `location` ), + KEY `stockdiary_inx_1` ( `datenew` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: stocklevel. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `stocklevel` ( + `id` varchar(255) NOT NULL, + `location` varchar(255) NOT NULL, + `product` varchar(255) NOT NULL, + `stocksecurity` double default NULL, + `stockmaximum` double default NULL, + PRIMARY KEY ( `id` ), + KEY `stocklevel_location` ( `location` ), + KEY `stocklevel_product` ( `product` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: suppliers. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `suppliers` ( + `id` varchar(255) NOT NULL, + `searchkey` varchar(255) NOT NULL, + `taxid` varchar(255) default NULL, + `name` varchar(255) NOT NULL, + `maxdebt` double NOT NULL default '0', + `address` varchar(255) default NULL, + `address2` varchar(255) default NULL, + `postal` varchar(255) default NULL, + `city` varchar(255) default NULL, + `region` varchar(255) default NULL, + `country` varchar(255) default NULL, + `firstname` varchar(255) default NULL, + `lastname` varchar(255) default NULL, + `email` varchar(255) default NULL, + `phone` varchar(255) default NULL, + `phone2` varchar(255) default NULL, + `fax` varchar(255) default NULL, + `notes` varchar(255) default NULL, + `visible` bit(1) NOT NULL default b'1', + `curdate` datetime default NULL, + `curdebt` double default '0', + `vatid` varchar(255) default NULL, + PRIMARY KEY ( `id` ), + KEY `suppliers_name_inx` ( `name` ), + UNIQUE INDEX `suppliers_skey_inx` ( `searchkey` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: taxcategories. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `taxcategories` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `taxcat_name_inx` ( `name` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: taxcustcategories. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `taxcustcategories` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `taxcustcat_name_inx` ( `name` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: taxes. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `taxes` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `category` varchar(255) NOT NULL, + `custcategory` varchar(255) default NULL, + `parentid` varchar(255) default NULL, + `rate` double NOT NULL default '0', + `ratecascade` bit(1) NOT NULL default b'0', + `rateorder` int(11) default NULL, + PRIMARY KEY ( `id` ), + KEY `taxes_cat_fk` ( `category` ), + KEY `taxes_custcat_fk` ( `custcategory` ), + UNIQUE INDEX `taxes_name_inx` ( `name` ), + KEY `taxes_taxes_fk` ( `parentid` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: taxlines. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `taxlines` ( + `id` varchar(255) NOT NULL, + `receipt` varchar(255) NOT NULL, + `taxid` varchar(255) NOT NULL, + `base` double NOT NULL default '0', + `amount` double NOT NULL default '0', + PRIMARY KEY ( `id` ), + KEY `taxlines_receipt` ( `receipt` ), + KEY `taxlines_tax` ( `taxid` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: taxsuppcategories. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `taxsuppcategories` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: thirdparties. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `thirdparties` ( + `id` varchar(255) NOT NULL, + `cif` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `address` varchar(255) default NULL, + `contactcomm` varchar(255) default NULL, + `contactfact` varchar(255) default NULL, + `payrule` varchar(255) default NULL, + `faxnumber` varchar(255) default NULL, + `phonenumber` varchar(255) default NULL, + `mobilenumber` varchar(255) default NULL, + `email` varchar(255) default NULL, + `webpage` varchar(255) default NULL, + `notes` varchar(255) default NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `thirdparties_cif_inx` ( `cif` ), + UNIQUE INDEX `thirdparties_name_inx` ( `name` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: ticketlines. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `ticketlines` ( + `ticket` varchar(255) NOT NULL, + `line` int(11) NOT NULL, + `product` varchar(255) default NULL, + `attributesetinstance_id` varchar(255) default NULL, + `units` double NOT NULL, + `price` double NOT NULL, + `taxid` varchar(255) NOT NULL, + `attributes` mediumblob default NULL, + PRIMARY KEY ( `ticket`, `line` ), + KEY `ticketlines_attsetinst` ( `attributesetinstance_id` ), + KEY `ticketlines_fk_2` ( `product` ), + KEY `ticketlines_fk_3` ( `taxid` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: tickets. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `tickets` ( + `id` varchar(255) NOT NULL, + `tickettype` int(11) NOT NULL default '0', + `ticketid` int(11) NOT NULL, + `person` varchar(255) NOT NULL, + `customer` varchar(255) default NULL, + `status` int(11) NOT NULL default '0', + PRIMARY KEY ( `id` ), + KEY `tickets_customers_fk` ( `customer` ), + KEY `tickets_fk_2` ( `person` ), + KEY `tickets_ticketid` ( `tickettype`, `ticketid` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: ticketsnum. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `ticketsnum` ( + `id` int(11) NOT NULL +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: ticketsnum_payment. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `ticketsnum_payment` ( + `id` int(11) NOT NULL auto_increment, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: ticketsnum_refund. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `ticketsnum_refund` ( + `id` int(11) NOT NULL +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: uom. Script date: 30/09/2015 13:07:00. */ +CREATE TABLE IF NOT EXISTS `uom` ( + `id` VARCHAR(255) NOT NULL, + `name` VARCHAR(255) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: vouchers. Script date: 30/09/2015 09:33:33. */ +CREATE TABLE IF NOT EXISTS `vouchers` ( + `id` VARCHAR(100) NOT NULL, + `voucher_number` VARCHAR(100) DEFAULT NULL, + `customer` VARCHAR(100) DEFAULT NULL, + `amount` DOUBLE DEFAULT NULL, + `status` CHAR(1) DEFAULT 'A', + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +-- ---------------------------- +-- FOREIGN KEYS AND CONSTRAINTS +-- ---------------------------- +-- Update foreign keys of attributeinstance +ALTER TABLE `attributeinstance` ADD CONSTRAINT `attinst_att` + FOREIGN KEY ( `attribute_id` ) REFERENCES `attribute` ( `id` ); + +ALTER TABLE `attributeinstance` ADD CONSTRAINT `attinst_set` + FOREIGN KEY ( `attributesetinstance_id` ) REFERENCES `attributesetinstance` ( `id` ) ON DELETE CASCADE; + +-- Update foreign keys of attributesetinstance +ALTER TABLE `attributesetinstance` ADD CONSTRAINT `attsetinst_set` + FOREIGN KEY ( `attributeset_id` ) REFERENCES `attributeset` ( `id` ) ON DELETE CASCADE; + +-- Update foreign keys of attributeuse +ALTER TABLE `attributeuse` ADD CONSTRAINT `attuse_att` + FOREIGN KEY ( `attribute_id` ) REFERENCES `attribute` ( `id` ); + +ALTER TABLE `attributeuse` ADD CONSTRAINT `attuse_set` + FOREIGN KEY ( `attributeset_id` ) REFERENCES `attributeset` ( `id` ) ON DELETE CASCADE; + +-- Update foreign keys of attributevalue +ALTER TABLE `attributevalue` ADD CONSTRAINT `attval_att` + FOREIGN KEY ( `attribute_id` ) REFERENCES `attribute` ( `id` ) ON DELETE CASCADE; + +-- Update foreign keys of categories +ALTER TABLE `categories` ADD CONSTRAINT `categories_fk_1` + FOREIGN KEY ( `parentid` ) REFERENCES `categories` ( `id` ); + +-- Update foreign keys of customers +ALTER TABLE `customers` ADD CONSTRAINT `customers_taxcat` + FOREIGN KEY ( `taxcategory` ) REFERENCES `taxcustcategories` ( `id` ); + +-- Update foreign keys of leaves +ALTER TABLE `leaves` ADD CONSTRAINT `leaves_pplid` + FOREIGN KEY ( `pplid` ) REFERENCES `people` ( `id` ); + +-- Update foreign keys of payments +ALTER TABLE `payments` ADD CONSTRAINT `payments_fk_receipt` + FOREIGN KEY ( `receipt` ) REFERENCES `receipts` ( `id` ); + +-- Update foreign keys of people +ALTER TABLE `people` ADD CONSTRAINT `people_fk_1` + FOREIGN KEY ( `role` ) REFERENCES `roles` ( `id` ); + +-- Update foreign keys of products +ALTER TABLE `products` ADD CONSTRAINT `products_attrset_fk` + FOREIGN KEY ( `attributeset_id` ) REFERENCES `attributeset` ( `id` ); + +ALTER TABLE `products` ADD CONSTRAINT `products_fk_1` + FOREIGN KEY ( `category` ) REFERENCES `categories` ( `id` ); + +ALTER TABLE `products` ADD CONSTRAINT `products_taxcat_fk` + FOREIGN KEY ( `taxcat` ) REFERENCES `taxcategories` ( `id` ); + +-- Update foreign keys of product_bundle +ALTER TABLE `products_bundle` ADD CONSTRAINT `products_bundle_fk_1` + FOREIGN KEY ( `product` ) REFERENCES `products`( `id` ); + +ALTER TABLE `products_bundle` ADD CONSTRAINT `products_bundle_fk_2` + FOREIGN KEY ( `product_bundle` ) REFERENCES `products`( `id` ); + +-- Update foreign keys of products_cat +ALTER TABLE `products_cat` ADD CONSTRAINT `products_cat_fk_1` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +-- Update foreign keys of products_com +ALTER TABLE `products_com` ADD CONSTRAINT `products_com_fk_1` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +ALTER TABLE `products_com` ADD CONSTRAINT `products_com_fk_2` + FOREIGN KEY ( `product2` ) REFERENCES `products` ( `id` ); + +-- Update foreign keys of receipts +ALTER TABLE `receipts` ADD CONSTRAINT `receipts_fk_money` + FOREIGN KEY ( `money` ) REFERENCES `closedcash` ( `money` ); + +-- Update foreign keys of reservation_customers +ALTER TABLE `reservation_customers` ADD CONSTRAINT `res_cust_fk_1` + FOREIGN KEY ( `id` ) REFERENCES `reservations` ( `id` ); + +ALTER TABLE `reservation_customers` ADD CONSTRAINT `res_cust_fk_2` + FOREIGN KEY ( `customer` ) REFERENCES `customers` ( `id` ); + +-- Update foreign keys of shift_breaks +ALTER TABLE `shift_breaks` ADD CONSTRAINT `shift_breaks_breakid` + FOREIGN KEY ( `breakid` ) REFERENCES `breaks` ( `id` ); + +ALTER TABLE `shift_breaks` ADD CONSTRAINT `shift_breaks_shiftid` + FOREIGN KEY ( `shiftid` ) REFERENCES `shifts` ( `id` ); + +-- Update foreign keys of stockcurrent +ALTER TABLE `stockcurrent` ADD CONSTRAINT `stockcurrent_attsetinst` + FOREIGN KEY ( `attributesetinstance_id` ) REFERENCES `attributesetinstance` ( `id` ); + +ALTER TABLE `stockcurrent` ADD CONSTRAINT `stockcurrent_fk_1` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +ALTER TABLE `stockcurrent` ADD CONSTRAINT `stockcurrent_fk_2` + FOREIGN KEY ( `location` ) REFERENCES `locations` ( `id` ); + +-- Update foreign keys of stockdiary +ALTER TABLE `stockdiary` ADD CONSTRAINT `stockdiary_attsetinst` + FOREIGN KEY ( `attributesetinstance_id` ) REFERENCES `attributesetinstance` ( `id` ); + +ALTER TABLE `stockdiary` ADD CONSTRAINT `stockdiary_fk_1` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +ALTER TABLE `stockdiary` ADD CONSTRAINT `stockdiary_fk_2` + FOREIGN KEY ( `location` ) REFERENCES `locations` ( `id` ); + +-- Update foreign keys of stocklevel +ALTER TABLE `stocklevel` ADD CONSTRAINT `stocklevel_location` + FOREIGN KEY ( `location` ) REFERENCES `locations` ( `id` ); + +ALTER TABLE `stocklevel` ADD CONSTRAINT `stocklevel_product` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +-- Update foreign keys of taxes +ALTER TABLE `taxes` ADD CONSTRAINT `taxes_cat_fk` + FOREIGN KEY ( `category` ) REFERENCES `taxcategories` ( `id` ); + +ALTER TABLE `taxes` ADD CONSTRAINT `taxes_custcat_fk` + FOREIGN KEY ( `custcategory` ) REFERENCES `taxcustcategories` ( `id` ); + +ALTER TABLE `taxes` ADD CONSTRAINT `taxes_taxes_fk` + FOREIGN KEY ( `parentid` ) REFERENCES `taxes` ( `id` ); + +-- Update foreign keys of taxlines +ALTER TABLE `taxlines` ADD CONSTRAINT `taxlines_receipt` + FOREIGN KEY ( `receipt` ) REFERENCES `receipts` ( `id` ); + +ALTER TABLE `taxlines` ADD CONSTRAINT `taxlines_tax` + FOREIGN KEY ( `taxid` ) REFERENCES `taxes` ( `id` ); + +-- Update foreign keys of ticketlines +ALTER TABLE `ticketlines` ADD CONSTRAINT `ticketlines_attsetinst` + FOREIGN KEY ( `attributesetinstance_id` ) REFERENCES `attributesetinstance` ( `id` ); + +ALTER TABLE `ticketlines` ADD CONSTRAINT `ticketlines_fk_2` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +ALTER TABLE `ticketlines` ADD CONSTRAINT `ticketlines_fk_3` + FOREIGN KEY ( `taxid` ) REFERENCES `taxes` ( `id` ); + +ALTER TABLE `ticketlines` ADD CONSTRAINT `ticketlines_fk_ticket` + FOREIGN KEY ( `ticket` ) REFERENCES `tickets` ( `id` ); + +-- Update foreign keys of tickets +ALTER TABLE `tickets` ADD CONSTRAINT `tickets_customers_fk` + FOREIGN KEY ( `customer` ) REFERENCES `customers` ( `id` ); + +ALTER TABLE `tickets` ADD CONSTRAINT `tickets_fk_2` + FOREIGN KEY ( `person` ) REFERENCES `people` ( `id` ); + +ALTER TABLE `tickets` ADD CONSTRAINT `tickets_fk_id` + FOREIGN KEY ( `id` ) REFERENCES `receipts` ( `id` ); + +-- ***************************************************************************** \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/scripts/MySQL-clearData.sql b/src/main/resources/com/unicenta/pos/scripts/MySQL-clearData.sql new file mode 100644 index 0000000..2039502 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/scripts/MySQL-clearData.sql @@ -0,0 +1,57 @@ +-- uniCenta oPOS - Touch Friendly Point Of Sale +-- Copyright (c) 2009-2017 uniCenta +-- https://unicenta.com +-- +-- This file is part of uniCenta oPOS. +-- +-- uniCenta oPOS is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- uniCenta oPOS is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +/* + * Script created by Jack, uniCenta 21/04/2017 08:00:00 + * Modified 21 Apr 2017 to lowercase + * Called by Transfer for v4.2 after MySQL-create-transfer.sql +*/ + +set foreign_key_checks = 0; + +-- drop default data +delete from people where `id` not in ('0'); +delete from categories; +delete from taxcategories; +delete from taxcustcategories; +delete from taxes; +delete from locations; +delete from floors; +delete from places; +delete from shifts; +delete from breaks; +delete from shift_breaks; +delete from closedcash; +delete from csvimport; +-- delete from customers; +delete FROM draweropened; +delete FROM leaves; +delete FROM lineremoved; +delete FROM payments; +delete FROM products_cat; +delete FROM products_com; +delete FROM products; +delete FROM receipts; +delete FROM roles; +delete FROM stockcurrent; +delete FROM stockdiary; +delete FROM stocklevel; +-- delete FROM suppliers; + +set foreign_key_checks = 0; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/scripts/MySQL-create-sp.sql b/src/main/resources/com/unicenta/pos/scripts/MySQL-create-sp.sql new file mode 100644 index 0000000..2b4e011 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/scripts/MySQL-create-sp.sql @@ -0,0 +1,45 @@ + +-- ADD STORED PROCEDURES + +-- Example: +-- call AddTblNotExist(Database(), 'atest'); + +CREATE PROCEDURE `AddTblNotExist`( + IN dbName tinytext, + IN tblName tinytext) +begin + IF NOT EXISTS ( + SELECT * FROM information_schema.TABLES + WHERE table_name=tblName + and table_schema=dbName + ) + THEN + set @ddl=CONCAT('CREATE TABLE ',dbName,'.',tblName); + prepare stmt from @ddl; + execute stmt; + END IF; +end + + +-- Example: +-- call AddColNotExist(Database(), 'atest', 'b', 'int unsigned not null default 1'); + +CREATE PROCEDURE `AddColNotExist`( + IN dbName tinytext, + IN tblName tinytext, + IN fldName tinytext, + IN fldDef text) +begin + IF NOT EXISTS ( + SELECT * FROM information_schema.COLUMNS + WHERE column_name=fldName + and table_name=tblName + and table_schema=dbName + ) + THEN + set @ddl=CONCAT('ALTER TABLE ',dbName,'.',tblName, + ' ADD COLUMN ',fldName,' ',fldDef); + prepare stmt from @ddl; + execute stmt; + END IF; +end \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/scripts/MySQL-create-transfer.sql b/src/main/resources/com/unicenta/pos/scripts/MySQL-create-transfer.sql new file mode 100644 index 0000000..6dbfb11 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/scripts/MySQL-create-transfer.sql @@ -0,0 +1,666 @@ +-- uniCenta oPOS is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- uniCenta oPOS is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +/* + * Script created by Jack, uniCenta 23/07/2016 08:00:00 + * + * Create tables IF NOT EXISTS tablename. +*/ + +-- DROP DATABASE IF EXISTS `unitest`; +-- CREATE DATABASE IF NOT EXISTS `unitest`; +-- USE `unitest`; + +/* Header line. Object: applications. Script date: 23/07/2016 08:00:00 */ +-- RECREATE applications -- +DROP TABLE `applications`; +CREATE TABLE IF NOT EXISTS `applications` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `version` varchar(255) NOT NULL, + `instdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + + +/* Header line. Object: attribute. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `attribute` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: attributeinstance. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `attributeinstance` ( + `id` varchar(255) NOT NULL, + `attributesetinstance_id` varchar(255) NOT NULL, + `attribute_id` varchar(255) NOT NULL, + `value` varchar(255) default NULL, + KEY `attinst_att` ( `attribute_id` ), + KEY `attinst_set` ( `attributesetinstance_id` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: attributeset. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `attributeset` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: attributesetinstance. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `attributesetinstance` ( + `id` varchar(255) NOT NULL, + `attributeset_id` varchar(255) NOT NULL, + `description` varchar(255) default NULL, + KEY `attsetinst_set` ( `attributeset_id` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: attributeuse. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `attributeuse` ( + `id` varchar(255) NOT NULL, + `attributeset_id` varchar(255) NOT NULL, + `attribute_id` varchar(255) NOT NULL, + `lineno` int(11) default NULL, + KEY `attuse_att` ( `attribute_id` ), + UNIQUE INDEX `attuse_line` ( `attributeset_id`, `lineno` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: attributevalue. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `attributevalue` ( + `id` varchar(255) NOT NULL, + `attribute_id` varchar(255) NOT NULL, + `value` varchar(255) default NULL, + KEY `attval_att` ( `attribute_id` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: breaks. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `breaks` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `visible` tinyint(1) NOT NULL default '1', + `notes` varchar(255) default NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: categories. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `categories` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `parentid` varchar(255) default NULL, + `image` mediumblob default NULL, + `texttip` varchar(255) default NULL, + `catshowname` smallint(6) NOT NULL default '1', + `catorder` varchar(255) default NULL, + KEY `categories_fk_1` ( `parentid` ), + UNIQUE INDEX `categories_name_inx` ( `name` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: closedcash. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `closedcash` ( + `money` varchar(255) NOT NULL, + `host` varchar(255) NOT NULL, + `hostsequence` int(11) NOT NULL, + `datestart` datetime NOT NULL, + `dateend` datetime default NULL, + `nosales` int(11) NOT NULL default '0', + KEY `closedcash_inx_1` ( `datestart` ), + UNIQUE INDEX `closedcash_inx_seq` ( `host`, `hostsequence` ), + PRIMARY KEY ( `money` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: csvimport. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `csvimport` ( + `id` varchar(255) NOT NULL, + `rownumber` varchar(255) default NULL, + `csverror` varchar(255) default NULL, + `reference` varchar(255) default NULL, + `code` varchar(255) default NULL, + `name` varchar(255) default NULL, + `pricebuy` double default NULL, + `pricesell` double default NULL, + `previousbuy` double default NULL, + `previoussell` double default NULL, + `category` varchar(255) default NULL, + `tax` varchar(255) default NULL, + `searchkey` varchar(255) default NULL + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: customers. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `customers` ( + `id` varchar(255) NOT NULL, + `searchkey` varchar(255) NOT NULL, + `taxid` varchar(255) default NULL, + `name` varchar(255) NOT NULL, + `taxcategory` varchar(255) default NULL, + `card` varchar(255) default NULL, + `maxdebt` double NOT NULL default '0', + `address` varchar(255) default NULL, + `address2` varchar(255) default NULL, + `postal` varchar(255) default NULL, + `city` varchar(255) default NULL, + `region` varchar(255) default NULL, + `country` varchar(255) default NULL, + `firstname` varchar(255) default NULL, + `lastname` varchar(255) default NULL, + `email` varchar(255) default NULL, + `phone` varchar(255) default NULL, + `phone2` varchar(255) default NULL, + `fax` varchar(255) default NULL, + `notes` varchar(255) default NULL, + `visible` bit(1) NOT NULL default b'1', + `curdate` datetime default NULL, + `curdebt` double default '0', + `image` mediumblob default NULL, + `isvip` bit(1) NOT NULL default b'0', + `discount` double default '0', + `memodate` datetime default NULL, + KEY `customers_card_inx` ( `card` ), + KEY `customers_name_inx` ( `name` ), + UNIQUE INDEX `customers_skey_inx` ( `searchkey` ), + KEY `customers_taxcat` ( `taxcategory` ), + KEY `customers_taxid_inx` ( `taxid` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: draweropened. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `draweropened` ( + `opendate` timestamp NOT NULL, + `name` varchar(255) default NULL, + `ticketid` varchar(255) default NULL +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: floors. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `floors` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `image` mediumblob default NULL, + UNIQUE INDEX `floors_name_inx` ( `name` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: leaves. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `leaves` ( + `id` varchar(255) NOT NULL, + `pplid` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `startdate` datetime NOT NULL, + `enddate` datetime NOT NULL, + `notes` varchar(255) default NULL, + KEY `leaves_pplid` ( `pplid` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: lineremoved. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `lineremoved` ( + `removeddate` timestamp NOT NULL, + `name` varchar(255) default NULL, + `ticketid` varchar(255) default NULL, + `productid` varchar(255) default NULL, + `productname` varchar(255) default NULL, + `units` double NOT NULL +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: locations. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `locations` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `address` varchar(255) default NULL, + UNIQUE INDEX `locations_name_inx` ( `name` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: moorers. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `moorers` ( + `vesselname` varchar(255) default NULL, + `size` int(11) default NULL, + `days` int(11) default NULL, + `power` bit(1) NOT NULL default b'0' +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: orders. Script date: 01/01/2017 00:00:01. */ +CREATE TABLE `orders` ( + `id` int(11) NOT NULL, + `orderid` varchar(50) DEFAULT NULL, + `qty` int(11) DEFAULT '1', + `details` varchar(255) DEFAULT NULL, + `attributes` varchar(255) DEFAULT NULL, + `notes` varchar(255) DEFAULT NULL, + `ticketid` varchar(50) DEFAULT NULL, + `ordertime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `displayid` int(11) DEFAULT '1', + `auxiliary` int(11) DEFAULT NULL, + `completetime` timestamp, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: payments. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `payments` ( + `id` varchar(255) NOT NULL, + `receipt` varchar(255) NOT NULL, + `payment` varchar(255) NOT NULL, + `total` double NOT NULL default '0', + `tip` double default '0', + `transid` varchar(255) default NULL, + `isprocessed` bit(1) default b'0', + `returnmsg` mediumblob default NULL, + `notes` varchar(255) default NULL, + `tendered` double default NULL, + `cardname` varchar(255) default NULL, + `voucher` varchar(255) default NULL, + KEY `payments_fk_receipt` ( `receipt` ), + KEY `payments_inx_1` ( `payment` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: people. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `people` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `apppassword` varchar(255) default NULL, + `card` varchar(255) default NULL, + `role` varchar(255) NOT NULL, + `visible` bit(1) NOT NULL, + `image` mediumblob default NULL, + KEY `people_card_inx` ( `card` ), + KEY `people_fk_1` ( `role` ), + UNIQUE INDEX `people_name_inx` ( `name` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: pickup_number. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `pickup_number` ( + `id` int(11) NOT NULL default '0' +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: places. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `places` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `x` int(11) NOT NULL, + `y` int(11) NOT NULL, + `floor` varchar(255) NOT NULL, + `customer` varchar(255) default NULL, + `waiter` varchar(255) default NULL, + `ticketid` varchar(255) default NULL, + `tablemoved` smallint(6) NOT NULL default '0', + UNIQUE INDEX `places_name_inx` ( `name` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: products. Script date: 02/04/2016 10:53:00. */ +CREATE TABLE IF NOT EXISTS `products` ( + `id` varchar(255) NOT NULL, + `reference` varchar(255) NOT NULL, + `code` varchar(255) NOT NULL, + `codetype` varchar(255) default NULL, + `name` varchar(255) NOT NULL, + `pricebuy` double NOT NULL default '0', + `pricesell` double NOT NULL default '0', + `category` varchar(255) NOT NULL, + `taxcat` varchar(255) NOT NULL, + `attributeset_id` varchar(255) default NULL, + `stockcost` double NOT NULL default '0', + `stockvolume` double NOT NULL default '0', + `image` mediumblob default NULL, + `iscom` bit(1) NOT NULL default b'0', + `isscale` bit(1) NOT NULL default b'0', + `isconstant` bit(1) NOT NULL default b'0', + `printkb` bit(1) NOT NULL default b'0', + `sendstatus` bit(1) NOT NULL default b'0', + `isservice` bit(1) NOT NULL default b'0', + `attributes` mediumblob default NULL, + `display` varchar(255) default NULL, + `isvprice` smallint(6) NOT NULL default '0', + `isverpatrib` smallint(6) NOT NULL default '0', + `texttip` varchar(255) default NULL, + `warranty` smallint(6) NOT NULL default '0', + `stockunits` double NOT NULL default '0', + `printto` varchar(255) default '1', + `supplier` varchar(255) default NULL, + `uom` varchar(255) default '0', + `memodate` datetime default NULL, + + PRIMARY KEY ( `id` ), + KEY `products_attrset_fx` ( `attributeset_id` ), + KEY `products_fk_1` ( `category` ), + UNIQUE INDEX `products_inx_0` ( `reference` ), + UNIQUE INDEX `products_inx_1` ( `code` ), + INDEX `products_name_inx` ( `name` ), + KEY `products_taxcat_fk` ( `taxcat` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: products_cat. Script date: 11/05/2016 05:25:00. */ +CREATE TABLE IF NOT EXISTS `products_bundle` ( + `id` varchar(255) NOT NULL, + `product` VARCHAR(255) NOT NULL, + `product_bundle` VARCHAR(255) NOT NULL, + `quantity` DOUBLE NOT NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `pbundle_inx_prod` ( `product` , `product_bundle` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: products_cat. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `products_cat` ( + `product` varchar(255) NOT NULL, + `catorder` int(11) default NULL, + PRIMARY KEY ( `product` ), + KEY `products_cat_inx_1` ( `catorder` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: products_com. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `products_com` ( + `id` varchar(255) NOT NULL, + `product` varchar(255) NOT NULL, + `product2` varchar(255) NOT NULL, + UNIQUE INDEX `pcom_inx_prod` ( `product`, `product2` ), + PRIMARY KEY ( `id` ), + KEY `products_com_fk_2` ( `product2` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: receipts. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `receipts` ( + `id` varchar(255) NOT NULL, + `money` varchar(255) NOT NULL, + `datenew` datetime NOT NULL, + `attributes` mediumblob default NULL, + `person` varchar(255) default NULL, + PRIMARY KEY ( `id` ), + KEY `receipts_fk_money` ( `money` ), + KEY `receipts_inx_1` ( `datenew` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: reservation_customers. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `reservation_customers` ( + `id` varchar(255) NOT NULL, + `customer` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ), + KEY `res_cust_fk_2` ( `customer` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: reservations. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `reservations` ( + `id` varchar(255) NOT NULL, + `created` datetime NOT NULL, + `datenew` datetime NOT NULL default '2015-01-01 00:00:00', + `title` varchar(255) NOT NULL, + `chairs` int(11) NOT NULL, + `isdone` bit(1) NOT NULL, + `description` varchar(255) default NULL, + PRIMARY KEY ( `id` ), + KEY `reservations_inx_1` ( `datenew` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: resources. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `resources` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `restype` int(11) NOT NULL, + `content` mediumblob default NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `resources_name_inx` ( `name` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: roles. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `roles` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `permissions` mediumblob default NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `roles_name_inx` ( `name` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: sharedtickets. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `sharedtickets` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `content` mediumblob default NULL, + `appuser` varchar(255) default NULL, + `pickupid` int(11) NOT NULL default '0', + `locked` varchar(20) default NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: shift_breaks. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `shift_breaks` ( + `id` varchar(255) NOT NULL, + `shiftid` varchar(255) NOT NULL, + `breakid` varchar(255) NOT NULL, + `starttime` timestamp NOT NULL, + `endtime` timestamp NOT NULL, + PRIMARY KEY ( `id` ), + KEY `shift_breaks_breakid` ( `breakid` ), + KEY `shift_breaks_shiftid` ( `shiftid` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: shifts. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `shifts` ( + `id` varchar(255) NOT NULL, + `startshift` datetime NOT NULL, + `endshift` datetime default NULL, + `pplid` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: stockcurrent. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `stockcurrent` ( + `location` varchar(255) NOT NULL, + `product` varchar(255) NOT NULL, + `attributesetinstance_id` varchar(255) default NULL, + `units` double NOT NULL, + KEY `stockcurrent_attsetinst` ( `attributesetinstance_id` ), + KEY `stockcurrent_fk_1` ( `product` ), + UNIQUE INDEX `stockcurrent_inx` ( `location`, `product`, `attributesetinstance_id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: stockdiary. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `stockdiary` ( + `id` varchar(255) NOT NULL, + `datenew` datetime NOT NULL, + `reason` int(11) NOT NULL, + `location` varchar(255) NOT NULL, + `product` varchar(255) NOT NULL, + `attributesetinstance_id` varchar(255) default NULL, + `units` double NOT NULL, + `price` double NOT NULL, + `appuser` varchar(255) default NULL, + `supplier` varchar(255) default NULL, + `supplierdoc` varchar(255) default NULL, + PRIMARY KEY ( `id` ), + KEY `stockdiary_attsetinst` ( `attributesetinstance_id` ), + KEY `stockdiary_fk_1` ( `product` ), + KEY `stockdiary_fk_2` ( `location` ), + KEY `stockdiary_inx_1` ( `datenew` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: stocklevel. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `stocklevel` ( + `id` varchar(255) NOT NULL, + `location` varchar(255) NOT NULL, + `product` varchar(255) NOT NULL, + `stocksecurity` double default NULL, + `stockmaximum` double default NULL, + PRIMARY KEY ( `id` ), + KEY `stocklevel_location` ( `location` ), + KEY `stocklevel_product` ( `product` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: suppliers. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `suppliers` ( + `id` varchar(255) NOT NULL, + `searchkey` varchar(255) NOT NULL, + `taxid` varchar(255) default NULL, + `name` varchar(255) NOT NULL, + `maxdebt` double NOT NULL default '0', + `address` varchar(255) default NULL, + `address2` varchar(255) default NULL, + `postal` varchar(255) default NULL, + `city` varchar(255) default NULL, + `region` varchar(255) default NULL, + `country` varchar(255) default NULL, + `firstname` varchar(255) default NULL, + `lastname` varchar(255) default NULL, + `email` varchar(255) default NULL, + `phone` varchar(255) default NULL, + `phone2` varchar(255) default NULL, + `fax` varchar(255) default NULL, + `notes` varchar(255) default NULL, + `visible` bit(1) NOT NULL default b'1', + `curdate` datetime default NULL, + `curdebt` double default '0', + `vatid` varchar(255) default NULL, + PRIMARY KEY ( `id` ), + KEY `suppliers_name_inx` ( `name` ), + UNIQUE INDEX `suppliers_skey_inx` ( `searchkey` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: taxcategories. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `taxcategories` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `taxcat_name_inx` ( `name` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: taxcustcategories. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `taxcustcategories` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `taxcustcat_name_inx` ( `name` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: taxes. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `taxes` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `category` varchar(255) NOT NULL, + `custcategory` varchar(255) default NULL, + `parentid` varchar(255) default NULL, + `rate` double NOT NULL default '0', + `ratecascade` bit(1) NOT NULL default b'0', + `rateorder` int(11) default NULL, + PRIMARY KEY ( `id` ), + KEY `taxes_cat_fk` ( `category` ), + KEY `taxes_custcat_fk` ( `custcategory` ), + UNIQUE INDEX `taxes_name_inx` ( `name` ), + KEY `taxes_taxes_fk` ( `parentid` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: taxlines. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `taxlines` ( + `id` varchar(255) NOT NULL, + `receipt` varchar(255) NOT NULL, + `taxid` varchar(255) NOT NULL, + `base` double NOT NULL default '0', + `amount` double NOT NULL default '0', + PRIMARY KEY ( `id` ), + KEY `taxlines_receipt` ( `receipt` ), + KEY `taxlines_tax` ( `taxid` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: taxsuppcategories. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `taxsuppcategories` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: thirdparties. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `thirdparties` ( + `id` varchar(255) NOT NULL, + `cif` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `address` varchar(255) default NULL, + `contactcomm` varchar(255) default NULL, + `contactfact` varchar(255) default NULL, + `payrule` varchar(255) default NULL, + `faxnumber` varchar(255) default NULL, + `phonenumber` varchar(255) default NULL, + `mobilenumber` varchar(255) default NULL, + `email` varchar(255) default NULL, + `webpage` varchar(255) default NULL, + `notes` varchar(255) default NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `thirdparties_cif_inx` ( `cif` ), + UNIQUE INDEX `thirdparties_name_inx` ( `name` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: ticketlines. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `ticketlines` ( + `ticket` varchar(255) NOT NULL, + `line` int(11) NOT NULL, + `product` varchar(255) default NULL, + `attributesetinstance_id` varchar(255) default NULL, + `units` double NOT NULL, + `price` double NOT NULL, + `taxid` varchar(255) NOT NULL, + `attributes` mediumblob default NULL, + PRIMARY KEY ( `ticket`, `line` ), + KEY `ticketlines_attsetinst` ( `attributesetinstance_id` ), + KEY `ticketlines_fk_2` ( `product` ), + KEY `ticketlines_fk_3` ( `taxid` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: tickets. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `tickets` ( + `id` varchar(255) NOT NULL, + `tickettype` int(11) NOT NULL default '0', + `ticketid` int(11) NOT NULL, + `person` varchar(255) NOT NULL, + `customer` varchar(255) default NULL, + `status` int(11) NOT NULL default '0', + PRIMARY KEY ( `id` ), + KEY `tickets_customers_fk` ( `customer` ), + KEY `tickets_fk_2` ( `person` ), + KEY `tickets_ticketid` ( `tickettype`, `ticketid` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: ticketsnum. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `ticketsnum` ( + `id` int(11) NOT NULL +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: ticketsnum_payment. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `ticketsnum_payment` ( +-- `id` int(11) NOT NULL auto_increment, + `id` int(11) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: ticketsnum_refund. Script date: 23/07/2016 08:00:00 */ +CREATE TABLE IF NOT EXISTS `ticketsnum_refund` ( + `id` int(11) NOT NULL +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: uom. Script date: 30/09/2015 13:07:00. */ +CREATE TABLE IF NOT EXISTS `uom` ( + `id` VARCHAR(255) NOT NULL, + `name` VARCHAR(255) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +/* Header line. Object: vouchers. Script date: 30/09/2015 09:33:33. */ +CREATE TABLE IF NOT EXISTS `vouchers` ( + `id` VARCHAR(100) NOT NULL, + `voucher_number` VARCHAR(100) DEFAULT NULL, + `customer` VARCHAR(100) DEFAULT NULL, + `amount` DOUBLE DEFAULT NULL, + `status` CHAR(1) DEFAULT 'A', + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/scripts/MySQL-create.sql b/src/main/resources/com/unicenta/pos/scripts/MySQL-create.sql new file mode 100644 index 0000000..3148f6c --- /dev/null +++ b/src/main/resources/com/unicenta/pos/scripts/MySQL-create.sql @@ -0,0 +1,978 @@ +/* Header line. Object: applications. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `applications` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `version` varchar(255) NOT NULL, + `instdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: attribute. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `attribute` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: attributeinstance. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `attributeinstance` ( + `id` varchar(255) NOT NULL, + `attributesetinstance_id` varchar(255) NOT NULL, + `attribute_id` varchar(255) NOT NULL, + `value` varchar(255) default NULL, + KEY `attinst_att` ( `attribute_id` ), + KEY `attinst_set` ( `attributesetinstance_id` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: attributeset. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `attributeset` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: attributesetinstance. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `attributesetinstance` ( + `id` varchar(255) NOT NULL, + `attributeset_id` varchar(255) NOT NULL, + `description` varchar(255) default NULL, + KEY `attsetinst_set` ( `attributeset_id` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: attributeuse. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `attributeuse` ( + `id` varchar(255) NOT NULL, + `attributeset_id` varchar(255) NOT NULL, + `attribute_id` varchar(255) NOT NULL, + `lineno` int(11) default NULL, + KEY `attuse_att` ( `attribute_id` ), + UNIQUE INDEX `attuse_line` ( `attributeset_id`, `lineno` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: attributevalue. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `attributevalue` ( + `id` varchar(255) NOT NULL, + `attribute_id` varchar(255) NOT NULL, + `value` varchar(255) default NULL, + KEY `attval_att` ( `attribute_id` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: breaks. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `breaks` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `visible` tinyint(1) NOT NULL default '1', + `notes` varchar(255) default NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: categories. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `categories` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `parentid` varchar(255) default NULL, + `image` mediumblob default NULL, + `texttip` varchar(255) default NULL, + `catshowname` smallint(6) NOT NULL default '1', + `catorder` varchar(255) default NULL, + KEY `categories_fk_1` ( `parentid` ), + UNIQUE INDEX `categories_name_inx` ( `name` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: closedcash. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `closedcash` ( + `money` varchar(255) NOT NULL, + `host` varchar(255) NOT NULL, + `hostsequence` int(11) NOT NULL, + `datestart` datetime NOT NULL, + `dateend` datetime default NULL, + `nosales` int(11) NOT NULL default '0', + KEY `closedcash_inx_1` ( `datestart` ), + UNIQUE INDEX `closedcash_inx_seq` ( `host`, `hostsequence` ), + PRIMARY KEY ( `money` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: csvimport. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `csvimport` ( + `id` varchar(255) NOT NULL, + `rownumber` varchar(255) default NULL, + `csverror` varchar(255) default NULL, + `reference` varchar(255) default NULL, + `code` varchar(255) default NULL, + `name` varchar(255) default NULL, + `pricebuy` double default NULL, + `pricesell` double default NULL, + `previousbuy` double default NULL, + `previoussell` double default NULL, + `category` varchar(255) default NULL, + `tax` varchar(255) default NULL, + `searchkey` varchar(255) default NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: customers. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `customers` ( + `id` varchar(255) NOT NULL, + `searchkey` varchar(255) NOT NULL, + `taxid` varchar(255) default NULL, + `name` varchar(255) NOT NULL, + `taxcategory` varchar(255) default NULL, + `card` varchar(255) default NULL, + `maxdebt` double NOT NULL default '0', + `address` varchar(255) default NULL, + `address2` varchar(255) default NULL, + `postal` varchar(255) default NULL, + `city` varchar(255) default NULL, + `region` varchar(255) default NULL, + `country` varchar(255) default NULL, + `firstname` varchar(255) default NULL, + `lastname` varchar(255) default NULL, + `email` varchar(255) default NULL, + `phone` varchar(255) default NULL, + `phone2` varchar(255) default NULL, + `fax` varchar(255) default NULL, + `notes` varchar(255) default NULL, + `visible` bit(1) NOT NULL default b'1', + `curdate` datetime default NULL, + `curdebt` double default '0', + `image` mediumblob default NULL, + `isvip` bit(1) NOT NULL default b'0', + `discount` double default '0', + `memodate` datetime default '2000-01-01 00:00:01', + KEY `customers_card_inx` ( `card` ), + KEY `customers_name_inx` ( `name` ), + UNIQUE INDEX `customers_skey_inx` ( `searchkey` ), + KEY `customers_taxcat` ( `taxcategory` ), + KEY `customers_taxid_inx` ( `taxid` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: draweropened. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `draweropened` ( + `opendate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `name` varchar(255) default NULL, + `ticketid` varchar(255) default NULL +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: floors. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `floors` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `image` mediumblob default NULL, + UNIQUE INDEX `floors_name_inx` ( `name` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: leaves. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `leaves` ( + `id` varchar(255) NOT NULL, + `pplid` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `startdate` datetime NOT NULL, + `enddate` datetime NOT NULL, + `notes` varchar(255) default NULL, + KEY `leaves_pplid` ( `pplid` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: lineremoved. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `lineremoved` ( + `removeddate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `name` varchar(255) default NULL, + `ticketid` varchar(255) default NULL, + `productid` varchar(255) default NULL, + `productname` varchar(255) default NULL, + `units` double NOT NULL +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: locations. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `locations` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `address` varchar(255) default NULL, + UNIQUE INDEX `locations_name_inx` ( `name` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: moorers. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `moorers` ( + `vesselname` varchar(255) default NULL, + `size` int(11) default NULL, + `days` int(11) default NULL, + `power` bit(1) NOT NULL default b'0' +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +CREATE TABLE IF NOT EXISTS `orders` ( + `id` MEDIUMINT NOT NULL AUTO_INCREMENT, + `orderid` varchar(50) DEFAULT NULL, + `qty` int(11) DEFAULT '1', + `details` varchar(255) DEFAULT NULL, + `attributes` varchar(255) DEFAULT NULL, + `notes` varchar(255) DEFAULT NULL, + `ticketid` varchar(50) DEFAULT NULL, + `ordertime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `displayid` int(11) DEFAULT '1', + `auxiliary` int(11) DEFAULT NULL, + `completetime` timestamp NULL, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: payments. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `payments` ( + `id` varchar(255) NOT NULL, + `receipt` varchar(255) NOT NULL, + `payment` varchar(255) NOT NULL, + `total` double NOT NULL default '0', + `tip` double default '0', + `transid` varchar(255) default NULL, + `isprocessed` bit(1) default b'0', + `returnmsg` mediumblob default NULL, + `notes` varchar(255) default NULL, + `tendered` double default NULL, + `cardname` varchar(255) default NULL, + `voucher` varchar(255) default NULL, + KEY `payments_fk_receipt` ( `receipt` ), + KEY `payments_inx_1` ( `payment` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: people. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `people` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `apppassword` varchar(255) default NULL, + `card` varchar(255) default NULL, + `role` varchar(255) NOT NULL, + `visible` bit(1) NOT NULL, + `image` mediumblob default NULL, + KEY `people_card_inx` ( `card` ), + KEY `people_fk_1` ( `role` ), + UNIQUE INDEX `people_name_inx` ( `name` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: pickup_number. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `pickup_number` ( + `id` int(11) NOT NULL default '0' +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: places. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `places` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `seats` varchar(6) NOT NULL DEFAULT '1', + `x` int(11) NOT NULL, + `y` int(11) NOT NULL, + `floor` varchar(255) NOT NULL, + `customer` varchar(255) default NULL, + `waiter` varchar(255) default NULL, + `ticketid` varchar(255) default NULL, + `tablemoved` smallint(6) NOT NULL default '0', + `width` int(11) NOT NULL, + `height` int(11) NOT NULL, + `guests` int(11) DEFAULT 0, + `occupied` datetime DEFAULT NULL, + UNIQUE INDEX `places_name_inx` ( `name` ), + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: products. Script date: 02/04/2016 10:53:00. */ +CREATE TABLE `products` ( + `id` varchar(255) NOT NULL, + `reference` varchar(255) NOT NULL, + `code` varchar(255) NOT NULL, + `codetype` varchar(255) default NULL, + `name` varchar(255) NOT NULL, + `pricebuy` double NOT NULL default '0', + `pricesell` double NOT NULL default '0', + `category` varchar(255) NOT NULL, + `taxcat` varchar(255) NOT NULL, + `attributeset_id` varchar(255) default NULL, + `stockcost` double NOT NULL default '0', + `stockvolume` double NOT NULL default '0', + `image` mediumblob default NULL, + `iscom` bit(1) NOT NULL default b'0', + `isscale` bit(1) NOT NULL default b'0', + `isconstant` bit(1) NOT NULL default b'0', + `printkb` bit(1) NOT NULL default b'0', + `sendstatus` bit(1) NOT NULL default b'0', + `isservice` bit(1) NOT NULL default b'0', + `attributes` mediumblob default NULL, + `display` varchar(255) default NULL, + `isvprice` smallint(6) NOT NULL default '0', + `isverpatrib` smallint(6) NOT NULL default '0', + `texttip` varchar(255) default NULL, + `warranty` smallint(6) NOT NULL default '0', + `stockunits` double NOT NULL default '0', + `printto` varchar(255) default '1', + `supplier` varchar(255) default NULL, + `uom` varchar(255) default '0', + `memodate` datetime default '2018-01-01 00:00:01', + + PRIMARY KEY ( `id` ), + KEY `products_attrset_fx` ( `attributeset_id` ), + KEY `products_fk_1` ( `category` ), + UNIQUE INDEX `products_inx_0` ( `reference` ), + UNIQUE INDEX `products_inx_1` ( `code` ), + INDEX `products_name_inx` ( `name` ), + KEY `products_taxcat_fk` ( `taxcat` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: products_cat. Script date: 11/05/2016 05:25:00. */ +CREATE TABLE `products_bundle` ( + `id` varchar(255) NOT NULL, + `product` VARCHAR(255) NOT NULL, + `product_bundle` VARCHAR(255) NOT NULL, + `quantity` DOUBLE NOT NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `pbundle_inx_prod` ( `product` , `product_bundle` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: products_cat. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `products_cat` ( + `product` varchar(255) NOT NULL, + `catorder` int(11) default NULL, + PRIMARY KEY ( `product` ), + KEY `products_cat_inx_1` ( `catorder` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: products_com. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `products_com` ( + `id` varchar(255) NOT NULL, + `product` varchar(255) NOT NULL, + `product2` varchar(255) NOT NULL, + UNIQUE INDEX `pcom_inx_prod` ( `product`, `product2` ), + PRIMARY KEY ( `id` ), + KEY `products_com_fk_2` ( `product2` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: receipts. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `receipts` ( + `id` varchar(255) NOT NULL, + `money` varchar(255) NOT NULL, + `datenew` datetime NOT NULL, + `attributes` mediumblob default NULL, + `person` varchar(255) default NULL, + PRIMARY KEY ( `id` ), + KEY `receipts_fk_money` ( `money` ), + KEY `receipts_inx_1` ( `datenew` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: reservation_customers. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `reservation_customers` ( + `id` varchar(255) NOT NULL, + `customer` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ), + KEY `res_cust_fk_2` ( `customer` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: reservations. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `reservations` ( + `id` varchar(255) NOT NULL, + `created` datetime NOT NULL, + `datenew` datetime NOT NULL default '2018-01-01 00:00:00', + `title` varchar(255) NOT NULL, + `chairs` int(11) NOT NULL, + `isdone` bit(1) NOT NULL, + `description` varchar(255) default NULL, + PRIMARY KEY ( `id` ), + KEY `reservations_inx_1` ( `datenew` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: resources. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `resources` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `restype` int(11) NOT NULL, + `content` mediumblob default NULL, + `version` varchar(10) default NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `resources_name_inx` ( `name` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: roles. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `roles` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `permissions` mediumblob default NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `roles_name_inx` ( `name` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: sharedtickets. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `sharedtickets` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `content` mediumblob default NULL, + `appuser` varchar(255) default NULL, + `pickupid` int(11) NOT NULL default '0', + `locked` varchar(20) default NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: shift_breaks. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `shift_breaks` ( + `id` varchar(255) NOT NULL, + `shiftid` varchar(255) NOT NULL, + `breakid` varchar(255) NOT NULL, + `starttime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `endtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY ( `id` ), + KEY `shift_breaks_breakid` ( `breakid` ), + KEY `shift_breaks_shiftid` ( `shiftid` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: shifts. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `shifts` ( + `id` varchar(255) NOT NULL, + `startshift` datetime NOT NULL, + `endshift` datetime default NULL, + `pplid` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: stockcurrent. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `stockcurrent` ( + `location` varchar(255) NOT NULL, + `product` varchar(255) NOT NULL, + `attributesetinstance_id` varchar(255) default NULL, + `units` double NOT NULL, + KEY `stockcurrent_attsetinst` ( `attributesetinstance_id` ), + KEY `stockcurrent_fk_1` ( `product` ), + UNIQUE INDEX `stockcurrent_inx` ( `location`, `product`, `attributesetinstance_id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: stockdiary. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `stockdiary` ( + `id` varchar(255) NOT NULL, + `datenew` datetime NOT NULL, + `reason` int(11) NOT NULL, + `location` varchar(255) NOT NULL, + `product` varchar(255) NOT NULL, + `attributesetinstance_id` varchar(255) default NULL, + `units` double NOT NULL, + `price` double NOT NULL, + `appuser` varchar(255) default NULL, + `supplier` varchar(255) default NULL, + `supplierdoc` varchar(255) default NULL, + PRIMARY KEY ( `id` ), + KEY `stockdiary_attsetinst` ( `attributesetinstance_id` ), + KEY `stockdiary_fk_1` ( `product` ), + KEY `stockdiary_fk_2` ( `location` ), + KEY `stockdiary_inx_1` ( `datenew` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: stocklevel. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `stocklevel` ( + `id` varchar(255) NOT NULL, + `location` varchar(255) NOT NULL, + `product` varchar(255) NOT NULL, + `stocksecurity` double default NULL, + `stockmaximum` double default NULL, + PRIMARY KEY ( `id` ), + KEY `stocklevel_location` ( `location` ), + KEY `stocklevel_product` ( `product` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: suppliers. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `suppliers` ( + `id` varchar(255) NOT NULL, + `searchkey` varchar(255) NOT NULL, + `taxid` varchar(255) default NULL, + `name` varchar(255) NOT NULL, + `maxdebt` double NOT NULL default '0', + `address` varchar(255) default NULL, + `address2` varchar(255) default NULL, + `postal` varchar(255) default NULL, + `city` varchar(255) default NULL, + `region` varchar(255) default NULL, + `country` varchar(255) default NULL, + `firstname` varchar(255) default NULL, + `lastname` varchar(255) default NULL, + `email` varchar(255) default NULL, + `phone` varchar(255) default NULL, + `phone2` varchar(255) default NULL, + `fax` varchar(255) default NULL, + `notes` varchar(255) default NULL, + `visible` bit(1) NOT NULL default b'1', + `curdate` datetime default NULL, + `curdebt` double default '0', + `vatid` varchar(255) default NULL, + PRIMARY KEY ( `id` ), + KEY `suppliers_name_inx` ( `name` ), + UNIQUE INDEX `suppliers_skey_inx` ( `searchkey` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: taxcategories. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `taxcategories` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `taxcat_name_inx` ( `name` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: taxcustcategories. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `taxcustcategories` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `taxcustcat_name_inx` ( `name` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: taxes. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `taxes` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `category` varchar(255) NOT NULL, + `custcategory` varchar(255) default NULL, + `parentid` varchar(255) default NULL, + `rate` double NOT NULL default '0', + `ratecascade` bit(1) NOT NULL default b'0', + `rateorder` int(11) default NULL, + PRIMARY KEY ( `id` ), + KEY `taxes_cat_fk` ( `category` ), + KEY `taxes_custcat_fk` ( `custcategory` ), + UNIQUE INDEX `taxes_name_inx` ( `name` ), + KEY `taxes_taxes_fk` ( `parentid` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: taxlines. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `taxlines` ( + `id` varchar(255) NOT NULL, + `receipt` varchar(255) NOT NULL, + `taxid` varchar(255) NOT NULL, + `base` double NOT NULL default '0', + `amount` double NOT NULL default '0', + PRIMARY KEY ( `id` ), + KEY `taxlines_receipt` ( `receipt` ), + KEY `taxlines_tax` ( `taxid` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: taxsuppcategories. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `taxsuppcategories` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: thirdparties. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `thirdparties` ( + `id` varchar(255) NOT NULL, + `cif` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `address` varchar(255) default NULL, + `contactcomm` varchar(255) default NULL, + `contactfact` varchar(255) default NULL, + `payrule` varchar(255) default NULL, + `faxnumber` varchar(255) default NULL, + `phonenumber` varchar(255) default NULL, + `mobilenumber` varchar(255) default NULL, + `email` varchar(255) default NULL, + `webpage` varchar(255) default NULL, + `notes` varchar(255) default NULL, + PRIMARY KEY ( `id` ), + UNIQUE INDEX `thirdparties_cif_inx` ( `cif` ), + UNIQUE INDEX `thirdparties_name_inx` ( `name` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: ticketlines. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `ticketlines` ( + `ticket` varchar(255) NOT NULL, + `line` int(11) NOT NULL, + `product` varchar(255) default NULL, + `attributesetinstance_id` varchar(255) default NULL, + `units` double NOT NULL, + `price` double NOT NULL, + `taxid` varchar(255) NOT NULL, + `attributes` mediumblob default NULL, + PRIMARY KEY ( `ticket`, `line` ), + KEY `ticketlines_attsetinst` ( `attributesetinstance_id` ), + KEY `ticketlines_fk_2` ( `product` ), + KEY `ticketlines_fk_3` ( `taxid` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: tickets. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `tickets` ( + `id` varchar(255) NOT NULL, + `tickettype` int(11) NOT NULL default '0', + `ticketid` int(11) NOT NULL, + `person` varchar(255) NOT NULL, + `customer` varchar(255) default NULL, + `status` int(11) NOT NULL default '0', + PRIMARY KEY ( `id` ), + KEY `tickets_customers_fk` ( `customer` ), + KEY `tickets_fk_2` ( `person` ), + KEY `tickets_ticketid` ( `tickettype`, `ticketid` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: ticketsnum. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `ticketsnum` ( + `id` int(11) NOT NULL +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: ticketsnum_payment. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `ticketsnum_payment` ( + `id` int(11) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: ticketsnum_refund. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `ticketsnum_refund` ( + `id` int(11) NOT NULL +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: uom. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `uom` ( + `id` VARCHAR(255) NOT NULL, + `name` VARCHAR(255) NOT NULL, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +/* Header line. Object: vouchers. Script date: 23/01/2018 08:00:00 */ +CREATE TABLE `vouchers` ( + `id` VARCHAR(100) NOT NULL, + `voucher_number` VARCHAR(100) DEFAULT NULL, + `customer` VARCHAR(100) DEFAULT NULL, + `amount` DOUBLE DEFAULT NULL, + `status` CHAR(1) DEFAULT 'A', + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +-- Update foreign keys of attributeinstance +ALTER TABLE `attributeinstance` ADD CONSTRAINT `attinst_att` + FOREIGN KEY ( `attribute_id` ) REFERENCES `attribute` ( `id` ); + +ALTER TABLE `attributeinstance` ADD CONSTRAINT `attinst_set` + FOREIGN KEY ( `attributesetinstance_id` ) REFERENCES `attributesetinstance` ( `id` ) ON DELETE CASCADE; + +-- Update foreign keys of attributesetinstance +ALTER TABLE `attributesetinstance` ADD CONSTRAINT `attsetinst_set` + FOREIGN KEY ( `attributeset_id` ) REFERENCES `attributeset` ( `id` ) ON DELETE CASCADE; + +-- Update foreign keys of attributeuse +ALTER TABLE `attributeuse` ADD CONSTRAINT `attuse_att` + FOREIGN KEY ( `attribute_id` ) REFERENCES `attribute` ( `id` ); + +ALTER TABLE `attributeuse` ADD CONSTRAINT `attuse_set` + FOREIGN KEY ( `attributeset_id` ) REFERENCES `attributeset` ( `id` ) ON DELETE CASCADE; + +-- Update foreign keys of attributevalue +ALTER TABLE `attributevalue` ADD CONSTRAINT `attval_att` + FOREIGN KEY ( `attribute_id` ) REFERENCES `attribute` ( `id` ) ON DELETE CASCADE; + +-- Update foreign keys of categories +ALTER TABLE `categories` ADD CONSTRAINT `categories_fk_1` + FOREIGN KEY ( `parentid` ) REFERENCES `categories` ( `id` ); + +-- Update foreign keys of customers + ALTER TABLE `customers` ADD CONSTRAINT `customers_taxcat` + FOREIGN KEY ( `taxcategory` ) REFERENCES `taxcustcategories` ( `id` ); + +-- Update foreign keys of leaves +ALTER TABLE `leaves` ADD CONSTRAINT `leaves_pplid` + FOREIGN KEY ( `pplid` ) REFERENCES `people` ( `id` ); + +-- Update foreign keys of payments +ALTER TABLE `payments` ADD CONSTRAINT `payments_fk_receipt` + FOREIGN KEY ( `receipt` ) REFERENCES `receipts` ( `id` ); + +-- Update foreign keys of people +ALTER TABLE `people` ADD CONSTRAINT `people_fk_1` + FOREIGN KEY ( `role` ) REFERENCES `roles` ( `id` ); + +-- Update foreign keys of products +ALTER TABLE `products` ADD CONSTRAINT `products_attrset_fk` + FOREIGN KEY ( `attributeset_id` ) REFERENCES `attributeset` ( `id` ); + +ALTER TABLE `products` ADD CONSTRAINT `products_fk_1` + FOREIGN KEY ( `category` ) REFERENCES `categories` ( `id` ); + +ALTER TABLE `products` ADD CONSTRAINT `products_taxcat_fk` + FOREIGN KEY ( `taxcat` ) REFERENCES `taxcategories` ( `id` ); + +-- Update foreign keys of product_bundle +ALTER TABLE `products_bundle` ADD CONSTRAINT `products_bundle_fk_1` + FOREIGN KEY ( `product` ) REFERENCES `products`( `id` ); + +ALTER TABLE `products_bundle` ADD CONSTRAINT `products_bundle_fk_2` + FOREIGN KEY ( `product_bundle` ) REFERENCES `products`( `id` ); + +-- Update foreign keys of products_cat +ALTER TABLE `products_cat` ADD CONSTRAINT `products_cat_fk_1` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +-- Update foreign keys of products_com +ALTER TABLE `products_com` ADD CONSTRAINT `products_com_fk_1` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +ALTER TABLE `products_com` ADD CONSTRAINT `products_com_fk_2` + FOREIGN KEY ( `product2` ) REFERENCES `products` ( `id` ); + +-- Update foreign keys of receipts +ALTER TABLE `receipts` ADD CONSTRAINT `receipts_fk_money` + FOREIGN KEY ( `money` ) REFERENCES `closedcash` ( `money` ); + +-- Update foreign keys of reservation_customers +ALTER TABLE `reservation_customers` ADD CONSTRAINT `res_cust_fk_1` + FOREIGN KEY ( `id` ) REFERENCES `reservations` ( `id` ); + +ALTER TABLE `reservation_customers` ADD CONSTRAINT `res_cust_fk_2` + FOREIGN KEY ( `customer` ) REFERENCES `customers` ( `id` ); + +-- Update foreign keys of shift_breaks +ALTER TABLE `shift_breaks` ADD CONSTRAINT `shift_breaks_breakid` + FOREIGN KEY ( `breakid` ) REFERENCES `breaks` ( `id` ); + +ALTER TABLE `shift_breaks` ADD CONSTRAINT `shift_breaks_shiftid` + FOREIGN KEY ( `shiftid` ) REFERENCES `shifts` ( `id` ); + +-- Update foreign keys of stockcurrent +ALTER TABLE `stockcurrent` ADD CONSTRAINT `stockcurrent_attsetinst` + FOREIGN KEY ( `attributesetinstance_id` ) REFERENCES `attributesetinstance` ( `id` ); + +ALTER TABLE `stockcurrent` ADD CONSTRAINT `stockcurrent_fk_1` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +ALTER TABLE `stockcurrent` ADD CONSTRAINT `stockcurrent_fk_2` + FOREIGN KEY ( `location` ) REFERENCES `locations` ( `id` ); + +-- Update foreign keys of stockdiary +ALTER TABLE `stockdiary` ADD CONSTRAINT `stockdiary_attsetinst` + FOREIGN KEY ( `attributesetinstance_id` ) REFERENCES `attributesetinstance` ( `id` ); + +ALTER TABLE `stockdiary` ADD CONSTRAINT `stockdiary_fk_1` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +ALTER TABLE `stockdiary` ADD CONSTRAINT `stockdiary_fk_2` + FOREIGN KEY ( `location` ) REFERENCES `locations` ( `id` ); + +-- Update foreign keys of stocklevel +ALTER TABLE `stocklevel` ADD CONSTRAINT `stocklevel_location` + FOREIGN KEY ( `location` ) REFERENCES `locations` ( `id` ); + +ALTER TABLE `stocklevel` ADD CONSTRAINT `stocklevel_product` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +-- Update foreign keys of taxes +ALTER TABLE `taxes` ADD CONSTRAINT `taxes_cat_fk` + FOREIGN KEY ( `category` ) REFERENCES `taxcategories` ( `id` ); + +ALTER TABLE `taxes` ADD CONSTRAINT `taxes_custcat_fk` + FOREIGN KEY ( `custcategory` ) REFERENCES `taxcustcategories` ( `id` ); + +ALTER TABLE `taxes` ADD CONSTRAINT `taxes_taxes_fk` + FOREIGN KEY ( `parentid` ) REFERENCES `taxes` ( `id` ); + +-- Update foreign keys of taxlines +ALTER TABLE `taxlines` ADD CONSTRAINT `taxlines_receipt` + FOREIGN KEY ( `receipt` ) REFERENCES `receipts` ( `id` ); + +ALTER TABLE `taxlines` ADD CONSTRAINT `taxlines_tax` + FOREIGN KEY ( `taxid` ) REFERENCES `taxes` ( `id` ); + +-- Update foreign keys of ticketlines +ALTER TABLE `ticketlines` ADD CONSTRAINT `ticketlines_attsetinst` + FOREIGN KEY ( `attributesetinstance_id` ) REFERENCES `attributesetinstance` ( `id` ); + +ALTER TABLE `ticketlines` ADD CONSTRAINT `ticketlines_fk_2` + FOREIGN KEY ( `product` ) REFERENCES `products` ( `id` ); + +ALTER TABLE `ticketlines` ADD CONSTRAINT `ticketlines_fk_3` + FOREIGN KEY ( `taxid` ) REFERENCES `taxes` ( `id` ); + +ALTER TABLE `ticketlines` ADD CONSTRAINT `ticketlines_fk_ticket` + FOREIGN KEY ( `ticket` ) REFERENCES `tickets` ( `id` ); + +-- Update foreign keys of tickets +ALTER TABLE `tickets` ADD CONSTRAINT `tickets_customers_fk` + FOREIGN KEY ( `customer` ) REFERENCES `customers` ( `id` ); + +ALTER TABLE `tickets` ADD CONSTRAINT `tickets_fk_2` + FOREIGN KEY ( `person` ) REFERENCES `people` ( `id` ); + +ALTER TABLE `tickets` ADD CONSTRAINT `tickets_fk_id` + FOREIGN KEY ( `id` ) REFERENCES `receipts` ( `id` ); + +-- ***************************************************************************** + +-- ADD roles +INSERT INTO roles(id, name, permissions) VALUES('0', 'Administrator role', $FILE{/com/unicenta/pos/templates/Role.Administrator.xml} ); +INSERT INTO roles(id, name, permissions) VALUES('1', 'Manager role', $FILE{/com/unicenta/pos/templates/Role.Manager.xml} ); +INSERT INTO roles(id, name, permissions) VALUES('2', 'Employee role', $FILE{/com/unicenta/pos/templates/Role.Employee.xml} ); +INSERT INTO roles(id, name, permissions) VALUES('3', 'Guest role', $FILE{/com/unicenta/pos/templates/Role.Guest.xml} ); + +-- ADD people +INSERT INTO people(id, name, apppassword, role, visible, image) VALUES ('0', 'Administrator', NULL, '0', TRUE, NULL); +INSERT INTO people(id, name, apppassword, role, visible, image) VALUES ('1', 'Manager', NULL, '1', TRUE, NULL); +INSERT INTO people(id, name, apppassword, role, visible, image) VALUES ('2', 'Employee', NULL, '2', TRUE, NULL); +INSERT INTO people(id, name, apppassword, role, visible, image) VALUES ('3', 'Guest', NULL, '3', TRUE, NULL); + +-- ADD resources -- +-- SYSTEM +INSERT INTO resources(id, name, restype, content) VALUES('00', 'Menu.Root', 0, $FILE{/com/unicenta/pos/templates/Menu.Root.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('02', 'Cash.Close', 0, $FILE{/com/unicenta/pos/templates/Cash.Close.xml}); +INSERT INTO resources(ID, name, restype, content) VALUES('03', 'Customer.Created', 0, $FILE{/com/unicenta/pos/templates/customer.created.xml}); +INSERT INTO resources(ID, name, restype, content) VALUES('04', 'Customer.Deleted', 0, $FILE{/com/unicenta/pos/templates/customer.deleted.xml}); +INSERT INTO resources(ID, name, restype, content) VALUES('05', 'Customer.Updated', 0, $FILE{/com/unicenta/pos/templates/customer.updated.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('06', 'payment.cash', 0, $FILE{/com/unicenta/pos/templates/payment.cash.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('07', 'Ticket.Buttons', 0, $FILE{/com/unicenta/pos/templates/Ticket.Buttons.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('08', 'Ticket.Close', 0, $FILE{/com/unicenta/pos/templates/Ticket.Close.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('09', 'Ticket.Line', 0, $FILE{/com/unicenta/pos/templates/Ticket.Line.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('10', 'Window.Title', 0, $FILE{/com/unicenta/pos/templates/Window.Title.txt}); + +-- IMAGES +INSERT INTO resources(id, name, restype, content) VALUES('11', 'img.001', 1, $FILE{/com/unicenta/images/.01.png}); +INSERT INTO resources(id, name, restype, content) VALUES('12', 'img.002', 1, $FILE{/com/unicenta/images/.02.png}); +INSERT INTO resources(id, name, restype, content) VALUES('13', 'img.005', 1, $FILE{/com/unicenta/images/.05.png}); +INSERT INTO resources(id, name, restype, content) VALUES('14', 'img.010', 1, $FILE{/com/unicenta/images/.10.png}); +INSERT INTO resources(id, name, restype, content) VALUES('15', 'img.020', 1, $FILE{/com/unicenta/images/.20.png}); +INSERT INTO resources(id, name, restype, content) VALUES('16', 'img.025', 1, $FILE{/com/unicenta/images/.25.png}); +INSERT INTO resources(id, name, restype, content) VALUES('17', 'img.050', 1, $FILE{/com/unicenta/images/.50.png}); +INSERT INTO resources(id, name, restype, content) VALUES('18', 'img.1', 1, $FILE{/com/unicenta/images/1.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('19', 'img.2', 1, $FILE{/com/unicenta/images/2.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('20', 'img.5', 1, $FILE{/com/unicenta/images/5.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('21', 'img.10', 1, $FILE{/com/unicenta/images/10.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('22', 'img.20', 1, $FILE{/com/unicenta/images/20.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('23', 'img.50', 1, $FILE{/com/unicenta/images/50.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('24', 'img.100', 1, $FILE{/com/unicenta/images/100.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('25', 'img.200', 1, $FILE{/com/unicenta/images/200.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('26', 'img.500', 1, $FILE{/com/unicenta/images/500.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('27', 'img.1000', 1, $FILE{/com/unicenta/images/1000.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('28', 'img.cash', 1, $FILE{/com/unicenta/images/cash.png}); +INSERT INTO resources(id, name, restype, content) VALUES('29', 'img.cashdrawer', 1, $FILE{/com/unicenta/images/cashdrawer.png}); +INSERT INTO resources(id, name, restype, content) VALUES('30', 'img.discount', 1, $FILE{/com/unicenta/images/discount.png}); +INSERT INTO resources(id, name, restype, content) VALUES('31', 'img.discount_b', 1, $FILE{/com/unicenta/images/discount_b.png}); +INSERT INTO resources(id, name, restype, content) VALUES('32', 'img.heart', 1, $FILE{/com/unicenta/images/heart.png}); +INSERT INTO resources(id, name, restype, content) VALUES('33', 'img.keyboard_48', 1, $FILE{/com/unicenta/images/keyboard_48.png}); +INSERT INTO resources(id, name, restype, content) VALUES('34', 'img.kit_print', 1, $FILE{/com/unicenta/images/kit_print.png}); +INSERT INTO resources(id, name, restype, content) VALUES('35', 'img.no_photo', 1, $FILE{/com/unicenta/images/no_photo.png}); +INSERT INTO resources(id, name, restype, content) VALUES('36', 'img.refundit', 1, $FILE{/com/unicenta/images/refundit.png}); +INSERT INTO resources(id, name, restype, content) VALUES('37', 'img.run_script', 1, $FILE{/com/unicenta/images/run_script.png}); +INSERT INTO resources(id, name, restype, content) VALUES('38', 'img.ticket_print', 1, $FILE{/com/unicenta/images/ticket_print.png}); +INSERT INTO resources(id, name, restype, content) VALUES('40', 'Printer.Ticket.Logo', 1, $FILE{/com/unicenta/images/printer.ticket.logo.jpg}); + +-- PRINTER +INSERT INTO resources(id, name, restype, content) VALUES('41', 'Printer.CloseCash.Preview', 0, $FILE{/com/unicenta/pos/templates/Printer.CloseCash.Preview.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('42', 'Printer.CloseCash', 0, $FILE{/com/unicenta/pos/templates/Printer.CloseCash.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('43', 'Printer.CustomerPaid', 0, $FILE{/com/unicenta/pos/templates/Printer.CustomerPaid.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('44', 'Printer.CustomerPaid2', 0, $FILE{/com/unicenta/pos/templates/Printer.CustomerPaid2.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('45', 'Printer.FiscalTicket', 0, $FILE{/com/unicenta/pos/templates/Printer.FiscalTicket.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('46', 'Printer.Inventory', 0, $FILE{/com/unicenta/pos/templates/Printer.Inventory.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('47', 'Printer.OpenDrawer', 0, $FILE{/com/unicenta/pos/templates/Printer.OpenDrawer.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('48', 'Printer.PartialCash', 0, $FILE{/com/unicenta/pos/templates/Printer.PartialCash.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('49', 'Printer.PrintLastTicket', 0, $FILE{/com/unicenta/pos/templates/Printer.PrintLastTicket.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('50', 'Printer.Product', 0, $FILE{/com/unicenta/pos/templates/Printer.Product.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('52', 'Printer.ReprintTicket', 0, $FILE{/com/unicenta/pos/templates/Printer.ReprintTicket.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('53', 'Printer.Start', 0, $FILE{/com/unicenta/pos/templates/Printer.Start.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('54', 'Printer.Ticket.P1', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P1.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('55', 'Printer.Ticket.P2', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P2.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('56', 'Printer.Ticket.P3', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P3.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('57', 'Printer.Ticket.P4', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P4.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('58', 'Printer.Ticket.P5', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P5.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('59', 'Printer.Ticket.P6', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P6.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('60', 'Printer.Ticket', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('61', 'Printer.Ticket2', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket2.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('62', 'Printer.TicketClose', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketClose.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('63', 'Printer.TicketLine', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketLine.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('64', 'Printer.TicketNew', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketLine.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('65', 'Printer.TicketPreview', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketPreview.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('66', 'Printer.Ticket_A4', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket_A4.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('67', 'Printer.TicketPreview_A4', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketPreview_A4.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('68', 'Printer.TicketRemote', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketRemote.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('69', 'Printer.TicketTotal', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketTotal.xml}); + +-- SCRIPTS +INSERT INTO resources(id, name, restype, content) VALUES('70', 'script.Keyboard', 0, $FILE{/com/unicenta/pos/templates/script.Keyboard.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('71', 'script.Linediscount', 0, $FILE{/com/unicenta/pos/templates/script.Linediscount.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('72', 'script.SendOrder', 0, $FILE{/com/unicenta/pos/templates/script.SendOrder.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('73', 'script.Totaldiscount', 0, $FILE{/com/unicenta/pos/templates/script.Totaldiscount.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('74', 'script.multibuy', 0, $FILE{/com/unicenta/pos/templates/script.multibuy.txt}); + +-- ADD CATEGORIES +INSERT INTO categories(id, name) VALUES ('000', 'Category Standard'); + +-- ADD TAXCATEGORIES +/* 002 added 31/01/2017 00:00:00. */ +INSERT INTO taxcategories(id, name) VALUES ('000', 'Tax Exempt'); +INSERT INTO taxcategories(id, name) VALUES ('001', 'Tax Standard'); +INSERT INTO taxcategories(id, name) VALUES ('002', 'Tax Other'); + +-- ADD TAXES +/* 002 added 31/01/2017 00:00:00. */ +INSERT INTO taxes(id, name, category, custcategory, parentid, rate, ratecascade, rateorder) VALUES ('000', 'Tax Exempt', '000', NULL, NULL, 0, FALSE, NULL); +INSERT INTO taxes(id, name, category, custcategory, parentid, rate, ratecascade, rateorder) VALUES ('001', 'Tax Standard', '001', NULL, NULL, 0.20, FALSE, NULL); +INSERT INTO taxes(id, name, category, custcategory, parentid, rate, ratecascade, rateorder) VALUES ('002', 'Tax Other', '002', NULL, NULL, 0, FALSE, NULL); + +-- ADD PRODUCTS +INSERT INTO products(id, reference, code, name, category, taxcat, isservice, display, printto) +VALUES ('xxx999_999xxx_x9x9x9', 'xxx999', 'xxx999', 'Free Line entry', '000', '001', 1, '<html><center>Free Line entry', '1'); +INSERT INTO products(id, reference, code, name, category, taxcat, isservice, display, printto) +VALUES ('xxx998_998xxx_x8x8x8', 'xxx998', 'xxx998', 'Service Charge', '000', '001', 1, '<html><center>Service Charge', '1'); + +-- ADD PRODUCTS_CAT +INSERT INTO products_cat(product) VALUES ('xxx999_999xxx_x9x9x9'); +INSERT INTO products_cat(product) VALUES ('xxx998_998xxx_x8x8x8'); + +-- ADD LOCATION +INSERT INTO locations(id, name, address) VALUES ('0','Location 1','Local'); + +-- ADD SUPPLIERS +INSERT INTO suppliers(id, searchkey, name) VALUES ('0','uniCenta','uniCenta'); + +-- ADD UOM +INSERT INTO uom(id, name) VALUES ('0','Each'); + +-- ADD FLOORS +INSERT INTO floors(id, name, image) VALUES ('0', 'Restaurant floor', $FILE{/com/unicenta/images/paperboard960_600.png}); + +-- ADD PLACES +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('1', 'Table 1', 100, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('2', 'Table 2', 250, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('3', 'Table 3', 400, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('4', 'Table 4', 550, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('5', 'Table 5', 700, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('6', 'Table 6', 850, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('7', 'Table 7', 100, 150, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('8', 'Table 8', 250, 150, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('9', 'Table 9', 400, 150, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('10', 'Table 10', 550, 150, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('11', 'Table 11', 700, 150, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('12', 'Table 12', 850, 150, '0', '1', 90, 45); + +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('13', 'Table 13', 100, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('14', 'Table 14', 250, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('15', 'Table 15', 400, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('16', 'Table 16', 550, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('17', 'Table 17', 700, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('18', 'Table 18', 850, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('19', 'Table 19', 100, 350, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('20', 'Table 20', 250, 350, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('21', 'Table 21', 400, 350, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('22', 'Table 22', 550, 350, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('23', 'Table 23', 700, 350, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('24', 'Table 24', 850, 350, '0', '1', 90, 45); + +-- ADD SHIFTS +INSERT INTO shifts(id, startshift, endshift, pplid) VALUES ('0', '2018-01-01 00:00:00.001', '2018-01-01 00:00:00.002','0'); + +-- ADD BREAKS +INSERT INTO breaks(id, name, visible, notes) VALUES ('0', 'Lunch Break', TRUE, NULL); +INSERT INTO breaks(id, name, visible, notes) VALUES ('1', 'Tea Break', TRUE, NULL); +INSERT INTO breaks(id, name, visible, notes) VALUES ('2', 'Mid Break', TRUE, NULL); + +-- ADD SHIFT_BREAKS +INSERT INTO shift_breaks(id, shiftid, breakid, starttime, endtime) VALUES ('0', '0', '0', '2018-01-01 00:00:00.003', '2018-01-01 00:00:00.004'); + +-- ADD SEQUENCES +INSERT INTO pickup_number VALUES(1); +INSERT INTO ticketsnum VALUES(1); +INSERT INTO ticketsnum_refund VALUES(1); +INSERT INTO ticketsnum_payment VALUES(1); + +-- ADD APPLICATION VERSION +INSERT INTO applications(id, name, version) VALUES($APP_ID{}, $APP_NAME{}, $APP_VERSION{}); \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/scripts/MySQL-create_original.sql b/src/main/resources/com/unicenta/pos/scripts/MySQL-create_original.sql new file mode 100644 index 0000000..6166642 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/scripts/MySQL-create_original.sql @@ -0,0 +1,721 @@ +-- uniCenta oPOS - Touch Friendly Point Of Sale +-- Copyright (c) 2009-2017 uniCenta +-- http://sourceforge.net/projects/unicentaopos +-- +-- This file is part of uniCenta oPOS. +-- +-- uniCenta oPOS is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- uniCenta oPOS is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +-- Database create script for MySQL +-- Copyright (c) 2009-2017 uniCenta +-- v4.00 + +CREATE TABLE `applications` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `version` varchar(255) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `roles` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `permissions` mediumblob, + PRIMARY KEY (`id`), + UNIQUE KEY `roles_name_inx` (`name`) +) ENGINE=innodb DEFAULT CHARSET=utf8; +INSERT INTO ROLES(ID, NAME, PERMISSIONS) VALUES('0', 'Administrator role', $FILE{/com/unicenta/pos/templates/Role.Administrator.xml} ); +INSERT INTO ROLES(ID, NAME, PERMISSIONS) VALUES('1', 'Manager role', $FILE{/com/unicenta/pos/templates/Role.Manager.xml} ); +INSERT INTO ROLES(ID, NAME, PERMISSIONS) VALUES('2', 'Employee role', $FILE{/com/unicenta/pos/templates/Role.Employee.xml} ); +INSERT INTO ROLES(ID, NAME, PERMISSIONS) VALUES('3', 'Guest role', $FILE{/com/unicenta/pos/templates/Role.Guest.xml} ); + +CREATE TABLE `people` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `apppassword` varchar(255) DEFAULT NULL, + `card` varchar(255) DEFAULT NULL, + `role` varchar(255) NOT NULL, + `visible` bit(1) NOT NULL, + `image` mediumblob, + PRIMARY KEY (`id`), + UNIQUE KEY `people_name_inx` (`name`), + KEY `people_fk_1` (`role`), + KEY `people_card_inx` (`card`), + CONSTRAINT `people_fk_1` FOREIGN KEY (`role`) REFERENCES `roles` (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; +INSERT INTO PEOPLE(ID, NAME, APPPASSWORD, ROLE, VISIBLE, IMAGE) VALUES ('0', 'Administrator', NULL, '0', TRUE, NULL); +INSERT INTO PEOPLE(ID, NAME, APPPASSWORD, ROLE, VISIBLE, IMAGE) VALUES ('1', 'Manager', NULL, '1', TRUE, NULL); +INSERT INTO PEOPLE(ID, NAME, APPPASSWORD, ROLE, VISIBLE, IMAGE) VALUES ('2', 'Employee', NULL, '2', TRUE, NULL); +INSERT INTO PEOPLE(ID, NAME, APPPASSWORD, ROLE, VISIBLE, IMAGE) VALUES ('3', 'Guest', NULL, '3', TRUE, NULL); + + +CREATE TABLE `resources` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `restype` int(11) NOT NULL, + `content` mediumblob, + PRIMARY KEY (`id`), + UNIQUE KEY `resources_name_inx` (`name`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('0', 'Menu.Root', 0, $FILE{/com/unicenta/pos/templates/Menu.Root.txt}); + +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('1', 'coin.2', 1, $FILE{/com/unicenta/pos/templates/coin.2.png}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('2', 'coin.1', 1, $FILE{/com/unicenta/pos/templates/coin.1.png}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('3', 'coin.50', 1, $FILE{/com/unicenta/pos/templates/coin.50.png}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('4', 'coin.20', 1, $FILE{/com/unicenta/pos/templates/coin.20.png}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('5', 'coin.10', 1, $FILE{/com/unicenta/pos/templates/coin.10.png}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('6', 'coin.05', 1, $FILE{/com/unicenta/pos/templates/coin.05.png}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('7', 'coin.02', 1, $FILE{/com/unicenta/pos/templates/coin.02.png}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('8', 'coin.01', 1, $FILE{/com/unicenta/pos/templates/coin.01.png}); + +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('9', 'img.cash', 1, $FILE{/com/unicenta/pos/templates/img.cash.png}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('10', 'img.cashdrawer', 1, $FILE{/com/unicenta/pos/templates/img.cashdrawer.png}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('11', 'img.discount', 1, $FILE{/com/unicenta/pos/templates/img.discount.png}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('12', 'img.empty', 1, $FILE{/com/unicenta/pos/templates/img.empty.png}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('13', 'img.heart', 1, $FILE{/com/unicenta/pos/templates/img.heart.png}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('14', 'img.no_photo', 1, $FILE{/com/unicenta/pos/templates/img.no_photo.png}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('15', 'img.kit_print', 1, $FILE{/com/unicenta/pos/templates/img.kit_print.png}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('16', 'img.refundit', 1, $FILE{/com/unicenta/pos/templates/img.refundit.png}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('17', 'img.run_script', 1, $FILE{/com/unicenta/pos/templates/img.run_script.png}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('18', 'img.ticket_print', 1, $FILE{/com/unicenta/pos/templates/img.ticket_print.png}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('19', 'img.user', 1, $FILE{/com/unicenta/pos/templates/img.user.png}); + +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('20', 'note.50', 1, $FILE{/com/unicenta/pos/templates/note.50.png}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('21', 'note.20', 1, $FILE{/com/unicenta/pos/templates/note.20.png}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('22', 'note.10', 1, $FILE{/com/unicenta/pos/templates/note.10.png}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('23', 'note.5', 1, $FILE{/com/unicenta/pos/templates/note.5.png}); + +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('24', 'payment.cash', 0, $FILE{/com/unicenta/pos/templates/payment.cash.txt}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('25', 'Printer.CloseCash', 0, $FILE{/com/unicenta/pos/templates/Printer.CloseCash.xml}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('26', 'Printer.CustomerPaid', 0, $FILE{/com/unicenta/pos/templates/Printer.CustomerPaid.xml}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('27', 'Printer.CustomerPaid2', 0, $FILE{/com/unicenta/pos/templates/Printer.CustomerPaid2.xml}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('28', 'Printer.FiscalTicket', 0, $FILE{/com/unicenta/pos/templates/Printer.FiscalTicket.xml}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('29', 'Printer.Inventory', 0, $FILE{/com/unicenta/pos/templates/Printer.Inventory.xml}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('30', 'Printer.OpenDrawer', 0, $FILE{/com/unicenta/pos/templates/Printer.OpenDrawer.xml}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('31', 'Printer.PartialCash', 0, $FILE{/com/unicenta/pos/templates/Printer.PartialCash.xml}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('32', 'Printer.Product', 0, $FILE{/com/unicenta/pos/templates/Printer.Product.xml}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('33', 'Printer.Start', 0, $FILE{/com/unicenta/pos/templates/Printer.Start.xml}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('34', 'Printer.Ticket', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.xml}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('35', 'Printer.Ticket2', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket2.xml}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('36', 'Printer.TicketClose', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketClose.xml}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('37', 'Printer.TicketRemote', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketRemote.xml}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('38', 'Printer.TicketLine', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketLine.xml}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('39', 'Printer.TicketNew', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketLine.xml}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('40', 'Printer.TicketPreview', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketPreview.xml}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('41', 'Printer.TicketTotal', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketTotal.xml}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('42', 'Printer.Ticket.Logo', 1, $FILE{/com/unicenta/pos/templates/printer.ticket.logo.png}); + +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('43', 'script.AddLineNote', 0, $FILE{/com/unicenta/pos/templates/script.AddLineNote.txt}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('44', 'script.Event.Total', 0, $FILE{/com/unicenta/pos/templates/script.Event.Total.txt}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('45', 'script.linediscount', 0, $FILE{/com/unicenta/pos/templates/script.linediscount.txt}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('46', 'script.ReceiptConsolidate', 0, $FILE{/com/unicenta/pos/templates/script.ReceiptConsolidate.txt}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('47', 'script.Refundit', 0, $FILE{/com/unicenta/pos/templates/script.Refundit.txt}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('48', 'script.SendOrder', 0, $FILE{/com/unicenta/pos/templates/script.SendOrder.txt}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('49', 'script.ServiceCharge', 0, $FILE{/com/unicenta/pos/templates/script.script.ServiceCharge.txt}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('50', 'script.SetPerson', 0, $FILE{/com/unicenta/pos/templates/script.SetPerson.txt}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('51', 'script.StockCurrentAdd', 0, $FILE{/com/unicenta/pos/templates/script.StockCurrentAdd.txt}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('52', 'script.StockCurrentSet', 0, $FILE{/com/unicenta/pos/templates/script.StockCurrentSet.txt}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('53', 'script.totaldiscount', 0, $FILE{/com/unicenta/pos/templates/script.totaldiscount.txt}); + +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('54', 'Ticket.Buttons', 0, $FILE{/com/unicenta/pos/templates/Ticket.Buttons.xml}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('55', 'Ticket.Close', 0, $FILE{/com/unicenta/pos/templates/Ticket.Close.xml}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('56', 'Ticket.Discount', 0, $FILE{/com/unicenta/pos/templates/Ticket.Discount.xml}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('57', 'Ticket.Line', 0, $FILE{/com/unicenta/pos/templates/Ticket.Line.xml}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('58', 'Ticket.TicketLineTaxesIncluded', 0, $FILE{/com/unicenta/pos/templates/Ticket.TicketLineTaxesIncluded.xml}); + +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('59', 'Window.Logo', 1, $FILE{/com/unicenta/pos/templates/window.logo.png}); +INSERT INTO RESOURCES(ID, NAME, RESTYPE, CONTENT) VALUES('60', 'Window.Title', 0, $FILE{/com/unicenta/pos/templates/Window.Title.txt}); + +CREATE TABLE `taxcustcategories` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `taxcustcat_name_inx` (`name`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `customers` ( + `id` varchar(255) NOT NULL, + `searchkey` varchar(255) NOT NULL, + `taxid` varchar(255) DEFAULT NULL, + `name` varchar(255) NOT NULL, + `taxcategory` varchar(255) DEFAULT NULL, + `card` varchar(255) DEFAULT NULL, + `maxdebt` double NOT NULL DEFAULT '0', + `address` varchar(255) DEFAULT NULL, + `address2` varchar(255) DEFAULT NULL, + `postal` varchar(255) DEFAULT NULL, + `city` varchar(255) DEFAULT NULL, + `region` varchar(255) DEFAULT NULL, + `country` varchar(255) DEFAULT NULL, + `firstname` varchar(255) DEFAULT NULL, + `lastname` varchar(255) DEFAULT NULL, + `email` varchar(255) DEFAULT NULL, + `phone` varchar(255) DEFAULT NULL, + `phone2` varchar(255) DEFAULT NULL, + `fax` varchar(255) DEFAULT NULL, + `notes` varchar(255) DEFAULT NULL, + `visible` bit(1) NOT NULL DEFAULT b'1', + `curdate` datetime DEFAULT NULL, + `curdebt` double DEFAULT '0', + `image` mediumblob, + PRIMARY KEY (`id`), + UNIQUE KEY `customers_skey_inx` (`searchkey`), + KEY `customers_taxcat` (`taxcategory`), + KEY `customers_taxid_inx` (`taxid`), + KEY `customers_name_inx` (`name`), + KEY `customers_card_inx` (`card`), + CONSTRAINT `customers_taxcat` FOREIGN KEY (`taxcategory`) REFERENCES `taxcustcategories` (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `taxsuppcategories` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `taxsuppcat_name_inx` (`name`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `suppliers` ( + `id` varchar(255) NOT NULL, + `searchkey` varchar(255) NOT NULL, + `taxid` varchar(255) DEFAULT NULL, + `name` varchar(255) NOT NULL, + `taxcategory` varchar(255) DEFAULT NULL, + `card` varchar(255) DEFAULT NULL, + `maxdebt` double NOT NULL DEFAULT '0', + `address` varchar(255) DEFAULT NULL, + `address2` varchar(255) DEFAULT NULL, + `postal` varchar(255) DEFAULT NULL, + `city` varchar(255) DEFAULT NULL, + `region` varchar(255) DEFAULT NULL, + `country` varchar(255) DEFAULT NULL, + `firstname` varchar(255) DEFAULT NULL, + `lastname` varchar(255) DEFAULT NULL, + `email` varchar(255) DEFAULT NULL, + `phone` varchar(255) DEFAULT NULL, + `phone2` varchar(255) DEFAULT NULL, + `fax` varchar(255) DEFAULT NULL, + `notes` varchar(255) DEFAULT NULL, + `visible` bit(1) NOT NULL DEFAULT b'1', + `curdate` datetime DEFAULT NULL, + `curdebt` double DEFAULT '0', + + PRIMARY KEY (`id`), + UNIQUE KEY `suppliers_skey_inx` (`searchkey`), + KEY `suppliers_taxcat` (`taxcategory`), + KEY `suppliers_taxid_inx` (`taxid`), + KEY `suppliers_name_inx` (`name`), + CONSTRAINT `suppliers_taxcat` FOREIGN KEY (`taxcategory`) REFERENCES `taxsuppcategories` (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `categories` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `parentid` varchar(255) DEFAULT NULL, + `image` mediumblob, + `texttip` varchar(255) DEFAULT NULL, + `catshowname` smallint(6) NOT NULL DEFAULT '1', + `catorder` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `categories_name_inx` (`name`), + KEY `categories_fk_1` (`parentid`), + CONSTRAINT `categories_fk_1` FOREIGN KEY (`parentid`) REFERENCES `categories` (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; +INSERT INTO CATEGORIES(ID, NAME) VALUES ('000', 'Category Standard'); + +CREATE TABLE `taxcategories` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `taxcat_name_inx` (`name`) +) ENGINE=innodb DEFAULT CHARSET=utf8; +INSERT INTO TAXCATEGORIES(ID, NAME) VALUES ('000', 'Tax Exempt'); +INSERT INTO TAXCATEGORIES(ID, NAME) VALUES ('001', 'Tax Standard'); + +CREATE TABLE `taxes` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `category` varchar(255) NOT NULL, + `custcategory` varchar(255) DEFAULT NULL, + `parentid` varchar(255) DEFAULT NULL, + `rate` double NOT NULL DEFAULT '0', + `ratecascade` bit(1) NOT NULL DEFAULT b'0', + `rateorder` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `taxes_name_inx` (`name`), + KEY `taxes_cat_fk` (`category`), + KEY `taxes_custcat_fk` (`custcategory`), + KEY `taxes_taxes_fk` (`parentid`), + CONSTRAINT `taxes_cat_fk` FOREIGN KEY (`category`) REFERENCES `taxcategories` (`id`), + CONSTRAINT `taxes_custcat_fk` FOREIGN KEY (`custcategory`) REFERENCES `taxcustcategories` (`id`), + CONSTRAINT `taxes_taxes_fk` FOREIGN KEY (`parentid`) REFERENCES `taxes` (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; +INSERT INTO TAXES(ID, NAME, CATEGORY, CUSTCATEGORY, PARENTID, RATE, RATECASCADE, RATEORDER) VALUES ('000', 'Tax Exempt', '000', NULL, NULL, 0, FALSE, NULL); +INSERT INTO TAXES(ID, NAME, CATEGORY, CUSTCATEGORY, PARENTID, RATE, RATECASCADE, RATEORDER) VALUES ('001', 'Tax Standard', '001', NULL, NULL, 0.20, FALSE, NULL); + +CREATE TABLE `attribute` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `attributevalue` ( + `id` varchar(255) NOT NULL, + `attribute_id` varchar(255) NOT NULL, + `value` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `attval_att` (`attribute_id`), + CONSTRAINT `attval_att` FOREIGN KEY (`attribute_id`) REFERENCES `attribute` (`id`) ON DELETE CASCADE +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `attributeset` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `attributeuse` ( + `id` varchar(255) NOT NULL, + `attributeset_id` varchar(255) NOT NULL, + `attribute_id` varchar(255) NOT NULL, + `lineno` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `attuse_line` (`attributeset_id`,`lineno`), + KEY `attuse_att` (`attribute_id`), + CONSTRAINT `attuse_att` FOREIGN KEY (`attribute_id`) REFERENCES `attribute` (`id`), + CONSTRAINT `attuse_set` FOREIGN KEY (`attributeset_id`) REFERENCES `attributeset` (`id`) ON DELETE CASCADE +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `attributesetinstance` ( + `id` varchar(255) NOT NULL, + `attributeset_id` varchar(255) NOT NULL, + `description` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `attsetinst_set` (`attributeset_id`), + CONSTRAINT `attsetinst_set` FOREIGN KEY (`attributeset_id`) REFERENCES `attributeset` (`id`) ON DELETE CASCADE +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `attributeinstance` ( + `id` varchar(255) NOT NULL, + `attributesetinstance_id` varchar(255) NOT NULL, + `attribute_id` varchar(255) NOT NULL, + `value` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `attinst_set` (`attributesetinstance_id`), + KEY `attinst_att` (`attribute_id`), + CONSTRAINT `attinst_att` FOREIGN KEY (`attribute_id`) REFERENCES `attribute` (`id`), + CONSTRAINT `attinst_set` FOREIGN KEY (`attributesetinstance_id`) REFERENCES `attributesetinstance` (`id`) ON DELETE CASCADE +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `products` ( + `id` varchar(255) NOT NULL, + `reference` varchar(255) NOT NULL, + `code` varchar(255) NOT NULL, + `codetype` varchar(255) DEFAULT NULL, + `name` varchar(255) NOT NULL, + `pricebuy` double NOT NULL DEFAULT '0', + `pricesell` double NOT NULL DEFAULT '0', + `category` varchar(255) NOT NULL, + `taxcat` varchar(255) NOT NULL, + `attributeset_id` varchar(255) DEFAULT NULL, + `stockcost` double DEFAULT NULL, + `stockvolume` double DEFAULT NULL, + `image` mediumblob, + `iscom` bit(1) NOT NULL DEFAULT b'0', + `isscale` bit(1) NOT NULL DEFAULT b'0', + `isconstant` bit(1) NOT NULL DEFAULT b'0', + `printkb` bit(1) NOT NULL DEFAULT b'0', + `sendstatus` bit(1) NOT NULL DEFAULT b'0', + `isservice` bit(1) NOT NULL DEFAULT b'0', + `attributes` mediumblob, + `display` varchar(255) DEFAULT NULL, + `isvprice` smallint(6) NOT NULL DEFAULT '0', + `isverpatrib` smallint(6) NOT NULL DEFAULT '0', + `texttip` varchar(255) DEFAULT NULL, + `warranty` smallint(6) NOT NULL DEFAULT '0', + `stockunits` double NOT NULL DEFAULT '0', + `printto` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `products_inx_0` (`reference`), + UNIQUE KEY `products_inx_1` (`code`), + UNIQUE KEY `products_name_inx` (`name`), + KEY `products_fk_1` (`category`), + KEY `products_taxcat_fk` (`taxcat`), + KEY `products_attrset_fk` (`attributeset_id`), + CONSTRAINT `products_attrset_fk` FOREIGN KEY (`attributeset_id`) REFERENCES `attributeset` (`id`), + CONSTRAINT `products_fk_1` FOREIGN KEY (`category`) REFERENCES `categories` (`id`), + CONSTRAINT `products_taxcat_fk` FOREIGN KEY (`taxcat`) REFERENCES `taxcategories` (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; +INSERT INTO PRODUCTS(ID, REFERENCE, CODE, NAME, CATEGORY, TAXCAT, ISSERVICE) +VALUES ('xxx999_999xxx_x9x9x9', 'xxx999', 'xxx999', '***', '000', '001', 1); +INSERT INTO PRODUCTS(ID, REFERENCE, CODE, NAME, CATEGORY, TAXCAT, ISSERVICE) +VALUES ('xxx998_998xxx_x8x8x8', 'xxx998', 'xxx998', '***', '000', '001', 1); + +CREATE TABLE `products_cat` ( + `product` varchar(255) NOT NULL, + `catorder` int(11) DEFAULT NULL, + PRIMARY KEY (`product`), + KEY `products_cat_inx_1` (`catorder`), + CONSTRAINT `products_cat_fk_1` FOREIGN KEY (`product`) REFERENCES `products` (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; +INSERT INTO PRODUCTS_CAT(PRODUCT) VALUES ('xxx999_999xxx_x9x9x9'); +INSERT INTO PRODUCTS_CAT(PRODUCT) VALUES ('xxx998_998xxx_x8x8x8'); + +CREATE TABLE `products_com` ( + `id` varchar(255) NOT NULL, + `product` varchar(255) NOT NULL, + `product2` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `pcom_inx_prod` (`product`,`product2`), + KEY `products_com_fk_2` (`product2`), + CONSTRAINT `products_com_fk_1` FOREIGN KEY (`product`) REFERENCES `products` (`id`), + CONSTRAINT `products_com_fk_2` FOREIGN KEY (`product2`) REFERENCES `products` (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `locations` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `address` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `locations_name_inx` (`name`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `stockdiary` ( + `id` varchar(255) NOT NULL, + `datenew` datetime NOT NULL, + `reason` int(11) NOT NULL, + `location` varchar(255) NOT NULL, + `product` varchar(255) NOT NULL, + `attributesetinstance_id` varchar(255) DEFAULT NULL, + `units` double NOT NULL, + `price` double NOT NULL, + `appuser` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `stockdiary_fk_1` (`product`), + KEY `stockdiary_attsetinst` (`attributesetinstance_id`), + KEY `stockdiary_fk_2` (`location`), + KEY `stockdiary_inx_1` (`datenew`), + CONSTRAINT `stockdiary_attsetinst` FOREIGN KEY (`attributesetinstance_id`) REFERENCES `attributesetinstance` (`id`), + CONSTRAINT `stockdiary_fk_1` FOREIGN KEY (`product`) REFERENCES `products` (`id`), + CONSTRAINT `stockdiary_fk_2` FOREIGN KEY (`location`) REFERENCES `locations` (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `stocklevel` ( + `id` varchar(255) NOT NULL, + `location` varchar(255) NOT NULL, + `product` varchar(255) NOT NULL, + `stocksecurity` double DEFAULT NULL, + `stockmaximum` double DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `stocklevel_product` (`product`), + KEY `stocklevel_location` (`location`), + CONSTRAINT `stocklevel_location` FOREIGN KEY (`location`) REFERENCES `locations` (`id`), + CONSTRAINT `stocklevel_product` FOREIGN KEY (`product`) REFERENCES `products` (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `stockcurrent` ( + `location` varchar(255) NOT NULL, + `product` varchar(255) NOT NULL, + `attributesetinstance_id` varchar(255) DEFAULT NULL, + `units` double NOT NULL, + UNIQUE KEY `stockcurrent_inx` (`location`,`product`,`attributesetinstance_id`), + KEY `stockcurrent_fk_1` (`product`), + KEY `stockcurrent_attsetinst` (`attributesetinstance_id`), + CONSTRAINT `stockcurrent_attsetinst` FOREIGN KEY (`attributesetinstance_id`) REFERENCES `attributesetinstance` (`id`), + CONSTRAINT `stockcurrent_fk_1` FOREIGN KEY (`product`) REFERENCES `products` (`id`), + CONSTRAINT `stockcurrent_fk_2` FOREIGN KEY (`location`) REFERENCES `locations` (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `closedcash` ( + `money` varchar(255) NOT NULL, + `host` varchar(255) NOT NULL, + `hostsequence` int(11) NOT NULL, + `datestart` datetime NOT NULL, + `dateend` datetime DEFAULT NULL, + `nosales` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`money`), + UNIQUE KEY `closedcash_inx_seq` (`host`,`hostsequence`), + KEY `closedcash_inx_1` (`datestart`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `receipts` ( + `id` varchar(255) NOT NULL, + `money` varchar(255) NOT NULL, + `datenew` datetime NOT NULL, + `attributes` mediumblob, + `person` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `receipts_fk_money` (`money`), + KEY `receipts_inx_1` (`datenew`), + CONSTRAINT `receipts_fk_money` FOREIGN KEY (`money`) REFERENCES `closedcash` (`money`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `tickets` ( + `id` varchar(255) NOT NULL, + `tickettype` int(11) NOT NULL DEFAULT '0', + `ticketid` int(11) NOT NULL, + `person` varchar(255) NOT NULL, + `customer` varchar(255) DEFAULT NULL, + `status` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + KEY `tickets_fk_2` (`person`), + KEY `tickets_customers_fk` (`customer`), + KEY `tickets_ticketid` (`tickettype`,`ticketid`), + CONSTRAINT `tickets_customers_fk` FOREIGN KEY (`customer`) REFERENCES `customers` (`id`), + CONSTRAINT `tickets_fk_2` FOREIGN KEY (`person`) REFERENCES `people` (`id`), + CONSTRAINT `tickets_fk_id` FOREIGN KEY (`id`) REFERENCES `receipts` (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `ticketsnum` ( + `id` int(11) NOT NULL +) ENGINE=innodb DEFAULT CHARSET=utf8; +INSERT INTO TICKETSNUM VALUES(1); + + +CREATE TABLE `ticketsnum_refund` ( + `id` int(11) NOT NULL +) ENGINE=innodb DEFAULT CHARSET=utf8; +INSERT INTO TICKETSNUM_REFUND VALUES(1); + +CREATE TABLE `ticketsnum_payment` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`id`) +) ENGINE=innodb AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +INSERT INTO TICKETSNUM_PAYMENT VALUES (DEFAULT); + +CREATE TABLE `ticketlines` ( + `ticket` varchar(255) NOT NULL, + `line` int(11) NOT NULL, + `product` varchar(255) DEFAULT NULL, + `attributesetinstance_id` varchar(255) DEFAULT NULL, + `units` double NOT NULL, + `price` double NOT NULL, + `taxid` varchar(255) NOT NULL, + `attributes` mediumblob, + PRIMARY KEY (`ticket`,`line`), + KEY `ticketlines_fk_2` (`product`), + KEY `ticketlines_attsetinst` (`attributesetinstance_id`), + KEY `ticketlines_fk_3` (`taxid`), + CONSTRAINT `ticketlines_attsetinst` FOREIGN KEY (`attributesetinstance_id`) REFERENCES `attributesetinstance` (`id`), + CONSTRAINT `ticketlines_fk_2` FOREIGN KEY (`product`) REFERENCES `products` (`id`), + CONSTRAINT `ticketlines_fk_3` FOREIGN KEY (`taxid`) REFERENCES `taxes` (`id`), + CONSTRAINT `ticketlines_fk_ticket` FOREIGN KEY (`ticket`) REFERENCES `tickets` (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `lineremoved` ( + `removeddate` timestamp NOT NULL DEFAULT current_timestamp, + `name` varchar(255) DEFAULT NULL, + `ticketid` varchar(255) DEFAULT NULL, + `productid` varchar(255) DEFAULT NULL, + `productname` varchar(255) DEFAULT NULL, + `units` double NOT NULL +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `payments` ( + `id` varchar(255) NOT NULL, + `receipt` varchar(255) NOT NULL, + `payment` varchar(255) NOT NULL, + `total` double NOT NULL DEFAULT '0', + `tip` double DEFAULT '0', + `transid` varchar(255) DEFAULT NULL, + `isprocessed` bit(1) DEFAULT b'0', + `returnmsg` mediumblob, + `notes` varchar(255) DEFAULT NULL, + `tendered` double DEFAULT NULL, + `cardname` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `payments_fk_receipt` (`receipt`), + KEY `payments_inx_1` (`payment`), + CONSTRAINT `payments_fk_receipt` FOREIGN KEY (`receipt`) REFERENCES `receipts` (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `taxlines` ( + `id` varchar(255) NOT NULL, + `receipt` varchar(255) NOT NULL, + `taxid` varchar(255) NOT NULL, + `base` double NOT NULL DEFAULT '0', + `amount` double NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + KEY `taxlines_tax` (`taxid`), + KEY `taxlines_receipt` (`receipt`), + CONSTRAINT `taxlines_receipt` FOREIGN KEY (`receipt`) REFERENCES `receipts` (`id`), + CONSTRAINT `taxlines_tax` FOREIGN KEY (`taxid`) REFERENCES `taxes` (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `floors` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `image` mediumblob, + PRIMARY KEY (`id`), + UNIQUE KEY `floors_name_inx` (`name`) +) ENGINE=innodb DEFAULT CHARSET=utf8; +INSERT INTO FLOORS(ID, NAME, IMAGE) VALUES ('0', 'Restaurant floor', $FILE{/com/unicenta/pos/templates/restaurant_floor.png}); + +CREATE TABLE `places` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `x` int(11) NOT NULL, + `y` int(11) NOT NULL, + `floor` varchar(255) NOT NULL, + `customer` varchar(255) DEFAULT NULL, + `waiter` varchar(255) DEFAULT NULL, + `ticketid` varchar(255) DEFAULT NULL, + `tablemoved` smallint(6) NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + UNIQUE KEY `places_name_inx` (`name`) +) ENGINE=innodb DEFAULT CHARSET=utf8; +INSERT INTO PLACES(ID, NAME, X, Y, FLOOR) VALUES ('1', 'Table 1', 100, 50, '0'); +INSERT INTO PLACES(ID, NAME, X, Y, FLOOR) VALUES ('2', 'Table 2', 250, 50, '0'); +INSERT INTO PLACES(ID, NAME, X, Y, FLOOR) VALUES ('3', 'Table 3', 400, 50, '0'); +INSERT INTO PLACES(ID, NAME, X, Y, FLOOR) VALUES ('4', 'Table 4', 550, 50, '0'); +INSERT INTO PLACES(ID, NAME, X, Y, FLOOR) VALUES ('5', 'Table 5', 700, 50, '0'); +INSERT INTO PLACES(ID, NAME, X, Y, FLOOR) VALUES ('6', 'Table 6', 850, 50, '0'); +INSERT INTO PLACES(ID, NAME, X, Y, FLOOR) VALUES ('7', 'Table 7', 100, 150, '0'); +INSERT INTO PLACES(ID, NAME, X, Y, FLOOR) VALUES ('8', 'Table 8', 250, 150, '0'); +INSERT INTO PLACES(ID, NAME, X, Y, FLOOR) VALUES ('9', 'Table 9', 400, 150, '0'); +INSERT INTO PLACES(ID, NAME, X, Y, FLOOR) VALUES ('10', 'Table 10', 550, 150, '0'); +INSERT INTO PLACES(ID, NAME, X, Y, FLOOR) VALUES ('11', 'Table 11', 700, 150, '0'); +INSERT INTO PLACES(ID, NAME, X, Y, FLOOR) VALUES ('12', 'Table 12', 850, 150, '0'); + +CREATE TABLE `reservations` ( + `id` varchar(255) NOT NULL, + `created` datetime NOT NULL, + `datenew` datetime NOT NULL DEFAULT '2013-01-01 00:00:00', + `title` varchar(255) NOT NULL, + `chairs` int(11) NOT NULL, + `isdone` bit(1) NOT NULL, + `description` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `reservations_inx_1` (`datenew`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `reservation_customers` ( + `id` varchar(255) NOT NULL, + `customer` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + KEY `res_cust_fk_2` (`customer`), + CONSTRAINT `res_cust_fk_1` FOREIGN KEY (`id`) REFERENCES `reservations` (`id`), + CONSTRAINT `res_cust_fk_2` FOREIGN KEY (`customer`) REFERENCES `customers` (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `thirdparties` ( + `id` varchar(255) NOT NULL, + `cif` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `address` varchar(255) DEFAULT NULL, + `contactcomm` varchar(255) DEFAULT NULL, + `contactfact` varchar(255) DEFAULT NULL, + `payrule` varchar(255) DEFAULT NULL, + `faxnumber` varchar(255) DEFAULT NULL, + `phonenumber` varchar(255) DEFAULT NULL, + `mobilenumber` varchar(255) DEFAULT NULL, + `email` varchar(255) DEFAULT NULL, + `webpage` varchar(255) DEFAULT NULL, + `notes` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `thirdparties_cif_inx` (`cif`), + UNIQUE KEY `thirdparties_name_inx` (`name`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `sharedtickets` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `content` mediumblob, + `appuser` varchar(255) DEFAULT NULL, + `pickupid` int(11) NOT NULL DEFAULT '0', + `locked` varchar(20) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +-- Added for Employee Presence Management +CREATE TABLE `shifts` ( + `id` varchar(255) NOT NULL, + `startshift` datetime NOT NULL, + `endshift` datetime DEFAULT NULL, + `pplid` varchar(255) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; +INSERT INTO SHIFTS(ID, STARTSHIFT, ENDSHIFT, PPLID) VALUES ('0', '2017-01-01 00:00:00.001', '2017-01-01 00:00:00.002','0'); + +CREATE TABLE `leaves` ( + `id` varchar(255) NOT NULL, + `pplid` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `startdate` datetime NOT NULL, + `enddate` datetime NOT NULL, + `notes` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `leaves_pplid` (`pplid`), + CONSTRAINT `leaves_pplid` FOREIGN KEY (`pplid`) REFERENCES `people` (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `breaks` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `visible` tinyint(1) NOT NULL DEFAULT '1', + `notes` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; +INSERT INTO BREAKS(ID, NAME, VISIBLE, NOTES) VALUES ('0', 'Lunch Break', TRUE, NULL); +INSERT INTO BREAKS(ID, NAME, VISIBLE, NOTES) VALUES ('1', 'Tea Break', TRUE, NULL); +INSERT INTO BREAKS(ID, NAME, VISIBLE, NOTES) VALUES ('2', 'Mid Break', TRUE, NULL); + +CREATE TABLE `shift_breaks` ( + `id` varchar(255) NOT NULL, + `shiftid` varchar(255) NOT NULL, + `breakid` varchar(255) NOT NULL, + `starttime` timestamp NOT NULL DEFAULT current_timestamp ON UPDATE current_timestamp, + `endtime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + KEY `shift_breaks_breakid` (`breakid`), + KEY `shift_breaks_shiftid` (`shiftid`), + CONSTRAINT `shift_breaks_breakid` FOREIGN KEY (`breakid`) REFERENCES `breaks` (`id`), + CONSTRAINT `shift_breaks_shiftid` FOREIGN KEY (`shiftid`) REFERENCES `shifts` (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; +INSERT INTO SHIFT_BREAKS(ID, SHIFTID, BREAKID, STARTTIME, ENDTIME) VALUES ('0', '0', '0', '2017-01-01 00:00:00.003', '2017-01-01 00:00:00.004'); + +CREATE TABLE `moorers` ( + `vesselname` varchar(255) DEFAULT NULL, + `size` int(11) DEFAULT NULL, + `days` int(11) DEFAULT NULL, + `power` bit(1) NOT NULL DEFAULT b'0' +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `csvimport` ( + `id` varchar(255) NOT NULL, + `rownumber` varchar(255) DEFAULT NULL, + `csverror` varchar(255) DEFAULT NULL, + `reference` varchar(1024) DEFAULT NULL, + `code` varchar(1024) DEFAULT NULL, + `name` varchar(1024) DEFAULT NULL, + `pricebuy` double DEFAULT NULL, + `pricesell` double DEFAULT NULL, + `previousbuy` double DEFAULT NULL, + `previoussell` double DEFAULT NULL, + `category` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE `pickup_number` ( + `id` int(11) NOT NULL DEFAULT '0' +) ENGINE=innodb DEFAULT CHARSET=utf8; +INSERT INTO PICKUP_NUMBER VALUES(1); + +CREATE TABLE `draweropened` ( + `opendate` timestamp NOT NULL DEFAULT current_timestamp, + `name` varchar(255) DEFAULT NULL, + `ticketid` varchar(255) DEFAULT NULL +) ENGINE=innodb DEFAULT CHARSET=utf8; + +INSERT INTO applications(id, name, version) VALUES($APP_ID{}, $APP_NAME{}, $APP_VERSION{}); \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/scripts/MySQL-dropFKeys.sql b/src/main/resources/com/unicenta/pos/scripts/MySQL-dropFKeys.sql new file mode 100644 index 0000000..f13ba13 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/scripts/MySQL-dropFKeys.sql @@ -0,0 +1,93 @@ +-- uniCenta oPOS - Touch Friendly Point Of Sale +-- Copyright (c) 2009-2017 uniCenta +-- https://unicenta.com +-- +-- This file is part of uniCenta oPOS. +-- +-- uniCenta oPOS is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- uniCenta oPOS is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +/* + * Script created by Jack, uniCenta 07/08/2016 08:00:00 + * Modified 10 Sept 2017 + * Called by Transfer for v4.4 after MySQL-create-transfer.sql +*/ + +set foreign_key_checks = 0; + +alter table people drop foreign key people_fk_1; + +alter table attributeinstance drop foreign key attinst_set; +alter table attributeinstance drop foreign key attinst_att; +alter table attributesetinstance drop foreign key attsetinst_set; +alter table attributeuse drop foreign key attuse_set; +alter table attributeuse drop foreign key attuse_att; +alter table attributevalue drop foreign key attval_att; + +alter table categories drop foreign key categories_fk_1; + +alter table customers drop foreign key customers_taxcat; + +alter table leaves drop foreign key leaves_pplid; + +alter table payments drop foreign key payments_fk_receipt; + +alter table products drop foreign key products_attrset_fk; +alter table products drop foreign key products_taxcat_fk; +alter table products drop foreign key products_fk_1; +alter table products drop index products_inx_0; +alter table products drop index products_inx_1; +alter table products drop index products_name_inx; + +alter table products_bundle drop foreign key products_bundle_fk_1; +alter table products_bundle drop foreign key products_bundle_fk_2; + +alter table products_cat drop foreign key products_cat_fk_1; + +alter table products_com drop foreign key products_com_fk_1; +alter table products_com drop foreign key products_com_fk_2; + +alter table receipts drop foreign key receipts_fk_money; + +alter table reservation_customers drop foreign key res_cust_fk_1; +alter table reservation_customers drop foreign key res_cust_fk_2; + +alter table shift_breaks drop foreign key shift_breaks_breakid; +alter table shift_breaks drop foreign key shift_breaks_shiftid; + +alter table stockcurrent drop foreign key stockcurrent_attsetinst; +alter table stockcurrent drop foreign key stockcurrent_fk_1; +alter table stockcurrent drop foreign key stockcurrent_fk_2; + +alter table stockdiary drop foreign key stockdiary_attsetinst; +alter table stockdiary drop foreign key stockdiary_fk_1; +alter table stockdiary drop foreign key stockdiary_fk_2; + +alter table stocklevel drop foreign key stocklevel_product; +alter table stocklevel drop foreign key stocklevel_location; + +alter table taxes drop foreign key taxes_cat_fk; +alter table taxes drop foreign key taxes_custcat_fk; +alter table taxes drop foreign key taxes_taxes_fk; + +alter table taxlines drop foreign key taxlines_tax; +alter table taxlines drop foreign key taxlines_receipt; + +alter table ticketlines drop foreign key ticketlines_attsetinst; +alter table ticketlines drop foreign key ticketlines_fk_ticket; +alter table ticketlines drop foreign key ticketlines_fk_2; +alter table ticketlines drop foreign key ticketlines_fk_3; + +alter table tickets drop foreign key tickets_customers_fk; +alter table tickets drop foreign key tickets_fk_2; +alter table tickets drop foreign key tickets_fk_id; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/scripts/MySQL-normalise-tables.sql b/src/main/resources/com/unicenta/pos/scripts/MySQL-normalise-tables.sql new file mode 100644 index 0000000..f550f81 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/scripts/MySQL-normalise-tables.sql @@ -0,0 +1,434 @@ +-- uniCenta oPOS - Touch Friendly Point Of Sale +-- Copyright (c) 2009-2017 uniCenta +-- https://unicenta.com +-- +-- This file is part of uniCenta oPOS. +-- +-- uniCenta oPOS is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- uniCenta oPOS is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +/* + * Script created by Jack, uniCenta 28/07/2016 08:00:00 + * + * Database upgrade script for MySQL + * Normalise TABLENAME to tablename + * lowercase is common to all platforms + * Linux default is lowercase whereas windows and Mac accepts UPPER OR lowercase +*/ + +-- +-- CLEAR THE DECKS +-- Need to clear any unsettled sales as properties is serialized and so may not +-- match the formats + +DELETE FROM sharedtickets; + +/* Alter table in target */ +-- ALTER TABLE APPLICATIONS RENAME `applications` , +-- DROP KEY PRIMARY, ADD PRIMARY KEY(`id`) ; +ALTER TABLE APPLICATIONS RENAME `applications_tmp` , + DROP KEY PRIMARY +ALTER TABLE `applications_tmp` RENAME `applications`, + ADD PRIMARY KEY(`id`); + +/* Alter table in target */ +ALTER TABLE ATTRIBUTE RENAME `attribute_tmp` , + DROP KEY `PRIMARY`; +ALTER TABLE `attribute_tmp` RENAME `attribute`, + ADD PRIMARY KEY (`id`); + +/* Alter table in target */ +ALTER TABLE ATTRIBUTEINSTANCE RENAME `attributeinstance_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `ATTINST_ATT` , + DROP KEY `ATTINST_SET` ; +ALTER TABLE `attributeinstance_tmp` RENAME `attributeinstance`, + ADD PRIMARY KEY (`id`), + ADD KEY `attinst_att`(`attribute_id`), + ADD KEY `attinst_set`(`attributesetinstance_id`); + +/* Alter table in target */ +ALTER TABLE ATTRIBUTESET RENAME `attributeset_tmp` , + DROP KEY `PRIMARY`; +ALTER TABLE `attributeset_tmp` RENAME `attributeset` , + ADD PRIMARY KEY(`id`) ; + +/* Alter table in target */ +ALTER TABLE ATTRIBUTESETINSTANCE RENAME `attributesetinstance_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `ATTSETINST_SET` ; +ALTER TABLE `attributesetinstance_tmp` RENAME `attributesetinstance` , + ADD PRIMARY KEY(`id`), + ADD KEY `attsetinst_set`(`attributeset_id`) ; + +/* Alter table in target */ +ALTER TABLE ATTRIBUTEUSE RENAME `attributeuse_tmp` , + DROP KEY `PRIMARY` , + DROP KEY `ATTUSE_ATT` , + DROP KEY `ATTUSE_LINE` ; +ALTER TABLE `attributeuse_tmp` RENAME `attributeuse` , + ADD PRIMARY KEY(`id`), + ADD KEY `attuse_att`(`attribute_id`) , + ADD UNIQUE KEY `attuse_line`(`attributeset_id`,`lineno`) ; + +/* Alter table in target */ +ALTER TABLE ATTRIBUTEVALUE RENAME `attributevalue_tmp` , + DROP KEY `PRIMARY` , + DROP KEY `ATTVAL_ATT` ; +ALTER TABLE `attributevalue_tmp` RENAME `attributevalue` , + ADD PRIMARY KEY(`id`) , + ADD KEY `attval_att`(`attribute_id`) ; + +/* Alter table in target */ +ALTER TABLE BREAKS RENAME `breaks_tmp` , + DROP KEY `PRIMARY` ; +ALTER TABLE `breaks_tmp` RENAME `breaks` , + ADD PRIMARY KEY(`id`) ; + +/* Alter table in target */ +ALTER TABLE CATEGORIES RENAME `categories_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `categories_fk_1` , + DROP KEY `CATEGORIES_NAME_INX` ; +ALTER TABLE `categories_tmp` RENAME `categories` , + ADD PRIMARY KEY(`id`) , + ADD KEY `categories_fk_1`(`parentid`) , + ADD UNIQUE KEY `categories_name_inx`(`name`) ; + +/* Alter table in target */ +ALTER TABLE CLOSEDCASH RENAME `closedcash_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `CLOSEDCASH_INX_1` , + DROP KEY `CLOSEDCASH_INX_SEQ` ; +ALTER TABLE `closedcash_tmp` RENAME `closedcash` , + ADD PRIMARY KEY(`money`) , + ADD KEY `closedcash_inx_1`(`datestart`) , + ADD UNIQUE KEY `closedcash_inx_seq`(`host`,`hostsequence`) ; + +/* Alter table in target */ +ALTER TABLE CSVIMPORT RENAME `csvimport_tmp` , + DROP KEY `PRIMARY` ; +ALTER TABLE `csvimport_tmp` RENAME `csvimport` , + ADD PRIMARY KEY(`id`) ; + +/* Alter table in target */ +ALTER TABLE CUSTOMERS RENAME `customers_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `CUSTOMERS_CARD_INX` , + DROP KEY `CUSTOMERS_NAME_INX` , + DROP KEY `CUSTOMERS_SKEY_INX` , + DROP KEY `CUSTOMERS_TAXCAT` , + DROP KEY `CUSTOMERS_TAXID_INX` ; +ALTER TABLE `customers_tmp` RENAME `customers` , + ADD PRIMARY KEY(`id`) , + ADD KEY `customers_card_inx`(`card`) , + ADD KEY `customers_name_inx`(`name`) , + ADD UNIQUE KEY `customers_skey_inx`(`searchkey`) , + ADD KEY `customers_taxcat`(`taxcategory`) , + ADD KEY `customers_taxid_inx`(`taxid`) ; + +/* Alter table in target */ +ALTER TABLE DRAWEROPENED RENAME `draweropened_tmp` ; +ALTER TABLE `draweropened_tmp` RENAME `draweropened` ; + +/* Alter table in target */ +ALTER TABLE FLOORS RENAME `floors_tmp` , + DROP KEY `PRIMARY` , + DROP KEY `FLOORS_NAME_INX` ; +ALTER TABLE `floors_tmp` RENAME `floors` , + ADD PRIMARY KEY(`id`) , + ADD UNIQUE KEY `floors_name_inx`(`name`) ; + +/* Alter table in target */ +ALTER TABLE LEAVES RENAME `leaves_tmp` , + DROP KEY `PRIMARY` , + DROP KEY `lEAVES_PPLID` ; +ALTER TABLE `leaves_tmp` RENAME `leaves` , + ADD PRIMARY KEY(`id`) , + ADD KEY `leaves_pplid`(`pplid`) ; + + +/* Alter table in target */ +ALTER TABLE LINEREMOVED RENAME `lineremoved_tmp` ; +ALTER TABLE `lineremoved_tmp` RENAME `lineremoved` ; + +/* Alter table in target */ +ALTER TABLE LOCATIONS RENAME `locations_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `LOCATIONS_NAME_INX` ; +ALTER TABLE `locations_tmp` RENAME `locations` , + ADD PRIMARY KEY(`id`) , + ADD UNIQUE KEY `locations_name_inx`(`name`) ; + +/* Alter table in target */ +ALTER TABLE MOORERS RENAME `moorers_tmp` ; +ALTER TABLE `moorers_tmp` RENAME `moorers` ; + +/* Alter table in target */ +ALTER TABLE PAYMENTS RENAME `payments_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `PAYMENTS_FK_RECEIPT` , + DROP KEY `PAYMENTS_INX_1` ; +ALTER TABLE `payments_tmp` RENAME `payments` , + ADD PRIMARY KEY(`id`) , + ADD KEY `payments_fk_receipt`(`receipt`) , + ADD KEY `payments_inx_1`(`payment`) ; + +/* Alter table in target */ +ALTER TABLE PEOPLE RENAME `people_tmp` , + DROP KEY `PRIMARY` , + DROP KEY `PEOPLE_CARD_INX` , + DROP KEY `PEOPLE_FK_1` , + DROP KEY `PEOPLE_NAME_INX` ; +ALTER TABLE `people_tmp` RENAME `people` , + ADD PRIMARY KEY(`id`) , + ADD KEY `people_card_inx`(`card`) , + ADD KEY `people_fk_1`(`role`) , + ADD UNIQUE KEY `people_name_inx`(`name`) ; + +/* Alter table in target */ +ALTER TABLE PLACES RENAME `places_tmp` , + DROP KEY `PRIMARY` , + DROP KEY `PLACES_NAME_INX` ; +ALTER TABLE `places_tmp` RENAME `places` , + ADD PRIMARY KEY(`id`) , + ADD UNIQUE KEY `places_name_inx`(`name`) ; + + +/* Alter table in target */ +ALTER TABLE PRODUCTS RENAME `products_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `PRODUCTS_ATTRSET_FK` , + DROP KEY `PRODUCTS_FK_1` , + DROP KEY `PRODUCTS_INX_0` , + DROP KEY `PRODUCTS_INX_1` , + DROP KEY `PRODUCTS_NAME_INX` , + DROP KEY `PRODUCTS_TAXCAT_FK` ; +ALTER TABLE `products_tmp` RENAME `products` , + ADD PRIMARY KEY(`id`) , + ADD KEY `products_attrset_fx`(`attributeset_id`) , + ADD KEY `products_fk_1`(`category`) , + ADD UNIQUE KEY `products_inx_0`(`reference`) , + ADD UNIQUE KEY `products_inx_1`(`code`) , + ADD KEY `products_name_inx`(`name`) , + ADD KEY `products_taxcat_fk`(`taxcat`) ; + +/* Alter table in target */ +ALTER TABLE PRODUCTS_CAT RENAME `products_cat_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `PRODUCTS_CAT_INX_1` ; +ALTER TABLE `products_cat_tmp` RENAME `products_cat` , + ADD PRIMARY KEY(`product`) , + ADD KEY `products_cat_inx_1`(`catorder`) ; + +/* Alter table in target */ +ALTER TABLE PRODUCTS_COM RENAME `products_com_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `PCOM_INX_PROD` , + DROP KEY `PRODUCTS_COM_FK_2` ; +ALTER TABLE `products_com_tmp` RENAME `products_com` , + ADD PRIMARY KEY(`id`) , + ADD UNIQUE KEY `pcom_inx_prod`(`product`,`product2`) , + ADD KEY `products_com_fk_2`(`product2`) ; + +/* Alter table in target */ +ALTER TABLE RECEIPTS RENAME `receipts_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `RECEIPTS_FK_MONEY` , + DROP KEY `RECEIPTS_INX_1` ; +ALTER TABLE `receipts_tmp` RENAME `receipts` , + ADD PRIMARY KEY(`id`) , + ADD KEY `receipts_fk_money`(`money`) , + ADD KEY `receipts_inx_1`(`datenew`) ; + + +/* Alter table in target */ +ALTER TABLE RESERVATION_CUSTOMERS RENAME `reservation_customers_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `RES_CUST_FK_2` ; +ALTER TABLE `reservation_customers_tmp` RENAME `reservation_customers` , + ADD PRIMARY KEY(`id`) , + ADD KEY `res_cust_fk_2`(`customer`) ; + + +/* Alter table in target */ +ALTER TABLE RESERVATIONS RENAME `reservations_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `RESERVATIONS_INX_1` ; +ALTER TABLE `reservations_tmp` RENAME `reservations` , + ADD PRIMARY KEY(`id`) , + ADD KEY `reservations_inx_1`(`datenew`) ; + +/* Alter table in target */ +ALTER TABLE RESOURCES RENAME `resources_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `RESOURCES_NAME_INX` ; +ALTER TABLE `resources_tmp` RENAME `resources` , + ADD PRIMARY KEY(`id`) , + ADD UNIQUE KEY `resources_name_inx`(`name`) ; + + +/* Alter table in target */ +ALTER TABLE ROLES RENAME `roles_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `ROLES_NAME_INX` ; +ALTER TABLE `roles_tmp` RENAME `roles` , + ADD PRIMARY KEY(`id`) , + ADD UNIQUE KEY `roles_name_inx`(`name`) ; + +/* Alter table in target */ +ALTER TABLE SHAREDTICKETS RENAME `sharedtickets_tmp` , + DROP KEY `PRIMARY` ; +ALTER TABLE `sharedtickets_tmp` RENAME `sharedtickets` , + ADD PRIMARY KEY(`id`) ; + +/* Alter table in target */ +ALTER TABLE SHIFT_BREAKS RENAME `shift_breaks_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `SHIFT_BREAKS_BREAKID` , + DROP KEY `SHIFT_BREAKS_SHIFTID` ; +ALTER TABLE `shift_breaks_tmp` RENAME `shift_breaks` , + ADD PRIMARY KEY(`id`) , + ADD KEY `shift_breaks_breakid`(`breakid`) , + ADD KEY `shift_breaks_shiftid`(`shiftid`) ; + +/* Alter table in target */ +ALTER TABLE SHIFTS RENAME `shifts_tmp` , + DROP KEY `PRIMARY` ; +ALTER TABLE `shifts_tmp` RENAME `shifts` , + ADD PRIMARY KEY(`id`) ; + +/* Alter table in target */ +ALTER TABLE STOCKCURRENT RENAME `stockcurrent_tmp` , +DROP KEY `STOCKCURRENT_ATTSETINST` , +DROP KEY `STOCKCURRENT_FK_1` , +DROP KEY `STOCKCURRENT_INX` ; +ALTER TABLE `stockcurrent_tmp` RENAME `stockcurrent` , +ADD KEY `stockcurrent_attsetinst`(`attributesetinstance_id`) , +ADD KEY `stockcurrent_fk_1`(`product`) , +ADD UNIQUE KEY `stockcurrent_inx`(`location`,`product`,`attributesetinstance_id`) ; + +/* Alter table in target */ +ALTER TABLE STOCKDIARY RENAME `stockdiary_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `STOCKDIARY_ATTSETINST` , + DROP KEY `STOCKDIARY_FK_1` , + DROP KEY `STOCKDIARY_FK_2` , + DROP KEY `STOCKDIARY_INX_1` ; +ALTER TABLE `stockdiary_tmp` RENAME `stockdiary` , + ADD PRIMARY KEY(`id`) , + ADD KEY `stockdiary_fk_1`(`product`) , + ADD KEY `stockdiary_fk_2`(`location`) , + ADD KEY `stockdiary_attsetinst`(`attributesetinstance_id`) , + ADD KEY `stockdiary_inx_1`(`datenew`) ; + + +/* Alter table in target */ +ALTER TABLE STOCKLEVEL RENAME `stocklevel_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `STOCKLEVEL_LOCATION` , + DROP KEY `STOCKLEVEL_PRODUCT` ; +ALTER TABLE `stocklevel_tmp` RENAME `stocklevel` , + ADD PRIMARY KEY(`id`) , + ADD KEY `stocklevel_location`(`location`) , + ADD KEY `stocklevel_product`(`product`) ; + +/* Alter table in target */ +ALTER TABLE TAXCATEGORIES RENAME `taxcategories_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `TAXCAT_NAME_INX` ; +ALTER TABLE `taxcategories_tmp` RENAME `taxcategories` , + ADD PRIMARY KEY(`id`) , + ADD UNIQUE KEY `taxcat_name_inx`(`name`) ; + +/* Alter table in target */ +ALTER TABLE TAXCUSTCATEGORIES RENAME `taxcustcategories_tmp` , + DROP KEY `PRIMARY`, +DROP KEY `TAXCUSTCAT_NAME_INX` ; +ALTER TABLE `taxcustcategories_tmp` RENAME `taxcustcategories` , + ADD PRIMARY KEY(`id`) , + ADD UNIQUE KEY `taxcustcat_name_inx`(`name`) ; + +/* Alter table in target */ +ALTER TABLE TAXES RENAME `taxes_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `TAXES_CAT_FK` , + DROP KEY `TAXES_CUSTCAT_FK` , + DROP KEY `TAXES_NAME_INX` , + DROP KEY `TAXES_TAXES_FK` ; +ALTER TABLE `taxes_tmp` RENAME `taxes` , + ADD PRIMARY KEY(`id`) , + ADD KEY `taxes_cat_fk`(`category`) , + ADD KEY `taxes_custcat_fk`(`custcategory`) , + ADD UNIQUE KEY `taxes_name_inx`(`name`) , + ADD KEY `taxes_taxes_fk`(`parentid`) ; + + +/* Alter table in target */ +ALTER TABLE TAXLINES RENAME `taxlines_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `TAXLINES_RECEIPT` , + DROP KEY `TAXLINES_TAX` ; +ALTER TABLE `taxlines_tmp` RENAME `taxlines` , + ADD PRIMARY KEY(`id`) , + ADD KEY `taxlines_receipt`(`receipt`) , + ADD KEY `taxlines_tax`(`taxid`) ; + + +/* Alter table in target */ +ALTER TABLE THIRDPARTIES RENAME `thirdparties_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `THIRDPARTIES_CIF_INX` , + DROP KEY `THIRDPARTIES_NAME_INX` ; +ALTER TABLE `thirdparties_tmp` RENAME `thirdparties` , + ADD PRIMARY KEY(`id`) , + ADD UNIQUE KEY `thirdparties_cif_inx`(`cif`) , + ADD UNIQUE KEY `thirdparties_name_inx`(`name`) ; + + +/* Alter table in target */ +ALTER TABLE TICKETLINES RENAME `ticketlines_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `TICKETLINES_ATTSETINST` , + DROP KEY `TICKETLINES_FK_2` , + DROP KEY `TICKETLINES_FK_3` ; +ALTER TABLE `ticketlines_tmp` RENAME `ticketlines` , + ADD PRIMARY KEY(`ticket`,`line`) , + ADD KEY `ticketlines_attsetinst`(`attributesetinstance_id`) , + ADD KEY `ticketlines_fk_2`(`product`) , + ADD KEY `ticketlines_fk_3`(`taxid`) ; + +/* Alter table in target */ +ALTER TABLE TICKETS RENAME `tickets_tmp` , + DROP KEY `PRIMARY`, + DROP KEY `tickets_CUSTOMERS_FK` , + DROP KEY `tickets_FK_2` , + DROP KEY `tickets_TICKETID` ; +ALTER TABLE `tickets_tmp` RENAME `tickets` , + ADD PRIMARY KEY(`id`) , + ADD KEY `tickets_customers_fk`(`customer`) , + ADD KEY `tickets_fk_2`(`person`) , + ADD KEY `tickets_ticketid`(`tickettype`,`ticketid`) ; + + +/* Alter table in target */ +ALTER TABLE TICKETSNUM RENAME `ticketsnum_tmp` ; +ALTER TABLE `ticketsnum_tmp` RENAME `ticketsnum` ; + +ALTER TABLE TICKETSNUM_PAYMENT RENAME `ticketsnum_payment_tmp` , + DROP KEY `PRIMARY` ; +ALTER TABLE `ticketsnum_payment_tmp` RENAME `ticketsnum_payment` , + ADD PRIMARY KEY(`id`) ; + +ALTER TABLE TICKETSNUM_REFUND RENAME `ticketsnum_refund_tmp` ; +ALTER TABLE `ticketsnum_refund_tmp` RENAME `ticketsnum_refund` ; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/scripts/MySQL-orders-table.sql b/src/main/resources/com/unicenta/pos/scripts/MySQL-orders-table.sql new file mode 100644 index 0000000..15e67d6 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/scripts/MySQL-orders-table.sql @@ -0,0 +1,35 @@ +-- uniCenta oPOS is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- uniCenta oPOS is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +/* + * Script created by Jack, uniCenta 20/11/2016 08:00:00 + * + * Create ORDERS table for Remote Display +*/ + +/* Header line. Object: orders. Script date: 01/01/2017 00:00:01. */ +CREATE TABLE IF NOT EXISTS `orders` ( + `id` int(11) NOT NULL, + `orderid` varchar(50) DEFAULT NULL, + `qty` int(11) DEFAULT '1', + `details` varchar(255) DEFAULT NULL, + `attributes` varchar(255) DEFAULT NULL, + `notes` varchar(255) DEFAULT NULL, + `ticketid` varchar(50) DEFAULT NULL, + `ordertime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `displayid` int(11) DEFAULT '1', + `auxiliary` int(11) DEFAULT NULL, + `completetime` timestamp, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + diff --git a/src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade-4.5.1.sql b/src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade-4.5.1.sql new file mode 100644 index 0000000..d55c033 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade-4.5.1.sql @@ -0,0 +1,45 @@ +-- uniCenta oPOS - Touch Friendly Point Of Sale +-- Copyright (c) 2009-2018 uniCenta +-- https://unicenta.com +-- +-- This file is part of uniCenta oPOS. +-- +-- uniCenta oPOS is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- uniCenta oPOS is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +-- Database upgrade script for MySQL +-- v4.5.1 - v4.5.2 17FEB2018 + +-- +-- CLEAR THE DECKS +-- +DELETE FROM sharedtickets; + +-- RECREATE applications -- +DROP TABLE `applications`; +CREATE TABLE IF NOT EXISTS `applications` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `version` varchar(255) NOT NULL, + `instdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +set foreign_key_checks = 0; + +DELETE FROM roles WHERE id = '0'; +INSERT INTO roles(id, name, permissions) VALUES('0', 'Administrator role', $FILE{/com/unicenta/pos/templates/Role.Administrator.xml} ); + +set foreign_key_checks = 1; + +INSERT INTO applications(id, name, version) VALUES($APP_ID{}, $APP_NAME{}, $APP_VERSION{}); \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade-4.5.2.sql b/src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade-4.5.2.sql new file mode 100644 index 0000000..df8581d --- /dev/null +++ b/src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade-4.5.2.sql @@ -0,0 +1,38 @@ +-- uniCenta oPOS - Touch Friendly Point Of Sale +-- Copyright (c) 2009-2018 uniCenta +-- https://unicenta.com +-- +-- This file is part of uniCenta oPOS. +-- +-- uniCenta oPOS is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- uniCenta oPOS is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +-- Database upgrade script for MySQL +-- v4.5.2 - v4.5.3 3MAR2018 + +-- +-- CLEAR THE DECKS +-- +DELETE FROM sharedtickets; + +-- RECREATE applications -- +DROP TABLE `applications`; +CREATE TABLE IF NOT EXISTS `applications` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `version` varchar(255) NOT NULL, + `instdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +INSERT INTO applications(id, name, version) VALUES($APP_ID{}, $APP_NAME{}, $APP_VERSION{}); \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade-4.5.3.sql b/src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade-4.5.3.sql new file mode 100644 index 0000000..3ca4f64 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade-4.5.3.sql @@ -0,0 +1,38 @@ +-- uniCenta oPOS - Touch Friendly Point Of Sale +-- Copyright (c) 2009-2018 uniCenta +-- https://unicenta.com +-- +-- This file is part of uniCenta oPOS. +-- +-- uniCenta oPOS is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- uniCenta oPOS is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +-- Database upgrade script for MySQL +-- v4.5.3 - v4.5.4 9MAY2018 + +-- +-- CLEAR THE DECKS +-- +DELETE FROM sharedtickets; + +-- RECREATE applications -- +DROP TABLE `applications`; +CREATE TABLE IF NOT EXISTS `applications` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `version` varchar(255) NOT NULL, + `instdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +INSERT INTO applications(id, name, version) VALUES($APP_ID{}, $APP_NAME{}, $APP_VERSION{}); \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade-4.5.4.sql b/src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade-4.5.4.sql new file mode 100644 index 0000000..594c851 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade-4.5.4.sql @@ -0,0 +1,54 @@ +-- uniCenta oPOS - Touch Friendly Point Of Sale +-- Copyright (c) 2009-2018 uniCenta +-- https://unicenta.com +-- +-- This file is part of uniCenta oPOS. +-- +-- uniCenta oPOS is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- uniCenta oPOS is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +-- Database upgrade script for MySQL +-- v4.5 - v4.5.5 3JUNE2018 + +-- +-- CLEAR THE DECKS +-- +DELETE FROM sharedtickets; + +set foreign_key_checks = 0; + +-- RECREATE applications -- +DROP TABLE `applications`; +CREATE TABLE IF NOT EXISTS `applications` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `version` varchar(255) NOT NULL, + `instdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +-- SYSTEM +DELETE FROM resources WHERE id = '00'; +INSERT INTO resources(id, name, restype, content) VALUES('00', 'Menu.Root', 0, $FILE{/com/unicenta/pos/templates/Menu.Root.txt}); + +-- COMMONS +DELETE FROM roles WHERE id = '0'; +INSERT INTO roles(id, name, permissions) VALUES('0', 'Administrator role', $FILE{/com/unicenta/pos/templates/Role.Administrator.xml} ); +DELETE FROM roles WHERE id = '1'; +INSERT INTO roles(id, name, permissions) VALUES('1', 'Manager role', $FILE{/com/unicenta/pos/templates/Role.Manager.xml} ); +DELETE FROM roles WHERE id = '2'; +INSERT INTO roles(id, name, permissions) VALUES('2', 'Employee role', $FILE{/com/unicenta/pos/templates/Role.Employee.xml} ); + +set foreign_key_checks = 1; + +INSERT INTO applications(id, name, version) VALUES($APP_ID{}, $APP_NAME{}, $APP_VERSION{}); \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade-4.5.sql b/src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade-4.5.sql new file mode 100644 index 0000000..5e970f8 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade-4.5.sql @@ -0,0 +1,48 @@ +-- uniCenta oPOS - Touch Friendly Point Of Sale +-- Copyright (c) 2009-2018 uniCenta +-- https://unicenta.com +-- +-- This file is part of uniCenta oPOS. +-- +-- uniCenta oPOS is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- uniCenta oPOS is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +-- Database upgrade script for MySQL +-- v4.5 - v4.5.1 27JAN2018 + +-- +-- CLEAR THE DECKS +-- +DELETE FROM sharedtickets; + +set foreign_key_checks = 0; + +-- RECREATE applications -- +DROP TABLE `applications`; +CREATE TABLE IF NOT EXISTS `applications` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `version` varchar(255) NOT NULL, + `instdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + +-- VERSIONS + +-- COMMONS +DELETE FROM roles WHERE id = '0'; +INSERT INTO roles(id, name, permissions) VALUES('0', 'Administrator role', $FILE{/com/unicenta/pos/templates/Role.Administrator.xml} ); + +set foreign_key_checks = 1; + +INSERT INTO applications(id, name, version) VALUES($APP_ID{}, $APP_NAME{}, $APP_VERSION{}); \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade_master.sql b/src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade_master.sql new file mode 100644 index 0000000..b9be8c6 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/scripts/MySQL-upgrade_master.sql @@ -0,0 +1,62 @@ +-- CLEAR THE DECKS +DELETE FROM sharedtickets; + +-- Switch OFF table foreign key relationships +set foreign_key_checks = 0; + +-- RECREATE applications table +DROP TABLE `applications`; +CREATE TABLE IF NOT EXISTS `applications` ( + `id` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `version` varchar(255) NOT NULL, + `instdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY ( `id` ) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact; + + +-- SYSTEM +DELETE FROM resources WHERE name = 'script.posapps'; + + +DELETE FROM resources WHERE id = '0'; +DELETE FROM resources WHERE id = '00'; +INSERT INTO resources(id, name, restype, content) VALUES('00', 'Menu.Root', 0, $FILE{/com/unicenta/pos/templates/Menu.Root.txt}); + +UPDATE resources SET content = $FILE{/com/unicenta/pos/templates/Ticket.Buttons.xml} WHERE name = 'Ticket.Buttons'; +COMMIT; + +UPDATE resources SET content = $FILE{/com/unicenta/pos/templates/Printer.Ticket.xml} WHERE name = 'Printer.Ticket'; +COMMIT; + +UPDATE resources SET content = $FILE{/com/unicenta/pos/templates/Ticket.Close.xml} WHERE name = 'Ticket.Close'; +COMMIT; + +UPDATE resources SET content = $FILE{/com/unicenta/pos/templates/Cash.Close.xml} WHERE name = 'Cash.Close'; +COMMIT; + +UPDATE resources SET content = $FILE{/com/unicenta/pos/templates/customer.created.xml} WHERE name = 'Customer.Created'; +COMMIT; + +UPDATE resources SET content = $FILE{/com/unicenta/pos/templates/customer.deleted.xml} WHERE name = 'Customer.Deleted'; +COMMIT; + +UPDATE resources SET content = $FILE{/com/unicenta/pos/templates/customer.updated.xml} WHERE name = 'Customer.Updated'; +COMMIT; + + +-- ROLES +DELETE FROM roles WHERE id = '0'; +INSERT INTO roles(id, name, permissions) VALUES('0', 'Administrator role', $FILE{/com/unicenta/pos/templates/Role.Administrator.xml} ); +DELETE FROM roles WHERE id = '1'; +INSERT INTO roles(id, name, permissions) VALUES('1', 'Manager role', $FILE{/com/unicenta/pos/templates/Role.Manager.xml} ); +DELETE FROM roles WHERE id = '2'; +INSERT INTO roles(id, name, permissions) VALUES('2', 'Employee role', $FILE{/com/unicenta/pos/templates/Role.Employee.xml} ); + + +-- Switch ON table foreign key relationships +set foreign_key_checks = 1; + +INSERT INTO applications(id, name, version) VALUES($APP_ID{}, $APP_NAME{}, $APP_VERSION{}); + +COMMIT; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/scripts/PostgreSQL-create.sql b/src/main/resources/com/unicenta/pos/scripts/PostgreSQL-create.sql new file mode 100644 index 0000000..625c440 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/scripts/PostgreSQL-create.sql @@ -0,0 +1,746 @@ +-- uniCenta oPOS - Touch Friendly Point Of Sale +-- Copyright (C) 2009-2017 uniCenta +-- http://sourceforge.net/projects/unicentaopos +-- +-- This file is part of uniCenta oPOS. +-- +-- uniCenta oPOS is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- uniCenta oPOS is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +-- Database create script for PostgreSQL +-- v4.1.4 + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE applications ( + id VARCHAR NOT NULL, + name VARCHAR NOT NULL, + version VARCHAR NOT NULL, + PRIMARY KEY (id) +); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE roles ( + id VARCHAR NOT NULL, + name VARCHAR NOT NULL, + permissions BYTEA, + PRIMARY KEY (id) +); +CREATE UNIQUE INDEX ROLES_NAME_INX ON roles(name); +INSERT INTO ROLES(id, name, permissions) VALUES('0', 'Administrator role', $FILE{/com/unicenta/pos/templates/Role.Administrator.xml} ); +INSERT INTO ROLES(id, name, permissions) VALUES('1', 'Manager role', $FILE{/com/unicenta/pos/templates/Role.Manager.xml} ); +INSERT INTO ROLES(id, name, permissions) VALUES('2', 'Employee role', $FILE{/com/unicenta/pos/templates/Role.Employee.xml} ); +INSERT INTO ROLES(id, name, permissions) VALUES('3', 'Guest role', $FILE{/com/unicenta/pos/templates/Role.Guest.xml} ); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE people ( + id VARCHAR NOT NULL, + name VARCHAR NOT NULL, + apppassword VARCHAR, + card VARCHAR, + role VARCHAR NOT NULL, + visible BOOLEAN NOT NULL, + image BYTEA, + PRIMARY KEY (id), + CONSTRAINT PEOPLE_FK_1 FOREIGN KEY (ROLE) REFERENCES roles(id) +); +CREATE UNIQUE INDEX PEOPLE_NAME_INX ON people(name); +CREATE INDEX PEOPLE_CARD_INX ON people(card); +INSERT INTO people(id, name, apppassword, role, visible, image) VALUES ('0', 'Administrator', NULL, '0', TRUE, NULL); +INSERT INTO people(id, name, apppassword, role, visible, image) VALUES ('1', 'Manager', NULL, '1', TRUE, NULL); +INSERT INTO people(id, name, apppassword, role, visible, image) VALUES ('2', 'Employee', NULL, '2', TRUE, NULL); +INSERT INTO people(id, name, apppassword, role, visible, image) VALUES ('3', 'Guest', NULL, '3', TRUE, NULL); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE resources ( + id VARCHAR NOT NULL, + name VARCHAR NOT NULL, + restype INTEGER NOT NULL, + content BYTEA, + PRIMARY KEY (id) +); +CREATE UNIQUE INDEX RESOURCES_NAME_INX ON resources(name); + +-- ADD resources -- +-- MENU +INSERT INTO resources(id, name, restype, content) VALUES('0', 'Menu.Root', 0, $FILE{/com/unicenta/pos/templates/Menu.Root.txt}); + +-- IMAGES +INSERT INTO resources(id, name, restype, content) VALUES('1', 'coin.01', 1, $FILE{/com/unicenta/pos/templates/coin.01.png}); +INSERT INTO resources(id, name, restype, content) VALUES('2', 'coin.02', 1, $FILE{/com/unicenta/pos/templates/coin.02.png}); +INSERT INTO resources(id, name, restype, content) VALUES('3', 'coin.05', 1, $FILE{/com/unicenta/pos/templates/coin.05.png}); +INSERT INTO resources(id, name, restype, content) VALUES('4', 'coin.1', 1, $FILE{/com/unicenta/pos/templates/coin.1.png}); +INSERT INTO resources(id, name, restype, content) VALUES('5', 'coin.10', 1, $FILE{/com/unicenta/pos/templates/coin.10.png}); +INSERT INTO resources(id, name, restype, content) VALUES('6', 'coin.2', 1, $FILE{/com/unicenta/pos/templates/coin.2.png}); +INSERT INTO resources(id, name, restype, content) VALUES('7', 'coin.20', 1, $FILE{/com/unicenta/pos/templates/coin.20.png}); +INSERT INTO resources(id, name, restype, content) VALUES('8', 'coin.50', 1, $FILE{/com/unicenta/pos/templates/coin.50.png}); +INSERT INTO resources(id, name, restype, content) VALUES('9', 'img.cash', 1, $FILE{/com/unicenta/pos/templates/img.cash.png}); +INSERT INTO resources(id, name, restype, content) VALUES('10', 'img.cashdrawer', 1, $FILE{/com/unicenta/pos/templates/img.cashdrawer.png}); +INSERT INTO resources(id, name, restype, content) VALUES('11', 'img.discount', 1, $FILE{/com/unicenta/pos/templates/img.discount.png}); +INSERT INTO resources(id, name, restype, content) VALUES('12', 'img.discount_b', 1, $FILE{/com/unicenta/pos/templates/img.discount_b.png}); +INSERT INTO resources(id, name, restype, content) VALUES('13', 'img.empty', 1, $FILE{/com/unicenta/pos/templates/img.empty.png}); +INSERT INTO resources(id, name, restype, content) VALUES('14', 'img.heart', 1, $FILE{/com/unicenta/pos/templates/img.heart.png}); +INSERT INTO resources(id, name, restype, content) VALUES('15', 'img.keyboard_32', 1, $FILE{/com/unicenta/pos/templates/img.keyboard_32.png}); +INSERT INTO resources(id, name, restype, content) VALUES('16', 'img.kit_print', 1, $FILE{/com/unicenta/pos/templates/img.kit_print.png}); +INSERT INTO resources(id, name, restype, content) VALUES('17', 'img.no_photo', 1, $FILE{/com/unicenta/pos/templates/img.no_photo.png}); +INSERT INTO resources(id, name, restype, content) VALUES('18', 'img.refundit', 1, $FILE{/com/unicenta/pos/templates/img.refundit.png}); +INSERT INTO resources(id, name, restype, content) VALUES('19', 'img.run_script', 1, $FILE{/com/unicenta/pos/templates/img.run_script.png}); +INSERT INTO resources(id, name, restype, content) VALUES('20', 'img.ticket_print', 1, $FILE{/com/unicenta/pos/templates/img.ticket_print.png}); +INSERT INTO resources(id, name, restype, content) VALUES('21', 'img.user', 1, $FILE{/com/unicenta/pos/templates/img.user.png}); +INSERT INTO resources(id, name, restype, content) VALUES('22', 'note.50', 1, $FILE{/com/unicenta/pos/templates/note.50.png}); +INSERT INTO resources(id, name, restype, content) VALUES('23', 'note.20', 1, $FILE{/com/unicenta/pos/templates/note.20.png}); +INSERT INTO resources(id, name, restype, content) VALUES('24', 'note.10', 1, $FILE{/com/unicenta/pos/templates/note.10.png}); +INSERT INTO resources(id, name, restype, content) VALUES('25', 'note.5', 1, $FILE{/com/unicenta/pos/templates/note.5.png}); + +-- PRINTER +INSERT INTO resources(id, name, restype, content) VALUES('26', 'Printer.CloseCash.Preview', 0, $FILE{/com/unicenta/pos/templates/Printer.CloseCash.Preview.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('27', 'Printer.CloseCash', 0, $FILE{/com/unicenta/pos/templates/Printer.CloseCash.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('28', 'Printer.CustomerPaid', 0, $FILE{/com/unicenta/pos/templates/Printer.CustomerPaid.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('29', 'Printer.CustomerPaid2', 0, $FILE{/com/unicenta/pos/templates/Printer.CustomerPaid2.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('30', 'Printer.FiscalTicket', 0, $FILE{/com/unicenta/pos/templates/Printer.FiscalTicket.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('31', 'Printer.Inventory', 0, $FILE{/com/unicenta/pos/templates/Printer.Inventory.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('32', 'Printer.OpenDrawer', 0, $FILE{/com/unicenta/pos/templates/Printer.OpenDrawer.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('33', 'Printer.PartialCash', 0, $FILE{/com/unicenta/pos/templates/Printer.PartialCash.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('34', 'Printer.PrintLastTicket', 0, $FILE{/com/unicenta/pos/templates/Printer.PrintLastTicket.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('35', 'Printer.Product', 0, $FILE{/com/unicenta/pos/templates/Printer.Product.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('36', 'Printer.ReprintTicket', 0, $FILE{/com/unicenta/pos/templates/Printer.ReprintTicket.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('37', 'Printer.Start', 0, $FILE{/com/unicenta/pos/templates/Printer.Start.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('38', 'Printer.Ticket.P1', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P1.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('39', 'Printer.Ticket.P2', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P2.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('40', 'Printer.Ticket.P3', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P3.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('41', 'Printer.Ticket.P4', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P4.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('42', 'Printer.Ticket.P5', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P5.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('43', 'Printer.Ticket.P6', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P6.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('44', 'Printer.Ticket', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('45', 'Printer.Ticket2', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket2.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('46', 'Printer.TicketClose', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketClose.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('47', 'Printer.TicketRemote', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketRemote.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('48', 'Printer.TicketLine', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketLine.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('49', 'Printer.TicketNew', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketLine.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('50', 'Printer.TicketPreview', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketPreview.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('51', 'Printer.TicketTotal', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketTotal.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('52', 'Printer.Ticket.Logo', 1, $FILE{/com/unicenta/pos/templates/printer.ticket.logo.png}); + +-- SCRIPTS +INSERT INTO resources(id, name, restype, content) VALUES('53', 'script.AddLineNote', 0, $FILE{/com/unicenta/pos/templates/script.AddLineNote.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('54', 'script.Event.Total', 0, $FILE{/com/unicenta/pos/templates/script.Event.Total.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('55', 'script.Keyboard', 0, $FILE{/com/unicenta/pos/templates/script.Keyboard.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('56', 'script.linediscount', 0, $FILE{/com/unicenta/pos/templates/script.linediscount.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('57', 'script.ReceiptConsolidate', 0, $FILE{/com/unicenta/pos/templates/script.ReceiptConsolidate.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('58', 'script.Refundit', 0, $FILE{/com/unicenta/pos/templates/script.Refundit.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('59', 'script.SendOrder', 0, $FILE{/com/unicenta/pos/templates/script.SendOrder.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('60', 'script.ServiceCharge', 0, $FILE{/com/unicenta/pos/templates/script.script.ServiceCharge.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('61', 'script.SetPerson', 0, $FILE{/com/unicenta/pos/templates/script.SetPerson.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('62', 'script.StockCurrentAdd', 0, $FILE{/com/unicenta/pos/templates/script.StockCurrentAdd.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('63', 'script.StockCurrentSet', 0, $FILE{/com/unicenta/pos/templates/script.StockCurrentSet.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('64', 'script.totaldiscount', 0, $FILE{/com/unicenta/pos/templates/script.totaldiscount.txt}); + +-- SYSTEM +INSERT INTO resources(id, name, restype, content) VALUES('65', 'payment.cash', 0, $FILE{/com/unicenta/pos/templates/payment.cash.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('66', 'ticket.addline', 0, $FILE{/com/unicenta/pos/templates/ticket.addline.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('67', 'ticket.change', 0, $FILE{/com/unicenta/pos/templates/ticket.change.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('68', 'Ticket.Buttons', 0, $FILE{/com/unicenta/pos/templates/Ticket.Buttons.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('69', 'Ticket.Close', 0, $FILE{/com/unicenta/pos/templates/Ticket.Close.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('70', 'Ticket.Discount', 0, $FILE{/com/unicenta/pos/templates/Ticket.Discount.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('71', 'Ticket.Line', 0, $FILE{/com/unicenta/pos/templates/Ticket.Line.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('72', 'ticket.removeline', 0, $FILE{/com/unicenta/pos/templates/ticket.removeline.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('73', 'ticket.setline', 0, $FILE{/com/unicenta/pos/templates/ticket.setline.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('74', 'Ticket.TicketLineTaxesIncluded', 0, $FILE{/com/unicenta/pos/templates/Ticket.TicketLineTaxesIncluded.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('75', 'Window.Logo', 1, $FILE{/com/unicenta/pos/templates/window.logo.png}); +INSERT INTO resources(id, name, restype, content) VALUES('76', 'Window.Title', 0, $FILE{/com/unicenta/pos/templates/Window.Title.txt}); + + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE taxcustcategories ( + id VARCHAR NOT NULL, + name VARCHAR NOT NULL, + PRIMARY KEY (id) +); +CREATE UNIQUE INDEX TAXCUSTCAT_NAME_INX ON taxcustcategories(name); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE CUSTOMERS ( + id varchar NOT NULL, + searchkey varchar NOT NULL, + taxid varchar default NULL, + name varchar NOT NULL, + taxcategory varchar default NULL, + card varchar default NULL, + maxdebt double precision default 0 NOT NULL, + address varchar default NULL, + address2 varchar default NULL, + postal varchar default NULL, + city varchar default NULL, + region varchar default NULL, + country varchar default NULL, + firstname varchar default NULL, + lastname varchar default NULL, + email varchar default NULL, + phone varchar default NULL, + phone2 varchar default NULL, + fax varchar default NULL, + notes varchar default NULL, + visible BOOLEAN NOT NULL DEFAULT TRUE, + curdate timestamp default NULL, + curdebt double precision default 0, + image bytea, + isvip BOOLEAN NOT NULL DEFAULT TRUE, + discount double precision default 0 NOT NULL, + PRIMARY KEY (id), + CONSTRAINT CUSTOMERS_TAXCAT FOREIGN KEY (taxcategory) REFERENCES taxcustcategories(id) +); +CREATE UNIQUE INDEX CUSTOMERS_SKEY_INX ON customers(searchkey); +CREATE INDEX CUSTOMERS_TAXID_INX ON customers(taxid); +CREATE INDEX CUSTOMERS_NAME_INX ON customers(name); +CREATE INDEX CUSTOMERS_CARD_INX ON customers(card); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE categories ( + id VARCHAR NOT NULL, + name VARCHAR NOT NULL, + parentid VARCHAR, + image BYTEA, + texttip VARCHAR DEFAULT NULL, + catshowname BOOLEAN NOT NULL DEFAULT TRUE, + catorder varchar default NULL, + PRIMARY KEY (id), + CONSTRAINT categories_fk_1 FOREIGN KEY (parentid) REFERENCES categories(id) +); +CREATE UNIQUE INDEX CATEGORIES_NAME_INX ON categories(name); +INSERT INTO categories(id, name) VALUES ('000', 'Category Standard'); +INSERT INTO categories(id, name) VALUES ('xxx999', '***'); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE taxcategories ( + id varchar NOT NULL, + name varchar NOT NULL, + PRIMARY KEY ( id ) +); +CREATE UNIQUE INDEX TAXCAT_NAME_INX ON taxcategories(name); +INSERT INTO taxcategories(id, name) VALUES ('000', 'Tax Exempt'); +INSERT INTO taxcategories(id, name) VALUES ('001', 'Tax Standard'); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE taxes ( + id varchar NOT NULL, + name varchar NOT NULL, + category varchar NOT NULL, + custcategory varchar default NULL, + parentid varchar default NULL, + rate double precision default 0 NOT NULL, + ratecascade BOOLEAN NOT NULL DEFAULT FALSE, + rateorder integer default NULL, + PRIMARY KEY (id), + CONSTRAINT TAXES_CAT_FK FOREIGN KEY (category) REFERENCES taxcategories(id), + CONSTRAINT TAXES_CUSTCAT_FK FOREIGN KEY (custcategory) REFERENCES taxcustcategories(id), + CONSTRAINT TAXES_TAXES_FK FOREIGN KEY (parentid) REFERENCES taxes(id) +); +CREATE UNIQUE INDEX TAXES_NAME_INX ON taxes(name); +INSERT INTO TAXES(id, name, category, custcategory, parentid, rate, ratecascade, rateorder) VALUES ('000', 'Tax Exempt', '000', NULL, NULL, 0, false, NULL); +INSERT INTO TAXES(id, name, category, custcategory, parentid, rate, ratecascade, rateorder) VALUES ('001', 'Tax Standard', '001', NULL, NULL, 0.10, false, NULL); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE attribute ( + id VARCHAR NOT NULL, + name VARCHAR NOT NULL, + PRIMARY KEY (id) +); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE attributevalue ( + id VARCHAR NOT NULL, + attribute_id VARCHAR NOT NULL, + value VARCHAR, + PRIMARY KEY (id), + CONSTRAINT attval_att FOREIGN KEY (attribute_id) REFERENCES attribute(id) ON DELETE CASCADE +); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE attributeset ( + id VARCHAR NOT NULL, + name VARCHAR NOT NULL, + PRIMARY KEY (id) +); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE attributeuse ( + id VARCHAR NOT NULL, + attributeset_id VARCHAR NOT NULL, + attribute_id VARCHAR NOT NULL, + lineno INTEGER, + PRIMARY KEY (id), + CONSTRAINT attuse_set FOREIGN KEY (attributeset_id) REFERENCES attributeset(id) ON DELETE CASCADE, + CONSTRAINT attuse_att FOREIGN KEY (attribute_id) REFERENCES attribute(id) +); +CREATE UNIQUE INDEX attuse_line ON attributeuse(attributeset_id, lineno); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE attributesetinstance ( + id VARCHAR NOT NULL, + attributeset_ID VARCHAR NOT NULL, + description VARCHAR, + PRIMARY KEY (id), + CONSTRAINT attsetinst_set FOREIGN KEY (attributeset_id) REFERENCES attributeset(id) ON DELETE CASCADE +); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE attributeinstance ( + id VARCHAR NOT NULL, + attributesetinstance_id VARCHAR NOT NULL, + attribute_id VARCHAR NOT NULL, + value VARCHAR, + PRIMARY KEY (id), + constraint attinst_set foreign key (attributesetinstance_id) references attributesetinstance(id) on delete cascade, + constraint attinst_att foreign key (attribute_id) references attribute(id) +); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE products ( + id varchar NOT NULL, + reference varchar NOT NULL, + code varchar NOT NULL, + codetype varchar default NULL, + name varchar NOT NULL, + pricebuy double precision default 0 NOT NULL, + pricesell double precision default 0 NOT NULL, + category varchar NOT NULL, + taxcat varchar NOT NULL, + attributeset_id varchar default NULL, + stockcost double precision default 0 NOT NULL, + stockvolume double precision default 0 NOT NULL, + image bytea default NULL, + iscom BOOLEAN NOT NULL DEFAULT FALSE, + isscale BOOLEAN NOT NULL DEFAULT FALSE, + isconstant BOOLEAN NOT NULL DEFAULT FALSE, + printkb BOOLEAN NOT NULL DEFAULT FALSE, + sendstatus BOOLEAN NOT NULL DEFAULT FALSE, + isservice BOOLEAN NOT NULL DEFAULT FALSE, + attributes bytea default NULL, + display varchar default NULL, + isvprice BOOLEAN NOT NULL DEFAULT FALSE, + isverpatrib BOOLEAN NOT NULL DEFAULT FALSE, + texttip varchar default NULL, + warranty BOOLEAN NOT NULL DEFAULT FALSE, + stockunits double precision default 0 NOT NULL, + printto varchar default '1', + supplier varchar default NULL, + uom varchar default '0', + PRIMARY KEY (ID), + CONSTRAINT PRODUCTS_FK_1 FOREIGN KEY (category) REFERENCES categories(id), + CONSTRAINT PRODUCTS_TAXCAT_FK FOREIGN KEY (taxcat) REFERENCES taxcategories(id), + CONSTRAINT PRODUCTS_ATTRSET_FK FOREIGN KEY (attributeset_id) REFERENCES attributeset(id) +); +CREATE UNIQUE INDEX PRODUCTS_INX_0 ON products(reference); +CREATE UNIQUE INDEX PRODUCTS_INX_1 ON products(code); +CREATE INDEX PRODUCTS_NAME_INX ON products(name); + +-- ADD PRODUCTS +INSERT INTO products(id, reference, code, name, category, taxcat, isservice, display, printto) +VALUES ('xxx999_999xxx_x9x9x9', 'xxx999', 'xxx999', '***', '000', '001', false, '<html><center>***', '1'); +INSERT INTO products(id, reference, code, name, category, taxcat, isservice, display, printto) +VALUES ('xxx998_998xxx_x8x8x8', 'xxx998', 'xxx998', '****', '000', '001', true, '<html><center>****', '1'); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE products_cat ( + product VARCHAR NOT NULL, + catorder INTEGER, + PRIMARY KEY (product), + CONSTRAINT PRODUCTS_CAT_FK_1 FOREIGN KEY (product) REFERENCES products(id) +); +CREATE INDEX PRODUCTS_CAT_INX_1 ON products_cat(catorder); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE products_com ( + id VARCHAR NOT NULL, + product VARCHAR NOT NULL, + product2 VARCHAR NOT NULL, + PRIMARY KEY (id), + CONSTRAINT PRODUCTS_COM_FK_1 FOREIGN KEY (product) REFERENCES products(id), + CONSTRAINT PRODUCTS_COM_FK_2 FOREIGN KEY (product2) REFERENCES products(id) +); +CREATE UNIQUE INDEX PCOM_INX_PROD ON products_com(product, product2); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE locations ( + id VARCHAR NOT NULL, + name VARCHAR NOT NULL, + address VARCHAR, + PRIMARY KEY (id) +); +CREATE UNIQUE INDEX LOCATIONS_NAME_INX ON locations(name); +INSERT INTO locations(id, name, address) VALUES('0', 'General', NULL); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE stockdiary ( + id varchar NOT NULL, + datenew timestamp NOT NULL, + reason integer NOT NULL, + location varchar NOT NULL, + product varchar NOT NULL, + attributesetinstance_id varchar, + units double precision default 0 NOT NULL, + price double precision default 0 NOT NULL, + appuser varchar, + supplier varchar default NULL, + supplierdoc varchar default NULL, + PRIMARY KEY (id), + CONSTRAINT STOCKDIARY_FK_1 FOREIGN KEY (product) REFERENCES products(id), + CONSTRAINT STOCKDIARY_ATTSETINST FOREIGN KEY (attributesetinstance_id) REFERENCES attributesetinstance(id), + CONSTRAINT STOCKDIARY_FK_2 FOREIGN KEY (location) REFERENCES locations(id) +); +CREATE INDEX STOCKDIARY_INX_1 ON stockdiary(datenew); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE stocklevel ( + id varchar NOT NULL, + location varchar NOT NULL, + product varchar NOT NULL, + stocksecurity double precision default 0 NOT NULL, + stockmaximum double precision default 0 NOT NULL, + PRIMARY KEY (id), + CONSTRAINT STOCKLEVEL_PRODUCT FOREIGN KEY (product) REFERENCES products(id), + CONSTRAINT STOCKLEVEL_LOCATION FOREIGN KEY (location) REFERENCES locations(id) +); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE stockcurrent ( + location varchar NOT NULL, + product varchar NOT NULL, + attributesetinstance_id varchar default NULL, + units double precision default 0 NOT NULL, + CONSTRAINT STOCKCURRENT_FK_1 FOREIGN KEY (product) REFERENCES products(id), + CONSTRAINT STOCKCURRENT_ATTSETINST FOREIGN KEY (attributesetinstance_id) REFERENCES attributesetinstance(id), + CONSTRAINT STOCKCURRENT_FK_2 FOREIGN KEY (location) REFERENCES locations(id) +); +CREATE UNIQUE INDEX STOCKCURRENT_INX ON stockcurrent(location, product, attributesetinstance_id); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE closedcash ( + money varchar NOT NULL, + host varchar NOT NULL, + hostsequence INTEGER NOT NULL, + datestart TIMESTAMP NOT NULL, + dateend TIMESTAMP, + nosales INTEGER DEFAULT 0 NOT NULL, + PRIMARY KEY(money) +); +CREATE INDEX CLOSEDCASH_INX_1 ON closedcash(datestart); +CREATE UNIQUE INDEX CLOSEDCASH_INX_SEQ ON closedcash(host, hostsequence); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE RECEIPTS ( + id VARCHAR NOT NULL, + MONEY VARCHAR NOT NULL, + datenew TIMESTAMP NOT NULL, + attributes BYTEA, + person VARCHAR, + PRIMARY KEY (id), +CONSTRAINT RECEIPTS_FK_MONEY FOREIGN KEY (money) REFERENCES closedcash(money) +); +CREATE INDEX RECEIPTS_INX_1 ON receipts(datenew); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE tickets ( + id VARCHAR NOT NULL, + tickettype INTEGER DEFAULT 0 NOT NULL, + ticketid INTEGER NOT NULL, + person VARCHAR NOT NULL, + customer VARCHAR DEFAULT NULL, + status INTEGER DEFAULT 0 NOT NULL, + PRIMARY KEY (id), + CONSTRAINT TICKETS_FK_ID FOREIGN KEY (id) REFERENCES receipts(id), + CONSTRAINT TICKETS_FK_2 FOREIGN KEY (PERSON) REFERENCES people(id), + CONSTRAINT TICKETS_CUSTOMERS_FK FOREIGN KEY (customer) REFERENCES customers(id) +); +CREATE INDEX TICKETS_TICKETID ON tickets(tickettype, ticketid); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE ticketlines ( + ticket VARCHAR NOT NULL, + line INTEGER NOT NULL, + product VARCHAR, + attributesetinstance_id VARCHAR, + units double precision default 0 NOT NULL, + price double precision default 0 NOT NULL, + taxid VARCHAR NOT NULL, + attributes BYTEA, + PRIMARY KEY (ticket, line), + CONSTRAINT TICKETLINES_FK_TICKET FOREIGN KEY (ticket) REFERENCES tickets(id), + CONSTRAINT TICKETLINES_FK_2 FOREIGN KEY (product) REFERENCES products(id), + CONSTRAINT TICKETLINES_ATTSETINST FOREIGN KEY (attributesetinstance_id) REFERENCES attributesetinstance(id), + CONSTRAINT TICKETLINES_FK_3 FOREIGN KEY (taxid) REFERENCES taxes(id) +); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ + CREATE TABLE lineremoved ( + removeddate TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + name VARCHAR DEFAULT NULL, + ticketid VARCHAR DEFAULT NULL, + productid VARCHAR DEFAULT NULL, + productname VARCHAR DEFAULT NULL, + units double precision default 0 NOT NULL +); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE payments ( + id varchar NOT NULL, + receipt varchar NOT NULL, + payment varchar NOT NULL, + total double precision default 0 NOT NULL, + tip double precision default 0 NOT NULL, + transid varchar default NULL, + isprocessed BOOLEAN NOT NULL DEFAULT FALSE, + returnmsg bytea default NULL, + notes varchar default NULL, + tendered double precision default 0 NOT NULL, + cardname varchar default NULL, + voucher varchar default NULL, + PRIMARY KEY (id), + CONSTRAINT PAYMENTS_FK_RECEIPT FOREIGN KEY (receipt) REFERENCES receipts(id) +); +CREATE INDEX PAYMENTS_INX_1 ON payments(payment); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE taxlines ( + id VARCHAR NOT NULL, + receipt VARCHAR NOT NULL, + taxid VARCHAR NOT NULL, + base double precision default 0 NOT NULL, + amount double precision default 0 NOT NULL, + PRIMARY KEY (id), + CONSTRAINT TAXLINES_TAX FOREIGN KEY (taxid) REFERENCES taxes(id), + CONSTRAINT TAXLINES_RECEIPT FOREIGN KEY (receipt) REFERENCES receipts(id) +); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE floors ( + id VARCHAR NOT NULL, + name VARCHAR NOT NULL, + image BYTEA, + PRIMARY KEY (id) +); +CREATE UNIQUE INDEX FLOORS_NAME_INX ON floors(name); +INSERT INTO floors(id, name, image) VALUES ('0', 'Restaurant floor', $FILE{/com/unicenta/pos/templates/restaurant_floor.png}); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE places ( + id VARCHAR NOT NULL, + name VARCHAR NOT NULL, + x INTEGER NOT NULL, + y INTEGER NOT NULL, + floor VARCHAR NOT NULL, + customer VARCHAR, + waiter VARCHAR, + ticketid VARCHAR, + tablemoved BOOLEAN NOT NULL DEFAULT FALSE, + PRIMARY KEY (id), + CONSTRAINT PLACES_FK_1 FOREIGN KEY (floor) REFERENCES floors(id) +); +CREATE UNIQUE INDEX PLACES_NAME_INX ON places(name); +INSERT INTO places(id, name, x, y, floor) VALUES ('1', 'Table 1', 80, 70, '0'); +INSERT INTO places(id, name, x, y, floor) VALUES ('2', 'Table 2', 250, 75, '0'); +INSERT INTO places(id, name, x, y, floor) VALUES ('3', 'Table 3', 400, 75, '0'); +INSERT INTO places(id, name, x, y, floor) VALUES ('4', 'Table 4', 80, 200, '0'); +INSERT INTO places(id, name, x, y, floor) VALUES ('5', 'Table 5', 260, 210, '0'); +INSERT INTO places(id, name, x, y, floor) VALUES ('6', 'Table 6', 430, 210, '0'); +INSERT INTO places(id, name, x, y, floor) VALUES ('7', 'Table 7', 80, 330, '0'); +INSERT INTO places(id, name, x, y, floor) VALUES ('8', 'Table 8', 190, 350, '0'); +INSERT INTO places(id, name, x, y, floor) VALUES ('9', 'Table 9', 295, 350, '0'); +INSERT INTO places(id, name, x, y, floor) VALUES ('10', 'Table 10', 430, 345, '0'); +INSERT INTO places(id, name, x, y, floor) VALUES ('11', 'Table 11', 550, 135, '0'); +INSERT INTO places(id, name, x, y, floor) VALUES ('12', 'Table 12', 550, 290, '0'); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE reservations ( + id VARCHAR NOT NULL, + created TIMESTAMP NOT NULL, + datenew TIMESTAMP DEFAULT '2016-01-01 00:00:00' NOT NULL, + title VARCHAR NOT NULL, + chairs INTEGER NOT NULL, + isdone BOOLEAN NOT NULL, + description VARCHAR, + PRIMARY KEY (id) +); +CREATE INDEX RESERVATIONS_INX_1 ON reservations(datenew); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE reservation_customers ( + id VARCHAR NOT NULL, + customer VARCHAR NOT NULL, + PRIMARY KEY (id), + CONSTRAINT RES_CUST_FK_1 FOREIGN KEY (id) REFERENCES reservations(id), + CONSTRAINT RES_CUST_FK_2 FOREIGN KEY (customer) REFERENCES customers(id) +); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE thirdparties ( + id VARCHAR NOT NULL, + cif VARCHAR NOT NULL, + name VARCHAR NOT NULL, + address VARCHAR, + concatcomm VARCHAR, + contactfact VARCHAR, + payrule VARCHAR, + faxnumber VARCHAR, + phonenumber VARCHAR, + mobilenumber VARCHAR, + email VARCHAR, + webpage VARCHAR, + notes VARCHAR, + PRIMARY KEY (id) +); +CREATE UNIQUE INDEX THIRDPARTIES_CIF_INX ON thirdparties(cif); +CREATE UNIQUE INDEX THIRDPARTIES_NAME_INX ON thirdparties(name); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE sharedtickets ( + id varchar NOT NULL, + name varchar NOT NULL, + content bytea default NULL, + appuser varchar default NULL, + pickupid integer NOT NULL default '0', + locked varchar default NULL, + PRIMARY KEY (id) +); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE shifts ( + id VARCHAR NOT NULL, + startshift TIMESTAMP NOT NULL, + endshift TIMESTAMP, + pplid VARCHAR NOT NULL, + PRIMARY KEY (id) +); +INSERT INTO shifts(id, startshift, endshift, pplid) VALUES ('0', '2016-01-01 00:00:00.001', '2016-01-01 00:00:00.002','0'); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE leaves ( + id VARCHAR NOT NULL, + pplid VARCHAR NOT NULL, + name VARCHAR NOT NULL, + startdate TIMESTAMP NOT NULL, + enddate TIMESTAMP NOT NULL, + notes VARCHAR, + PRIMARY KEY (ID), + CONSTRAINT lEAVES_PPLID FOREIGN KEY (pplid) REFERENCES people(id) +); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE breaks ( + id VARCHAR NOT NULL, + name VARCHAR NOT NULL, + notes VARCHAR, + visible BOOLEAN NOT NULL, + PRIMARY KEY (id) +); +INSERT INTO breaks(id, name, visible, notes) VALUES ('0', 'Lunch Break', TRUE, NULL); +INSERT INTO breaks(id, name, visible, notes) VALUES ('1', 'Tea Break', TRUE, NULL); +INSERT INTO breaks(id, name, visible, notes) VALUES ('2', 'Mid Break', TRUE, NULL); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE shift_breaks ( + id VARCHAR NOT NULL, + shiftid VARCHAR NOT NULL, + breakid VARCHAR NOT NULL, + starttime TIMESTAMP NOT NULL, + endtime TIMESTAMP, + PRIMARY KEY (id), + CONSTRAINT SHIFT_BREAKS_BREAKID FOREIGN KEY (breakid) REFERENCES breaks(id), + CONSTRAINT SHIFT_BREAKS_SHIFTID FOREIGN KEY (shiftid) REFERENCES shifts(id) +); +INSERT INTO shift_breaks(id, shiftid, breakid, starttime, endtime) VALUES ('0', '0', '0', '2016-01-01 00:00:00.003', '2016-01-01 00:00:00.004'); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE moorers ( + vesselname VARCHAR, + size INTEGER, + days INTEGER, + power BOOLEAN NOT NULL DEFAULT FALSE +); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE csvimport ( + id VARCHAR NOT NULL, + rownumber VARCHAR, + csverror VARCHAR, + reference VARCHAR, + code VARCHAR, + name VARCHAR, + pricebuy double precision, + pricesell double precision, + previousbuy double precision, + previoussell double precision, + category VARCHAR, + tax VARCHAR, + searchkey VARCHAR, + PRIMARY KEY (ID) +); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE suppliers ( + id varchar NOT NULL, + searchkey varchar NOT NULL, + taxid varchar default NULL, + name varchar NOT NULL, + maxdebt double precision default 0 NOT NULL, + address varchar default NULL, + address2 varchar default NULL, + postal varchar default NULL, + city varchar default NULL, + region varchar default NULL, + country varchar default NULL, + firstname varchar default NULL, + lastname varchar default NULL, + email varchar default NULL, + phone varchar default NULL, + phone2 varchar default NULL, + fax varchar default NULL, + notes varchar default NULL, + visible BOOLEAN NOT NULL DEFAULT TRUE, + curdate timestamp default NULL, + curdebt double precision default 0, + vatid varchar default NULL, + PRIMARY KEY ( id ) +); +CREATE UNIQUE INDEX SUPPLIERS_SKEY_INX ON suppliers(searchkey); +CREATE INDEX SUPPLIERS_NAME_INX ON suppliers(name); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE uom ( + id VARCHAR NOT NULL, + name VARCHAR NOT NULL, + PRIMARY KEY ( id ) +); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE TABLE vouchers ( + id VARCHAR NOT NULL, + voucher_number VARCHAR DEFAULT NULL, + customer VARCHAR DEFAULT NULL, + amount double precision default 0 NOT NULL, + status CHAR(1) DEFAULT 'A', + PRIMARY KEY ( id ) +); + +/* Header line. Object: vouchers. Script date: 08/05/2016 18:00:00. */ +CREATE SEQUENCE ticketsnum START WITH 1; +CREATE SEQUENCE ticketsnum_refund START WITH 1; +CREATE SEQUENCE ticketsnum_payment START WITH 1; +CREATE SEQUENCE pickup_number START WITH 1; + +CREATE TABLE draweropened ( + opendate TIMESTAMP DEFAULT NOW(), + name VARCHAR, + ticketid VARCHAR +); + +INSERT INTO applications(id, name, version) VALUES($APP_ID{}, $APP_NAME{}, $APP_VERSION{}); \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/scripts/SQLite-create.sql b/src/main/resources/com/unicenta/pos/scripts/SQLite-create.sql new file mode 100644 index 0000000..b27f019 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/scripts/SQLite-create.sql @@ -0,0 +1,699 @@ + +CREATE TABLE applications ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + version varchar(255) NOT NULL, + instdate timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP , + PRIMARY KEY (id) +); + +CREATE TABLE attribute ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE attributeinstance ( + id varchar(255) NOT NULL, + attributesetinstance_id varchar(255) NOT NULL, + attribute_id varchar(255) NOT NULL, + value varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE attributeset ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE attributesetinstance ( + id varchar(255) NOT NULL, + attributeset_id varchar(255) NOT NULL, + description varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE attributeuse ( + id varchar(255) NOT NULL, + attributeset_id varchar(255) NOT NULL, + attribute_id varchar(255) NOT NULL, + lineno int(11) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE attributevalue ( + id varchar(255) NOT NULL, + attribute_id varchar(255) NOT NULL, + value varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE breaks ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + visible tinyint(1) NOT NULL default 1 , + notes varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE categories ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + parentid varchar(255) default NULL, + image mediumblob default NULL, + texttip varchar(255) default NULL, + catshowname smallint(6) NOT NULL default 1 , + catorder varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE closedcash ( + money varchar(255) NOT NULL, + host varchar(255) NOT NULL, + hostsequence int(11) NOT NULL, + datestart datetime NOT NULL, + dateend datetime default NULL, + nosales int(11) NOT NULL default 0 , + PRIMARY KEY (money) +); + +CREATE TABLE csvimport ( + id varchar(255) NOT NULL, + rownumber varchar(255) default NULL, + csverror varchar(255) default NULL, + reference varchar(255) default NULL, + code varchar(255) default NULL, + name varchar(255) default NULL, + pricebuy double default NULL, + pricesell double default NULL, + previousbuy double default NULL, + previoussell double default NULL, + category varchar(255) default NULL, + tax varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE customers ( + id varchar(255) NOT NULL, + searchkey varchar(255) NOT NULL, + taxid varchar(255) default NULL, + name varchar(255) NOT NULL, + taxcategory varchar(255) default NULL, + card varchar(255) default NULL, + maxdebt double NOT NULL default 0 , + address varchar(255) default NULL, + address2 varchar(255) default NULL, + postal varchar(255) default NULL, + city varchar(255) default NULL, + region varchar(255) default NULL, + country varchar(255) default NULL, + firstname varchar(255) default NULL, + lastname varchar(255) default NULL, + email varchar(255) default NULL, + phone varchar(255) default NULL, + phone2 varchar(255) default NULL, + fax varchar(255) default NULL, + notes varchar(255) default NULL, + visible int(1) NOT NULL default 1 , + curdate datetime default NULL, + curdebt double default 0 , + image mediumblob default NULL, + isvip int(1) NOT NULL default 0 , + discount double default 0 , + memodate datetime default CURRENT_TIMESTAMP , + PRIMARY KEY (id) +); + +CREATE TABLE draweropened ( + opendate timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP , + name varchar(255) default NULL, + ticketid varchar(255) default NULL +); + +CREATE TABLE floors ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + image mediumblob default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE leaves ( + id varchar(255) NOT NULL, + pplid varchar(255) NOT NULL, + name varchar(255) NOT NULL, + startdate datetime NOT NULL, + enddate datetime NOT NULL, + notes varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE lineremoved ( + removeddate timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP , + name varchar(255) default NULL, + ticketid varchar(255) default NULL, + productid varchar(255) default NULL, + productname varchar(255) default NULL, + units double NOT NULL +); + +CREATE TABLE locations ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + address varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE moorers ( + vesselname varchar(255) default NULL, + size int(11) default NULL, + days int(11) default NULL, + power int(1) NOT NULL default 0 +); + +CREATE TABLE IF NOT EXISTS orders ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + orderid varchar(50) DEFAULT NULL, + qty int(11) DEFAULT 1 , + details varchar(255) DEFAULT NULL, + attributes varchar(255) DEFAULT NULL, + notes varchar(255) DEFAULT NULL, + ticketid varchar(50) DEFAULT NULL, + ordertime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP , + displayid int(11) DEFAULT 1 , + auxiliary int(11) DEFAULT NULL, + completetime timestamp NULL +); + +CREATE TABLE payments ( + id varchar(255) NOT NULL, + receipt varchar(255) NOT NULL, + payment varchar(255) NOT NULL, + total double NOT NULL default 0 , + tip double default 0 , + transid varchar(255) default NULL, + isprocessed int(1) default 0 , + returnmsg mediumblob default NULL, + notes varchar(255) default NULL, + tendered double default NULL, + cardname varchar(255) default NULL, + voucher varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE people ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + apppassword varchar(255) default NULL, + card varchar(255) default NULL, + role varchar(255) NOT NULL, + visible int(1) NOT NULL, + image mediumblob default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE pickup_number ( + id int(11) NOT NULL default 0 +); + +CREATE TABLE places ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + seats varchar(6) NOT NULL DEFAULT 1 , + x int(11) NOT NULL, + y int(11) NOT NULL, + floor varchar(255) NOT NULL, + customer varchar(255) default NULL, + waiter varchar(255) default NULL, + ticketid varchar(255) default NULL, + tablemoved smallint(6) NOT NULL default 0 , + width int(11) NOT NULL, + height int(11) NOT NULL, + guests int(11) DEFAULT 0, + occupied datetime DEFAULT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE products ( + id varchar(255) NOT NULL, + reference varchar(255) NOT NULL, + code varchar(255) NOT NULL, + codetype varchar(255) default NULL, + name varchar(255) NOT NULL, + pricebuy double NOT NULL default 0 , + pricesell double NOT NULL default 0 , + category varchar(255) NOT NULL, + taxcat varchar(255) NOT NULL, + attributeset_id varchar(255) default NULL, + stockcost double NOT NULL default 0 , + stockvolume double NOT NULL default 0 , + image mediumblob default NULL, + iscom int(1) NOT NULL default 0 , + isscale int(1) NOT NULL default 0 , + isconstant smallint(1) NOT NULL default 0 , + printkb int(1) NOT NULL default 0 , + sendstatus int(1) NOT NULL default 0 , + isservice int(1) NOT NULL default 0 , + attributes mediumblob default NULL, + display varchar(255) default NULL, + isvprice smallint(6) NOT NULL default 0 , + isverpatrib smallint(6) NOT NULL default 0 , + texttip varchar(255) default NULL, + warranty smallint(6) NOT NULL default 0 , + stockunits double NOT NULL default 0 , + printto varchar(255) default 1 , + supplier varchar(255) default NULL, + uom varchar(255) default 0 , + memodate datetime default '2018-01-01 00:00:01' , + PRIMARY KEY (id) +); + +CREATE TABLE products_bundle ( + id varchar(255) NOT NULL, + product VARCHAR(255) NOT NULL, + product_bundle VARCHAR(255) NOT NULL, + quantity DOUBLE NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE products_cat ( + product varchar(255) NOT NULL, + catorder int(11) default NULL, + PRIMARY KEY (product) +); + +CREATE TABLE products_com ( + id varchar(255) NOT NULL, + product varchar(255) NOT NULL, + product2 varchar(255) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE receipts ( + id varchar(255) NOT NULL, + money varchar(255) NOT NULL, + datenew datetime NOT NULL, + attributes mediumblob default NULL, + person varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE reservation_customers ( + id varchar(255) NOT NULL, + customer varchar(255) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE reservations ( + id varchar(255) NOT NULL, + created datetime NOT NULL, + datenew datetime NOT NULL default '2018-01-01 00:00:00' , + title varchar(255) NOT NULL, + chairs int(11) NOT NULL, + isdone int(1) NOT NULL, + description varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE resources ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + restype int(11) NOT NULL, + content mediumblob default NULL, + version varchar(10) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE roles ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + permissions mediumblob default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE sharedtickets ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + content mediumblob default NULL, + appuser varchar(255) default NULL, + pickupid int(11) NOT NULL default 0 , + locked varchar(20) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE shift_breaks ( + id varchar(255) NOT NULL, + shiftid varchar(255) NOT NULL, + breakid varchar(255) NOT NULL, + starttime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP , + endtime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP , + PRIMARY KEY (id) +); + +CREATE TABLE shifts ( + id varchar(255) NOT NULL, + startshift datetime NOT NULL, + endshift datetime default NULL, + pplid varchar(255) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE stockcurrent ( + location varchar(255) NOT NULL, + product varchar(255) NOT NULL, + attributesetinstance_id varchar(255) default NULL, + units double NOT NULL +); + +CREATE TABLE stockdiary ( + id varchar(255) NOT NULL, + datenew datetime NOT NULL, + reason int(11) NOT NULL, + location varchar(255) NOT NULL, + product varchar(255) NOT NULL, + attributesetinstance_id varchar(255) default NULL, + units double NOT NULL, + price double NOT NULL, + appuser varchar(255) default NULL, + supplier varchar(255) default NULL, + supplierdoc varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE stocklevel ( + id varchar(255) NOT NULL, + location varchar(255) NOT NULL, + product varchar(255) NOT NULL, + stocksecurity double default NULL, + stockmaximum double default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE suppliers ( + id varchar(255) NOT NULL, + searchkey varchar(255) NOT NULL, + taxid varchar(255) default NULL, + name varchar(255) NOT NULL, + maxdebt double NOT NULL default 0 , + address varchar(255) default NULL, + address2 varchar(255) default NULL, + postal varchar(255) default NULL, + city varchar(255) default NULL, + region varchar(255) default NULL, + country varchar(255) default NULL, + firstname varchar(255) default NULL, + lastname varchar(255) default NULL, + email varchar(255) default NULL, + phone varchar(255) default NULL, + phone2 varchar(255) default NULL, + fax varchar(255) default NULL, + notes varchar(255) default NULL, + visible int(1) NOT NULL default 1 , + curdate datetime default NULL, + curdebt double default 0 , + vatid varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE taxcategories ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE taxcustcategories ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE taxes ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + category varchar(255) NOT NULL, + custcategory varchar(255) default NULL, + parentid varchar(255) default NULL, + rate double NOT NULL default 0 , + ratecascade int(1) NOT NULL default 0 , + rateorder int(11) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE taxlines ( + id varchar(255) NOT NULL, + receipt varchar(255) NOT NULL, + taxid varchar(255) NOT NULL, + base double NOT NULL default 0 , + amount double NOT NULL default 0 , + PRIMARY KEY (id) +); + +CREATE TABLE taxsuppcategories ( + id varchar(255) NOT NULL, + name varchar(255) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE thirdparties ( + id varchar(255) NOT NULL, + cif varchar(255) NOT NULL, + name varchar(255) NOT NULL, + address varchar(255) default NULL, + contactcomm varchar(255) default NULL, + contactfact varchar(255) default NULL, + payrule varchar(255) default NULL, + faxnumber varchar(255) default NULL, + phonenumber varchar(255) default NULL, + mobilenumber varchar(255) default NULL, + email varchar(255) default NULL, + webpage varchar(255) default NULL, + notes varchar(255) default NULL, + PRIMARY KEY (id) +); + +CREATE TABLE ticketlines ( + ticket varchar(255) NOT NULL, + line int(11) NOT NULL, + product varchar(255) default NULL, + attributesetinstance_id varchar(255) default NULL, + units double NOT NULL, + price double NOT NULL, + taxid varchar(255) NOT NULL, + attributes mediumblob default NULL, + PRIMARY KEY (ticket , line) +); + +CREATE TABLE tickets ( + id varchar(255) NOT NULL, + tickettype int(11) NOT NULL default 0 , + ticketid int(11) NOT NULL, + person varchar(255) NOT NULL, + customer varchar(255) default NULL, + status int(11) NOT NULL default 0 , + PRIMARY KEY (id) +); + +CREATE TABLE ticketsnum ( + id int(11) NOT NULL +); + +CREATE TABLE ticketsnum_payment ( + id int(11) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE ticketsnum_refund ( + id int(11) NOT NULL +); + +CREATE TABLE uom ( + id VARCHAR(255) NOT NULL, + name VARCHAR(255) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE vouchers ( + id VARCHAR(100) NOT NULL, + voucher_number VARCHAR(100) DEFAULT NULL, + customer VARCHAR(100) DEFAULT NULL, + amount DOUBLE DEFAULT NULL, + status CHAR(1) DEFAULT A , + PRIMARY KEY (id) +); + +-- ADD roles +INSERT INTO roles(id, name, permissions) VALUES('0', 'Administrator role', $FILE{/com/unicenta/pos/templates/Role.Administrator.xml} ); +INSERT INTO roles(id, name, permissions) VALUES('1', 'Manager role', $FILE{/com/unicenta/pos/templates/Role.Manager.xml} ); +INSERT INTO roles(id, name, permissions) VALUES('2', 'Employee role', $FILE{/com/unicenta/pos/templates/Role.Employee.xml} ); +INSERT INTO roles(id, name, permissions) VALUES('3', 'Guest role', $FILE{/com/unicenta/pos/templates/Role.Guest.xml} ); + +-- ADD people +INSERT INTO people(id, name, apppassword, role, visible, image) VALUES ('0', 'Administrator', NULL, '0', 1, NULL); +INSERT INTO people(id, name, apppassword, role, visible, image) VALUES ('1', 'Manager', NULL, '1', 1, NULL); +INSERT INTO people(id, name, apppassword, role, visible, image) VALUES ('2', 'Employee', NULL, '2', 1, NULL); +INSERT INTO people(id, name, apppassword, role, visible, image) VALUES ('3', 'Guest', NULL, '3', 1, NULL); + +-- ADD resources -- +-- SYSTEM +INSERT INTO resources(id, name, restype, content) VALUES('00', 'Menu.Root', 0, $FILE{/com/unicenta/pos/templates/Menu.Root.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('02', 'Cash.Close', 0, $FILE{/com/unicenta/pos/templates/Cash.Close.xml}); +INSERT INTO resources(ID, name, restype, content) VALUES('03', 'Customer.Created', 0, $FILE{/com/unicenta/pos/templates/customer.created.xml}); +INSERT INTO resources(ID, name, restype, content) VALUES('04', 'Customer.Deleted', 0, $FILE{/com/unicenta/pos/templates/customer.deleted.xml}); +INSERT INTO resources(ID, name, restype, content) VALUES('05', 'Customer.Updated', 0, $FILE{/com/unicenta/pos/templates/customer.updated.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('06', 'payment.cash', 0, $FILE{/com/unicenta/pos/templates/payment.cash.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('07', 'Ticket.Buttons', 0, $FILE{/com/unicenta/pos/templates/Ticket.Buttons.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('08', 'Ticket.Close', 0, $FILE{/com/unicenta/pos/templates/Ticket.Close.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('09', 'Ticket.Line', 0, $FILE{/com/unicenta/pos/templates/Ticket.Line.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('10', 'Window.Title', 0, $FILE{/com/unicenta/pos/templates/Window.Title.txt}); + +-- IMAGES +INSERT INTO resources(id, name, restype, content) VALUES('11', 'img.001', 1, $FILE{/com/unicenta/images/.01.png}); +INSERT INTO resources(id, name, restype, content) VALUES('12', 'img.002', 1, $FILE{/com/unicenta/images/.02.png}); +INSERT INTO resources(id, name, restype, content) VALUES('13', 'img.005', 1, $FILE{/com/unicenta/images/.05.png}); +INSERT INTO resources(id, name, restype, content) VALUES('14', 'img.010', 1, $FILE{/com/unicenta/images/.10.png}); +INSERT INTO resources(id, name, restype, content) VALUES('15', 'img.020', 1, $FILE{/com/unicenta/images/.20.png}); +INSERT INTO resources(id, name, restype, content) VALUES('16', 'img.025', 1, $FILE{/com/unicenta/images/.25.png}); +INSERT INTO resources(id, name, restype, content) VALUES('17', 'img.050', 1, $FILE{/com/unicenta/images/.50.png}); +INSERT INTO resources(id, name, restype, content) VALUES('18', 'img.1', 1, $FILE{/com/unicenta/images/1.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('19', 'img.2', 1, $FILE{/com/unicenta/images/2.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('20', 'img.5', 1, $FILE{/com/unicenta/images/5.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('21', 'img.10', 1, $FILE{/com/unicenta/images/10.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('22', 'img.20', 1, $FILE{/com/unicenta/images/20.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('23', 'img.50', 1, $FILE{/com/unicenta/images/50.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('24', 'img.100', 1, $FILE{/com/unicenta/images/100.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('25', 'img.200', 1, $FILE{/com/unicenta/images/200.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('26', 'img.500', 1, $FILE{/com/unicenta/images/500.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('27', 'img.1000', 1, $FILE{/com/unicenta/images/1000.00.png}); +INSERT INTO resources(id, name, restype, content) VALUES('28', 'img.cash', 1, $FILE{/com/unicenta/images/cash.png}); +INSERT INTO resources(id, name, restype, content) VALUES('29', 'img.cashdrawer', 1, $FILE{/com/unicenta/images/cashdrawer.png}); +INSERT INTO resources(id, name, restype, content) VALUES('30', 'img.discount', 1, $FILE{/com/unicenta/images/discount.png}); +INSERT INTO resources(id, name, restype, content) VALUES('31', 'img.discount_b', 1, $FILE{/com/unicenta/images/discount_b.png}); +INSERT INTO resources(id, name, restype, content) VALUES('32', 'img.heart', 1, $FILE{/com/unicenta/images/heart.png}); +INSERT INTO resources(id, name, restype, content) VALUES('33', 'img.keyboard_48', 1, $FILE{/com/unicenta/images/keyboard_48.png}); +INSERT INTO resources(id, name, restype, content) VALUES('34', 'img.kit_print', 1, $FILE{/com/unicenta/images/kit_print.png}); +INSERT INTO resources(id, name, restype, content) VALUES('35', 'img.no_photo', 1, $FILE{/com/unicenta/images/no_photo.png}); +INSERT INTO resources(id, name, restype, content) VALUES('36', 'img.refundit', 1, $FILE{/com/unicenta/images/refundit.png}); +INSERT INTO resources(id, name, restype, content) VALUES('37', 'img.run_script', 1, $FILE{/com/unicenta/images/run_script.png}); +INSERT INTO resources(id, name, restype, content) VALUES('38', 'img.ticket_print', 1, $FILE{/com/unicenta/images/ticket_print.png}); +INSERT INTO resources(id, name, restype, content) VALUES('40', 'Printer.Ticket.Logo', 1, $FILE{/com/unicenta/images/printer.ticket.logo.jpg}); + +-- PRINTER +INSERT INTO resources(id, name, restype, content) VALUES('41', 'Printer.CloseCash.Preview', 0, $FILE{/com/unicenta/pos/templates/Printer.CloseCash.Preview.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('42', 'Printer.CloseCash', 0, $FILE{/com/unicenta/pos/templates/Printer.CloseCash.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('43', 'Printer.CustomerPaid', 0, $FILE{/com/unicenta/pos/templates/Printer.CustomerPaid.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('44', 'Printer.CustomerPaid2', 0, $FILE{/com/unicenta/pos/templates/Printer.CustomerPaid2.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('45', 'Printer.FiscalTicket', 0, $FILE{/com/unicenta/pos/templates/Printer.FiscalTicket.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('46', 'Printer.Inventory', 0, $FILE{/com/unicenta/pos/templates/Printer.Inventory.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('47', 'Printer.OpenDrawer', 0, $FILE{/com/unicenta/pos/templates/Printer.OpenDrawer.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('48', 'Printer.PartialCash', 0, $FILE{/com/unicenta/pos/templates/Printer.PartialCash.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('49', 'Printer.PrintLastTicket', 0, $FILE{/com/unicenta/pos/templates/Printer.PrintLastTicket.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('50', 'Printer.Product', 0, $FILE{/com/unicenta/pos/templates/Printer.Product.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('52', 'Printer.ReprintTicket', 0, $FILE{/com/unicenta/pos/templates/Printer.ReprintTicket.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('53', 'Printer.Start', 0, $FILE{/com/unicenta/pos/templates/Printer.Start.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('54', 'Printer.Ticket.P1', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P1.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('55', 'Printer.Ticket.P2', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P2.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('56', 'Printer.Ticket.P3', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P3.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('57', 'Printer.Ticket.P4', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P4.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('58', 'Printer.Ticket.P5', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P5.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('59', 'Printer.Ticket.P6', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.P6.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('60', 'Printer.Ticket', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('61', 'Printer.Ticket2', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket2.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('62', 'Printer.TicketClose', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketClose.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('63', 'Printer.TicketLine', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketLine.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('64', 'Printer.TicketNew', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketLine.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('65', 'Printer.TicketPreview', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketPreview.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('66', 'Printer.Ticket_A4', 0, $FILE{/com/unicenta/pos/templates/Printer.Ticket_A4.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('67', 'Printer.TicketPreview_A4', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketPreview_A4.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('68', 'Printer.TicketRemote', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketRemote.xml}); +INSERT INTO resources(id, name, restype, content) VALUES('69', 'Printer.TicketTotal', 0, $FILE{/com/unicenta/pos/templates/Printer.TicketTotal.xml}); + +-- SCRIPTS +INSERT INTO resources(id, name, restype, content) VALUES('70', 'script.Keyboard', 0, $FILE{/com/unicenta/pos/templates/script.Keyboard.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('71', 'script.Linediscount', 0, $FILE{/com/unicenta/pos/templates/script.Linediscount.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('73', 'script.SendOrder', 0, $FILE{/com/unicenta/pos/templates/script.SendOrder.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('74', 'script.Totaldiscount', 0, $FILE{/com/unicenta/pos/templates/script.Totaldiscount.txt}); +INSERT INTO resources(id, name, restype, content) VALUES('75', 'script.multibuy', 0, $FILE{/com/unicenta/pos/templates/script.multibuy.txt}); + +-- ADD CATEGORIES +INSERT INTO categories(id, name) VALUES ('000', 'Category Standard'); + +-- ADD TAXCATEGORIES +/* 002 added 31/01/2017 00:00:00. */ +INSERT INTO taxcategories(id, name) VALUES ('000', 'Tax Exempt'); +INSERT INTO taxcategories(id, name) VALUES ('001', 'Tax Standard'); +INSERT INTO taxcategories(id, name) VALUES ('002', 'Tax Other'); + +-- ADD TAXES +/* 002 added 31/01/2017 00:00:00. */ +INSERT INTO taxes(id, name, category, custcategory, parentid, rate, ratecascade, rateorder) VALUES ('000', 'Tax Exempt', '000', NULL, NULL, 0, 0, NULL); +INSERT INTO taxes(id, name, category, custcategory, parentid, rate, ratecascade, rateorder) VALUES ('001', 'Tax Standard', '001', NULL, NULL, 0.20, 0, NULL); +INSERT INTO taxes(id, name, category, custcategory, parentid, rate, ratecascade, rateorder) VALUES ('002', 'Tax Other', '002', NULL, NULL, 0, 0, NULL); + +-- ADD PRODUCTS +INSERT INTO products(id, reference, code, name, category, taxcat, isservice, display, printto) +VALUES ('xxx999_999xxx_x9x9x9', 'xxx999', 'xxx999', 'Free Line entry', '000', '001', 1, '<html><center>Free Line entry', '1'); +INSERT INTO products(id, reference, code, name, category, taxcat, isservice, display, printto) +VALUES ('xxx998_998xxx_x8x8x8', 'xxx998', 'xxx998', 'Service Charge', '000', '001', 1, '<html><center>Service Charge', '1'); + +-- ADD PRODUCTS_CAT +INSERT INTO products_cat(product) VALUES ('xxx999_999xxx_x9x9x9'); +INSERT INTO products_cat(product) VALUES ('xxx998_998xxx_x8x8x8'); + +-- ADD LOCATION +INSERT INTO locations(id, name, address) VALUES ('0','Location 1','Local'); + +-- ADD SUPPLIERS +INSERT INTO suppliers(id, searchkey, name) VALUES ('0','unicenta','unicenta'); + +-- ADD UOM +INSERT INTO uom(id, name) VALUES ('0','Each'); + +-- ADD FLOORS +INSERT INTO floors(id, name, image) VALUES ('0', 'Restaurant floor', $FILE{/com/unicenta/images/paperboard960_600.png}); + +-- ADD PLACES +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('1', 'Table 1', 100, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('2', 'Table 2', 250, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('3', 'Table 3', 400, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('4', 'Table 4', 550, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('5', 'Table 5', 700, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('6', 'Table 6', 850, 50, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('7', 'Table 7', 100, 150, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('8', 'Table 8', 250, 150, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('9', 'Table 9', 400, 150, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('10', 'Table 10', 550, 150, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('11', 'Table 11', 700, 150, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('12', 'Table 12', 850, 150, '0', '1', 90, 45); + +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('13', 'Table 13', 100, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('14', 'Table 14', 250, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('15', 'Table 15', 400, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('16', 'Table 16', 550, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('17', 'Table 17', 700, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('18', 'Table 18', 850, 250, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('19', 'Table 19', 100, 350, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('20', 'Table 20', 250, 350, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('21', 'Table 21', 400, 350, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('22', 'Table 22', 550, 350, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('23', 'Table 23', 700, 350, '0', '1', 90, 45); +INSERT INTO places(id, name, x, y, floor, seats, width, height) VALUES ('24', 'Table 24', 850, 350, '0', '1', 90, 45); + +-- ADD SHIFTS +INSERT INTO shifts(id, startshift, endshift, pplid) VALUES ('0', '2018-01-01 00:00:00.001', '2018-01-01 00:00:00.002','0'); + +-- ADD BREAKS +INSERT INTO breaks(id, name, visible, notes) VALUES ('0', 'Lunch Break', 1, NULL); +INSERT INTO breaks(id, name, visible, notes) VALUES ('1', 'Tea Break', 1, NULL); +INSERT INTO breaks(id, name, visible, notes) VALUES ('2', 'Mid Break', 1, NULL); + +-- ADD SHIFT_BREAKS +INSERT INTO shift_breaks(id, shiftid, breakid, starttime, endtime) VALUES ('0', '0', '0', '2018-01-01 00:00:00.003', '2018-01-01 00:00:00.004'); + +-- ADD SEQUENCES +INSERT INTO pickup_number VALUES(1); +INSERT INTO ticketsnum VALUES(1); +INSERT INTO ticketsnum_refund VALUES(1); +INSERT INTO ticketsnum_payment VALUES(1); + +-- ADD APPLICATION VERSION +INSERT INTO applications(id, name, version) VALUES($APP_ID{}, $APP_NAME{}, $APP_VERSION{}); diff --git a/src/main/resources/com/unicenta/pos/templates/APrinter.FiscalTicket.xml b/src/main/resources/com/unicenta/pos/templates/APrinter.FiscalTicket.xml new file mode 100644 index 0000000..9e9a559 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/APrinter.FiscalTicket.xml @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + --> +<output> + <fiscalreceipt> + #foreach ($ticketline in $ticket.getLines()) + <!-- setting $vatinfo to the values contained in the fiscal printer vat table--> + #if (${ticketline.getTaxInfo().getRate()}==0.04) + #set ($vatinfo ="1") + #elseif (${ticketline.getTaxInfo().getRate()}==0.1) + #set ($vatinfo ="2") + #elseif (${ticketline.getTaxInfo().getRate()}==0.2) + #set ($vatinfo ="3") + #else + #set ($vatinfo ="1") + #end + #if ($ticketline.isProductCom()) + <line price="${ticketline.getValue()}" units="${ticketline.getMultiply()}" tax="${vatinfo}">*${ticketline.printName()}</line> + #else + <line price="${ticketline.getValue()}" units="${ticketline.getMultiply()}" tax="${vatinfo}">${ticketline.printName()}</line> + #end + #end + <message>Items count: ${ticket.printArticlesCount()}</message> + #foreach ($paymentline in $ticket.payment) + #if ($paymentline.name == "cash") + <total paid="${paymentline.getPaid()}">Cash</total> + #end + #if ($paymentline.name == "cashrefund") + <total paid="${paymentline.getTotal()}">Refund</total> + #end + #if ($paymentline.name == "ccard") + <total paid="${paymentline.getTotal()}">Mag card</total> + #end + #if ($paymentline.name == "ccardrefund") + <total paid="${paymentline.getTotal()}">Mag card refund</total> + #end + #if ($paymentline.name == "cheque") + <total paid="${paymentline.getTotal()}">Cheque</total> + #end + #if ($paymentline.name == "chequerefund") + <total paid="${paymentline.getTotal()}">Cheque refund</total> + #end + #end + </fiscalreceipt> +<!-- Other commands --> +<!-- + <fiscalzreport/> + <fiscalxreport/> +--> +</output> diff --git a/src/main/resources/com/unicenta/pos/templates/Cash.Close.xml b/src/main/resources/com/unicenta/pos/templates/Cash.Close.xml new file mode 100644 index 0000000..a9a30ca --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Cash.Close.xml @@ -0,0 +1,25 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// http://sourceforge.net/projects/unicentaopos +// +// This file is part of uniCenta oPOS. +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +// ************************************************************************** +// Cash.Close +// This script runs in the cash.close event + + + + diff --git a/src/main/resources/com/unicenta/pos/templates/Menu.Root.txt b/src/main/resources/com/unicenta/pos/templates/Menu.Root.txt new file mode 100644 index 0000000..e2bc8a2 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Menu.Root.txt @@ -0,0 +1,151 @@ +group = menu.addGroup("Menu.Main"); + group.addPanel("/com/unicenta/images/sale.png", "Menu.Ticket", "com.unicenta.pos.sales.JPanelTicketSales"); + group.addPanel("/com/unicenta/images/saleedit.png", "Menu.TicketEdit", "com.unicenta.pos.sales.JPanelTicketEdits"); + group.addPanel("/com/unicenta/images/customerpay.png", "Menu.CustomersPayment", "com.unicenta.pos.customers.CustomersPayment"); + group.addPanel("/com/unicenta/images/payments.png", "Menu.Payments", "com.unicenta.pos.panels.JPanelPayments"); + group.addPanel("/com/unicenta/images/calculator.png", "Menu.CloseTPV", "com.unicenta.pos.panels.JPanelCloseMoney"); + +group = menu.addGroup("Menu.Backoffice"); + submenu = group.addSubmenu("/com/unicenta/images/plugin.png", "Menu.Plugins", "plugins.configure"); + + submenu = group.addSubmenu("/com/unicenta/images/customer.png", "Menu.Customers", "com.unicenta.pos.forms.MenuCustomers"); + submenu.addTitle("Menu.Panel.Customers.Forms"); + submenu.addPanel("/com/unicenta/images/customer.png", "Menu.CustomersManagement", "com.unicenta.pos.customers.CustomersPanel"); + + submenu.addTitle("Menu.Panel.Customers.Reports"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Customers.Reports.Report", "/com/unicenta/reports/customers.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Customers.Reports.Sales", "/com/unicenta/reports/customers_sales.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Customers.Reports.Debtors", "/com/unicenta/reports/customers_debtors.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Customers.Reports.Diary", "/com/unicenta/reports/customers_diary.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Customers.Reports.Cards", "/com/unicenta/reports/customers_cards.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Customers.Reports.List", "/com/unicenta/reports/customers_list.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Customers.Reports.Export", "/com/unicenta/reports/customers_export.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Customers.Reports.Vouchers", "/com/unicenta/reports/customers_vouchers.bs"); + + submenu = group.addSubmenu("/com/unicenta/images/stockmaint.png", "Menu.Suppliers", "com.unicenta.pos.forms.MenuSuppliers"); + submenu.addTitle("Menu.Panel.Suppliers.Forms"); + submenu.addPanel("/com/unicenta/images/customer.png", "Menu.SuppliersManagement", "com.unicenta.pos.suppliers.SuppliersPanel"); + submenu.addTitle("Menu.Panel.Suppliers.Reports"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Suppliers.Reports.Report", "/com/unicenta/reports/suppliers.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Suppliers.Reports.Products", "/com/unicenta/reports/suppliers_products.bs"); +// submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Suppliers.Reports.Creditors", "/com/unicenta/reports/suppliers_creditors.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Suppliers.Reports.Diary", "/com/unicenta/reports/suppliers_diary.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Suppliers.Reports.Sales", "/com/unicenta/reports/suppliers_sales.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Suppliers.Reports.List", "/com/unicenta/reports/suppliers_list.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Suppliers.Reports.Export", "/com/unicenta/reports/suppliers_export.bs"); + + submenu = group.addSubmenu("/com/unicenta/images/products.png", "Menu.StockManagement", "com.unicenta.pos.forms.MenuStockManagement"); + submenu.addTitle("Menu.Panel.Stock.Forms"); + + submenu.addPanel("/com/unicenta/images/category.png", "Menu.Categories", "com.unicenta.pos.inventory.CategoriesPanel"); + submenu.addPanel("/com/unicenta/images/products.png", "Menu.Products", "com.unicenta.pos.inventory.ProductsPanel"); + submenu.addPanel("/com/unicenta/images/location.png", "Menu.ProductsWarehouse", "com.unicenta.pos.inventory.ProductsWarehousePanel"); + submenu.addPanel("/com/unicenta/images/stockmaint.png", "Menu.StockMovement", "com.unicenta.pos.inventory.StockManagement"); + submenu.addPanel("/com/unicenta/images/auxiliary.png", "Menu.Auxiliar", "com.unicenta.pos.inventory.AuxiliarPanel"); + submenu.addPanel("/com/unicenta/images/bundle.png", "Menu.Bundle", "com.unicenta.pos.inventory.BundlePanel"); + submenu.addPanel("/com/unicenta/images/attributes.png", "Menu.Attributes", "com.unicenta.pos.inventory.AttributesPanel"); + submenu.addPanel("/com/unicenta/images/attributes.png", "Menu.AttributeValues", "com.unicenta.pos.inventory.AttributeValuesPanel"); + submenu.addPanel("/com/unicenta/images/attributes.png", "Menu.AttributeSets", "com.unicenta.pos.inventory.AttributeSetsPanel"); + submenu.addPanel("/com/unicenta/images/attributes.png", "Menu.AttributeUse", "com.unicenta.pos.inventory.AttributeUsePanel"); + submenu.addPanel("/com/unicenta/images/products.png", "Menu.Uom", "com.unicenta.pos.inventory.UomPanel"); + + submenu.addTitle("Menu.Panel.Stock.Reports"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Inventory", "/com/unicenta/reports/inventory.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Inventory2", "/com/unicenta/reports/inventory_b.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Inventory.Reports.Diary", "/com/unicenta/reports/inventory_diary.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.InventoryBroken", "/com/unicenta/reports/inventory_broken.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.InventoryDiff", "/com/unicenta/reports/inventory_diff.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.InventoryDiffDetail", "/com/unicenta/reports/inventory_diffdetail.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.InventoryListDetail", "/com/unicenta/reports/inventory_listdetail.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Products", "/com/unicenta/reports/products.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.SaleCatalog", "/com/unicenta/reports/salecatalog.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.ProductLabels", "/com/unicenta/reports/labels_product.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.BarcodeSheet", "/com/unicenta/reports/labels_barcode_sheet.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.ShelfEdgeLabels", "/com/unicenta/reports/labels_barcode_shelfedge.bs"); + + + submenu = group.addSubmenu("/com/unicenta/images/sales.png", "Menu.SalesManagement", "com.unicenta.pos.forms.MenuSalesManagement"); + submenu.addTitle("Menu.Panel.Sales.Reports"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Closing", "/com/unicenta/reports/sales_closedpos.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Closing1", "/com/unicenta/reports/sales_closedpos_1.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.CashRegisterLog", "/com/unicenta/reports/sales_cashregisterlog.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.ExtendedCashRegisterLog", "/com/unicenta/reports/sales_extendedcashregisterlog.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.CashFlow", "/com/unicenta/reports/sales_cashflow.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.PaymentReport", "/com/unicenta/reports/sales_payments.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.CategorySales", "/com/unicenta/reports/sales_categorysales.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.CategorySales1", "/com/unicenta/reports/sales_categorysales_1.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.ClosedProducts", "/com/unicenta/reports/sales_closedproducts.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.ClosedProducts1", "/com/unicenta/reports/sales_closedproducts_1.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.ExtendedByProducts", "/com/unicenta/reports/sales_extproducts.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.SalesProfit", "/com/unicenta/reports/sales_productsalesprofit.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.SaleTaxes", "/com/unicenta/reports/sales_saletaxes.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.TaxCatSales", "/com/unicenta/reports/sales_taxcatsales.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.ReportTaxes", "/com/unicenta/reports/sales_taxes.bs"); + submenu.addTitle("Menu.Panel.Sales.Charts"); + submenu.addPanel("/com/unicenta/images/chart.png", "Menu.ProductSales", "/com/unicenta/reports/sales_chart_productsales.bs"); + submenu.addPanel("/com/unicenta/images/chart.png", "Menu.ProductCategorySalesPieChart", "/com/unicenta/reports/sales_chart_piesalescat.bs"); + submenu.addPanel("/com/unicenta/images/chart.png", "Menu.SalesChart", "/com/unicenta/reports/sales_chart_sales.bs"); + submenu.addPanel("/com/unicenta/images/chart.png", "Menu.TimeSeriesProduct", "/com/unicenta/reports/sales_chart_timeseriesproduct.bs"); + submenu.addPanel("/com/unicenta/images/chart.png", "Menu.Top10Sales", "/com/unicenta/reports/sales_chart_top10.bs"); + + + submenu = group.addSubmenu("/com/unicenta/images/maintain.png", "Menu.Maintenance", "com.unicenta.pos.forms.MenuMaintenance"); + submenu.addTitle("Menu.Panel.Maintenance.Forms"); + submenu.addPanel("/com/unicenta/images/resources.png", "Menu.Resources", "com.unicenta.pos.admin.ResourcesPanel"); + submenu.addPanel("/com/unicenta/images/roles.png", "Menu.Roles", "com.unicenta.pos.admin.RolesPanel"); + submenu.addPanel("/com/unicenta/images/user.png", "Menu.Users", "com.unicenta.pos.admin.PeoplePanel"); + submenu.addPanel("/com/unicenta/images/bookmark.png", "Menu.TaxCategories", "com.unicenta.pos.inventory.TaxCategoriesPanel"); + submenu.addPanel("/com/unicenta/images/bookmark.png", "Menu.TaxCustCategories", "com.unicenta.pos.inventory.TaxCustCategoriesPanel"); + submenu.addPanel("/com/unicenta/images/bookmark.png", "Menu.Taxes", "com.unicenta.pos.inventory.TaxPanel"); + submenu.addPanel("/com/unicenta/images/location.png", "Menu.Locations", "com.unicenta.pos.inventory.LocationsPanel"); + submenu.addPanel("/com/unicenta/images/floors.png", "Menu.Floors", "com.unicenta.pos.mant.JPanelFloors"); + submenu.addPanel("/com/unicenta/images/tables.png", "Menu.Tables", "com.unicenta.pos.mant.JPanelPlaces"); + submenu.addPanel("/com/unicenta/images/products.png", "Menu.Vouchers", "com.unicenta.pos.voucher.VoucherPanel"); + + submenu.addTitle("Menu.Panel.Maintenance.Reports"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.UsersReport", "/com/unicenta/reports/users.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.UserSells", "/com/unicenta/reports/users_sales.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.UserNoSales", "/com/unicenta/reports/users_nosales.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.UserVoids", "/com/unicenta/reports/users_voids.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Customers.Reports.Vouchers", "/com/unicenta/reports/customers_vouchers.bs"); + +// EPM + submenu = group.addSubmenu("/com/unicenta/images/users.png", "Menu.PresenceManagement", "com.unicenta.pos.forms.MenuEmployees"); + submenu.addTitle("Menu.PresenceManagement"); + submenu.addPanel("/com/unicenta/images/coffee.png", "Menu.Breaks", "com.unicenta.pos.epm.BreaksPanel"); + submenu.addPanel("/com/unicenta/images/leaves.png", "Menu.Leaves", "com.unicenta.pos.epm.LeavesPanel"); + submenu.addTitle("Menu.Employees.Reports"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.EPM.DailyPresenceReport", "/com/unicenta/reports/epm_dailypresence.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.EPM.DailyScheduleReport", "/com/unicenta/reports/epm_dailyschedule.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.EPM.PerformanceReport", "/com/unicenta/reports/epm_performance.bs"); + + + group = menu.addGroup("Menu.Utilities"); + submenu = group.addSubmenu("/com/unicenta/images/utilities.png", "Menu.Tools", "com.unicenta.pos.imports.JPanelCSV"); + submenu.addTitle("Menu.Import"); + submenu.addPanel("/com/unicenta/images/import.png", "Menu.CSVImport", "com.unicenta.pos.imports.JPanelCSVImport"); + submenu.addPanel("/com/unicenta/images/import.png", "Menu.CSVStockQty", "com.unicenta.pos.imports.StockQtyImport"); + submenu.addPanel("/com/unicenta/images/import.png", "Menu.CustomerCSVImport", "com.unicenta.pos.imports.CustomerCSVImport"); + submenu.addPanel("/com/unicenta/images/database.png", "Menu.CSVReset", "com.unicenta.pos.imports.JPanelCSVCleardb"); + submenu.addPanel("/com/unicenta/images/database.png", "Menu.Transfer", "com.unicenta.pos.transfer.Transfer"); + submenu.addTitle("Menu.Import.Reports"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Tools.NewProducts", "/com/unicenta/reports/tools_newproducts.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Tools.UpdatedPrices", "/com/unicenta/reports/tools_updatedprices.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Tools.StockQtyUpdate", "/com/unicenta/reports/tools_inventoryqtyupdate.bs"); +// submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Tools.BadPrices", "/com/unicenta/reports/tools_badprice.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Tools.InvalidCategory", "/com/unicenta/reports/tools_invalidcategory.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Tools.MissingData", "/com/unicenta/reports/tools_missingdata.bs"); + submenu.addPanel("/com/unicenta/images/reports.png", "Menu.Tools.InvalidData", "/com/unicenta/reports/tools_invaliddata.bs"); + + group = menu.addGroup("Menu.System"); + group.addChangePasswordAction(); + group.addPanel("/com/unicenta/images/configuration.png", "Menu.Configuration", "com.unicenta.pos.config.JPanelConfiguration"); + group.addPanel("/com/unicenta/images/printer.png", "Menu.Printer", "com.unicenta.pos.panels.JPanelPrinter"); + group.addPanel("/com/unicenta/images/timer.png", "Menu.CheckInCheckOut", "com.unicenta.pos.epm.JPanelEmployeePresence"); + +// Deprecated options. Only required with Openbravo ERP software +// submenu.addTitle("Menu.Maintenance.ERP"); +// submenu.addExecution("/com/unicenta/images/openbravo.png", "Menu.ERPProducts", "com.unicenta.possync.ProductsSyncCreate"); +// submenu.addExecution("/com/unicenta/images/openbravo.png", "Menu.ERPOrders", "com.unicenta.possync.OrdersSyncCreate"); + + group.addExitAction(); \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.CloseCash.Preview.xml b/src/main/resources/com/unicenta/pos/templates/Printer.CloseCash.Preview.xml new file mode 100644 index 0000000..7cbf66e --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.CloseCash.Preview.xml @@ -0,0 +1,126 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + This file is part of uniCenta oPOS. + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +--> + +<output> + <ticket> + <image>Printer.Ticket.Logo</image> + <line></line> + <line></line> + <line size="1"> + <text align ="center" bold="true" length="42">Close Cash Preview</text> + </line> + <line></line> + <line><text length="18" bold="true">Printed:</text><text>${payments.printDate()}</text></line> + <line><text length="18" bold="true">Printed by:</text><text>${payments.printUser()}</text></line> + <line><text length="18" bold="true">Terminal:</text><text>${payments.printHost()}</text></line> + <line><text length="18" bold="true">Sequence:</text><text>${payments.printSequence()}</text></line> + <line><text length="18" bold="true">Last Close Date:</text><text>${payments.printDateStart()}</text></line> + <line><text>------------------------------------------</text></line> + <line></line> + <line> + <text align ="left" bold="true" length="32">Payments Report</text> + <text align ="right" bold="true" length="10">Amount</text> + </line> + <line><text>------------------------------------------</text></line> + #foreach ($line in $payments.getPaymentLines()) + <line> + <text align ="left" length="32">${line.printType()} ${line.printReason()}</text> + <text align ="right" length="10">${line.printValue()}</text> + </line> + #end + <line><text>------------------------------------------</text></line> + <line> + <text align ="left" length="32" bold="true">Total Sales</text> + <text align ="right" length="10" bold="true">${payments.printPaymentsTotal()}</text> + </line> + <line> + <text align ="left" length="22">Number of Payments:</text> + <text align ="right" length="10">${payments.printPayments()}</text> + </line> + <line></line> + <line> + <text align ="left" bold="true" length="32">Tax Analysis</text> + <text align ="right" bold="true" length="10">Amount</text> + </line> + <line><text>------------------------------------------</text></line> + #foreach ($line in $payments.getSaleLines()) + <line> + <text align ="left" length="32">${line.printTaxName()}</text> + <text align ="right" length="10">${line.printTaxes()}</text> + </line> + #end + <line><text>------------------------------------------</text></line> +<!-- START OF VOIDS --> + <line size="1"><text align="center" length="42" bold="true">Line Voids</text></line> + <line> + <text align ="left" length="6" bold="true">Tkt</text> + <text align ="left" length="12" bold="true">User</text> + <text align ="left" length="19" bold="true">Product</text> + <text align ="right" length="5" bold="true">Total</text> + </line> + <line><text>------------------------------------------</text></line> + #foreach ($line in $payments.getRemovedProductLines()) + <line> + <text align ="left" length="6">${line.printTicketId()}</text> + <text align ="left" length="11">${line.printWorkerName()}</text> + <text align ="left" length="1"></text> + <text align ="left" length="19">${line.printProductName()}</text> + <text align ="right" length="5">${line.printTotalUnits()}</text> + </line> + #end + <line><text>------------------------------------------</text></line> + <line></line> +<!-- END OF VOIDS --> + +<!-- START OF NO SALES --> + <line size="1"><text align="center" length="42" bold="true">No Sales</text></line> + <line> + <text align ="left" length="34" bold="true">User</text> + <text align ="right" length="8" bold="true">Ticket</text> + </line> + <line><text>------------------------------------------</text></line> + #foreach ($line in $payments.getDrawerOpenedLines()) + <line> + <text align ="left" length="34">${line.printUserName()}</text> + <text align ="right" length="8">${line.printTicketId()}</text> + </line> + #end + <line><text>------------------------------------------</text></line> + <line></line> +<!-- END OF NO SALES --> + + <line> + <text align ="left" length="32">Receipts:</text> + <text align ="right" length="10">${payments.printSales()}</text> + </line> + <line></line> + <line size="1"> + <text align ="left" length="32" bold="true">SubTotal</text> + <text align ="right" length="10" bold="true">${payments.printSalesBase()}</text> + </line> + <line size="1"> + <text align ="left" length="32" bold="true">Taxes</text> + <text align ="right" length="10" bold="true">${payments.printSalesTaxes()}</text> + </line> + <line size="1"> + <text align ="left" length="32" bold="true">Totals</text> + <text align ="right" length="10" bold="true">${payments.printSalesTotal()}</text> + </line> + </ticket> +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.CloseCash.xml b/src/main/resources/com/unicenta/pos/templates/Printer.CloseCash.xml new file mode 100644 index 0000000..6ef7d60 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.CloseCash.xml @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + This file is part of uniCenta oPOS. + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +--> + +<output> + <ticket> + <image>Printer.Ticket.Logo</image> + <line></line> + <line></line> + <line size="1"> + <text align ="center" bold="true" length="42">Close Cash Report</text> + </line> + <line></line> + <line> + <text align ="left" bold="true" length="30">Payments Report</text> + <text align ="right" bold="true" length="12">Amount</text> + </line> + <line><text>------------------------------------------</text></line> + #foreach ($line in $payments.getPaymentLines()) + <line> + <text align ="left" length="30">${line.printType()} ${line.printReason()}</text> + <text align ="right" length="12">${line.printValue()}</text> + </line> + #end + <line><text>------------------------------------------</text></line> + <line> + <text align ="left" length="30" bold="true">Total Sales</text> + <text align ="right" length="12" bold="true">${payments.printPaymentsTotal()}</text> + </line> + <line> + <text align ="left" length="30">Number of Payments:</text> + <text align ="right" length="12">${payments.printPayments()}</text> + </line> + <line></line> + <line> + <text align ="left" bold="true" length="30">Tax Analysis</text> + <text align ="right" bold="true" length="12">Amount</text> + </line> + <line><text>------------------------------------------</text></line> + #foreach ($line in $payments.getSaleLines()) + <line> + <text align ="left" length="30">${line.printTaxName()}</text> + <text align ="right" length="12">${line.printTaxes()}</text> + </line> + #end + <line><text>------------------------------------------</text></line> +<!-- START OF VOIDS --> + <line size="1"><text align="center" length="42" bold="true">Line Voids</text></line> + <line> + <text align ="left" length="6" bold="true">Tkt</text> + <text align ="left" length="12" bold="true">User</text> + <text align ="left" length="19" bold="true">Product</text> + <text align ="right" length="5" bold="true">Total</text> + </line> + <line><text>------------------------------------------</text></line> + #foreach ($line in $payments.getRemovedProductLines()) + <line> + <text align ="left" length="6">${line.printTicketId()}</text> + <text align ="left" length="11">${line.printWorkerName()}</text> + <text align ="left" length="1"></text> + <text align ="left" length="19">${line.printProductName()}</text> + <text align ="right" length="5">${line.printTotalUnits()}</text> + </line> + #end + <line><text>------------------------------------------</text></line> + <line></line> +<!-- END OF VOIDS --> + +<!-- START OF NO SALES --> + <line size="1"><text align="center" length="42" bold="true">No Sales</text></line> + <line> + <text align ="left" length="34" bold="true">User</text> + <text align ="right" length="8" bold="true">Ticket</text> + </line> + <line><text>------------------------------------------</text></line> + #foreach ($line in $payments.getDrawerOpenedLines()) + <line> + <text align ="left" length="34">${line.printUserName()}</text> + <text align ="right" length="8">${line.printTicketId()}</text> + </line> + #end + <line><text>------------------------------------------</text></line> + <line></line> +<!-- END OF NO SALES --> + + <line> + <text align ="left" length="3">Receipts:</text> + <text align ="right" length="12">${payments.printSales()}</text> + </line> + <line></line> + <line size="1"> + <text align ="left" length="30" bold="true">SubTotal</text> + <text align ="right" length="12" bold="true">${payments.printSalesBase()}</text> + </line> + <line size="1"> + <text align ="left" length="30" bold="true">Taxes</text> + <text align ="right" length="12" bold="true">${payments.printSalesTaxes()}</text> + </line> + <line size="1"> + <text align ="left" length="30" bold="true">Totals</text> + <text align ="right" length="12" bold="true">${payments.printSalesTotal()}</text> + </line> + <line><text>------------------------------------------</text></line> + <line><text length="18" bold="true">Closed by:</text><text>${payments.printUser()}</text></line> + <line><text length="18" bold="true">Terminal:</text><text>${payments.printHost()}</text></line> + <line><text length="18" bold="true">Sequence:</text><text>${payments.printSequence()}</text></line> + <line><text length="18" bold="true">Start Date:</text><text>${payments.printDateStart()}</text></line> + <line><text length="18" bold="true">End Date:</text><text>${payments.printDateEnd()}</text></line> + + </ticket> +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.CustomerPaid.xml b/src/main/resources/com/unicenta/pos/templates/Printer.CustomerPaid.xml new file mode 100644 index 0000000..4da2783 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.CustomerPaid.xml @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty or + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. + If not, see <http://www.gnu.org/licenses/>. + +--> +<output> + <display> + <line> + <text align="left" length="10">Total paid</text> + <text align="right" length="10">${ticket.printTotalPaid()}</text> + </line> + <line> + <text align="center" length="20">Thank You for your custom</text> + </line> + </display> + <ticket> + <image>Printer.Ticket.Logo</image> + <line></line> + <line> + <text align="center" length="42">Printer.CustomerPaid</text> + </line> + <line> + <text align="center" length="42">You can change this template</text> + </line> + <line> + <text align="center" length="42">in the Resources panel</text> + </line> + <line></line> + <line> + <text align="left" length="15">Receipt:</text> + <text>${ticket.printId()}</text> + </line> + <line> + <text align="left" length="15">Date:</text> + <text>${ticket.printDate()}</text> + </line> + + #if ($ticket.getCustomer()) + <line> + <text align="left" length="15">Account:</text> + <text>${ticket.getCustomer().printTaxid()}</text> + </line> + <line> + <text align="left" length="15">Customer:</text> + <text>${ticket.getCustomer().printName()}</text> + </line> + + #end + + <line></line> + <line size="1"> + <text align ="left" length="32" bold="true">Total Paid</text> + <text align ="right" length="10" bold="true">${ticket.printTotalPaid()}</text> + </line> + <line></line> + <line> + <text align ="left" length="32" bold="true">Account Balance</text> + <text align ="right" length="10" bold="true">${customer.printCurDebt()}</text> + </line> + + #foreach ($paymentline in $ticket.payments) + #if ($paymentline.name == "cash") + <line></line> + <line> + <text bold="true">Cash</text> + </line> + <line> + <text align="left" length="22">Tendered:</text> + <text align ="right" length="20">${paymentline.printPaid()}</text> + </line> + <line> + <text align="left" length="22">Change:</text> + <text align ="right" length="20">${paymentline.printChange()}</text> + </line> + #end + + #if ($paymentline.name == "ccard") + <line></line> + <line> + <text bold="true">Mag card</text> + </line> + <line> + <text align ="right" length="42">${paymentline.printTotal()}</text> + </line> + <line> + <text align ="left" length="22">Number:</text> + <text>${paymentline.printCardNumber()}</text> + </line> + <line> + <text align ="left" length="22">Expiry Date:</text> + <text>${paymentline.printExpirationDate()}</text> + </line> + <line> + <text align ="left" length="22">Operation:</text> + <text>${paymentline.printTransactionID()}</text> + </line> + <line> + <text align ="left" length="22">Authorization:</text> + <text>${paymentline.printAuthorization()}</text> + </line> + #end + + #if ($paymentline.name == "cheque") + <line></line> + <line> + <text bold="true">Cheque</text> + </line> + <line> + <text align ="right" length="42">${paymentline.printTotal()}</text> + </line> + #end + + #if ($paymentline.name == "voucherin") + <line></line> + <line> + <text bold="true">Voucher</text> + </line> + <line> + <text align ="right" length="42">${paymentline.printTotal()}</text> + </line> + #end + #end + <line></line> + <line> + <text align="left" length="15">Cashier:</text> + <text>${ticket.printUser()}</text> + </line> + <line></line> + <line> + <text align="center" length="42">Thank You for your custom</text> + </line> + </ticket> + + #foreach ($paymentline in $ticket.payments) + #if ($paymentline.name == "cash") + <opendrawer/> + #end + + #if ($paymentline.name == "cashrefund") + <opendrawer/> + #end + #end +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.CustomerPaid2.xml b/src/main/resources/com/unicenta/pos/templates/Printer.CustomerPaid2.xml new file mode 100644 index 0000000..4a21907 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.CustomerPaid2.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + --> +<output> + <display> + <line> + <text align="left" length="10">Total Paid</text> + <text align="right" length="10">${ticket.printTotalPaid()}</text> + </line> + <line> + <text align="center" length="20">Thank You for your custom</text> + </line> + </display> +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.FiscalTicket.xml b/src/main/resources/com/unicenta/pos/templates/Printer.FiscalTicket.xml new file mode 100644 index 0000000..e735b08 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.FiscalTicket.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + --> +<output> + <fiscalreceipt> + #foreach ($ticketline in $ticket.getLines()) + <!-- setting $vatinfo to the values contained in the fiscal printer vat table--> + #if (${ticketline.getTaxInfo().getRate()}==0.04) + #set ($vatinfo ="1") + #elseif (${ticketline.getTaxInfo().getRate()}==0.1) + #set ($vatinfo ="2") + #elseif (${ticketline.getTaxInfo().getRate()}==0.2) + #set ($vatinfo ="3") + #else #set ($vatinfo ="1") + #end + #if ($ticketline.isProductCom()) + <line price="${ticketline.getValue()}" units="${ticketline.getMultiply()}" tax="${vatinfo}">*${ticketline.printName()}</line> + #else + <line price="${ticketline.getValue()}" units="${ticketline.getMultiply()}" tax="${vatinfo}">${ticketline.printName()}</line> + #end + #end + <message>Items count: ${ticket.printArticlesCount()}</message> + #foreach ($paymentline in $ticket.payment) + #if ($paymentline.name == "cash") + <total paid="${paymentline.getPaid()}">Cash</total> + #end + #if ($paymentline.name == "cashrefund") + <total paid="${paymentline.getTotal()}">Refund</total> + #end + #if ($paymentline.name == "ccard") + <total paid="${paymentline.getTotal()}">Mag card</total> + #end + #if ($paymentline.name == "ccardrefund") + <total paid="${paymentline.getTotal()}">Mag card refund</total> + #end + #if ($paymentline.name == "cheque") + <total paid="${paymentline.getTotal()}">Cheque</total> + #end + #if ($paymentline.name == "chequerefund") + <total paid="${paymentline.getTotal()}">Cheque refund</total> + #end + #end + </fiscalreceipt> +<!-- Other commands --> +<!-- + <fiscalzreport/> + <fiscalxreport/> +--> +</output> diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.Inventory.xml b/src/main/resources/com/unicenta/pos/templates/Printer.Inventory.xml new file mode 100644 index 0000000..d8f5735 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.Inventory.xml @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + https://unicenta.com + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + --> + +<output> + <ticket> + <image>Printer.Ticket.Logo</image> + <line></line> + <line><text align="center" length="42">You can change Printer.Inventory template</text></line> + <line><text align="center" length="42">in the Resources panel</text></line> + <line></line> + <line><text align="center" bold="true" length="42">Inventory Record</text></line> + <line> + <text align ="left" bold="true" length="12">Date : </text> + <text align ="left" length="30">${inventoryrecord.printDate()}</text></line> + <line><text align ="left" bold="true" length="12">Reason : </text> + <text align ="left" length="30">${inventoryrecord.printReason()}</text></line> + <line><text align ="left" bold="true" length="12">User : </text> + <text align ="left" length="30">${inventoryrecord.printUser()}</text></line> + <line><text align ="left" bold="true" length="12">Location : </text> + <text align ="left" length="30">${inventoryrecord.printLocation()}</text></line> + <line><text align ="left" bold="true" length="12">Supplier : </text> + <text align ="left" length="30">${inventoryrecord.printSupplier()}</text></line> + <line><text align ="left" bold="true" length="12">Document : </text> + <text align ="left" length="30">${inventoryrecord.printSupplierDoc()}</text></line> + + <line size="1"> + #if ($inventoryrecord.isInput()) + <text align ="center" bold="true" length="42">In</text> + #else + <text align ="center" bold="true" length="42">Out</text> + #end + </line> + <line></line> + <line> + <text align ="left" bold="true" length="17">Item</text> + <text align ="right" bold="true" length="10">Price</text> + <text align ="right" bold="true" length="5">Qty</text> + <text align ="right" bold="true" length="10">Value</text> + </line> + <line> + <text>------------------------------------------</text> + </line> + #foreach ($inventoryline in $inventoryrecord.getLines()) + <line> + <text align ="left" length="17">${inventoryline.printName()}</text> + <text align ="right" length="10">${inventoryline.printPrice()}</text> + <text align ="right" length="5">x${inventoryline.printMultiply()}</text> + <text align ="right" length="10">${inventoryline.printSubValue()}</text> + </line> + #if ($inventoryline.productAttSetInstId) + <line><text align ="left" length="42">${inventoryline.productAttSetInstDesc}</text></line> + #end + #end + <line><text>------------------------------------------</text></line> + <line></line> + <line> + <text align ="left" bold="true" length="27">Totals :</text> + <text align ="right" bold="true" length="5">${inventoryrecord.printTotalArticles()}</text> + <text align ="right" bold="true" length="10">${inventoryrecord.printSubTotal()}</text> + </line> + <line></line> + <line><text align="center" length="42">Please keep this ticket</text></line> + </ticket> +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.OpenDrawer.xml b/src/main/resources/com/unicenta/pos/templates/Printer.OpenDrawer.xml new file mode 100644 index 0000000..be13014 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.OpenDrawer.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. + If not, see <http://www.gnu.org/licenses/>. + + --> +<output> + + <opendrawer/> + +</output> diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.PartialCash.xml b/src/main/resources/com/unicenta/pos/templates/Printer.PartialCash.xml new file mode 100644 index 0000000..e63f0da --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.PartialCash.xml @@ -0,0 +1,201 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + --> +<output> + <ticket> + <image>Printer.Ticket.Logo</image> + <line></line> + <line></line> + <line size="1"><text align="center" length="42" bold="true">Partial Cash Report</text></line> + <line></line> + +<!-- START OF SEQUENCE DETAIL --> + <line><text length="18" bold="true">Run by:</text><text>${payments.printUser()}</text></line> + <line><text length="18" bold="true">Terminal:</text><text>${payments.printHost()}</text></line> + <line><text length="18" bold="true">Sequence:</text><text>${payments.printSequence()}</text></line> + <line><text length="18" bold="true">Start Date:</text><text>${payments.printDateStart()}</text></line> + <line><text length="18" bold="true">End Date:</text><text>${payments.printDateEnd()}</text></line> + <line></line> +<!-- END OF SEQUENCE DETAIL --> + +<!-- START OF SALES --> + <line size="1"><text align="center" length="42" bold="true">Sales</text></line> + <line> + <text align ="left" length="16" bold="true">Name</text> + <text align ="right" length="6" bold="true">Sold</text> + <text align ="right" length="10" bold="true">Net</text> + <text align ="right" length="10" bold="true">Total</text> + </line> + <line><text>------------------------------------------</text></line> + #foreach ($line in $payments.getProductSalesLines()) + <line> + <text align ="left" length="16">${line.printProductName()}</text> + <text align ="right" length="6">${line.printProductUnits()}</text> + <text align ="right" length="10">${line.printProductPriceNet()}</text> + <text align ="right" length="10">${line.printProductSubValue()}</text> + </line> + #end + <line><text>------------------------------------------</text></line> + <line> + <text align ="left" length="16" bold="true">Total</text> + <text align ="right" length="6" bold="true">${payments.printProductSalesTotalUnits()}</text> + <text align ="right" length="10" bold="true">${payments.printSalesBase()}</text> + <text align ="right" length="10" bold="true">${payments.printProductSalesTotal()}</text> + </line> + <line></line> +<!-- END OF SALES SUMMARY --> + +<!-- START OF CATEGORIES SUMMARY --> + <line size="1"><text align="center" length="42" bold="true">Product Categories</text></line> + <line> + <text align ="left" length="16" bold="true">Name</text> + <text align ="right" length="6" bold="true">Sold</text> + <text align ="right" length="10" bold="true"></text> + <text align ="right" length="10" bold="true">Total</text> + </line> + <line><text>------------------------------------------</text></line> + #foreach ($line in $payments.getCategorySalesLines()) + <line> + <text align ="left" length="16">${line.printCategoryName()}</text> + <text align ="right" length="6">${line.printCategoryUnits()}</text> + <text align ="right" length="10"></text> + <text align ="right" length="10">${line.printCategorySum()}</text> + </line> + #end + <line><text>------------------------------------------</text></line> + <line><text align ="left" length="16" bold="true">Total</text> + <text align ="right" length="6" bold="true">${payments.printCategorySalesTotalUnits()}</text> + <text align ="right" length="10" bold="true"></text> + <text align ="right" length="10" bold="true">${payments.printCategorySalesTotal()}</text> + </line> + <line></line> +<!-- END OF CATEGORIES SUMMARY --> + +<!-- START OF VOIDS --> + <line size="1"><text align="center" length="42" bold="true">Line Voids</text></line> + <line> + <text align ="left" length="6" bold="true">Tkt</text> + <text align ="left" length="12" bold="true">User</text> + <text align ="left" length="19" bold="true">Product</text> + <text align ="right" length="5" bold="true">Total</text> + </line> + <line><text>------------------------------------------</text></line> + #foreach ($line in $payments.getRemovedProductLines()) + <line> + <text align ="left" length="6">${line.printTicketId()}</text> + <text align ="left" length="11">${line.printWorkerName()}</text> + <text align ="left" length="1"></text> + <text align ="left" length="19">${line.printProductName()}</text> + <text align ="right" length="5">${line.printTotalUnits()}</text> + </line> + #end + <line><text>------------------------------------------</text></line> + <line></line> +<!-- END OF VOIDS --> + +<!-- START OF NO SALES --> + <line size="1"><text align="center" length="42" bold="true">No Sales</text></line> + <line> + <text align ="left" length="34" bold="true">User</text> + <text align ="right" length="8" bold="true">Ticket</text> + </line> + <line><text>------------------------------------------</text></line> + #foreach ($line in $payments.getDrawerOpenedLines()) + <line> + <text align ="left" length="34">${line.printUserName()}</text> + <text align ="right" length="8">${line.printTicketId()}</text> + </line> + #end + <line><text>------------------------------------------</text></line> + <line></line> +<!-- END OF NO SALES --> + +<!-- START OF TAXES ANALYSIS --> + <line size="1"><text align="center" length="42" bold="true">Taxes</text></line> + <line> + <text align ="left" length="12" bold="true">Name</text> + <text align ="right" length="10" bold="true">Net</text> + <text align ="right" length="10" bold="true">Gross</text> + <text align ="right" length="10" bold="true">Total</text> + </line> + <line><text>------------------------------------------</text></line> + #foreach ($line in $payments.getSaleLines()) + <line> + <text align ="left" length="12">${line.printTaxName()}</text> + <text align ="right" length="10">${line.printTaxNet()}</text> + <text align ="right" length="10">${line.printTaxGross()}</text> + <text align ="right" length="10">${line.printTaxes()}</text> + + </line> + #end + <line><text>------------------------------------------</text></line> + <line></line> +<!-- END OF TAXES ANALYSIS --> + +<!-- START OF PAYMENTS --> + <line size="1"><text align="center" length="42" bold="true">Payments</text></line> + <line> + <text align ="left" length="32" bold="true">Type</text> + <text align ="right" length="10" bold="true">Total</text> + </line> + <line><text>------------------------------------------</text></line> + #foreach ($line in $payments.getPaymentLines()) + <line> + <text align ="left" length="22">${line.printType()}</text> + <text align ="right" length="10">${line.printReason()}</text> + <text align ="right" length="10">${line.printValue()}</text> + </line> + #end + <line><text>------------------------------------------</text></line> + <line> + <text align ="left" length="30" bold="true">Total</text> + <text align ="right" length="12" bold="true">${payments.printPaymentsTotal()}</text> + </line> + <line></line> +<!-- END OF PAYMENTS RECEIVED --> + +<!-- START OF TOTALS SUMMARY --> + <line><text>******************************************</text></line> + <line size="1"><text align="center" length="42" bold="true">SUMMARY</text></line> + <line><text>******************************************</text></line> + <line><text align ="left" length="30" bold="true">Tickets</text> + <text align ="right" length="12" bold="true">${payments.printSales()}</text> + </line> + <line><text align ="left" length="30" bold="true">Ticket Lines</text> + <text align ="right" length="12" bold="true">${payments.printProductSalesRows()}</text> + </line> + <line><text align ="left" length="30" bold="true">Payments</text> + <text align ="right" length="12" bold="true">${payments.printPayments()}</text> + </line> + <line><text align ="left" length="30" bold="true">Net Sales</text> + <text align ="right" length="12" bold="true">${payments.printSalesBase()}</text> + </line> + <line><text align ="left" length="30" bold="true">Tax</text> + <text align ="right" length="12" bold="true">${payments.printSalesTaxes()}</text> + </line> + <line><text align ="left" length="30" bold="true">Gross Sales</text> + <text align ="right" length="12" bold="true">${payments.printSalesTotal()}</text> + </line> +<!-- END OF TOTALS SUMMARY --> + + </ticket> + +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.PrintLastTicket.xml b/src/main/resources/com/unicenta/pos/templates/Printer.PrintLastTicket.xml new file mode 100644 index 0000000..06129e5 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.PrintLastTicket.xml @@ -0,0 +1,405 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + --> + +<output> + + <display> + <line><text align="left" length="8">Total</text><text align="right" length="12">${ticket.printTotal()}</text></line> + <line><text align="center" length="20">Thank you</text></line> + </display> + + <ticket> + <image>Printer.Ticket.Logo</image> + <line> + </line> + #if (${ticket.printTicketHeaderLine1()} != "") + <line> + <text align="center" length="42">${ticket.printTicketHeaderLine1()}</text> + </line> + #end + #if (${ticket.printTicketHeaderLine2()} != "") + <line> + <text align="center" length="42">${ticket.printTicketHeaderLine2()}</text> + </line> + #end + #if (${ticket.printTicketHeaderLine3()} != "") + <line> + <text align="center" length="42">${ticket.printTicketHeaderLine3()}</text> + </line> + #end + #if (${ticket.printTicketHeaderLine4()} != "") + <line> + <text align="center" length="42">${ticket.printTicketHeaderLine4()}</text> + </line> + #end + #if (${ticket.printTicketHeaderLine5()} != "") + <line> + <text align="center" length="42">${ticket.printTicketHeaderLine5()}</text> + </line> + #end + #if (${ticket.printTicketHeaderLine6()} != "") + <line> + <text align="center" length="42">${ticket.printTicketHeaderLine6()}</text> + </line> + #end + + <line> + <text align="center" length="42">Printer.PrintLastTicket</text> + </line> + <line></line> + #if (${ticket.ticketType} == 0) + <line> + <text align="left" length="15">Receipt:</text> + <text>${ticket.printId()}</text> + </line> + #end + #if (${ticket.ticketType} == 1) + <line> + <text align="left" length="15">Refund:</text> + <text>${ticket.printId()}</text> + </line> + #end + + <line> + <text align="left" length="15">Date:</text> + <text>${ticket.printDate()}</text> + </line> + <line> + <text align="left" length="15">Terminal: </text> + <text>${ticket.getHost()}</text> + </line> + <line> + <text align="left" length="15">Served by:</text> + <text>${ticket.printUser()}</text> + </line> + + #if ($ticket.getCustomer()) + <line> + <text align="left" length="15">Account #:</text> + <text>${ticket.getCustomer().printTaxCustomerID()}</text> + </line> + <line> + <text align="left" length="15">Customer:</text> + <text>${ticket.getCustomer().printName()}</text> + </line> + <line> + <text align="left" length="15">Address:</text> + <text>${ticket.getCustomer().printAddress()}</text> + </line> + <line> + <text align="left" length="15">Postal:</text> + <text>${ticket.getCustomer().printPostal()}</text> + </line> + <line> + <text align="left" length="15">Phone:</text> + <text>${ticket.getCustomer().printPhone()}</text> + </line> + <line> + <text align="left" length="15">Current Debt:</text> + <text>${ticket.getCustomer().printCurDebt()}</text> + </line> + #end + + #if (${tickettext.place} != ${place}) + <line> + <text align="left" length="15">Table:</text> + <text>${place}</text> + </line> + #end + <line></line> + + <line> + <text align ="left" length="17">Item</text> + <text align ="right" length="8">Price</text> + <text align ="right" length="7">Qty</text> + <text align ="right" length="10">Value</text> + </line> + <line> + <text align="left" length="42">------------------------------------------</text> + </line> + + #foreach ($ticketline in $ticket.getLines()) + <line> + #if ($ticketline.isProductCom()) + <text align ="left" length="17">*${ticketline.printName()}</text> + #else + <text align ="left" length="17">${ticketline.printName()}</text> + #end +<!-- Print line to show Prices pre-Tax + <text align ="right" length="8">${ticketline.printPrice()}</text> + <text align ="right" length="7">x${ticketline.printMultiply()}</text> + <text align ="right" length="8">${ticketline.printSubValue()}</text> + </line> +--> + +<!-- Print line to show Prices inc. Tax --> + <text align ="right" length="8">${ticketline.printPriceTax()}</text> + <text align ="right" length="7">x${ticketline.printMultiply()}</text> + <text align ="right" length="10">${ticketline.printValue()}</text> + </line> + +<!-- un-comment line below if you want to add a product's properties --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("ingredients", "")}</text> </line> --> + +<!-- un-comment line below if you want to add a user input sales line's Note --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("notes", "")}</text> </line> --> + +<!-- un-comment line below if you want to add a product's barcode --> + <!-- <line><text align ="left" length="12">Barcode : </text>${ticketline.printCode()}</text></line> --> + +<!-- un-comment line below if you want to add a product's Reference --> + <!-- <line><text align ="left" length="12">Reference : </text>${ticketline.printReference()}</text></line> --> + + #if ($ticketline.productAttSetInstId) + <line> + <text align ="left" length="42">${ticketline.productAttSetInstDesc}</text> + </line> + #end + #end + + <line><text align="left" length="42">------------------------------------------</text></line> + <line><text>Items count: </text><text align ="left" length="14">${ticket.printArticlesCount()}</text></line> + <line></line> + <line><text align ="left" bold="true" length="16">Subtotal</text><text align ="right" length="26">${ticket.printSubTotal()}</text></line> + <line><text align ="left" length="16">Tax</text><text align ="right" length="26">${ticket.printTax()}</text></line> + <line></line> + <line size="1"><text align ="left" length="16" bold="true">Balance Due</text><text align ="right" length="26" bold="true">${ticket.printTotal()}</text></line> + <line></line> + + #foreach ($taxinfo in $taxes) +<!-- #set( $taxline = $ticket.getTaxLine($taxinfo)) --> + <line> + <text align ="left" length="18">${taxline.getTaxInfo()}</text> + <text align ="right" length="12">${taxline.printSubTotal()}</text> + <text align ="right" length="12">${taxline.printTax()}</text> + </line> + #end + <line></line> + + #foreach ($paymentline in $ticket.payments) + #if ($paymentline.name == "cash") + <line><text bold="true">Cash</text></line> + <line> + <text align="left" length="22">Tendered:</text> + <text align ="right" length="20">${paymentline.printPaid()}</text> + </line> + <line> + <text align="left" length="22">Change:</text> + <text align ="right" length="20">${paymentline.printChange()}</text> + </line> + #end + + #if ($paymentline.name == "cashrefund") + <line> + <text align="left" length="22" bold="true">Refund</text> + <text align ="right" length="20">${paymentline.printTotal()}</text> + </line> + #end + #if ($paymentline.name == "cheque") + <line> + <text align="left" length="22" bold="true">Cheque</text> + <text align ="right" length="20">${paymentline.printTotal()}</text> + </line> + #end + #if ($paymentline.name == "chequerefund") + <line> + <text align="left" length="22" bold="true">Cheque Refund</text> + <text align ="right" length="20">${paymentline.printTotal()}</text> + </line> + #end + #if ($paymentline.name == "voucherin") + <line> + <text align="left" length="22" bold="true">Voucher</text> + <text align ="right" length="20">${paymentline.printTotal()}</text> + </line> + #end + #if ($paymentline.name == "voucherout") + <line> + <text align="left" length="22" bold="true">Note Refund</text> + <text align ="right" length="20">${paymentline.printTotal()}</text> + </line> + #end + #if ($paymentline.name == "slip") + <line> + <text align="left" length="22" bold="true">Slip</text> + <text align ="right" length="20">${paymentline.printTotal()}</text> + </line> + #end + #if ($paymentline.name == "free") + <line> + <text align="left" length="22" bold="true">Free</text> + <text align ="right" length="20">${paymentline.printTotal()}</text> + </line> + #end + #if ($paymentline.name == "debt") + <line> + <text align="left" length="22" bold="true">On Account</text> + <text align ="right" length="20">${paymentline.printTotal()}</text> + </line> + #end + #end + + #if (${ticket.printTicketFooterLine1()} != "") + <line></line> + <line> + <text align="center" length="42">${ticket.printTicketFooterLine1()}</text> + </line> + <line><text>==========================================</text></line> + #end + #if (${ticket.printTicketFooterLine2()} != "") + <line><text>${ticket.printTicketFooterLine2()}</text></line> + #end + #if (${ticket.printTicketFooterLine3()} != "") + <line><text>${ticket.printTicketFooterLine3()}</text></line> + #end + #if (${ticket.printTicketFooterLine4()} != "") + <line><text>${ticket.printTicketFooterLine4()}</text></line> + #end + #if (${ticket.printTicketFooterLine5()} != "") + <line><text>${ticket.printTicketFooterLine5()}</text></line> + #end + #if (${ticket.printTicketFooterLine6()} != "") + <line><text>${ticket.printTicketFooterLine6()}</text></line> + #end + <line></line> + + #foreach ($paymentline in $ticket.payments) + #if ($paymentline.name == "ccard") + #if ($paymentline.chipAndPin) + <line size="1"> + <text align="center" length="42" bold="true">CARD SALE</text> + </line> + <line size="1"> + <text>${paymentline.getCardName()}</text> + </line> + <line> + <text>${paymentline.printCardNumber()}</text> + </line> + <line></line> + <line size="1"> + <text align="left" length="10">AMOUNT</text> + <text align ="right" length="32">${paymentline.printTotal()}</text></line> + <line> + <text>Tranx ID : </text> + <text>${paymentline.printTransactionID()}</text> + </line> + <line> + <text>Auth Code : </text> + <text>${paymentline.printAuthorization()}</text> + </line> + <line> + <text>Verified By : </text> + <text>${paymentline.printVerification()}</text> + </line> + #end + #if (!$paymentline.chipAndPin) + <line size="1"> + <text align="center" length="42" bold="true">CARD SALE</text> + </line> + <line size="1"> + <text>${paymentline.getCardName()}</text> + </line> + <line> + <text>${paymentline.printCardNumber()}</text> + </line> + <line></line> + <line size="1"> + <text align="left" length="10">AMOUNT</text> + <text align ="right" length="32">${paymentline.printTotal()}</text></line> + <text align ="left" length="22">Expiration Date:</text> + <text>${paymentline.printExpirationDate()}</text> + </line> + <line> + <text>Operation : </text> + <text>${paymentline.printTransactionID()}</text> + </line> + <line> + <text>Auth Code : </text> + <text>${paymentline.printAuthorization()}</text> + </line> + <line></line> + #end + #if ($ticket.hasTip()) + <line> + <text align ="left" length="16">Tip:</text> + <text align ="right" length="26">_______________</text></line> + <line></line> + + <line size="1"> + <text align ="left" length="16" bold="false">Total</text> + <text align ="right" length="26" bold="false">_______________</text></line> + <line></line> + <line></line> + <line size="1"> + <text align ="left" length="42" bold="false">__________________________________________</text> + </line> + <line size="1"> + <text align ="center" length="42" bold="false">Signature</text> + </line> + #else + <line size="1"> + <text align ="left" length="16" bold="true">Total</text> + <text align ="right" length="26" bold="true">${ticket.printTotal()}</text> + </line> + #end + #end + #if ($paymentline.name == "ccardrefund") + <line size="1"> + <text align="center" length="42" bold="true">CARD REFUND</text> + </line> + <line size="1"> + <text>${paymentline.getCardName()}</text> + </line> + <line> + <text>${paymentline.printCardNumber()}</text> + </line> + <line></line> + <line size="1"> + <text align="left" length="10">AMOUNT</text> + <text align ="right" length="32">${paymentline.printTotal()}</text></line> + <line> + <text align ="left" length="22">Expiration Date:</text> + <text>${paymentline.printExpirationDate()}</text></line> + <line> + <text>Tranx ID : </text> + <text>${paymentline.printTransactionID()}</text> + </line> + <line> + <text>Auth Code : </text> + <text>${paymentline.printAuthorization()}</text> + </line> + <line></line> + #end + #end + +</ticket> + +#foreach ($paymentline in $ticket.payments) +#if ($paymentline.name == "cash") + <opendrawer/> +#end + #if ($paymentline.name == "cashrefund") + <opendrawer/> + #end +#end + +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.Product.xml b/src/main/resources/com/unicenta/pos/templates/Printer.Product.xml new file mode 100644 index 0000000..0ca57f5 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.Product.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + --> +<output> + <ticket> + <image>Printer.Ticket.Logo</image> + <line> + <text align="center" length="42">N.I.F. 00.000.000 X</text> + </line> + <line size="1"> + <text align ="center" length="42" bold="true">${product.printName()}</text> + </line> + <line></line> + <line size="3"> + <text>Eur.</text> + <text align ="right" length="6">${product.printPriceEur()}</text> + </line> + <line size="2"> + <text>Pts.</text> + <text align ="right" length="6">${product.printPricePts()}</text> + </line> + <barcode type="EAN13">${product.printCode()}</barcode> + </ticket> +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.ReprintTicket.xml b/src/main/resources/com/unicenta/pos/templates/Printer.ReprintTicket.xml new file mode 100644 index 0000000..9d14a1a --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.ReprintTicket.xml @@ -0,0 +1,303 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + --> + +<output> + + <display> + <line><text align="left" length="8">Total</text><text align="right" length="12">${ticket.printTotal()}</text></line> + <line><text align="center" length="20">Thank you</text></line> + </display> + + <ticket> + <image>Printer.Ticket.Logo</image> + <line></line> + #if (${ticket.printTicketHeaderLine1()} != "") + <line><text align="center" length="42">${ticket.printTicketHeaderLine1()}</text></line> + #end + #if (${ticket.printTicketHeaderLine2()} != "") + <line><text align="center" length="42">${ticket.printTicketHeaderLine2()}</text></line> + #end + #if (${ticket.printTicketHeaderLine3()} != "") + <line><text align="center" length="42">${ticket.printTicketHeaderLine3()}</text></line> + #end + #if (${ticket.printTicketHeaderLine4()} != "") + <line><text align="center" length="42">${ticket.printTicketHeaderLine4()}</text></line> + #end + #if (${ticket.printTicketHeaderLine5()} != "") + <line><text align="center" length="42">${ticket.printTicketHeaderLine5()}</text></line> + #end + #if (${ticket.printTicketHeaderLine6()} != "") + <line><text align="center" length="42">${ticket.printTicketHeaderLine6()}</text></line> + #end + + <line><text align="center" length="42">Printer.ReprintTicket</text></line> + <line></line> + #if (${ticket.ticketType} == 0) + <line><text align="left" length="15">Receipt:</text><text>${ticket.printId()}</text></line> + #end + #if (${ticket.ticketType} == 1) + <line><text align="left" length="15">Refund:</text><text>${ticket.printId()}</text></line> + #end + + <line><text align="left" length="15">Date:</text><text>${ticket.printDate()}</text></line> + <line><text align="left" length="15">Terminal: </text><text>${ticket.getHost()}</text></line> + <line><text align="left" length="15">Served by:</text><text>${ticket.printUser()}</text></line> + + #if ($ticket.getCustomer()) + <line><text align="left" length="15">Account #:</text><text>${ticket.getCustomer().printTaxCustomerID()}</text></line> + <line><text align="left" length="15">Customer:</text><text>${ticket.getCustomer().printName()}</text></line> + <line><text align="left" length="15">Address:</text><text>${ticket.getCustomer().printAddress()}</text></line> + <line><text align="left" length="15">Postal:</text><text>${ticket.getCustomer().printPostal()}</text></line> + <line><text align="left" length="15">Phone:</text><text>${ticket.getCustomer().printPhone1()}</text></line> + <line><text align="left" length="15">Current Debt:</text><text>${ticket.getCustomer().printCurDebt()}</text></line> + #end + + #if (${tickettext.place} != ${place}) + <line><text align="left" length="15">Table:</text><text>${place}</text></line> + #end + <line></line> + + <line> + <text align ="left" length="17">Item</text> + <text align ="right" length="8">Price</text> + <text align ="right" length="7">Qty</text> + <text align ="right" length="10">Value</text> + </line> + <line><text align="left" length="42">------------------------------------------</text></line> + + #foreach ($ticketline in $ticket.getLines()) + <line> + #if ($ticketline.isProductCom()) + <text align ="left" length="17">*${ticketline.printName()}</text> + #else + <text align ="left" length="17">${ticketline.printName()}</text> + #end + <!-- Print line to show Prices pre-Tax + <text align ="right" length="8">${ticketline.printPrice()}</text> + <text align ="right" length="7">x${ticketline.printMultiply()}</text> + <text align ="right" length="8">${ticketline.printSubValue()}</text> + </line> + --> + + <!-- Print line to show Prices inc. Tax --> + <text align ="right" length="8">${ticketline.printPriceTax()}</text> + <text align ="right" length="7">x${ticketline.printMultiply()}</text> + <text align ="right" length="10">${ticketline.printValue()}</text> + </line> + +<!-- un-comment line below if you want to add a product's properties --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("ingredients", "")}</text> </line> --> + +<!-- un-comment line below if you want to add a user input sales line's Note --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("notes", "")}</text> </line> --> + +<!-- un-comment line below if you want to add a product's barcode --> + <!-- <line><text align ="left" length="12">Barcode : </text>${ticketline.printCode()}</text></line> --> + +<!-- un-comment line below if you want to add a product's Reference --> + <!-- <line><text align ="left" length="12">Reference : </text>${ticketline.printReference()}</text></line> --> + + #if ($ticketline.productAttSetInstId) + <line><text align ="left" length="42">${ticketline.productAttSetInstDesc}</text></line> + #end + #end + + <line><text align="left" length="42">------------------------------------------</text></line> + <line><text>Items count: </text><text align ="left" length="14">${ticket.printArticlesCount()}</text></line> + <line></line> + <line><text align ="left" bold="true" length="16">Subtotal</text><text align ="right" length="26">${ticket.printSubTotal()}</text></line> + <line><text align ="left" length="16">Tax</text><text align ="right" length="26">${ticket.printTax()}</text></line> + <line></line> + <line size="1"><text align ="left" length="16" bold="true">Balance Due</text> + <text align ="right" length="26" bold="true">${ticket.printTotal()}</text> + </line> + <line></line> + + #foreach ($taxinfo in $taxes) +<!-- #set( $taxline = $ticket.getTaxLine($taxinfo)) --> + <line> + <text align ="left" length="18">${taxline.getTaxInfo()}</text> + <text align ="right" length="12">${taxline.printSubTotal()}</text> + <text align ="right" length="12">${taxline.printTax()}</text> + </line> + #end + <line></line> + + #foreach ($paymentline in $ticket.payments) + #if ($paymentline.name == "cash") + <line><text bold="true">Cash</text></line> + <line><text align="left" length="22">Tendered:</text><text align ="right" length="20">${paymentline.printPaid()}</text></line> + <line><text align="left" length="22">Change:</text><text align ="right" length="20">${paymentline.printChange()}</text></line> + #end + + #if ($paymentline.name == "cashrefund") + <line> + <text align="left" length="22" bold="true">Refund</text> + <text align ="right" length="20">${paymentline.printTotal()}</text> + </line> + #end + #if ($paymentline.name == "cheque") + <line> + <text align="left" length="22" bold="true">Cheque</text> + <text align ="right" length="20">${paymentline.printTotal()}</text> + </line> + #end + #if ($paymentline.name == "chequerefund") + <line> + <text align="left" length="22" bold="true">Cheque Refund</text> + <text align ="right" length="20">${paymentline.printTotal()}</text> + </line> + #end + #if ($paymentline.name == "voucherin") + <line> + <text align="left" length="22" bold="true">Voucher</text> + <text align ="right" length="20">${paymentline.printTotal()}</text> + </line> + #end + #if ($paymentline.name == "voucherout") + <line> + <text align="left" length="22" bold="true">Note Refund</text> + <text align ="right" length="20">${paymentline.printTotal()}</text> + </line> + #end + #if ($paymentline.name == "slip") + <line> + <text align="left" length="22" bold="true">Slip</text> + <text align ="right" length="20">${paymentline.printTotal()}</text> + </line> + #end + #if ($paymentline.name == "free") + <line> + <text align="left" length="22" bold="true">Free</text> + <text align ="right" length="20">${paymentline.printTotal()}</text> + </line> + #end + #if ($paymentline.name == "debt") + <line> + <text align="left" length="22" bold="true">On Account</text> + <text align ="right" length="20">${paymentline.printTotal()}</text> + </line> + #end + #end + + #if (${ticket.printTicketFooterLine1()} != "") + <line></line> + <line> + <text align="center" length="42">${ticket.printTicketFooterLine1()}</text> + </line> + <line><text>==========================================</text></line> + #end + #if (${ticket.printTicketFooterLine2()} != "") + <line><text>${ticket.printTicketFooterLine2()}</text></line> + #end + #if (${ticket.printTicketFooterLine3()} != "") + <line><text>${ticket.printTicketFooterLine3()}</text></line> + #end + #if (${ticket.printTicketFooterLine4()} != "") + <line><text>${ticket.printTicketFooterLine4()}</text></line> + #end + #if (${ticket.printTicketFooterLine5()} != "") + <line><text>${ticket.printTicketFooterLine5()}</text></line> + #end + #if (${ticket.printTicketFooterLine6()} != "") + <line><text>${ticket.printTicketFooterLine6()}</text></line> + #end + <line></line> + + #foreach ($paymentline in $ticket.payments) + #if ($paymentline.name == "ccard") + #if ($paymentline.chipAndPin) + <line size="1"><text align="center" length="42" bold="true">CARD SALE</text></line> + <line size="1"><text>${paymentline.getCardName()}</text></line> + <line><text>${paymentline.printCardNumber()}</text></line> + <line></line> + <line size="1"> + <text align="left" length="10">AMOUNT</text> + <text align ="right" length="32">${paymentline.printTotal()}</text></line> + <line><text>Tranx ID : </text><text>${paymentline.printTransactionID()}</text></line> + <line><text>Auth Code : </text><text>${paymentline.printAuthorization()}</text></line> + <line><text>Verified By : </text><text>${paymentline.printVerification()}</text></line> + #end + #if (!$paymentline.chipAndPin) + <line size="1"><text align="center" length="42" bold="true">CARD SALE</text></line> + <line size="1"><text>${paymentline.getCardName()}</text></line> + <line><text>${paymentline.printCardNumber()}</text></line> + <line></line> + <line size="1"> + <text align="left" length="10">AMOUNT</text> + <text align ="right" length="32">${paymentline.printTotal()}</text> + </line> + <line> + <text align ="left" length="22">Expiration Date:</text> + <text>${paymentline.printExpirationDate()}</text> + </line> + <line><text>Operation : </text><text>${paymentline.printTransactionID()}</text></line> + <line><text>Auth Code : </text><text>${paymentline.printAuthorization()}</text></line> + <line></line> + #end + #if ($ticket.hasTip()) + <line><text align ="left" length="16">Tip:</text><text align ="right" length="26">_______________</text></line> + <line></line> + <line size="1"> + <text align ="left" length="16" bold="false">Total</text> + <text align ="right" length="26" bold="false">_______________</text></line> + <line></line> + <line></line> + <line size="1"> + <text align ="left" length="42" bold="false">__________________________________________</text> + </line> + <line size="1"> + <text align ="center" length="42" bold="false">Signature</text> + </line> + #else + <line size="1"> + <text align ="left" length="16" bold="true">Total</text> + <text align ="right" length="26" bold="true">${ticket.printTotal()}</text> + </line> + #end + #end + #if ($paymentline.name == "ccardrefund") + <line size="1"><text align="center" length="42" bold="true">CARD REFUND</text></line> + <line size="1"><text>${paymentline.getCardName()}</text></line> + <line><text>${paymentline.printCardNumber()}</text></line> + <line></line> + <line size="1"><text align="left" length="10">AMOUNT</text><text align ="right" length="32">${paymentline.printTotal()}</text></line> + <line><text align ="left" length="22">Expiration Date:</text><text>${paymentline.printExpirationDate()}</text></line> + <line><text>Tranx ID : </text><text>${paymentline.printTransactionID()}</text></line> + <line><text>Auth Code : </text><text>${paymentline.printAuthorization()}</text></line> + <line></line> + #end + #end + +</ticket> + +<!-- unComment this block if you want to open Cashdrawer in Print Preview +#foreach ($paymentline in $ticket.payments) + #if ($paymentline.name == "cash") + <opendrawer/> + #end + #if ($paymentline.name == "cashrefund") + <opendrawer/> + #end +#end --> + +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.Start.xml b/src/main/resources/com/unicenta/pos/templates/Printer.Start.xml new file mode 100644 index 0000000..c6f7214 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.Start.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + --> + +<output> +<!-- DISPLAY ANIMATION OPTIONS --> +<!-- <display animation="flyer"> --> +<!-- <display animation="scroll"> --> +<!-- <display animation="blink"> --> +<!-- <display animation="curtain"> --> + + <display animation="none"> + <line><text align="center" length="20">uniCenta oPOS</text></line> + <line><text align="center" length="20">Touch Friendly POS</text></line> + </display> +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P1.xml b/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P1.xml new file mode 100644 index 0000000..648780a --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P1.xml @@ -0,0 +1,86 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +--> + +<output> + <display> + <line> + <text align="left" length="10">Order sent to P1</text> + <text align="right" length="10">${ticket.printTotal()}</text> + </line> + <line> + <text align="center" length="20">Thank you.</text> + </line> + </display> + + <ticket printer="1"> + <line></line> + <line></line> + <line size = "1"><text bold = "true" align="center" length="42">Printer 1</text></line> + <line></line> + <line size = "1"><text>Order : </text><text bold = "true">${ticket.getPickupId()}</text></line> + + #if (${tickettext.place} != ${place}) + <line size = "1"><text align="left" length="15">Table:</text><text>${place}</text></line> + #end + + <line><text align="left" length="15">Date:</text><text>${ticket.printDate()}</text></line> + <line><text align="left" length="15">Sent from: </text><text>${ticket.getHost()}</text></line> + <line><text align="left" length="15">Server:</text><text>${ticket.printUser()}</text></line> + + #if ($ticket.getCustomer()) + <line><text align="left" length="15">Customer:</text><text>${ticket.getCustomer().getName()}</text></line> + <line><text align="left" length="15">Account #:</text><text>${ticket.getCustomer().getTaxid()}</text></line> + #end + + <line></line> + <line><text align ="left" length="17">Item</text><text align ="right" length="5"></text></line> + <line><text>------------------------------------------</text></line> + + #foreach ($ticketline in $ticket.getLines()) + #if($ticketline.printPrinter().equals("1")) + #if($ticketline.getProperty("ticket.updated").equals("true")) + #if ($ticketline.isProductCom()) + <line size="1"><text align ="left" length="37">--${ticketline.printName()}</text></line> + #else + <line size="1"> + <text align ="left" length="5"> ${ticketline.printMultiply()}x</text> + <text align ="left" length="37"> ${ticketline.printName()}</text> + </line> + #end + + <!-- un-comment line below if you want to add a product's properties --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("ingredients", "")}</text> </line> --> + + <!-- un-comment line below if you want to add a user input sales line's Note --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("notes", "")}</text> </line> --> + + <!-- Add the following lines only for 2.30 Attributes --> + #if ($ticketline.productAttSetInstId) + <line><text align ="left" length="42">${ticketline.productAttSetInstDesc}</text></line> + <line></line> + #end + ${ticketline.setProperty("ticket.updated", "false")} + #end + #end + #end + </ticket> +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P2.xml b/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P2.xml new file mode 100644 index 0000000..533d8c5 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P2.xml @@ -0,0 +1,86 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +--> + +<output> + <display> + <line> + <text align="left" length="10">Order sent to P2</text> + <text align="right" length="10">${ticket.printTotal()}</text> + </line> + <line> + <text align="center" length="20">Thank you.</text> + </line> + </display> + + <ticket printer="2"> + <line></line> + <line></line> + <line size = "1"><text bold = "true" align="center" length="42">Printer 2</text></line> + <line></line> + <line size = "1"><text>Order : </text><text bold = "true">${ticket.getPickupId()}</text></line> + + <line><text align="left" length="15">Date:</text><text>${ticket.printDate()}</text></line> + <line><text align="left" length="15">Sent from: </text><text>${ticket.getHost()}</text></line> + <line><text align="left" length="15">Server:</text><text>${ticket.printUser()}</text></line> + + #if ($ticket.getCustomer()) + <line><text align="left" length="15">Customer:</text><text>${ticket.getCustomer().getName()}</text></line> + <line><text align="left" length="15">Account #:</text><text>${ticket.getCustomer().getTaxid()}</text></line> + #end + + #if (${tickettext.place} != ${place}) + <line><text align="left" length="15">Table:</text><text>${place}</text></line> + #end + + <line></line> + <line><text align ="left" length="17">Item</text><text align ="right" length="5"></text></line> + <line><text>------------------------------------------</text></line> + + #foreach ($ticketline in $ticket.getLines()) + #if($ticketline.printPrinter().equals("2")) + #if($ticketline.getProperty("ticket.updated").equals("true")) + #if ($ticketline.isProductCom()) + <line size="1"><text align ="left" length="37">--${ticketline.printName()}</text></line> + #else + <line size="1"> + <text align ="left" length="5"> ${ticketline.printMultiply()}x</text> + <text align ="left" length="37"> ${ticketline.printName()}</text> + </line> + #end + + <!-- un-comment line below if you want to add a product's properties --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("ingredients", "")}</text> </line> --> + + <!-- un-comment line below if you want to add a user input sales line's Note --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("notes", "")}</text> </line> --> + + <!-- Add the following lines only for 2.30 Attributes --> + #if ($ticketline.productAttSetInstId) + <line><text align ="left" length="42">${ticketline.productAttSetInstDesc}</text></line> + <line></line> + #end + ${ticketline.setProperty("ticket.updated", "false")} + #end + #end + #end + </ticket> +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P3.xml b/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P3.xml new file mode 100644 index 0000000..2792a1f --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P3.xml @@ -0,0 +1,86 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +--> + +<output> + <display> + <line> + <text align="left" length="10">Order sent to P3</text> + <text align="right" length="10">${ticket.printTotal()}</text> + </line> + <line> + <text align="center" length="20">Thank you.</text> + </line> + </display> + + <ticket printer="3"> + <line></line> + <line></line> + <line size = "1"><text bold = "true" align="center" length="42">Printer 3</text></line> + <line></line> + <line size = "1"><text>Order : </text><text bold = "true">${ticket.getPickupId()}</text></line> + + <line><text align="left" length="15">Date:</text><text>${ticket.printDate()}</text></line> + <line><text align="left" length="15">Sent from: </text><text>${ticket.getHost()}</text></line> + <line><text align="left" length="15">Server:</text><text>${ticket.printUser()}</text></line> + + #if ($ticket.getCustomer()) + <line><text align="left" length="15">Customer:</text><text>${ticket.getCustomer().getName()}</text></line> + <line><text align="left" length="15">Account #:</text><text>${ticket.getCustomer().getTaxid()}</text></line> + #end + + #if (${tickettext.place} != ${place}) + <line><text align="left" length="15">Table:</text><text>${place}</text></line> + #end + + <line></line> + <line><text align ="left" length="17">Item</text><text align ="right" length="5"></text></line> + <line><text>------------------------------------------</text></line> + + #foreach ($ticketline in $ticket.getLines()) + #if($ticketline.printPrinter().equals("3")) + #if($ticketline.getProperty("ticket.updated").equals("true")) + #if ($ticketline.isProductCom()) + <line size="1"><text align ="left" length="37">--${ticketline.printName()}</text></line> + #else + <line size="1"> + <text align ="left" length="5"> ${ticketline.printMultiply()}x</text> + <text align ="left" length="37"> ${ticketline.printName()}</text> + </line> + #end + + <!-- un-comment line below if you want to add a product's properties --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("ingredients", "")}</text> </line> --> + + <!-- un-comment line below if you want to add a user input sales line's Note --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("notes", "")}</text> </line> --> + + <!-- Add the following lines only for 2.30 Attributes --> + #if ($ticketline.productAttSetInstId) + <line><text align ="left" length="42">${ticketline.productAttSetInstDesc}</text></line> + <line></line> + #end + ${ticketline.setProperty("ticket.updated", "false")} + #end + #end + #end + </ticket> +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P4.xml b/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P4.xml new file mode 100644 index 0000000..947a212 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P4.xml @@ -0,0 +1,86 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +--> + +<output> + <display> + <line> + <text align="left" length="10">Order sent to P4</text> + <text align="right" length="10">${ticket.printTotal()}</text> + </line> + <line> + <text align="center" length="20">Thank you.</text> + </line> + </display> + + <ticket printer="4"> + <line></line> + <line></line> + <line size = "1"><text bold = "true" align="center" length="42">Printer 4</text></line> + <line></line> + <line size = "1"><text>Order : </text><text bold = "true">${ticket.getPickupId()}</text></line> + + <line><text align="left" length="15">Date:</text><text>${ticket.printDate()}</text></line> + <line><text align="left" length="15">Sent from: </text><text>${ticket.getHost()}</text></line> + <line><text align="left" length="15">Server:</text><text>${ticket.printUser()}</text></line> + + #if ($ticket.getCustomer()) + <line><text align="left" length="15">Customer:</text><text>${ticket.getCustomer().getName()}</text></line> + <line><text align="left" length="15">Account #:</text><text>${ticket.getCustomer().getTaxid()}</text></line> + #end + + #if (${tickettext.place} != ${place}) + <line><text align="left" length="15">Table:</text><text>${place}</text></line> + #end + + <line></line> + <line><text align ="left" length="17">Item</text><text align ="right" length="5"></text></line> + <line><text>------------------------------------------</text></line> + + #foreach ($ticketline in $ticket.getLines()) + #if($ticketline.printPrinter().equals("4")) + #if($ticketline.getProperty("ticket.updated").equals("true")) + #if ($ticketline.isProductCom()) + <line size="1"><text align ="left" length="37">--${ticketline.printName()}</text></line> + #else + <line size="1"> + <text align ="left" length="5"> ${ticketline.printMultiply()}x</text> + <text align ="left" length="37"> ${ticketline.printName()}</text> + </line> + #end + + <!-- un-comment line below if you want to add a product's properties --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("ingredients", "")}</text> </line> --> + + <!-- un-comment line below if you want to add a user input sales line's Note --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("notes", "")}</text> </line> --> + + <!-- Add the following lines only for 2.30 Attributes --> + #if ($ticketline.productAttSetInstId) + <line><text align ="left" length="42">${ticketline.productAttSetInstDesc}</text></line> + <line></line> + #end + ${ticketline.setProperty("ticket.updated", "false")} + #end + #end + #end + </ticket> +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P5.xml b/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P5.xml new file mode 100644 index 0000000..0e9f623 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P5.xml @@ -0,0 +1,86 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +--> + +<output> + <display> + <line> + <text align="left" length="10">Order sent to P5</text> + <text align="right" length="10">${ticket.printTotal()}</text> + </line> + <line> + <text align="center" length="20">Thank you.</text> + </line> + </display> + + <ticket printer="5"> + <line></line> + <line></line> + <line size = "1"><text bold = "true" align="center" length="42">Printer 5</text></line> + <line></line> + <line size = "1"><text>Order : </text><text bold = "true">${ticket.getPickupId()}</text></line> + + <line><text align="left" length="15">Date:</text><text>${ticket.printDate()}</text></line> + <line><text align="left" length="15">Sent from: </text><text>${ticket.getHost()}</text></line> + <line><text align="left" length="15">Server:</text><text>${ticket.printUser()}</text></line> + + #if ($ticket.getCustomer()) + <line><text align="left" length="15">Customer:</text><text>${ticket.getCustomer().getName()}</text></line> + <line><text align="left" length="15">Account #:</text><text>${ticket.getCustomer().getTaxid()}</text></line> + #end + + #if (${tickettext.place} != ${place}) + <line><text align="left" length="15">Table:</text><text>${place}</text></line> + #end + + <line></line> + <line><text align ="left" length="17">Item</text><text align ="right" length="5"></text></line> + <line><text>------------------------------------------</text></line> + + #foreach ($ticketline in $ticket.getLines()) + #if($ticketline.printPrinter().equals("5")) + #if($ticketline.getProperty("ticket.updated").equals("true")) + #if ($ticketline.isProductCom()) + <line size="1"><text align ="left" length="37">--${ticketline.printName()}</text></line> + #else + <line size="1"> + <text align ="left" length="5"> ${ticketline.printMultiply()}x</text> + <text align ="left" length="37"> ${ticketline.printName()}</text> + </line> + #end + + <!-- un-comment line below if you want to add a product's properties --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("ingredients", "")}</text> </line> --> + + <!-- un-comment line below if you want to add a user input sales line's Note --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("notes", "")}</text> </line> --> + + <!-- Add the following lines only for 2.30 Attributes --> + #if ($ticketline.productAttSetInstId) + <line><text align ="left" length="42">${ticketline.productAttSetInstDesc}</text></line> + <line></line> + #end + ${ticketline.setProperty("ticket.updated", "false")} + #end + #end + #end + </ticket> +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P6.xml b/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P6.xml new file mode 100644 index 0000000..ac00dff --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.P6.xml @@ -0,0 +1,86 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +--> + +<output> + <display> + <line> + <text align="left" length="10">Order sent to P6</text> + <text align="right" length="10">${ticket.printTotal()}</text> + </line> + <line> + <text align="center" length="20">Thank you.</text> + </line> + </display> + + <ticket printer="6"> + <line></line> + <line></line> + <line size = "1"><text bold = "true" align="center" length="42">Printer 6</text></line> + <line></line> + <line size = "1"><text>Order : </text><text bold = "true">${ticket.getPickupId()}</text></line> + + <line><text align="left" length="15">Date:</text><text>${ticket.printDate()}</text></line> + <line><text align="left" length="15">Sent from: </text><text>${ticket.getHost()}</text></line> + <line><text align="left" length="15">Server:</text><text>${ticket.printUser()}</text></line> + + #if ($ticket.getCustomer()) + <line><text align="left" length="15">Customer:</text><text>${ticket.getCustomer().getName()}</text></line> + <line><text align="left" length="15">Account #:</text><text>${ticket.getCustomer().getTaxid()}</text></line> + #end + + #if (${tickettext.place} != ${place}) + <line><text align="left" length="15">Table:</text><text>${place}</text></line> + #end + + <line></line> + <line><text align ="left" length="17">Item</text><text align ="right" length="5"></text></line> + <line><text>------------------------------------------</text></line> + + #foreach ($ticketline in $ticket.getLines()) + #if($ticketline.printPrinter().equals("6")) + #if($ticketline.getProperty("ticket.updated").equals("true")) + #if ($ticketline.isProductCom()) + <line size="1"><text align ="left" length="37">--${ticketline.printName()}</text></line> + #else + <line size="1"> + <text align ="left" length="5"> ${ticketline.printMultiply()}x</text> + <text align ="left" length="37"> ${ticketline.printName()}</text> + </line> + #end + + <!-- un-comment line below if you want to add a product's properties --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("ingredients", "")}</text> </line> --> + + <!-- un-comment line below if you want to add a user input sales line's Note --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("notes", "")}</text> </line> --> + + <!-- Add the following lines only for 2.30 Attributes --> + #if ($ticketline.productAttSetInstId) + <line><text align ="left" length="42">${ticketline.productAttSetInstDesc}</text></line> + <line></line> + #end + ${ticketline.setProperty("ticket.updated", "false")} + #end + #end + #end + </ticket> +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.xml b/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.xml new file mode 100644 index 0000000..6e82338 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.Ticket.xml @@ -0,0 +1,270 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2019 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + --> + +<output> + + <display> + <line><text align="left" length="8">Total</text><text align="right" length="12">${ticket.printTotal()}</text></line> + <line><text align="center" length="20">Thank you</text></line> + </display> + + <ticket> + <image>Printer.Ticket.Logo</image> + <line> + </line> + #if (${ticket.printTicketHeaderLine1()} != "") + <line><text align="center" length="42">${ticket.printTicketHeaderLine1()}</text></line> + #end + #if (${ticket.printTicketHeaderLine2()} != "") + <line><text align="center" length="42">${ticket.printTicketHeaderLine2()}</text></line> + #end + #if (${ticket.printTicketHeaderLine3()} != "") + <line><text align="center" length="42">${ticket.printTicketHeaderLine3()}</text></line> + #end + #if (${ticket.printTicketHeaderLine4()} != "") + <line><text align="center" length="42">${ticket.printTicketHeaderLine4()}</text></line> + #end + #if (${ticket.printTicketHeaderLine5()} != "") + <line><text align="center" length="42">${ticket.printTicketHeaderLine5()}</text></line> + #end + #if (${ticket.printTicketHeaderLine6()} != "") + <line><text align="center" length="42">${ticket.printTicketHeaderLine6()}</text></line> + #end + + <line><text align="center" length="42">Printer.Ticket</text></line> + <line></line> + #if (${ticket.ticketType} == 0) + <line><text align="left" length="15">Receipt:</text><text>${ticket.printId()}</text></line> + #end + #if (${ticket.ticketType} == 1) + <line><text align="left" length="15">Refund:</text><text>${ticket.printId()}</text></line> + #end + + <line><text align="left" length="15">Date:</text><text>${ticket.printDate()}</text></line> + <line><text align="left" length="15">Terminal: </text><text>${ticket.getHost()}</text></line> + <line><text align="left" length="15">Served by:</text><text>${ticket.printUser()}</text></line> + + #if ($ticket.getCustomer()) + <line><text align="left" length="15">Account #:</text><text>${ticket.getCustomer().printTaxCustomerID()}</text></line> + <line><text align="left" length="15">Customer:</text><text>${ticket.getCustomer().printName()}</text></line> + <line><text align="left" length="15">Address:</text><text>${ticket.getCustomer().printAddress()}</text></line> + <line><text align="left" length="15">Postal:</text><text>${ticket.getCustomer().printPostal()}</text></line> + <line><text align="left" length="15">Phone:</text><text>${ticket.getCustomer().printPhone1()}</text></line> + <line><text align="left" length="15">Current Debt:</text><text>${ticket.getCustomer().printCurDebt()}</text></line> + <line><text align="left" length="15">Balance:</text><text>${ticket.getCustomer().printCurBal()}</text></line> + <line><text align="left" length="15">TaxId:</text><text>${ticket.getCustomer().getTaxid()}</text></line> + #end + + #if (${tickettext.place} != ${place}) + <line><text align="left" length="15">Table:</text><text>${place}</text></line> + #end + <line></line> + <line> + <text align ="left" length="17">Item</text> + <text align ="right" length="8">Price</text> + <text align ="right" length="7">Qty</text> + <text align ="right" length="10">Value</text> + </line> + <line><text align="left" length="42">------------------------------------------</text></line> + + #foreach ($ticketline in $ticket.getLines()) + <line> + #if ($ticketline.isProductCom()) + <text align ="left" length="17">*${ticketline.printName()}</text> + #else + <text align ="left" length="17">${ticketline.printName()}</text> + #end + <!-- Print line to show Prices pre-Tax + <text align ="right" length="8">${ticketline.printPrice()}</text> + <text align ="right" length="7">x${ticketline.printMultiply()}</text> + <text align ="right" length="8">${ticketline.printSubValue()}</text> + </line> + --> + + <!-- Print line to show Prices inc. Tax --> + <text align ="right" length="8">${ticketline.printPriceTax()}</text> + <text align ="right" length="7">x${ticketline.printMultiply()}</text> + <text align ="right" length="10">${ticketline.printValue()}</text> + </line> + + <!-- un-comment line below if you want to add a product's properties --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("ingredients", "")}</text> </line> --> + + <!-- un-comment line below if you want to add a user input sales line's Note --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("notes", "")}</text> </line> --> + + <!-- un-comment line below if you want to add a product's barcode --> + <!-- <line><text align ="left" length="12">Barcode : </text>${ticketline.printCode()}</text></line> --> + + <!-- un-comment line below if you want to add a product's Reference --> + <!-- <line><text align ="left" length="12">Reference : </text>${ticketline.printReference()}</text></line> --> + + #if ($ticketline.productAttSetInstId) + <line><text align ="left" length="42">${ticketline.productAttSetInstDesc}</text></line> + #end + #end + + <line><text align="left" length="42">------------------------------------------</text></line> + <line><text>Items count: </text><text align ="left" length="14">${ticket.printArticlesCount()}</text></line> + <line></line> + <line> + <text align ="left" bold="true" length="16">Subtotal</text> + <text align ="right" length="26">${ticket.printSubTotal()}</text> + </line> + <line> + <text align ="left" length="16">Tax</text> + <text align ="right" length="26">${ticket.printTax()}</text> + </line> + <line></line> + <line size="1"> + <text align ="left" length="16" bold="true">Balance Due</text> + <text align ="right" length="26" bold="true">${ticket.printTotal()}</text> + </line> + <line></line> + + #foreach ($taxinfo in $taxes) + #set( $taxline = $ticket.getTaxLine($taxinfo)) + <line> + <text align ="left" length="18">${taxline.getTaxInfo()}</text> + <text align ="right" length="12">${taxline.printSubTotal()}</text> + <text align ="right" length="12">${taxline.printTax()}</text> + </line> + #end + <line></line> + + #foreach ($paymentline in $ticket.payments) + #if ($paymentline.name == "cash") + <line><text bold="true">Cash</text></line> + <line><text align="left" length="22">Tendered:</text><text align ="right" length="20">${paymentline.printPaid()}</text></line> + <line><text align="left" length="22">Change:</text><text align ="right" length="20">${paymentline.printChange()}</text></line> + #end + + #if ($paymentline.name == "cashrefund") + <line><text align="left" length="22" bold="true">Refund</text><text align ="right" length="20">${paymentline.printPaid()}</text></line> + #end + #if ($paymentline.name == "cheque") + <line><text align="left" length="22" bold="true">Cheque</text><text align ="right" length="20">${paymentline.printPaid()}</text></line> + #end + #if ($paymentline.name == "chequerefund") + <line><text align="left" length="22" bold="true">Cheque Refund</text><text align ="right" length="20">${paymentline.printPaid()}</text></line> + #end + #if ($paymentline.name == "voucherin") + <line><text align="left" length="22" bold="true">Voucher : ${paymentline.printVoucherNumber()}</text><text align ="right" length="20">${paymentline.printPaid()}</text></line> + #end + #if ($paymentline.name == "voucherout") + <line><text align="left" length="22" bold="true">Voucher Refund : ${paymentline.printVoucherNumber()}</text><text align ="right" length="20">${paymentline.printPaid()}</text></line> + #end + #if ($paymentline.name == "slip") + <line><text align="left" length="22" bold="true">Slip</text><text align ="right" length="20">${paymentline.printPaid()}</text></line> + #end + #if ($paymentline.name == "free") + <line><text align="left" length="22" bold="true">Free</text><text align ="right" length="20">${paymentline.printPaid()}</text></line> + #end + #if ($paymentline.name == "debt") + <line><text align="left" length="22" bold="true">On Account</text><text align ="right" length="20">${paymentline.printPaid()}</text></line> + #end + #end + + #if (${ticket.printTicketFooterLine1()} != "") + <line></line> + <line><text align="center" length="42">${ticket.printTicketFooterLine1()}</text></line> + <line><text>==========================================</text></line> + #end + #if (${ticket.printTicketFooterLine2()} != "") + <line><text>${ticket.printTicketFooterLine2()}</text></line> + #end + #if (${ticket.printTicketFooterLine3()} != "") + <line><text>${ticket.printTicketFooterLine3()}</text></line> + #end + #if (${ticket.printTicketFooterLine4()} != "") + <line><text>${ticket.printTicketFooterLine4()}</text></line> + #end + #if (${ticket.printTicketFooterLine5()} != "") + <line><text>${ticket.printTicketFooterLine5()}</text></line> + #end + #if (${ticket.printTicketFooterLine6()} != "") + <line><text>${ticket.printTicketFooterLine6()}</text></line> + #end + <line></line> + + #foreach ($paymentline in $ticket.payments) + + #if ($paymentline.name == "ccard") + #if ($paymentline.chipAndPin) + <line size="1"><text align="center" length="42" bold="true">CARD SALE</text></line> + <line size="1"><text>${paymentline.getCardName()}</text></line> + <line><text>${paymentline.printCardNumber()}</text></line> + <line></line> + <line size="1"><text align="left" length="10">AMOUNT</text><text align ="right" length="32">${paymentline.printTotal()}</text></line> + <line><text>Tranx ID : </text><text>${paymentline.printTransactionID()}</text></line> + <line><text>Auth Code : </text><text>${paymentline.printAuthorization()}</text></line> + <line><text>Verified By : </text><text>${paymentline.printVerification()}</text></line> + <line><text>Card # (last 4) : </text><text>${paymentline.printLastFourDigits()}</text></line> + #end + #if (!$paymentline.chipAndPin) + <line size="1"><text align="center" length="42" bold="true">CARD SALE</text></line> + <line size="1"><text>${paymentline.getCardName()}</text></line> + <line><text>${paymentline.printCardNumber()}</text></line> + <line></line> + <line size="1"><text align="left" length="10">AMOUNT</text><text align ="right" length="32">${paymentline.printTotal()}</text></line> + <line><text align ="left" length="22">Expiration Date:</text><text>${paymentline.printExpirationDate()}</text></line> + <line><text>Operation : </text><text>${paymentline.printTransactionID()}</text></line> + <line><text>Auth Code : </text><text>${paymentline.printAuthorization()}</text></line> + <line></line> + #end + #if ($ticket.hasTip()) + <line><text align ="left" length="16">Tip:</text><text align ="right" length="26">_______________</text></line> + <line></line> + <line size="1"><text align ="left" length="16" bold="false">Total</text><text align ="right" length="26" bold="false">_______________</text></line> + <line></line> + <line></line> + <line size="1"><text align ="left" length="42" bold="false">__________________________________________</text></line> + <line size="1"><text align ="center" length="42" bold="false">Signature</text></line> + #else + <line size="1"><text align ="left" length="16" bold="true">Total</text><text align ="right" length="26" bold="true">${paymentline.printTotal()}</text></line> + #end + #end + #if ($paymentline.name == "ccardrefund") + <line size="1"><text align="center" length="42" bold="true">CARD REFUND</text></line> + <line size="1"><text>${paymentline.getCardName()}</text></line> + <line><text>${paymentline.printCardNumber()}</text></line> + <line></line> + <line size="1"><text align="left" length="10">AMOUNT</text><text align ="right" length="32">${paymentline.printTotal()}</text></line> + <line><text align ="left" length="22">Expiration Date:</text><text>${paymentline.printExpirationDate()}</text></line> + <line><text>Tranx ID : </text><text>${paymentline.printTransactionID()}</text></line> + <line><text>Auth Code : </text><text>${paymentline.printAuthorization()}</text></line> + <line></line> + #end + #end + + </ticket> + + #foreach ($paymentline in $ticket.payments) + #if ($paymentline.name == "cash") + <opendrawer/> + #end + #if ($paymentline.name == "cashrefund") + <opendrawer/> + #end + #end + +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.Ticket2.xml b/src/main/resources/com/unicenta/pos/templates/Printer.Ticket2.xml new file mode 100644 index 0000000..99a0c2d --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.Ticket2.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + --> +<output> + <display> + <line> + <text align="left" length="8">Total:</text> + <text align="right" length="12">${ticket.printTotal()}</text> + </line> + <line> + <text align="center" length="20">Thank You for your custom</text> + </line> + </display> + #foreach ($paymentline in $ticket.payments) + #if ($paymentline.name == "cash") + <opendrawer/> + #end + #if ($paymentline.name == "cashrefund") + <opendrawer/> + #end + #end +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.TicketClose.xml b/src/main/resources/com/unicenta/pos/templates/Printer.TicketClose.xml new file mode 100644 index 0000000..4208fbf --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.TicketClose.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + + This displays amount tendered and change on customer display + + --> +<output> + <display> + #foreach ($paymentline in $ticket.payments) + <line> + <text align="left" length="8">Given:</text> + <text align ="right" length="12">${paymentline.printPaid()}</text> + </line> + <line> + <text align="left" length="8">Change:</text> + <text align ="right" length="12">${paymentline.printChange()}</text> + </line> + #end + </display> +</output> diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.TicketLine.xml b/src/main/resources/com/unicenta/pos/templates/Printer.TicketLine.xml new file mode 100644 index 0000000..3524579 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.TicketLine.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + --> +<output> + <display> + <line> + #if ($ticketline.isProductCom()) + <text align="left" length="15">*${ticketline.printName()}</text> + #else + <text align="left" length="15">${ticketline.printName()}</text> + #end + <text align="right" length="5">x${ticketline.printMultiply()}</text> + </line> + <line> +<!-- These lines for values without tax + <text align="right" length="10">${ticketline.printPrice()}</text> + <text align="right" length="10">${ticketline.printSubValue()}</text> +--> +<!-- These lines for values with tax --> + <text align ="right" length="10">${ticketline.printPriceTax()}</text> + <text align ="right" length="10">${ticketline.printValue()}</text> + + </line> + </display> +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.TicketNew.xml b/src/main/resources/com/unicenta/pos/templates/Printer.TicketNew.xml new file mode 100644 index 0000000..b0848d1 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.TicketNew.xml @@ -0,0 +1,319 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +--> +<output> + <display> + <line> + <text align="left" length="10">Total</text> + <text align="right" length="10">${ticket.printTotal()}</text> + </line> + <line> + <text align="center" length="20">Thank you for your custom</text> + </line> + </display> + <ticket> + <image>Printer.Ticket.Logo</image> + <line></line> + #if (${ticket.printTicketHeaderLine1()} != "") + <line> + <text align="center" length="42">${ticket.printTicketHeaderLine1()}</text> + </line> + #end + #if (${ticket.printTicketHeaderLine2()} != "") + <line> + <text align="center" length="42">${ticket.printTicketHeaderLine2()}</text> + </line> + #end + #if (${ticket.printTicketHeaderLine3()} != "") + <line> + <text align="center" length="42">${ticket.printTicketHeaderLine3()}</text> + </line> + #end + #if (${ticket.printTicketHeaderLine4()} != "") + <line> + <text align="center" length="42">${ticket.printTicketHeaderLine4()}</text> + </line> + #end + #if (${ticket.printTicketHeaderLine5()} != "") + <line> + <text align="center" length="42">${ticket.printTicketHeaderLine5()}</text> + </line> + #end + #if (${ticket.printTicketHeaderLine6()} != "") + <line> + <text align="center" length="42">${ticket.printTicketHeaderLine6()}</text> + </line> + #end + <line> + <text align="center" length="42">Printer.TicketNew</text> + </line> + <line></line> + #if (${ticket.ticketType} == 0) + <line> + <text align="left" length="15">Receipt:</text> + <text>${ticket.printId()}</text> + </line> + #end + #if (${ticket.ticketType} == 1) + <line> + <text align="left" length="15">Refund:</text> + <text>${ticket.printId()}</text> + </line> + #end + <line> + <text align="left" length="15">Date:</text> + <text>${ticket.printDate()}</text> + </line> + #if ($ticket.getCustomer()) + <line> + <text align="left" length="15">Customer:</text> + <text>${ticket.getCustomer().printName()}</text> + </line> + <line> + <text align="left" length="15">Account #:</text> + <text>${ticket.getCustomer().printTaxid()}</text> + </line> + <line> + <text align="left" length="15">Current Debt:</text> + <text>${ticket.getCustomer().printCurDebt()}</text> + </line> + #end + + #if (${tickettext.place} != ${place}) + <line> + <text align="left" length="15">Table:</text> + <text>${place}</text> + </line> + #end + + <line> + <text align="left" length="15">Served by:</text> + <text>${ticket.printUser()}</text> + </line> + <line></line> + <line> + <text align ="left" length="17">Item</text> + <text align ="right" length="8">Price</text> + <text align ="right" length="7">Qty</text> + <text align ="right" length="10">Value</text> + </line> + <line> + <text>------------------------------------------</text> + </line> + + #foreach ($ticketline in $ticket.getLines()) + <line> + #if ($ticketline.isProductCom()) + <text align ="left" length="17">*${ticketline.printName()}</text> + #else + <text align ="left" length="17">${ticketline.printName()}</text> + #end + <text align ="right" length="8">${ticketline.printPriceTax()}</text> + <text align ="right" length="7">x${ticketline.printMultiply()}</text> + <text align ="right" length="10">${ticketline.printValue()}</text> + </line> + #if ($ticketline.productAttSetInstId) + <line> + <text align ="left" length="42">${ticketline.productAttSetInstDesc}</text> + </line> + #end + #end + <line> + <text>------------------------------------------</text> + </line> + <line> + <text>Items count: </text> + <text align ="left" length="14">${ticket.printArticlesCount()}</text> + </line> + <line></line> + <line size="1"> + <text align ="left" length="16" bold="true">Total</text> + <text align ="right" length="26" bold="true">${ticket.printTotal()}</text> + </line> + #foreach ($paymentline in $ticket.payments) + #if ($paymentline.name == "cash") + <line> + <text bold="true">Cash</text> + </line> + <line> + <text align="left" length="22">Tendered:</text> + <text align ="right" length="20">${paymentline.printPaid()}</text> + </line> + <line> + <text align="left" length="22">Change:</text> + <text align ="right" length="20">${paymentline.printChange()}</text> + </line> + #end + #if ($paymentline.name == "cashrefund") + <line> + <text bold="true">Refund</text> + </line> + <line> + <text align ="right" length="42">${paymentline.printTotal()}</text> + </line> + #end + #if ($paymentline.name == "ccard") + <line> + <text bold="true">Card</text> + </line> + <line> + <text align ="right" length="42">${paymentline.printTotal()}</text> + </line> + <line> + <text align ="left" length="22">Card Number:</text> + <text>${paymentline.printCardNumber()}</text> + </line> + <line> + <text align ="left" length="22">Expiration Date:</text> + <text>${paymentline.printExpirationDate()}</text> + </line> + <line> + <text align ="left" length="22">Operation:</text> + <text>${paymentline.printTransactionID()}</text> + </line> + <line> + <text align ="left" length="22">Authorisation:</text> + <text>${paymentline.printAuthorization()}</text> + </line> + #end + #if ($paymentline.name == "ccardrefund") + <line> + <text bold="true">Card Refund</text> + </line> + <line> + <text align ="right" length="42">${paymentline.printTotal()}</text> + </line> + #end + #if ($paymentline.name == "cheque") + <line></line> + <line> + <text bold="true">Cheque</text> + </line> + <line> + <text align ="right" length="42">${paymentline.printTotal()}</text> + </line> + #end + #if ($paymentline.name == "chequerefund") + <line></line> + <line> + <text bold="true">Cheque Refund</text> + </line> + <line> + <text align ="right" length="42">${paymentline.printTotal()}</text> + </line> + #end + #if ($paymentline.name == "voucherin") + <line></line> + <line> + <text bold="true">Voucher</text> + </line> + <line> + <text align ="right" length="42">${paymentline.printTotal()}</text> + </line> + #end + #if ($paymentline.name == "voucherout") + <line></line> + <line> + <text bold="true">Note Refund</text> + </line> + <line> + <text align ="right" length="42">${paymentline.printTotal()}</text> + </line> + #end + #if ($paymentline.name == "free") + <line></line> + <line> + <text bold="true">Free</text> + </line> + <line> + <text align ="right" length="42">${paymentline.printTotal()}</text> + </line> + #end + #if ($paymentline.name == "debt") + <line></line> + <line> + <text bold="true">On Account</text> + </line> + <line> + <text align ="right" length="42">${paymentline.printTotal()}</text> + </line> + #end + #end + <line></line> + <line> + <text align ="left" bold="true" length="16">Nett of Tax:</text> + <text align ="right" length="26">${ticket.printSubTotal()}</text> + </line> + <line> + <text align ="left" length="16">Taxes:</text> + <text align ="right" length="26">${ticket.printTax()}</text> + </line> + #foreach ($taxinfo in $taxes) + <line> + <text align ="left" length="18">${taxinfo.getTaxInfo()}</text> + <text align ="right" length="12">${taxinfo.printSubTotal()}</text> + <text align ="right" length="12">${taxinfo.printTax()}</text> + </line> + #end + <line></line> + <line> + <text align="center" length="42">${ticket.printTicketFooterLine1()}</text> + </line> + <line> + <text>==========================================</text> + </line> + #end + #if (${ticket.printTicketFooterLine2()} != "") + <line> + <text>${ticket.printTicketFooterLine2()}</text> + </line> + #end + #if (${ticket.printTicketFooterLine3()} != "") + <line> + <text>${ticket.printTicketFooterLine3()}</text> + </line> + #end + #if (${ticket.printTicketFooterLine4()} != "") + <line> + <text>${ticket.printTicketFooterLine4()}</text> + </line> + #end + #if (${ticket.printTicketFooterLine5()} != "") + <line> + <text>${ticket.printTicketFooterLine5()}</text> + </line> + #end + #if (${ticket.printTicketFooterLine6()} != "") + <line> + <text>${ticket.printTicketFooterLine6()}</text> + </line> + #end + </ticket> + + #foreach ($paymentline in $ticket.payments) + #if ($paymentline.name == "cash") + <opendrawer/> + #end + #if ($paymentline.name == "cashrefund") + <opendrawer/> + #end + #end +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.TicketPreview.xml b/src/main/resources/com/unicenta/pos/templates/Printer.TicketPreview.xml new file mode 100644 index 0000000..29000b4 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.TicketPreview.xml @@ -0,0 +1,245 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + --> + +<output> + + <display> + <line><text align="left" length="8">Total</text><text align="right" length="12">${ticket.printTotal()}</text></line> + <line><text align="center" length="20">Thank you</text></line> + </display> + + <ticket> + <image>Printer.Ticket.Logo</image> + <line></line> + #if (${ticket.printTicketHeaderLine1()} != "") + <line><text align="center" length="42">${ticket.printTicketHeaderLine1()}</text></line> + #end + #if (${ticket.printTicketHeaderLine2()} != "") + <line><text align="center" length="42">${ticket.printTicketHeaderLine2()}</text></line> + #end + #if (${ticket.printTicketHeaderLine3()} != "") + <line><text align="center" length="42">${ticket.printTicketHeaderLine3()}</text></line> + #end + #if (${ticket.printTicketHeaderLine4()} != "") + <line><text align="center" length="42">${ticket.printTicketHeaderLine4()}</text></line> + #end + #if (${ticket.printTicketHeaderLine5()} != "") + <line><text align="center" length="42">${ticket.printTicketHeaderLine5()}</text></line> + #end + #if (${ticket.printTicketHeaderLine6()} != "") + <line><text align="center" length="42">${ticket.printTicketHeaderLine6()}</text></line> + #end + + <line><text align="center" length="42">Printer.TicketPreview</text></line> + <line></line> + #if (${ticket.ticketType} == 0) + <line><text align="left" length="15">Receipt:</text><text>${ticket.printId()}</text></line> + #end + #if (${ticket.ticketType} == 1) + <line><text align="left" length="15">Refund:</text><text>${ticket.printId()}</text></line> + #end + + <line><text align="left" length="15">Date:</text><text>${ticket.printDate()}</text></line> + <line><text align="left" length="15">Terminal: </text><text>${ticket.getHost()}</text></line> + <line><text align="left" length="15">Served by:</text><text>${ticket.printUser()}</text></line> + + #if ($ticket.getCustomer()) + <line><text align="left" length="15">Account #:</text><text>${ticket.getCustomer().printTaxCustomerID()}</text></line> + <line><text align="left" length="15">Customer:</text><text>${ticket.getCustomer().printName()}</text></line> + <line><text align="left" length="15">Address:</text><text>${ticket.getCustomer().printAddress()}</text></line> + <line><text align="left" length="15">Postal:</text><text>${ticket.getCustomer().printPostal()}</text></line> + <line><text align="left" length="15">Phone:</text><text>${ticket.getCustomer().printPhone1()}</text></line> + <line><text align="left" length="15">Current Debt:</text><text>${ticket.getCustomer().printCurDebt()}</text></line> + <line><text align="left" length="15">Balance:</text><text>${ticket.getCustomer().printCurBal()}</text></line> + #end + + #if (${tickettext.place} != ${place}) + <line><text align="left" length="15">Table:</text><text>${place}</text></line> + #end + <line></line> + <line> + <text align ="left" length="17">Item</text> + <text align ="right" length="8">Price</text> + <text align ="right" length="7">Qty</text> + <text align ="right" length="10">Value</text> + </line> + <line><text align="left" length="42">------------------------------------------</text></line> + + #foreach ($ticketline in $ticket.getLines()) + <line> + #if ($ticketline.isProductCom()) + <text align ="left" length="17">*${ticketline.printName()}</text> + #else + <text align ="left" length="17">${ticketline.printName()}</text> + #end +<!-- Print line to show Prices pre-Tax + <text align ="right" length="8">${ticketline.printPrice()}</text> + <text align ="right" length="7">x${ticketline.printMultiply()}</text> + <text align ="right" length="8">${ticketline.printSubValue()}</text> + </line> +--> + +<!-- Print line to show Prices inc. Tax --> + <text align ="right" length="8">${ticketline.printPriceTax()}</text> + <text align ="right" length="7">x${ticketline.printMultiply()}</text> + <text align ="right" length="10">${ticketline.printValue()}</text> + </line> + +<!-- un-comment line below if you want to add a product's properties --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("ingredients", "")}</text> </line> --> + +<!-- un-comment line below if you want to add a user input sales line's Note --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("notes", "")}</text> </line> --> + +<!-- un-comment line below if you want to add a product's barcode --> + <!-- <line><text align ="left" length="12">Barcode : </text>${ticketline.printCode()}</text></line> --> + +<!-- un-comment line below if you want to add a product's Reference --> + <!-- <line><text align ="left" length="12">Reference : </text>${ticketline.printReference()}</text></line> --> + + #if ($ticketline.productAttSetInstId) + <line><text align ="left" length="42">${ticketline.productAttSetInstDesc}</text></line> + #end + #end + + <line><text align="left" length="42">------------------------------------------</text></line> + <line><text>Items count: </text><text align ="left" length="14">${ticket.printArticlesCount()}</text></line> + <line></line> + <line> + <text align ="left" bold="true" length="16">Subtotal</text> + <text align ="right" length="26">${ticket.printSubTotal()}</text> + </line> + <line> + <text align ="left" length="16">Tax</text> + <text align ="right" length="26">${ticket.printTax()}</text> + </line> + <line></line> + <line size="1"> + <text align ="left" length="16" bold="true">Balance Due</text> + <text align ="right" length="26" bold="true">${ticket.printTotal()}</text> + </line> + <line></line> + + + + #foreach ($paymentline in $ticket.payments) + #if ($paymentline.name == "cash") + <line><text bold="true">Cash</text></line> + <line><text align="left" length="22">Tendered:</text><text align ="right" length="20">${paymentline.printPaid()}</text></line> + <line><text align="left" length="22">Change:</text><text align ="right" length="20">${paymentline.printChange()}</text></line> + #end + + #if ($paymentline.name == "cashrefund") + <line><text align="left" length="22" bold="true">Refund</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #if ($paymentline.name == "cheque") + <line><text align="left" length="22" bold="true">Cheque</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #if ($paymentline.name == "chequerefund") + <line><text align="left" length="22" bold="true">Cheque Refund</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #if ($paymentline.name == "voucherin") + <line><text align="left" length="22" bold="true">Voucher</text><text align ="right" length="20">${paymentline.printPaid()}</text></line> + #end + #if ($paymentline.name == "voucherout") + <line><text align="left" length="22" bold="true">Voucher Refund<text align ="right" length="20">${paymentline.printPaid()}</text></line> + #end + #if ($paymentline.name == "slip") + <line><text align="left" length="22" bold="true">Slip</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #if ($paymentline.name == "free") + <line><text align="left" length="22" bold="true">Free</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #if ($paymentline.name == "debt") + <line><text align="left" length="22" bold="true">On Account</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #end + + #if (${ticket.printTicketFooterLine1()} != "") + <line></line> + <line><text align="center" length="42">${ticket.printTicketFooterLine1()}</text></line> + <line><text>==========================================</text></line> + #end + #if (${ticket.printTicketFooterLine2()} != "") + <line><text>${ticket.printTicketFooterLine2()}</text></line> + #end + #if (${ticket.printTicketFooterLine3()} != "") + <line><text>${ticket.printTicketFooterLine3()}</text></line> + #end + #if (${ticket.printTicketFooterLine4()} != "") + <line><text>${ticket.printTicketFooterLine4()}</text></line> + #end + #if (${ticket.printTicketFooterLine5()} != "") + <line><text>${ticket.printTicketFooterLine5()}</text></line> + #end + #if (${ticket.printTicketFooterLine6()} != "") + <line><text>${ticket.printTicketFooterLine6()}</text></line> + #end + <line></line> + + #foreach ($paymentline in $ticket.payments) + #if ($paymentline.name == "ccard") + #if ($paymentline.chipAndPin) + <line size="1"><text align="center" length="42" bold="true">CARD SALE</text></line> + <line><text align = "center" length="42" bold="true">A card payment was received</text></line> + <line></line> + <line size="1"><text align="left" length="10">AMOUNT</text><text align ="right" length="32">${paymentline.printTotal()}</text></line> + #end + #if (!$paymentline.chipAndPin) + <line size="1"><text align="center" length="42" bold="true">CARD SALE</text></line> + <line><text align = "center" length="42" bold="true">A card payment was received</text></line> + <line></line> + <line size="1"><text align="left" length="10">AMOUNT</text><text align ="right" length="32">${paymentline.printTotal()}</text></line> + #end + #if ($ticket.hasTip()) + <line><text align ="left" length="16">Tip:</text><text align ="right" length="26">_______________</text></line> + <line></line> + <line size="1"><text align ="left" length="16" bold="false">Total</text><text align ="right" length="26" bold="false">_______________</text></line> + <line></line> + <line></line> + <line size="1"><text align ="left" length="42" bold="false">__________________________________________</text></line> + <line size="1"><text align ="center" length="42" bold="false">Signature</text></line> + #else + <line size="1"><text align ="left" length="16" bold="true">Total</text><text align ="right" length="26" bold="true">${paymentline.printTotal()}</text></line> + #end + #end + #if ($paymentline.name == "ccardrefund") + <line size="1"><text align="center" length="42" bold="true">CARD SALE</text></line> + <line></line> + <line><text align = "center" length="42" bold="true">A card payment was received</text></line> + <line></line> + <line size="1"><text align="left" length="10">AMOUNT</text><text align ="right" length="32">${paymentline.printTotal()}</text></line> + #end + #end + + </ticket> + +#foreach ($paymentline in $ticket.payments) + #if ($paymentline.name == "cash") + <opendrawer/> + #end + #if ($paymentline.name == "cashrefund") + <opendrawer/> + #end +#end + +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.TicketPreview_A4.xml b/src/main/resources/com/unicenta/pos/templates/Printer.TicketPreview_A4.xml new file mode 100644 index 0000000..94d6426 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.TicketPreview_A4.xml @@ -0,0 +1,243 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Contributed by: Julian Roberts, Brockley Estate, Tasmania + Additional changes: uniCenta 2015 + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + --> + +<output> + + <display> + <line><text align="left" length="8">Total</text><text align="right" length="12">${ticket.printTotal()}</text></line> + <line><text align="center" length="20">Thank you</text></line> + </display> + + <ticket> + <image>Printer.Ticket.Logo</image> + <line></line> + #if (${ticket.printTicketHeaderLine1()} != "") + <line><text align="center" length="126">${ticket.printTicketHeaderLine1()}</text></line> + #end + #if (${ticket.printTicketHeaderLine2()} != "") + <line><text align="center" length="126">${ticket.printTicketHeaderLine2()}</text></line> + #end + #if (${ticket.printTicketHeaderLine3()} != "") + <line><text align="center" length="126">${ticket.printTicketHeaderLine3()}</text></line> + #end + #if (${ticket.printTicketHeaderLine4()} != "") + <line><text align="center" length="126">${ticket.printTicketHeaderLine4()}</text></line> + #end + #if (${ticket.printTicketHeaderLine5()} != "") + <line><text align="center" length="126">${ticket.printTicketHeaderLine5()}</text></line> + #end + #if (${ticket.printTicketHeaderLine6()} != "") + <line><text align="center" length="126">${ticket.printTicketHeaderLine6()}</text></line> + #end + + <line><text align="center" length="126">Printer.TicketPreview</text></line> + <line></line> + #if (${ticket.ticketType} == 0) + <line><text align="left" length="15">Receipt:</text><text>${ticket.printId()}</text></line> + #end + #if (${ticket.ticketType} == 1) + <line><text align="left" length="15">Refund:</text><text>${ticket.printId()}</text></line> + #end + + <line><text align="left" length="15">Date:</text><text>${ticket.printDate()}</text></line> + <line><text align="left" length="15">Terminal: </text><text>${ticket.getHost()}</text></line> + <line><text align="left" length="15">Served by:</text><text>${ticket.printUser()}</text></line> + + #if ($ticket.getCustomer()) + <line><text align="left" length="15">Account #:</text><text>${ticket.getCustomer().printTaxCustomerID()}</text></line> + <line><text align="left" length="15">Customer:</text><text>${ticket.getCustomer().printName()}</text></line> + <line><text align="left" length="15">Address:</text><text>${ticket.getCustomer().printAddress()}</text></line> + <line><text align="left" length="15">Postal:</text><text>${ticket.getCustomer().printPostal()}</text></line> + <line><text align="left" length="15">Phone:</text><text>${ticket.getCustomer().printPhone1()}</text></line> + <line><text align="left" length="15">Current Debt:</text><text>${ticket.getCustomer().printCurDebt()}</text></line> + <line><text align="left" length="15">Balance:</text><text>${ticket.getCustomer().printCurBal()}</text></line> + #end + + #if (${tickettext.place} != ${place}) + <line><text align="left" length="15">Table:</text><text>${place}</text></line> + #end + <line></line> + <line> + <text align ="left" length="83">Item</text> + <text align ="right" length="10">Price</text> + <text align ="right" length="5">Qty</text> + <text align ="right" length="10">Value</text> + </line> + <line><text align="left" length="108">------------------------------------------</text></line> + + #foreach ($ticketline in $ticket.getLines()) + <line> + #if ($ticketline.isProductCom()) + <text align ="left" length="83">*${ticketline.printName()}</text> + #else + <text align ="left" length="83">${ticketline.printName()}</text> + #end +<!-- Print line to show Prices pre-Tax --> + <text align ="right" length="10">${ticketline.printPrice()}</text> + <text align ="right" length="5">x${ticketline.printMultiply()}</text> + <text align ="right" length="10">${ticketline.printSubValue()}</text> + </line> + +<!-- Print line to show Prices inc. Tax + <text align ="right" length="10">${ticketline.printPriceTax()}</text> + <text align ="right" length="5">x${ticketline.printMultiply()}</text> + <text align ="right" length="10">${ticketline.printValue()}</text> + </line> +--> + +<!-- un-comment line below if you want to add a product's properties --> + <!-- <line><text align ="left" length="108">${ticketline.getProperty("ingredients", "")}</text> </line> --> + +<!-- un-comment line below if you want to add a user input sales line's Note --> + <!-- <line><text align ="left" length="108">${ticketline.getProperty("notes", "")}</text> </line> --> + +<!-- un-comment line below if you want to add a product's barcode --> + <!-- <line><text align ="left" length="30">Barcode : </text>${ticketline.printCode()}</text></line> --> + +<!-- un-comment line below if you want to add a product's Reference --> + <!-- <line><text align ="left" length="30">Reference : </text>${ticketline.printReference()}</text></line> --> + + #if ($ticketline.productAttSetInstId) + <line><text align ="left" length="42">${ticketline.productAttSetInstDesc}</text></line> + #end + #end + + <line><text align="left" length="108">------------------------------------------</text></line> + <line><text>Items count: </text><text align ="left" length="14">${ticket.printArticlesCount()}</text></line> + <line></line> + <line> + <text align ="left" bold="true" length="16">Subtotal</text> + <text align ="right" length="26">${ticket.printSubTotal()}</text> + </line> + <line> + <text align ="left" length="16">Tax</text> + <text align ="right" length="26">${ticket.printTax()}</text> + </line> + <line></line> + <line size="1"> + <text align ="left" length="16" bold="true">Balance Due</text> + <text align ="right" length="26" bold="true">${ticket.printTotal()}</text> + </line> + <line></line> + + #foreach ($paymentline in $ticket.payments) + #if ($paymentline.name == "cash") + <line><text bold="true">Cash</text></line> + <line><text align="left" length="22">Tendered:</text><text align ="right" length="20">${paymentline.printPaid()}</text></line> + <line><text align="left" length="22">Change:</text><text align ="right" length="20">${paymentline.printChange()}</text></line> + #end + + #if ($paymentline.name == "cashrefund") + <line><text align="left" length="22" bold="true">Refund</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #if ($paymentline.name == "cheque") + <line><text align="left" length="22" bold="true">Cheque</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #if ($paymentline.name == "chequerefund") + <line><text align="left" length="22" bold="true">Cheque Refund</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #if ($paymentline.name == "voucherin") + <line><text align="left" length="22" bold="true">Voucher</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #if ($paymentline.name == "voucherout") + <line><text align="left" length="22" bold="true">Note Refund</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #if ($paymentline.name == "slip") + <line><text align="left" length="22" bold="true">Slip</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #if ($paymentline.name == "free") + <line><text align="left" length="22" bold="true">Free</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #if ($paymentline.name == "debt") + <line><text align="left" length="22" bold="true">On Account</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #end + + #if (${ticket.printTicketFooterLine1()} != "") + <line></line> + <line><text align="center" length="108">${ticket.printTicketFooterLine1()}</text></line> + <line><text>==========================================</text></line> + #end + #if (${ticket.printTicketFooterLine2()} != "") + <line><text>${ticket.printTicketFooterLine2()}</text></line> + #end + #if (${ticket.printTicketFooterLine3()} != "") + <line><text>${ticket.printTicketFooterLine3()}</text></line> + #end + #if (${ticket.printTicketFooterLine4()} != "") + <line><text>${ticket.printTicketFooterLine4()}</text></line> + #end + #if (${ticket.printTicketFooterLine5()} != "") + <line><text>${ticket.printTicketFooterLine5()}</text></line> + #end + #if (${ticket.printTicketFooterLine6()} != "") + <line><text>${ticket.printTicketFooterLine6()}</text></line> + #end + <line></line> + + #foreach ($paymentline in $ticket.payments) + #if ($paymentline.name == "ccard") + #if ($paymentline.chipAndPin) + <line size="1"><text align="center" length="126" bold="true">CARD SALE</text></line> + <line><text align = "center" length="126" bold="true">A card payment was received</text></line> + <line></line> + <line size="1"><text align="left" length="10">AMOUNT</text><text align ="right" length="32">${paymentline.printTotal()}</text></line> + #end + #if (!$paymentline.chipAndPin) + <line size="1"><text align="center" length="126" bold="true">CARD SALE</text></line> + <line><text align = "center" length="126" bold="true">A card payment was received</text></line> + <line></line> + <line size="1"><text align="left" length="10">AMOUNT</text><text align ="right" length="32">${paymentline.printTotal()}</text></line> + #end + #if ($ticket.hasTip()) + <line><text align ="left" length="16">Tip:</text><text align ="right" length="26">_______________</text></line> + <line></line> + <line size="1"><text align ="left" length="16" bold="false">Total</text><text align ="right" length="26" bold="false">_______________</text></line> + <line></line> + <line></line> + <line size="1"><text align ="left" length="126" bold="false">__________________________________________</text></line> + <line size="1"><text align ="center" length="126" bold="false">Signature</text></line> + #else + <line size="1"><text align ="left" length="16" bold="true">Total</text><text align ="right" length="26" bold="true">${paymentline.printTotal()}</text></line> + #end + #end + #if ($paymentline.name == "ccardrefund") + <line size="1"><text align="center" length="126" bold="true">CARD SALE</text></line> + <line></line> + <line><text align = "center" length="126" bold="true">A card payment was received</text></line> + <line></line> + <line size="1"><text align="left" length="10">AMOUNT</text><text align ="right" length="32">${paymentline.printTotal()}</text></line> + #end + #end + + </ticket> + +#foreach ($paymentline in $ticket.payments) + #if ($paymentline.name == "cash") + <opendrawer/> + #end + #if ($paymentline.name == "cashrefund") + <opendrawer/> + #end +#end + +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.TicketRemote.xml b/src/main/resources/com/unicenta/pos/templates/Printer.TicketRemote.xml new file mode 100644 index 0000000..31a6c1f --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.TicketRemote.xml @@ -0,0 +1,116 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +--> + +<output> + + <display> + <line> + <text align="left" length="8">Sent!</text> + <text align="right" length="12">${ticket.printTotal()}</text> + </line> + <line> + <text align="center" length="20">Thank you</text> + </line> + </display> + + <ticket printer = "2"> + <line></line> + <line></line> + <line size = "1"> + <text bold = "true" align="center" length="42">ORDER</text> + </line> + <line></line> + + #if (${tickettext.place} != ${place}) + <line size ="1"> + <text bold="true" align="left" length="15">Table:</text> + <text bold="true">${place}</text> + </line> + #end + + <line> + <text align="left" length="15">Server:</text> + <text>${ticket.printUser()}</text> + </line> + + <line> + <text align="left" length="15">Date:</text> + <text>${ticket.printDate()}</text> + </line> + <line> + <text align="left" length="15">Receipt:</text> + <text>${ticket.printId()}</text> + </line> + + #if ($ticket.getCustomer()) + <line> + <text align="left" length="15">Customer:</text> + <text>${ticket.getCustomer().getName()}</text> + </line> + <line> + <text align="left" length="15">Account #:</text> + <text>${ticket.getCustomer().getTaxid()}</text> + </line> + #end + + <line></line> + <line> + <text align ="left" length="17">Item</text> + <text align ="right" length="5"></text> + </line> + <line> + <text>------------------------------------------</text> + </line> + + #foreach ($ticketline in $ticket.getLines()) +<!-- Show Product's assigned Printer +<line><text align="left" length="15">Printer :</text><text>${ticketline.printPrinter()}</text></line>--> + + #if(($ticketline.printPrinter()) && ($ticketline.getProperty("sendstatus").equals("No"))) + <line size = "1"> + <text align ="left" length="5">${ticketline.printMultiply()}x</text> + #if ($ticketline.isProductCom()) + <text align ="left" length="37">--${ticketline.printName()}</text> + #else + <text align ="left" length="37">${ticketline.printName()}</text> + #end + </line> + + <!-- un-comment line below if you want to add a product's properties --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("ingredients", "")}</text> </line> --> + + <!-- un-comment line below if you want to add a user input sales line's Note --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("notes", "")}</text> </line> --> + + #if ($ticketline.productAttSetInstId) + <line> + <text align ="left" length="42"> ${ticketline.productAttSetInstDesc}</text> + </line> + <line></line> + #end + #end + #end + <line> + <text>------------------------------------------</text> + </line> + </ticket> +</output> diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.TicketTotal.xml b/src/main/resources/com/unicenta/pos/templates/Printer.TicketTotal.xml new file mode 100644 index 0000000..a4a4426 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.TicketTotal.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + --> +<output> + <display> + <line> + <text align="left" length="8">Total:</text> + <text align="right" length="12">${ticket.printTotal()}</text> + </line> + <line> + <text align="center" length="20">Thank You for your custom</text> + </line> + </display> +</output> diff --git a/src/main/resources/com/unicenta/pos/templates/Printer.Ticket_A4.xml b/src/main/resources/com/unicenta/pos/templates/Printer.Ticket_A4.xml new file mode 100644 index 0000000..a9cc185 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Printer.Ticket_A4.xml @@ -0,0 +1,259 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Contributed by: Julian Roberts, Brockley Estate, Tasmania + Additional changes: uniCenta 2015 + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + --> + +<output> + +<display> + <line><text align="left" length="10">Total</text><text align="right" length="10">${ticket.printTotal()}</text></line> + <line><text align="center" length="20">Thank you for your custom</text></line> +</display> + +<ticket> + <line></line> + <image>Printer.Ticket.Logo</image> + <line></line> + <line><text align="center" length="126">Tax Invoice</text></line> + <line></line> + + #if (${ticket.printTicketHeaderLine1()} != "") + <line> + <text align="center" length="126">${ticket.printTicketHeaderLine1()}</text> + </line> + #end + #if (${ticket.printTicketHeaderLine2()} != "") + <line> + <text align="center" length="126">${ticket.printTicketHeaderLine2()}</text> + </line> + #end + #if (${ticket.printTicketHeaderLine3()} != "") + <line> + <text align="center" length="126">${ticket.printTicketHeaderLine3()}</text> + </line> + #end + #if (${ticket.printTicketHeaderLine4()} != "") + <line> + <text align="center" length="126">${ticket.printTicketHeaderLine4()}</text> + </line> + #end + #if (${ticket.printTicketHeaderLine5()} != "") + <line> + <text align="center" length="126">${ticket.printTicketHeaderLine5()}</text> + </line> + #end + #if (${ticket.printTicketHeaderLine6()} != "") + <line> + <text align="center" length="126">${ticket.printTicketHeaderLine6()}</text> + </line> + #end + + <line></line> + + + #if (${ticket.ticketType} == 0) + <line><text align="left" length="15">Receipt:</text><text>${ticket.printId()}</text></line> + #end + + #if (${ticket.ticketType} == 1) + <line><text align="left" length="15">Refund:</text><text>${ticket.printId()}</text></line> + #end + <line><text align="left" length="15">Date:</text><text>${ticket.printDate()}</text></line> + + #if ($ticket.getCustomer()) + <line><text align="left" length="15">Account #:</text><text>${ticket.getCustomer().printTaxCustomerID()}</text></line> + <line><text align="left" length="15">Customer:</text><text>${ticket.getCustomer().printName()}</text></line> + <line><text align="left" length="15">Address:</text><text>${ticket.getCustomer().printAddress()}</text></line> + <line><text align="left" length="15">Postal:</text><text>${ticket.getCustomer().printPostal()}</text></line> + <line><text align="left" length="15">Phone:</text><text>${ticket.getCustomer().printPhone1()}</text></line> + <line><text align="left" length="15">Current Debt:</text><text>${ticket.getCustomer().printCurDebt()}</text></line> + <line><text align="left" length="15">Balance:</text><text>${ticket.getCustomer().printCurBal()}</text></line> + #end + + #if (${tickettext.place} != ${place}) + <line><text align="left" length="15">Table/Room:</text><text>${place}</text></line> + #end + + <line><text align="left" length="15">Served by:</text><text>${ticket.printUser()}</text></line> + <line></line> + <line><text align ="left" length="83">Item</text><text align ="right" length="10">Price</text><text align ="right" length="5">Qty</text><text align ="right" length="10">Value</text></line> + <line><text align="left" length="108">------------------------------------------------------------------------------------------------------------</text></line> + +#foreach ($ticketline in $ticket.getLines()) + <line> + + #if ($ticketline.isProductCom()) + <text align ="left" length="83">*${ticketline.printName()}</text> + #else + <text align ="left" length="83">${ticketline.printName()}</text> + #end + <text align ="right" length="10">${ticketline.printPriceTax()}</text> + <text align ="right" length="5">x${ticketline.printMultiply()}</text> + <text align ="right" length="10">${ticketline.printValue()}</text> + </line> + + <!-- un-comment line below if you want to add a product's properties --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("ingredients", "")}</text> </line> --> + + <!-- un-comment line below if you want to add a user input sales line's Note --> + <!-- <line><text align ="left" length="42">${ticketline.getProperty("notes", "")}</text> </line> --> + + #if ($ticketline.productAttSetInstId) + <line><text align ="left" length="42">${ticketline.productAttSetInstDesc}</text></line> + #end +#end + <line><text align="left" length="108">------------------------------------------------------------------------------------------------------------</text></line> + <line><text>Items count: </text><text align ="left" length="14">${ticket.printArticlesCount()}</text></line> + +#foreach ($paymentline in $ticket.payments) + + #if ($paymentline.name == "cash") + <line><text bold="true">Cash</text></line> +<!-- <line><text align="left" length="22">Tendered:</text><text align ="right" length="20">${paymentline.printTendered()}</text></line> --> + <line><text align="left" length="22">Change:</text><text align ="right" length="20">${paymentline.printChange()}</text></line> + #end + + #if ($paymentline.name == "cashrefund") + <line><text bold="true">Refund</text></line> + <line><text align ="right" length="108">${paymentline.printTotal()}</text></line> + #end + + #if ($paymentline.name == "ccard") + <line><text bold="true">Card</text></line> + <line> <text>Card Type</text></line> + <line> + <text>${paymentline.getCardName()}</text> + </line> + <line><text align ="right" length="108">${paymentline.printTotal()}</text></line> + #end + + #if ($paymentline.name == "ccardrefund") + <line><text bold="true">Card Refund</text></line> + <line> <text>Card Type</text></line> + <line> + <text>${paymentline.getCardName()}</text> + </line> + <line><text align ="right" length="108">${paymentline.printTotal()}</text></line> + #end + + #if ($paymentline.name == "cheque") + <line></line> + <line><text bold="true">Cheque</text></line> + <line><text align ="right" length="108">${paymentline.printTotal()}</text></line> + #end + + #if ($paymentline.name == "chequerefund") + <line></line> + <line><text bold="true">Cheque Refund</text></line> + <line><text align ="right" length="108">${paymentline.printTotal()}</text></line> + #end + + #if ($paymentline.name == "voucherin") + <line></line> + <line><text bold="true">Voucher</text></line> + <line><text align ="right" length="108">${paymentline.printTotal()}</text></line> + #end + + #if ($paymentline.name == "voucherout") + <line></line> + <line><text bold="true">Note Refund</text></line> + <line><text align ="right" length="108">${paymentline.printTotal()}</text></line> + #end + + #if ($paymentline.name == "free") + <line></line> + <line><text bold="true">Free</text></line> + <line><text align ="right" length="108">${paymentline.printTotal()}</text></line> + #end + + #if ($paymentline.name == "debt") + <line></line> + <line><text bold="true">On Account</text></line> + <line><text align ="right" length="108">${paymentline.printTotal()}</text></line> + #end +#end + + + <line></line> + <line><text align ="left" length="16">Taxable Items:</text><text align ="right" length="92">${ticket.printSubTotal()}</text></line> + <line><text align ="left" length="22">Tax Included in total:</text><text align ="right" length="86">${ticket.printTax()}</text></line> + <line></line> + + <line></line> + <line size="1"><text align ="left" length="16" bold="true">Total</text><text align ="right" length="92" bold="true">${ticket.printTotal()}</text></line> + +<!-- #foreach ($taxinfo in $taxes) --> +<!-- #set( $taxline = $ticket.getTaxLine($taxinfo)) --> +<!-- <line> --> +<!-- <text align ="left" length="18">${taxline.getTaxInfo()}</text> --> +<!-- <text align ="right" length="12">${taxline.printSubTotal()}</text> --> +<!-- <text align ="right" length="12">${taxline.printTax()}</text> --> +<!-- </line> --> +<!--#end --> + + <line></line> + #if (${ticket.printTicketFooterLine1()} != "") + <line> + <text align="center" length="105">${ticket.printTicketFooterLine1()}</text> + </line> + <line> + <text>==========================================</text> + </line> + #end + #if (${ticket.printTicketFooterLine2()} != "") + <line> + <text>${ticket.printTicketFooterLine2()}</text> + </line> + #end + #if (${ticket.printTicketFooterLine3()} != "") + <line> + <text>${ticket.printTicketFooterLine3()}</text> + </line> + #end + #if (${ticket.printTicketFooterLine4()} != "") + <line> + <text>${ticket.printTicketFooterLine4()}</text> + </line> + #end + #if (${ticket.printTicketFooterLine5()} != "") + <line> + <text>${ticket.printTicketFooterLine5()}</text> + </line> + #end + #if (${ticket.printTicketFooterLine6()} != "") + <line> + <text>${ticket.printTicketFooterLine6()}</text> + </line> + #end + <line></line> +<!-- <line><barcode type="CODE128">${ticket.printId()}</barcode></line> --> + +</ticket> + +#foreach ($paymentline in $ticket.payments) + #if ($paymentline.name == "cash") + <opendrawer/> + #end + #if ($paymentline.name == "cashrefund") + <opendrawer/> + #end +#end + +</output> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Role.Administrator.xml b/src/main/resources/com/unicenta/pos/templates/Role.Administrator.xml new file mode 100644 index 0000000..7c0c214 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Role.Administrator.xml @@ -0,0 +1,198 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. + If not, see <http://www.gnu.org/licenses/>. +--> + +<!-- + The Administrator Role Permissions has full access to all uniCenta oPOS + functionality. + The Administrator Role should only be used to make system changes. + + *** Do not change unless you know what you are doing *** +--> + + +<permissions> + <class name="plugins.configure"/> + <class name="com.unicenta.pos.panels.JPanelCloseMoney"/> + <class name="com.unicenta.pos.panels.JPanelCloseMoneyReprint"/> + <class name="com.unicenta.pos.panels.JPanelPayments"/> + <class name="com.unicenta.pos.sales.JPanelTicketEdits"/> + <class name="com.unicenta.pos.sales.JPanelTicketSales"/> + + <class name="payment.bank"/> + <class name="payment.cash"/> + <class name="payment.cheque"/> + <class name="payment.debt"/> + <class name="payment.free"/> + <class name="payment.magcard"/> + <class name="payment.slip"/> + <class name="payment.voucher"/> + <class name="refund.cash"/> + <class name="refund.cheque"/> + <class name="refund.magcard"/> + <class name="refund.voucher"/> + <class name="sales.ChangeTaxOptions"/> + <class name="sales.DeleteLines"/> + <class name="sales.DeleteTicket"/> + <class name="sales.EditLines"/> + <class name="sales.EditTicket"/> + <class name="sales.Layout"/> + <class name="sales.Override"/> + <class name="sales.PrintRemote"/> + <class name="sales.PrintTicket"/> + <class name="sales.RefundTicket"/> + <class name="sales.ShowList"/> + <class name="sales.Total"/> + <class name="sales.ViewSharedTicket"/> + +<!-- Standard button scripts --> + <class name="button.opendrawer"/> + <class name="button.print"/> + <class name="button.Totaldiscount"/> + +<!-- Additional button scripts --> + <class name="button.keyboard"/> + <class name="button.Linediscount"/> + <class name="button.refundit"/> + <class name="button.scharge"/> + <class name="button.sendorder"/> + +<class name="com.unicenta.pos.forms.MenuCustomers"/> + <class name="com.unicenta.pos.customers.CustomersPanel"/> + <class name="/com/unicenta/reports/customers.bs"/> + <class name="/com/unicenta/reports/customers_cards.bs"/> + <class name="/com/unicenta/reports/customers_debtors.bs"/> + <class name="/com/unicenta/reports/customers_diary.bs"/> + <class name="/com/unicenta/reports/customers_export.bs"/> + <class name="/com/unicenta/reports/customers_list.bs"/> + <class name="/com/unicenta/reports/customers_sales.bs"/> + + +<class name="com.unicenta.pos.forms.MenuSuppliers"/> + <class name="com.unicenta.pos.suppliers.SuppliersPanel"/> + <class name="/com/unicenta/reports/suppliers.bs"/> + <class name="/com/unicenta/reports/suppliers_b.bs"/> + <class name="/com/unicenta/reports/suppliers_creditors.bs"/> + <class name="/com/unicenta/reports/suppliers_diary.bs"/> + <class name="/com/unicenta/reports/suppliers_export.bs"/> + <class name="/com/unicenta/reports/suppliers_list.bs"/> + <class name="/com/unicenta/reports/suppliers_products.bs"/> + <class name="/com/unicenta/reports/suppliers_sales.bs"/> + +<class name="com.unicenta.pos.forms.MenuStockManagement"/> + <class name="com.unicenta.pos.inventory.AttributeSetsPanel"/> + <class name="com.unicenta.pos.inventory.AttributesPanel"/> + <class name="com.unicenta.pos.inventory.AttributeUsePanel"/> + <class name="com.unicenta.pos.inventory.AttributeValuesPanel"/> + <class name="com.unicenta.pos.inventory.AuxiliarPanel"/> + <class name="com.unicenta.pos.inventory.BundlePanel"/> + <class name="com.unicenta.pos.inventory.CategoriesPanel"/> + + <class name="com.unicenta.pos.inventory.ProductsPanel"/> + <class name="com.unicenta.pos.inventory.ProductsWarehousePanel"/> + <class name="com.unicenta.pos.inventory.StockDiaryPanel"/> + <class name="com.unicenta.pos.inventory.StockManagement"/> + <class name="com.unicenta.pos.inventory.TaxCategoriesPanel"/> + <class name="com.unicenta.pos.inventory.TaxCustCategoriesPanel"/> + <class name="com.unicenta.pos.inventory.TaxPanel"/> + <class name="com.unicenta.pos.inventory.UomPanel"/> + + <class name="/com/unicenta/reports/inventory.bs"/> + <class name="/com/unicenta/reports/inventory_b.bs"/> + <class name="/com/unicenta/reports/inventory_broken.bs"/> + <class name="/com/unicenta/reports/inventory_diary.bs"/> + <class name="/com/unicenta/reports/inventory_diff.bs"/> + <class name="/com/unicenta/reports/inventory_diffdetail.bs"/> + <class name="/com/unicenta/reports/inventory_listdetail.bs"/> + <class name="/com/unicenta/reports/labels_barcode_sheet.bs"/> + <class name="/com/unicenta/reports/labels_barcode_shelfedge.bs"/> <class name="/com/unicenta/reports/productscatalog.bs"/> + <class name="/com/unicenta/reports/labels_product.bs"/> + <class name="/com/unicenta/reports/products.bs"/> + <class name="/com/unicenta/reports/salecatalog.bs"/> + +<class name="com.unicenta.pos.forms.MenuSalesManagement"/> + <class name="/com/unicenta/reports/sales_cashflow.bs"/> + <class name="/com/unicenta/reports/sales_cashregisterlog.bs"/> + <class name="/com/unicenta/reports/sales_categorysales.bs"/> + <class name="/com/unicenta/reports/sales_categorysales_1.bs"/> + <class name="/com/unicenta/reports/sales_closedpos.bs"/> + <class name="/com/unicenta/reports/sales_closedpos_1.bs"/> + <class name="/com/unicenta/reports/sales_closedproducts.bs"/> + <class name="/com/unicenta/reports/sales_closedproducts_1.bs"/> + <class name="/com/unicenta/reports/sales_extendedcashregisterlog.bs"/> + <class name="/com/unicenta/reports/sales_extproducts.bs"/> + <class name="/com/unicenta/reports/sales_payments.bs"/> + <class name="/com/unicenta/reports/sales_productsalesprofit.bs"/> + <class name="/com/unicenta/reports/sales_saletaxes.bs"/> + <class name="/com/unicenta/reports/sales_taxcatsales.bs"/> + <class name="/com/unicenta/reports/sales_taxes.bs"/> + + <class name="/com/unicenta/reports/sales_chart_piesalescat.bs"/> + <class name="/com/unicenta/reports/sales_chart_productsales.bs"/> + <class name="/com/unicenta/reports/sales_chart_sales.bs"/> + <class name="/com/unicenta/reports/sales_chart_timeseriesproduct.bs"/> + <class name="/com/unicenta/reports/sales_chart_top10.bs"/> + +<class name="com.unicenta.pos.forms.MenuMaintenance"/> + <class name="com.unicenta.pos.admin.PeoplePanel"/> + <class name="com.unicenta.pos.admin.ResourcesPanel"/> + <class name="com.unicenta.pos.admin.RolesPanel"/> + <class name="com.unicenta.pos.inventory.LocationsPanel"/> + <class name="com.unicenta.pos.mant.JPanelFloors"/> + <class name="com.unicenta.pos.mant.JPanelPlaces"/> + <class name="com.unicenta.pos.voucher.VoucherPanel"/> + <class name="/com/unicenta/reports/customers_vouchers.bs"/> + <class name="/com/unicenta/reports/users.bs"/> + <class name="/com/unicenta/reports/users_nosales.bs"/> + <class name="/com/unicenta/reports/users_sales.bs"/> + <class name="/com/unicenta/reports/users_tips.bs"/> + <class name="/com/unicenta/reports/users_voids.bs"/> + +<class name="com.unicenta.pos.imports.JPanelCSV"/> + <class name="com.unicenta.pos.imports.CustomerCSVImport"/> + <class name="com.unicenta.pos.imports.JPanelCSVCleardb"/> + <class name="com.unicenta.pos.imports.JPanelCSVImport"/> + <class name="com.unicenta.pos.imports.StockQtyImport"/> + <class name="com.unicenta.pos.transfer.Transfer"/> + <class name="/com/unicenta/reports/tools_invalidcategory.bs"/> + <class name="/com/unicenta/reports/tools_invaliddata.bs"/> + <class name="/com/unicenta/reports/tools_inventoryqtyupdate.bs"/> + <class name="/com/unicenta/reports/tools_missingdata.bs"/> + <class name="/com/unicenta/reports/tools_newproducts.bs"/> + <class name="/com/unicenta/reports/tools_updatedprices.bs"/> +// <class name="/com/unicenta/reports/tools_badprice.bs"/> + +<!-- EPM --> +<class name="com.unicenta.pos.forms.MenuEmployees" /> + <class name="com.unicenta.pos.epm.BreaksPanel" /> + <class name="com.unicenta.pos.epm.JPanelEmployeePresence" /> + <class name="com.unicenta.pos.epm.LeavesPanel" /> + <class name="/com/unicenta/reports/epm_dailypresence.bs" /> + <class name="/com/unicenta/reports/epm_dailyschedule.bs" /> + <class name="/com/unicenta/reports/epm_performance.bs" /> + +<!-- <class name="com.unicenta.possync.ProductsSyncCreate"/> --> +<!-- <class name="com.unicenta.possync.OrdersSyncCreate"/> --> + <class name="Menu.ChangePassword"/> + <class name="com.unicenta.pos.panels.JPanelPrinter"/> + <class name="com.unicenta.pos.config.JPanelConfiguration"/> + +</permissions> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Role.Employee.xml b/src/main/resources/com/unicenta/pos/templates/Role.Employee.xml new file mode 100644 index 0000000..57866ae --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Role.Employee.xml @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. + If not, see <http://www.gnu.org/licenses/>. +--> + +<!-- + The Administrator Role Permissions has full access to all uniCenta oPOS + functionality. + The Administrator Role should only be used to make system changes. + + *** Do not change unless you know what you are doing *** +--> + + +<permissions> + <class name="com.unicenta.pos.customers.CustomersPayment"/> + <class name="com.unicenta.pos.panels.JPanelPayments"/> + <class name="com.unicenta.pos.sales.JPanelTicketEdits"/> + <class name="com.unicenta.pos.sales.JPanelTicketSales"/> + + <class name="payment.cash"/> + <class name="payment.cheque"/> + <class name="payment.debt"/> + <class name="payment.free"/> + <class name="payment.magcard"/> + <class name="payment.slip"/> + <class name="payment.voucher"/> + <class name="sales.DeleteLines"/> + <class name="sales.EditLines"/> + <class name="sales.EditTicket"/> + <class name="sales.PrintRemote"/> + <class name="sales.PrintTicket"/> + <class name="sales.Total"/> + <class name="sales.ViewSharedTicket"/> + +<!-- Standard button scripts --> + <class name="button.opendrawer"/> + <class name="button.print"/> + <class name="button.Totaldiscount"/> + +<!-- Additional button scripts --> + <class name="button.keyboard"/> + <class name="button.Linediscount"/> + <class name="button.scharge"/> + <class name="button.sendorder"/> + +<class name="com.unicenta.pos.forms.MenuCustomers"/> + <class name="com.unicenta.pos.customers.CustomersPanel"/> + <class name="/com/unicenta/reports/customers.bs"/> + <class name="/com/unicenta/reports/customers_cards.bs"/> + +<class name="com.unicenta.pos.forms.MenuSuppliers"/> + <class name="com.unicenta.pos.suppliers.SuppliersPanel"/> + <class name="/com/unicenta/reports/suppliers.bs"/> + +<class name="com.unicenta.pos.forms.MenuMaintenance"/> + <class name="com.unicenta.pos.voucher.VoucherPanel"/> + +<!-- EPM --> +<class name="com.unicenta.pos.forms.MenuEmployees" /> + <class name="Menu.ChangePassword"/> + <class name="com.unicenta.pos.panels.JPanelPrinter"/> + <class name="com.unicenta.pos.config.JPanelConfiguration"/> + +</permissions> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Role.Guest.xml b/src/main/resources/com/unicenta/pos/templates/Role.Guest.xml new file mode 100644 index 0000000..e6d1a32 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Role.Guest.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + --> +<permissions> + <class name="com.unicenta.pos.sales.JPanelTicketSales"/> + <class name="button.keyboard"/> +</permissions> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Role.Manager.xml b/src/main/resources/com/unicenta/pos/templates/Role.Manager.xml new file mode 100644 index 0000000..7addf2c --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Role.Manager.xml @@ -0,0 +1,198 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. + If not, see <http://www.gnu.org/licenses/>. +--> + +<!-- + The Administrator Role Permissions has full access to all uniCenta oPOS + functionality. + The Administrator Role should only be used to make system changes. + + *** Do not change unless you know what you are doing *** +--> + + +<permissions> + <class name="com.unicenta.pos.customers.CustomersPayment"/> + <class name="com.unicenta.pos.panels.JPanelCloseMoney"/> + <class name="com.unicenta.pos.panels.JPanelCloseMoneyReprint"/> + <class name="com.unicenta.pos.panels.JPanelPayments"/> + <class name="com.unicenta.pos.sales.JPanelTicketEdits"/> + <class name="com.unicenta.pos.sales.JPanelTicketSales"/> + + <class name="payment.bank"/> + <class name="payment.cash"/> + <class name="payment.cheque"/> + <class name="payment.debt"/> + <class name="payment.free"/> + <class name="payment.magcard"/> + <class name="payment.slip"/> + <class name="payment.voucher"/> + <class name="refund.cash"/> + <class name="refund.cheque"/> + <class name="refund.magcard"/> + <class name="refund.voucher"/> + <class name="sales.ChangeTaxOptions"/> + <class name="sales.DeleteLines"/> + <class name="sales.DeleteTicket"/> + <class name="sales.EditLines"/> + <class name="sales.EditTicket"/> + <class name="sales.Layout"/> + <class name="sales.Override"/> + <class name="sales.PrintRemote"/> + <class name="sales.PrintTicket"/> + <class name="sales.RefundTicket"/> + <class name="sales.ShowList"/> + <class name="sales.Total"/> + <class name="sales.ViewSharedTicket"/> + +<!-- Standard button scripts --> + <class name="button.opendrawer"/> + <class name="button.print"/> + <class name="button.Totaldiscount"/> + +<!-- Additional button scripts --> + <class name="button.keyboard"/> + <class name="button.Linediscount"/> + <class name="button.refundit"/> + <class name="button.scharge"/> + <class name="button.sendorder"/> + +<class name="com.unicenta.pos.forms.MenuCustomers"/> + <class name="com.unicenta.pos.customers.CustomersPanel"/> + <class name="/com/unicenta/reports/customers.bs"/> + <class name="/com/unicenta/reports/customers_cards.bs"/> + <class name="/com/unicenta/reports/customers_debtors.bs"/> + <class name="/com/unicenta/reports/customers_diary.bs"/> + <class name="/com/unicenta/reports/customers_export.bs"/> + <class name="/com/unicenta/reports/customers_list.bs"/> + <class name="/com/unicenta/reports/customers_sales.bs"/> + + +<class name="com.unicenta.pos.forms.MenuSuppliers"/> + <class name="com.unicenta.pos.suppliers.SuppliersPanel"/> + <class name="/com/unicenta/reports/suppliers.bs"/> + <class name="/com/unicenta/reports/suppliers_b.bs"/> + <class name="/com/unicenta/reports/suppliers_creditors.bs"/> + <class name="/com/unicenta/reports/suppliers_diary.bs"/> + <class name="/com/unicenta/reports/suppliers_export.bs"/> + <class name="/com/unicenta/reports/suppliers_list.bs"/> + <class name="/com/unicenta/reports/suppliers_products.bs"/> + <class name="/com/unicenta/reports/suppliers_sales.bs"/> + +<class name="com.unicenta.pos.forms.MenuStockManagement"/> + <class name="com.unicenta.pos.inventory.AttributeSetsPanel"/> + <class name="com.unicenta.pos.inventory.AttributesPanel"/> + <class name="com.unicenta.pos.inventory.AttributeUsePanel"/> + <class name="com.unicenta.pos.inventory.AttributeValuesPanel"/> + <class name="com.unicenta.pos.inventory.AuxiliarPanel"/> + <class name="com.unicenta.pos.inventory.BundlePanel"/> + <class name="com.unicenta.pos.inventory.CategoriesPanel"/> + + <class name="com.unicenta.pos.inventory.ProductsPanel"/> + <class name="com.unicenta.pos.inventory.ProductsWarehousePanel"/> + <class name="com.unicenta.pos.inventory.StockDiaryPanel"/> + <class name="com.unicenta.pos.inventory.StockManagement"/> + <class name="com.unicenta.pos.inventory.TaxCategoriesPanel"/> + <class name="com.unicenta.pos.inventory.TaxCustCategoriesPanel"/> + <class name="com.unicenta.pos.inventory.TaxPanel"/> + <class name="com.unicenta.pos.inventory.UomPanel"/> + + <class name="/com/unicenta/reports/inventory.bs"/> + <class name="/com/unicenta/reports/inventory_b.bs"/> + <class name="/com/unicenta/reports/inventory_broken.bs"/> + <class name="/com/unicenta/reports/inventory_diary.bs"/> + <class name="/com/unicenta/reports/inventory_diff.bs"/> + <class name="/com/unicenta/reports/inventory_diffdetail.bs"/> + <class name="/com/unicenta/reports/inventory_listdetail.bs"/> + <class name="/com/unicenta/reports/labels_barcode_sheet.bs"/> + <class name="/com/unicenta/reports/labels_barcode_shelfedge.bs"/> <class name="/com/unicenta/reports/productscatalog.bs"/> + <class name="/com/unicenta/reports/labels_product.bs"/> + <class name="/com/unicenta/reports/products.bs"/> + <class name="/com/unicenta/reports/salecatalog.bs"/> + +<class name="com.unicenta.pos.forms.MenuSalesManagement"/> + <class name="/com/unicenta/reports/sales_cashflow.bs"/> + <class name="/com/unicenta/reports/sales_cashregisterlog.bs"/> + <class name="/com/unicenta/reports/sales_categorysales.bs"/> + <class name="/com/unicenta/reports/sales_categorysales_1.bs"/> + <class name="/com/unicenta/reports/sales_closedpos.bs"/> + <class name="/com/unicenta/reports/sales_closedpos_1.bs"/> + <class name="/com/unicenta/reports/sales_closedproducts.bs"/> + <class name="/com/unicenta/reports/sales_closedproducts_1.bs"/> + <class name="/com/unicenta/reports/sales_extendedcashregisterlog.bs"/> + <class name="/com/unicenta/reports/sales_extproducts.bs"/> + <class name="/com/unicenta/reports/sales_payments.bs"/> + <class name="/com/unicenta/reports/sales_productsalesprofit.bs"/> + <class name="/com/unicenta/reports/sales_saletaxes.bs"/> + <class name="/com/unicenta/reports/sales_taxcatsales.bs"/> + <class name="/com/unicenta/reports/sales_taxes.bs"/> + + <class name="/com/unicenta/reports/sales_chart_piesalescat.bs"/> + <class name="/com/unicenta/reports/sales_chart_productsales.bs"/> + <class name="/com/unicenta/reports/sales_chart_sales.bs"/> + <class name="/com/unicenta/reports/sales_chart_timeseriesproduct.bs"/> + <class name="/com/unicenta/reports/sales_chart_top10.bs"/> + +<class name="com.unicenta.pos.forms.MenuMaintenance"/> + <class name="com.unicenta.pos.admin.PeoplePanel"/> + <class name="com.unicenta.pos.admin.ResourcesPanel"/> + <class name="com.unicenta.pos.admin.RolesPanel"/> + <class name="com.unicenta.pos.inventory.LocationsPanel"/> + <class name="com.unicenta.pos.mant.JPanelFloors"/> + <class name="com.unicenta.pos.mant.JPanelPlaces"/> + <class name="com.unicenta.pos.voucher.VoucherPanel"/> + <class name="/com/unicenta/reports/customers_vouchers.bs"/> + <class name="/com/unicenta/reports/users.bs"/> + <class name="/com/unicenta/reports/users_nosales.bs"/> + <class name="/com/unicenta/reports/users_sales.bs"/> + <class name="/com/unicenta/reports/users_tips.bs"/> + <class name="/com/unicenta/reports/users_voids.bs"/> + +<class name="com.unicenta.pos.imports.JPanelCSV"/> + <class name="com.unicenta.pos.imports.CustomerCSVImport"/> + <class name="com.unicenta.pos.imports.JPanelCSVCleardb"/> + <class name="com.unicenta.pos.imports.JPanelCSVImport"/> + <class name="com.unicenta.pos.imports.StockQtyImport"/> + <class name="com.unicenta.pos.transfer.Transfer"/> + <class name="/com/unicenta/reports/tools_invalidcategory.bs"/> + <class name="/com/unicenta/reports/tools_invaliddata.bs"/> + <class name="/com/unicenta/reports/tools_inventoryqtyupdate.bs"/> + <class name="/com/unicenta/reports/tools_missingdata.bs"/> + <class name="/com/unicenta/reports/tools_newproducts.bs"/> + <class name="/com/unicenta/reports/tools_updatedprices.bs"/> +// <class name="/com/unicenta/reports/tools_badprice.bs"/> + +<!-- EPM --> +<class name="com.unicenta.pos.forms.MenuEmployees" /> + <class name="com.unicenta.pos.epm.BreaksPanel" /> + <class name="com.unicenta.pos.epm.JPanelEmployeePresence" /> + <class name="com.unicenta.pos.epm.LeavesPanel" /> + <class name="/com/unicenta/reports/epm_dailypresence.bs" /> + <class name="/com/unicenta/reports/epm_dailyschedule.bs" /> + <class name="/com/unicenta/reports/epm_performance.bs" /> + +<!-- <class name="com.unicenta.possync.ProductsSyncCreate"/> --> +<!-- <class name="com.unicenta.possync.OrdersSyncCreate"/> --> + <class name="Menu.ChangePassword"/> + <class name="com.unicenta.pos.panels.JPanelPrinter"/> + <class name="com.unicenta.pos.config.JPanelConfiguration"/> + +</permissions> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Ticket.Buttons.xml b/src/main/resources/com/unicenta/pos/templates/Ticket.Buttons.xml new file mode 100644 index 0000000..94d9bf8 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Ticket.Buttons.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + --> + +<!-- To ENABLE a feature remove the beginning and end of line commentors --> +<!-- To DISABLE a feature you must add the beginning and of line commentors --> + +<configuration> +<!-- Sales Ticket Button Bar - Show icons **************************************** --> + + <!-- SET Sales Ticket Refund Item (Default=DISABLED) --> + <!-- <button key="button.refundit" image="img.refundit" code="script.Refundit"/> --> + + <!-- SET Sales Ticket ServiceCharge (Default=DISABLED) --> + <!-- <button key="button.scharge" image="img.heart" code="script.ServiceCharge"/> --> + + <!-- SET Sales line Note (Default=DISABLED) --> + <!-- <button key="button.note" image="img.refundit" code="script.addlinenote"/> --> + + <!-- SET Line or Total Discount (Default=TotalDiscount= ENABLED) --> + <button key="button.Totaldiscount" image="img.discount" code="script.Totaldiscount"/> + <button key="button.Linediscount" image="img.discount_b" code="script.Linediscount"/> + + <!-- SET Waiter's name (Default=DISABLED) --> + <!-- <button key="button.setperson" image="img.user" code="script.SetPerson"/> --> + + <!-- SET Remote Printer (Default=DISABLED) --> + <!-- <button key="button.sendorder" image="img.kit_print" code="script.SendOrder"/> --> + + <!-- SET Ticket Print Preview (Default=ENABLED) --> + <button key="button.print" image="img.ticket_print" template="Printer.TicketPreview"/> + + <!-- SET Open Cashdrawer (Default=ENABLED) --> + <button key="button.opendrawer" image="img.cashdrawer" template="Printer.OpenDrawer"/> + <!-- SET Virtual Keyboard (Default=ENABLED) --> + <button key="button.keyboard" image="img.keyboard_48" code="script.Keyboard"/> + +<!-- END Sales Ticket Button Bar - Show icons --> + +<!-- SET Ticket Button Bar - Text Only ****************************************************************** --> + <!-- <button key="button.refundit" name="button.refundit" code="script.Refundit"/> --> + <!-- <button key="button.Linediscount" name="button.Linediscount" code="script.Linediscount"/> --> + <!-- <button key="button.Totaldiscount" name="button.Totaldiscount" code="script.Totaldiscount"/> --> + <!-- <button key="button.setperson" name="button.setperson" code="script.SetPerson"/> --> + <!-- <button key="button.sendorder" name="button.sendorder" code="script.SendOrder"/> --> + <!-- <button key="button.print" titlekey="button.print" template="Printer.TicketPreview"/> --> + <!-- <button key="button.opendrawer" titlekey="button.opendrawer" template="Printer.OpenDrawer"/> --> + <!-- <button key="button.keyboard" titlekey="button.keyboard" template="script.Keyboard"/> --> +<!-- END Ticket Button Bar - Text Only --> + +<!-- SET Product Area Size ********************************************* --> + <!-- Maximum Category height for 800x480 for PDA in Full Screen mode --> + <!-- <cat-height value="100" /> --> + + <!-- Maximum Category height for 800x600 --> + <!-- <cat-height value="155" /> --> + + <!-- Maximum Category height for 1024x768 in Full Screen mode (Default=ENABLED) --> + <cat-height value="320" /> + + <!-- Maximum Category height for 1280x1024 in Full Screen mode --> + <!-- <cat-height value="640" /> --> +<!-- END Product Area Size --> + +<!-- SET Product Button Sizes ****************************************** --> + <!-- Small Product button size in Sales screen (Default=DISABLED) --> + <!-- <img-width value="64"/> --> + <!-- <img-height value="48"/> --> + + <!-- Medium Product button size in Sales screen (Default=ENABLED) --> + <img-width value="107"/> + <img-height value="60"/> + +<!-- Large Product button size in Sales screen (Default=DISABLED)--> + <!-- <img-width value="128"/> --> + <!-- <img-height value="96"/> --> +<!-- END Product Button Size --> + +<!-- Print Receipt (Default=ENABLED) --> + <printselected value="true"/> + + <!-- ADDITIONAL FEATURES ************************************************* --> + <!-- SET Show Change in Cash Sale (Default=ENABLED --> + <event key="ticket.close" code="Ticket.Close"/> + <event key="cash.close" code="Cash.Close"/> + +<!-- Execute your own scripts by EVENTS triggered by Sales Screen --> + <!-- <event key="ticket.change" code="script.multibuy"/> Discount 2 different products --> + <!-- <event key="ticket.change" code="script.YourChangeScript"/> after a ticketline is changed --> + <!-- <event key="ticket.addline" code="script.YourAddLineScript"/> before a ticketline is added --> + <!-- <event key="ticket.setline" code="script.YourSetLineScript"/> before an exisitng ticketline is changed --> + <!-- <event key="ticket.removeline" code="script.YourRemoveLineScript"/> before a ticketline is deleted --> + <!-- <event key="ticket.show" code="script.YourShowScript"/> before the receipt is shown --> + <!-- <event key="ticket.total" code="script.YourTotalScript"/> after the equals button --> + <!-- <event key="ticket.save" code="script.YourSaveScript"/> after payment OK button --> + <!-- <event key="ticket.close" code="script.YourCloseScript"/> after ticket is stored in database and ticket number assigned --> + + + <taxesincluded value="true"/> + <taxcategoryid value="001"/> + <pricevisible value="true" /> + +</configuration> diff --git a/src/main/resources/com/unicenta/pos/templates/Ticket.Close.xml b/src/main/resources/com/unicenta/pos/templates/Ticket.Close.xml new file mode 100644 index 0000000..6b34e93 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Ticket.Close.xml @@ -0,0 +1,59 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// http://sourceforge.net/projects/unicentaopos +// +// This file is part of uniCenta oPOS. +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +// ************************************************************************** +// Ticket.Close +// This script displays the amount of Cash Change (CashTendered - TicketValue) to be given to Customer + + import java.awt.Font; + import javax.swing.plaf.FontUIResource; + import com.unicenta.pos.payment.PaymentInfo; + import javax.swing.JOptionPane; + import javax.swing.JDialog; + + +boolean isCash = false; +String change = ""; +PaymentInfo p = ticket.payments.getFirst(); + +if ("cash".equals(p.getName())) { + isCash = true; + change = p.printChange(); +} + +// Get details of the original font before we change it otherwise all dialogboxes will use new settings +JOptionPane pane = new JOptionPane(); +Font originalFont=pane.getFont(); + +UIManager.put("OptionPane.buttonFont", new FontUIResource(new Font("ARIAL",Font.PLAIN,20))); +message = "Change: " + change; + JLabel FontText = new JLabel(message); + FontText.setFont (new Font ( "Arial", Font.BOLD, 36) ); + +if(isCash) { + JOptionPane pane = new JOptionPane(); + pane.setMessage(FontText); + pane.setPreferredSize( new Dimension(450,150)); + JDialog dialog = pane.createDialog("Cash payment"); + new Thread(new Runnable() { void run() { + dialog.show(); + } }).start(); +} + +// Return to default settings +UIManager.put("OptionPane.buttonFont", new FontUIResource(new Font(originalFont.getName(),originalFont.getStyle(),originalFont.getSize()))); \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Ticket.Line.xml b/src/main/resources/com/unicenta/pos/templates/Ticket.Line.xml new file mode 100644 index 0000000..036ea17 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Ticket.Line.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + --> + +<!-- This sales transaction screen is great for Retailers! --> +<line> + <column name="label.item" width="185" align="left" value="<html> + #if ($ticketline.isProductCom()) <i>*&nbsp;&nbsp; + ${ticketline.printName()}</i> + #else + ${ticketline.printName()} + #end + <br>${ticketline.getProductAttSetInstDesc()}"/> + + <column name="label.price" width="50" align="right" value="${ticketline.printPrice()}"/> + <column name="label.units" width="50" align="right" value="x${ticketline.printMultiply()}"/> + <column name="label.tax" width="50" align="right" value="${ticketline.printTaxRate()}"/> + <column name="label.value" width="100" align="right" value="${ticketline.printValue()}"/> + <column name="label.printto" width="5" align="center" value="${ticketline.printPrinter()}"/> +<!--<column name="label.sendorder" width="5" align="left" value="${ticketline.getProperty('printkb','?')}"/> --> +<!--<column name="label.sendstatus" width="5" align="left" value="${ticketline.getProperty('sendstatus','?')}"/> --> +</line> + +<!-- This sales transaction screen is great for Hospitality! +<line> + <column name="label.item2" width="235" align="left" value="<html> + #if ($ticketline.isProductCom()) + <i>*&nbsp;&nbsp;${ticketline.printName()}</i> + #else + ${ticketline.printName()} + #end + <br>${ticketline.getProductAttSetInstDesc()}"/> + + <column name="label.units2" width="50" align="right" value="x${ticketline.printMultiply()}"/> + <column name="label.value2" width="100" align="right" value="${ticketline.printValue()}"/> + <column name="label.printto" width="5" align="center" value="${ticketline.printPrinter()}"/> +</line> + --> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Ticket.TicketLineTaxesIncluded.xml b/src/main/resources/com/unicenta/pos/templates/Ticket.TicketLineTaxesIncluded.xml new file mode 100644 index 0000000..e8c419b --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Ticket.TicketLineTaxesIncluded.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + uniCenta oPOS - Touch friendly Point Of Sale + Copyright (c) 2009-2018 uniCenta. + http://sourceforge.net/projects/unicentaopos + + This file is part of uniCenta oPOS. + + uniCenta oPOS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + uniCenta oPOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + --> + +<line> + <column name="label.item" width="125" align="left" value="<html> + #if ($ticketline.isProductCom()) + <i>*&nbsp;&nbsp;${ticketline.printName()}</i> + #else ${ticketline.printName()} + + #end"/> + <column name="label.price" width="80" align="right" value="${ticketline.printPriceTax()}"/> + <column name="label.units" width="50" align="right" value="x${ticketline.printMultiply()}"/> + <column name="label.tax" width="100" align="right" value="${ticketline.printTaxRate()}"/> + <column name="label.value" width="80" align="right" value="${ticketline.printValue()}"/> +</line> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/Window.Title.txt b/src/main/resources/com/unicenta/pos/templates/Window.Title.txt new file mode 100644 index 0000000..d818753 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/Window.Title.txt @@ -0,0 +1 @@ +uniCenta oPOS - Touch Friendly Point Of Sale \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/customer.created.xml b/src/main/resources/com/unicenta/pos/templates/customer.created.xml new file mode 100644 index 0000000..2f962f0 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/customer.created.xml @@ -0,0 +1,27 @@ +// Customer.Created +// This script initialises the uniCenta posApps CUSTOMER CREATED +// REST API web services +// +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// http://sourceforge.net/projects/unicentaopos +// +// This file is part of uniCenta oPOS. +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +// ************************************************************************** + +import uk.co.pos_apps.PosApps; + +PosApps.createCustomer(device, customer); \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/customer.deleted.xml b/src/main/resources/com/unicenta/pos/templates/customer.deleted.xml new file mode 100644 index 0000000..07118a0 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/customer.deleted.xml @@ -0,0 +1,27 @@ +// Customer.Deleted +// This script initialises the uniCenta posApps CUSTOMER DELETED +// REST API web services +// +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// http://sourceforge.net/projects/unicentaopos +// +// This file is part of uniCenta oPOS. +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +// ************************************************************************** + +import uk.co.pos_apps.PosApps; + +PosApps.deleteCustomer(device, customer); \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/customer.updated.xml b/src/main/resources/com/unicenta/pos/templates/customer.updated.xml new file mode 100644 index 0000000..0bd5e42 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/customer.updated.xml @@ -0,0 +1,27 @@ +// Customer.Updated +// This script initialises the uniCenta posApps CUSTOMER UPDATED +// REST API web services +// +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// http://sourceforge.net/projects/unicentaopos +// +// This file is part of uniCenta oPOS. +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +// ************************************************************************** + +import uk.co.pos_apps.PosApps; + +PosApps.updateCustomer(device, customer); \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/payment.cash.txt b/src/main/resources/com/unicenta/pos/templates/payment.cash.txt new file mode 100644 index 0000000..d7b093f --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/payment.cash.txt @@ -0,0 +1,41 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// http://sourceforge.net/projects/unicentaopos +// +// This file is part of uniCenta oPOS. +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +// ************************************************************************* + +// ************************************************************************* +// All currency payment denominations to show in Payment forms +// You can find additional prepared currency styles in the Configs folder of +// uniCenta oPOS install folder. Use the Import button to load +// +// To INCLUDE a denomination remove "//" from the line +// To EXCLUDE a denomination add "//" to the line +// ************************************************************************* + +payment.addButton("img.50", 50.0); +payment.addButton("img.20", 20.0); +payment.addButton("img.10", 10.0); +payment.addButton("img.5", 5.0); +payment.addButton("img.2", 2.0); +payment.addButton("img.1", 1.00); +payment.addButton("img.050", 0.50); +payment.addButton("img.020", 0.20); +payment.addButton("img.010", 0.10); +payment.addButton("img.005", 0.05); +payment.addButton("img.002", 0.02); +payment.addButton("img.001", 0.01); \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/script.Keyboard.txt b/src/main/resources/com/unicenta/pos/templates/script.Keyboard.txt new file mode 100644 index 0000000..8ac6769 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/script.Keyboard.txt @@ -0,0 +1,29 @@ +// script.Keyboard.txt +// This script launches uniCenta Virtual Keyboard +// +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// http://sourceforge.net/projects/unicentaopos +// +// This file is part of uniCenta oPOS. +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +// ************************************************************************** + +Runtime runtime = Runtime.getRuntime(); +// Windows +Process proc = runtime.getRuntime() .exec("cmd /C start osk.exe"); + +// Ubuntu +// Process proc = runtime.getRuntime() .exec("onboard"); \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/script.Linediscount.txt b/src/main/resources/com/unicenta/pos/templates/script.Linediscount.txt new file mode 100644 index 0000000..e1db363 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/script.Linediscount.txt @@ -0,0 +1,51 @@ +// script.Linediscount +// +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// http://sourceforge.net/projects/unicentaopos +// +// This file is part of uniCenta oPOS. +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +// ************************************************************************** +// This script applies UsersInput %Discount for the Item Line value +// To use in the sales screen: Highlight the line you want to discount +// Then Tap in the %Discount amount and touch the % button + +import com.unicenta.format.Formats; +import com.unicenta.pos.ticket.TicketLineInfo; +import com.unicenta.pos.ticket.TicketProductInfo; + +discountrate = sales.getInputValue() / 100.0; + +index = sales.getSelectedIndex(); +if (index >= 0) { + line = ticket.getLine(index); + if (line.getPrice() > 0.0 && discountrate > 0.0) { + sdiscount = Formats.PERCENT.formatValue(discountrate); + ticket.insertLine(index + 1, + new TicketLineInfo( + "Line Discount " + sdiscount, + line.getProductTaxCategoryID(), + line.getProductPrinter(), + line.getMultiply(), + -(double)Math.abs(line.getNewPrice() * discountrate * 100) / 100, + line.getTaxInfo())); + sales.setSelectedIndex(index + 1); + } else { + java.awt.Toolkit.getDefaultToolkit().beep(); + } +} else { + java.awt.Toolkit.getDefaultToolkit().beep(); +} \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/script.SendOrder.txt b/src/main/resources/com/unicenta/pos/templates/script.SendOrder.txt new file mode 100644 index 0000000..98f224e --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/script.SendOrder.txt @@ -0,0 +1,76 @@ +// script.SendOrder +// Sends an item in a Sale to a remote Printers +// +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// http://sourceforge.net/projects/unicentaopos +// +// This file is part of uniCenta oPOS. +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +// ************************************************************************** + +private boolean printedP1 = false; +private boolean printedP2 = false; +private boolean printedP3 = false; +private boolean printedP4 = false; +private boolean printedP5 = false; +private boolean printedP6 = false; + +for(int i= 0; i < ticket.getLinesCount(); i++){ + line = ticket.getLine(i); + + if (line.getProperty("product.printer")!=null) { + + if (line.getProperty("product.printer").equals("1")) { + if((printedP1 == false) && line.getProperty("ticket.updated").equals("true")) { + sales.printTicket("Printer.Ticket.P1"); + printedP1 = true; + } + } + + if (line.getProperty("product.printer").equals("2")) { + if((printedP2 == false) && line.getProperty("ticket.updated").equals("true")){ + sales.printTicket("Printer.Ticket.P2"); + printedP2 = true; + } + } + if (line.getProperty("product.printer").equals("3")) { + if((printedP3 == false) && line.getProperty("ticket.updated").equals("true")){ + sales.printTicket("Printer.Ticket.P3"); + printedP3 = true; + } + } + + if (line.getProperty("product.printer").equals("4")) { + if((printedP4 == false) && line.getProperty("ticket.updated").equals("true")){ + sales.printTicket("Printer.Ticket.P4"); + printedP4 = true; + } + } + if (line.getProperty("product.printer").equals("5")) { + if((printedP5 == false) && line.getProperty("ticket.updated").equals("true")){ + sales.printTicket("Printer.Ticket.P5"); + printedP5 = true; + } + } + + if (line.getProperty("product.printer").equals("6")) { + if((printedP6 == false) && line.getProperty("ticket.updated").equals("true")){ + sales.printTicket("Printer.Ticket.P6"); + printedP6 = true; + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/script.Totaldiscount.txt b/src/main/resources/com/unicenta/pos/templates/script.Totaldiscount.txt new file mode 100644 index 0000000..3dbe8ed --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/script.Totaldiscount.txt @@ -0,0 +1,54 @@ +// script.Totaldiscount +// +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// http://sourceforge.net/projects/unicentaopos +// +// This file is part of uniCenta oPOS. +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +// ************************************************************************** +// This script applies UsersInput %Discount for the Total Ticket +// each Line value is recalculated and annotated +// To use in the sales screen: Highlight the line you want to discount +// Then Tap in the %Discount amount and touch the % button + +import com.unicenta.format.Formats; +import com.unicenta.pos.ticket.TicketLineInfo; +import com.unicenta.pos.ticket.TicketProductInfo; + +discountrate = sales.getInputValue() / 100.0; + +index = sales.getSelectedIndex(); +if (index >= 0) { + if (ticket.getTotal() > 0.0 && discountrate > 0.0) { + sdiscount = Formats.PERCENT.formatValue((discountrate)); + for (int number= 0; number < ticket.getLinesCount(); number++) { + line = ticket.getLine(number); + ticket.setLine(number, + new TicketLineInfo( + line.getProductID(), + line.getProductName() + " - Item Discount @ " + sdiscount, + line.getProductTaxCategoryID(), + line.getProductPrinter(), + line.getMultiply(), + line.getNewPrice() - (double)Math.abs(line.getNewPrice() * discountrate * 100) /100, + line.getTaxInfo())); + } + } else { + java.awt.Toolkit.getDefaultToolkit().beep(); + } +} else { + java.awt.Toolkit.getDefaultToolkit().beep(); +} \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/script.multibuy.txt b/src/main/resources/com/unicenta/pos/templates/script.multibuy.txt new file mode 100644 index 0000000..d8fbd7f --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/script.multibuy.txt @@ -0,0 +1,82 @@ +// +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright © 2009-2020 uniCenta +// +// This file is part of uniCenta oPOS. +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. +// ************************************************************************** + +import com.unicenta.pos.ticket.TicketLineInfo; + +index = sales.getSelectedIndex(); +if (index != -1) + +{ + line = ticket.getLine(index); + int count = Integer.parseInt(line.getProperty("COUNT", "0")); + Double newPrice1 = new Double(line.getProperty("PRICE", "0")); + String groupName = line.getProperty("GROUP", "0"); + if (count > 0) { + int productCount = 0; + int discountsAlreadyApplied = 0; + String productID = line.getProductID(); + + for (TicketLineInfo ticketLine: ticket.getLines()) { + boolean grouped = groupName.equals(ticketLine.getProperty("GROUP", "0")); + boolean multi = count > 0; + if (multi && grouped) { + productCount++; + } + if (ticketLine.getProductName().contains("Buy")) { + discountsAlreadyApplied = discountsAlreadyApplied + count; + } + } + + if (count == (productCount - discountsAlreadyApplied)) { + + newPrice2 = -(line.getPriceTax() * count) + newPrice1; + + + ticket.insertLine(ticket.getLinesCount(), + new TicketLineInfo( + "Buy " + count + " for £" + (line.getProperty("PRICE")),ox + line.getProductTaxCategoryID(), + "", + 1, + 0, + line.getTaxInfo())); + + + sales.setSelectedIndex(ticket.getLinesCount() - 1); + index = sales.getSelectedIndex(); + line = ticket.getLine(index); + line.setPriceTax(newPrice2); + sales.setSelectedIndex(ticket.getLinesCount() - 2); + + + + /* Remove BOGO property to start fresh */ + for (i = 0; i < ticket.getLinesCount(); i++) { + if (productID.equals(ticket.getLine(i).getProductID())) { + ticket.getLine(i).setProperty("COUNT", "0"); + } + } + } + + + sales.setSelectedIndex(ticket.getLinesCount() - 1); + } +} +//END MULTI BUY \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/template.Ticket.A4_Beta.vm b/src/main/resources/com/unicenta/pos/templates/template.Ticket.A4_Beta.vm new file mode 100644 index 0000000..f2e1a82 --- /dev/null +++ b/src/main/resources/com/unicenta/pos/templates/template.Ticket.A4_Beta.vm @@ -0,0 +1,208 @@ +#set ( $leftm= " " ) ## Uses spaces to set the LEFT margin - 10 is default for A4 +#set ( $len= 'length="130"' ) ## Sets the line LENGTH - 130 is default for A4 + +<ticket> + <image>Printer.Ticket.Logo</image> + <line size="1"><text align="center" $len>$leftm Printer.TicketPreview_A4</text></line> + <line></line> + + <line> + #if (${ticket.ticketType} == 0) + <text align="left" length="40">$leftm Receipt: ${ticket.printId()}</text> + #if (${ticket.printTicketHeaderLine1()} != "") + <text align="right" length="90">$leftm ${ticket.printTicketHeaderLine1()}</text> + #end + #end + #if (${ticket.ticketType} == 1) + <text align="left" length="40">$leftm Refund: ${ticket.printId()}</text> + #if (${ticket.printTicketHeaderLine1()} != "") + <text align="right" length="90">$leftm ${ticket.printTicketHeaderLine1()}</text> + #end + #end + </line> + <line> + <text align="left" length="20">$leftm Date: </text><text length="20">${ticket.printDate()}</text> + #if (${ticket.printTicketHeaderLine2()} != "") + <text align="right" length="90">$leftm ${ticket.printTicketHeaderLine2()}</text> + #end + </line> + <line> + <text align="left" length="20">$leftm Terminal: </text><text length="20">${ticket.getHost()}</text> + #if (${ticket.printTicketHeaderLine3()} != "") + <text align="right" length="90">$leftm ${ticket.printTicketHeaderLine3()}</text> + #end + </line> + <line> + <text align="left" length="20">$leftm Server: </text><text length="20">${ticket.printUser()}</text> + #if (${ticket.printTicketHeaderLine4()} != "") + <text align="right" length="90">${ticket.printTicketHeaderLine4()}</text> + #end + </line> + <line> + #if (${tickettext.place} != ${place}) + <text align="left" length="20">$leftm Table:</text><text length="20">${place}</text> + #if (${ticket.printTicketHeaderLine5()} != "") + <text align="right" length="90">${ticket.printTicketHeaderLine5()}</text> + #end + #else + #if (${ticket.printTicketHeaderLine5()} != "") + <text align="right" $len>${ticket.printTicketHeaderLine5()}</text> + #end + #end + </line> + <line> + #if (${ticket.printTicketHeaderLine6()} != "") + <text align="right" $len>${ticket.printTicketHeaderLine6()}</text> + #end + </line> + + #if ($ticket.getCustomer()) + <line><text align="left">$leftm Account #: </text><text>${ticket.getCustomer().printTaxCustomerID()}</text></line> + <line><text align="left">$leftm Customer: </text><text>${ticket.getCustomer().printName()}</text></line> + <line><text align="left">$leftm Address: </text><text>${ticket.getCustomer().printAddress()}</text></line> + <line><text align="left">$leftm Postal: </text><text>${ticket.getCustomer().printPostal()}</text></line> + <line><text align="left">$leftm Phone: </text><text>${ticket.getCustomer().printPhone1()}</text></line> + <line><text align="left">$leftm Current Debt: </text><text>${ticket.getCustomer().printCurDebt()}</text></line> + #end + + <line></line> + <line><text align="left" $len>$leftm ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────</text></line> + <line> + <text align ="left" length="20" bold="true">$leftm REFERENCE</text> + <text align ="left" length="74" bold="true">$leftm ITEM</text> + <text align ="right" length="10" bold="true">PRICE</text> + <text align ="right" length="10" bold="true">QTY</text> + <text align ="right" bold="true">$leftm VALUE</text> + </line> + <line><text align="left" $len>$leftm ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────</text></line> + + #foreach ($ticketline in $ticket.getLines()) + <line> + #if ($ticketline.isProductCom()) + <text align ="left" length="20">$leftm ★${ticketline.printReference()}</text> + <text align ="left" length="74">$leftm ${ticketline.printName()}</text> + #else + <text align ="left" length="20">$leftm ${ticketline.printReference()}</text> + <text align ="left" length="74">$leftm ${ticketline.printName()}</text> + #end + + <text align ="right" length="11">${ticketline.printPriceTax()}</text> + <text align ="right" length="10">${ticketline.printMultiply()}</text> + <text align ="right" length="15">${ticketline.printValue()}</text> + </line> + + #if ($ticketline.productAttSetInstId) + <line><text align ="left" length="74">$leftm $leftm ★★ ${ticketline.productAttSetInstDesc}</text></line> + #end + #end + + <line><text align="left" $len>$leftm ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────</text></line> + <line><text>$leftm Items count: </text><text align ="left" length="15">${ticket.printArticlesCount()}</text></line> + <line></line> + <line> + <text align="right" length="115">$leftm Subtotal</text> + <text align ="right" length="15">${ticket.printSubTotal()}</text> + </line> + <line> + <text align ="right" length="115">$leftm Tax</text> + <text align ="right" length="15">${ticket.printTax()}</text> + </line> + <line><text align="right" $len>$leftm ───────────────</text></line> + <line></line> + <line size="1"> + <text align ="right" length="115" bold="true">$leftm Balance Due</text> + <text align ="right" length="15" bold="true">${ticket.printTotal()}</text> + </line> + <line><text align="right" $len>$leftm ═══════════════</text></line> + <line></line> + + #foreach ($paymentline in $ticket.payments) + #if ($paymentline.name == "cash") + <line><text bold="true">$leftm Cash</text></line> + <line><text align="left" length="22">$leftm Tendered:</text><text align ="right" length="20">${paymentline.printPaid()}</text></line> + <line><text align="left" length="22">$leftm Change:</text><text align ="right" length="20">${paymentline.printChange()}</text></line> + #end + + #if ($paymentline.name == "cashrefund") + <line><text align="left" length="22" bold="true">$leftm Refund</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #if ($paymentline.name == "cheque") + <line><text align="left" length="22" bold="true">$leftm Cheque</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #if ($paymentline.name == "chequerefund") + <line><text align="left" length="22" bold="true">$leftm Cheque Refund</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #if ($paymentline.name == "voucherin") + <line><text align="left" length="22" bold="true">$leftm Voucher</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #if ($paymentline.name == "voucherout") + <line><text align="left" length="22" bold="true">$leftm Note Refund</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #if ($paymentline.name == "slip") + <line><text align="left" length="22" bold="true">$leftm Slip</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #if ($paymentline.name == "free") + <line><text align="left" length="22" bold="true">$leftm Free</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #if ($paymentline.name == "debt") + <line><text align="left" length="22" bold="true">$leftm On Account</text><text align ="right" length="20">${paymentline.printTotal()}</text></line> + #end + #end + + #if (${ticket.printTicketFooterLine1()} != "") + <line></line> + <line><text align="center" $len>$leftm ${ticket.printTicketFooterLine1()}</text></line> + <line><text align="left" $len>$leftm ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────</text></line> + #end + #if (${ticket.printTicketFooterLine2()} != "") + <line><text>$leftm ${ticket.printTicketFooterLine2()}</text></line> + #end + #if (${ticket.printTicketFooterLine3()} != "") + <line><text>$leftm ${ticket.printTicketFooterLine3()}</text></line> + #end + #if (${ticket.printTicketFooterLine4()} != "") + <line><text>$leftm ${ticket.printTicketFooterLine4()}</text></line> + #end + #if (${ticket.printTicketFooterLine5()} != "") + <line><text>$leftm ${ticket.printTicketFooterLine5()}</text></line> + #end + #if (${ticket.printTicketFooterLine6()} != "") + <line><text>$leftm ${ticket.printTicketFooterLine6()}</text></line> + #end + <line></line> + + #foreach ($paymentline in $ticket.payments) + #if ($paymentline.name == "ccard") + #if ($paymentline.chipAndPin) + <line size="1"><text align="center" $len bold="true">$leftm CARD SALE</text></line> + <line><text align = "center" $len bold="true">$leftm A card payment was received</text></line> + <line></line> + <line size="1"><text align="left">$leftm AMOUNT</text><text align ="right" length="32">${paymentline.printTotal()}</text></line> + #end + #if (!$paymentline.chipAndPin) + <line size="1"><text align="center" $len bold="true">$leftm CARD SALE</text></line> + <line><text align = "center" $len bold="true">$leftm A card payment was received</text></line> + <line></line> + <line size="1"><text align="left">$leftm AMOUNT</text><text align ="right" length="32">${paymentline.printTotal()}</text></line> + #end + #if ($ticket.hasTip()) + <line><text align ="left">$leftm Tip: </text><text align ="right" length="26">_______________</text></line> + <line></line> + <line size="1"><text align ="left" bold="false">$leftm Total </text><text align ="right" length="26" bold="false">_______________</text></line> + <line></line> + <line></line> + <line size="1"><text align ="left" bold="false">$leftm __________________________________________</text></line> + <line size="1"><text align ="center" bold="false">$leftm Signature</text></line> + #else + <line size="1"><text align ="left" bold="true">$leftm Total</text><text align ="right" length="26" bold="true">${paymentline.printTotal()}</text></line> + #end + #end + #if ($paymentline.name == "ccardrefund") + <line size="1"><text align="center" $len bold="true">$leftm CARD SALE</text></line> + <line></line> + <line><text align = "center" $len bold="true">$leftm A card payment was received</text></line> + <line></line> + <line size="1"><text align="left">$leftm AMOUNT</text><text align ="right" length="32">${paymentline.printTotal()}</text></line> + #end + #end +</ticket> \ No newline at end of file diff --git a/src/main/resources/com/unicenta/pos/templates/template.Ticket.A4_Beta.zip b/src/main/resources/com/unicenta/pos/templates/template.Ticket.A4_Beta.zip new file mode 100644 index 0000000000000000000000000000000000000000..fd6a318abc0f1941184c0131ff1ce409f0e376ea GIT binary patch literal 2404 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 Yop^ttvjh0R&%;6c^===-IDdBk0$puIRsaA1 literal 0 HcmV?d00001 diff --git a/src/main/resources/com/unicenta/reports/customers.bs b/src/main/resources/com/unicenta/reports/customers.bs new file mode 100644 index 0000000..f42e6a6 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers.bs @@ -0,0 +1,52 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see <http://www.gnu.org/licenses/>. + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.Customers.Reports.Report"); +report.setReport("/com/unicenta/reports/customers"); +report.setResourceBundle("com/unicenta/reports/customers_messages"); + +report.setSentence("SELECT ID, TAXID, " + + "NAME, ADDRESS, ADDRESS2, CITY, POSTAL, " + + "NOTES, CARD, MAXDEBT, CURDATE, CURDEBT, " + + "FIRSTNAME, LASTNAME "+ + "FROM customers " + + "WHERE VISIBLE = " + app.getSession().DB.TRUE() + " AND ?(QBF_FILTER)"); + +report.addParameter("ID"); +report.addParameter("NAME"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsCustomer()); + +report.addField("ID", com.unicenta.data.loader.Datas.STRING); +report.addField("TAXID", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("ADDRESS", com.unicenta.data.loader.Datas.STRING); +report.addField("ADDRESS2", com.unicenta.data.loader.Datas.STRING); +report.addField("CITY", com.unicenta.data.loader.Datas.STRING); +report.addField("POSTAL", com.unicenta.data.loader.Datas.STRING); +report.addField("NOTES", com.unicenta.data.loader.Datas.STRING); +report.addField("CARD", com.unicenta.data.loader.Datas.STRING); +report.addField("MAXDEBT", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("CURDATE", com.unicenta.data.loader.Datas.TIMESTAMP); +report.addField("CURDEBT", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("FIRSTNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("LASTNAME", com.unicenta.data.loader.Datas.STRING); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/customers.jrxml b/src/main/resources/com/unicenta/reports/customers.jrxml new file mode 100644 index 0000000..230a951 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers.jrxml @@ -0,0 +1,358 @@ +<?xml version="1.0" encoding="UTF-8"?> +<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="customers" pageWidth="595" pageHeight="842" columnWidth="535" leftMargin="30" rightMargin="30" topMargin="20" bottomMargin="20" uuid="483cf3a5-e533-4773-8e36-e0b65c997c7e"> + <property name="ireport.scriptlethandling" value="0"/> + <property name="ireport.encoding" value="UTF-8"/> + <property name="ireport.zoom" value="1.5"/> + <property name="ireport.x" value="0"/> + <property name="ireport.y" value="0"/> + <import value="net.sf.jasperreports.engine.*"/> + <import value="java.util.*"/> + <import value="net.sf.jasperreports.engine.data.*"/> + <queryString> + <![CDATA[SELECT ID, NAME, ADDRESS, NOTES, CARD, MAXDEBT, CURDATE, CURDEBT +FROM CUSTOMERS +WHERE VISIBLE = TRUE AND CARD IS NOT NULL AND CARD <> '']]> + </queryString> + <field name="ID" class="java.lang.String"/> + <field name="NAME" class="java.lang.String"/> + <field name="TAXID" class="java.lang.String"/> + <field name="ADDRESS" class="java.lang.String"/> + <field name="ADDRESS2" class="java.lang.String"/> + <field name="CITY" class="java.lang.String"/> + <field name="POSTAL" class="java.lang.String"/> + <field name="MAXDEBT" class="java.lang.Double"/> + <field name="CURDEBT" class="java.lang.Double"/> + <field name="CURDATE" class="java.util.Date"/> + <field name="NOTES" class="java.lang.String"/> + <field name="CARD" class="java.lang.String"/> + <background> + <band/> + </background> + <title> + <band/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/customers_b.bs b/src/main/resources/com/unicenta/reports/customers_b.bs new file mode 100644 index 0000000..b795992 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_b.bs @@ -0,0 +1,45 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.CustomersBReport"); +report.setReport("/com/unicenta/reports/customers"); +report.setResourceBundle("com/unicenta/reports/customers_messages"); + +// report.setSentence("SELECT ID, TAXID, NAME, ADDRESS, NOTES, CARD, MAXDEBT, CURDATE, CURDEBT " + +// "FROM customers " + +// "WHERE VISIBLE = " + app.getSession().DB.TRUE() + " AND CURDEBT IS NOT NULL AND CURDEBT > 0"); + +// JG:uniCenta 9 Jan 11 to allow <> 0 +report.setSentence("SELECT ID, TAXID, NAME, ADDRESS, NOTES, CARD, MAXDEBT, CURDATE, CURDEBT " + + "FROM customers " + + "WHERE VISIBLE = " + app.getSession().DB.TRUE() + " AND CURDEBT IS NOT NULL AND CURDEBT <> 0"); + +report.addField("ID", com.unicenta.data.loader.Datas.STRING); +report.addField("TAXID", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("ADDRESS", com.unicenta.data.loader.Datas.STRING); +report.addField("NOTES", com.unicenta.data.loader.Datas.STRING); +report.addField("CARD", com.unicenta.data.loader.Datas.STRING); +report.addField("MAXDEBT", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("CURDATE", com.unicenta.data.loader.Datas.TIMESTAMP); +report.addField("CURDEBT", com.unicenta.data.loader.Datas.DOUBLE); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/customers_cards.bs b/src/main/resources/com/unicenta/reports/customers_cards.bs new file mode 100644 index 0000000..2f43316 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_cards.bs @@ -0,0 +1,49 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.Customers.Reports.Cards"); +report.setReport("/com/unicenta/reports/customers_cards"); +report.setResourceBundle("com/unicenta/reports/customers_messages"); + +report.setSentence("SELECT ID, TAXID, NAME, CARD, " + + "FIRSTNAME, LASTNAME, " + + "ADDRESS, ADDRESS2, CITY, POSTAL, " + + "IMAGE " + + "FROM customers " + + "WHERE VISIBLE = " + app.getSession().DB.TRUE() + " AND ?(QBF_FILTER)"); + +report.addParameter("ID"); +report.addParameter("NAME"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsCustomer()); + +report.addField("ID", com.unicenta.data.loader.Datas.STRING); +report.addField("TAXID", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("CARD", com.unicenta.data.loader.Datas.STRING); +report.addField("FIRSTNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("LASTNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("ADDRESS", com.unicenta.data.loader.Datas.STRING); +report.addField("ADDRESS2", com.unicenta.data.loader.Datas.STRING); +report.addField("CITY", com.unicenta.data.loader.Datas.STRING); +report.addField("POSTAL", com.unicenta.data.loader.Datas.STRING); +report.addField("IMAGE", com.unicenta.data.loader.Datas.IMAGE); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/customers_cards.jrxml b/src/main/resources/com/unicenta/reports/customers_cards.jrxml new file mode 100644 index 0000000..b47e52f --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_cards.jrxml @@ -0,0 +1,181 @@ + + + + + + + + + + + + '']]> + + + + + + + + + + + + + + + + + <band/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/customers_debtors.bs b/src/main/resources/com/unicenta/reports/customers_debtors.bs new file mode 100644 index 0000000..64bedc9 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_debtors.bs @@ -0,0 +1,51 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.Customers.Reports.Debtors"); +report.setReport("/com/unicenta/reports/customers_debtors"); +report.setResourceBundle("com/unicenta/reports/customers_messages"); + +report.setSentence("SELECT ID, TAXID, NAME, ADDRESS, CURDEBT, CURDATE " + + "FROM customers " + + "WHERE VISIBLE = " + app.getSession().DB.TRUE() + " AND ?(QBF_FILTER)" + + "ORDER BY NAME "); + +report.addParameter("ID"); +report.addParameter("NAME"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsCustomer()); + +report.addParameter("CURDATE"); +report.addParameter("CURDATE"); + +paramdates = new com.unicenta.pos.reports.JParamsDatesInterval(); +paramdates.setStartDate(com.unicenta.beans.DateUtils.getToday()); +// JG - 8 Jan 14 paramdates.setEndDate(com.unicenta.beans.DateUtils.getToday()); +paramdates.setEndDate(com.unicenta.beans.DateUtils.getTodayMinutes()); +report.addQBFFilter(paramdates); + +report.addField("ID", com.unicenta.data.loader.Datas.STRING); +report.addField("TAXID", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("ADDRESS", com.unicenta.data.loader.Datas.STRING); +report.addField("CURDEBT", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("CURDATE", com.unicenta.data.loader.Datas.TIMESTAMP); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/customers_debtors.jrxml b/src/main/resources/com/unicenta/reports/customers_debtors.jrxml new file mode 100644 index 0000000..afeec0d --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_debtors.jrxml @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + <band/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/customers_diary.bs b/src/main/resources/com/unicenta/reports/customers_diary.bs new file mode 100644 index 0000000..b488844 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_diary.bs @@ -0,0 +1,61 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.Customers.Reports.Diary"); +report.setReport("/com/unicenta/reports/customers_diary"); +report.setResourceBundle("com/unicenta/reports/customers_messages"); + +report.setSentence("SELECT " + + "receipts.DATENEW, " + + "tickets.TICKETID, " + + "payments.PAYMENT, " + + "payments.TOTAL, " + + "customers.TAXID, " + + "customers.NAME " + + "FROM receipts, tickets, customers, payments " + + "WHERE receipts.ID = tickets.ID AND receipts.ID = payments.RECEIPT " + + "AND tickets.CUSTOMER = customers.ID " + +// JG AUG 2014 +// "AND (payments.PAYMENT = 'debt' OR payments.PAYMENT = 'debtpaid') " + + "AND ?(QBF_FILTER) " + + "ORDER BY customers.NAME, receipts.DATENEW DESC"); + +report.addParameter("receipts.DATENEW"); +report.addParameter("receipts.DATENEW"); + +paramdates = new com.unicenta.pos.reports.JParamsDatesInterval(); +paramdates.setStartDate(com.unicenta.beans.DateUtils.getToday()); +// JG - 8 Jan 14 paramdates.setEndDate(com.unicenta.beans.DateUtils.getToday()); +paramdates.setEndDate(com.unicenta.beans.DateUtils.getTodayMinutes()); +report.addQBFFilter(paramdates); + +report.addParameter("customers.ID"); +report.addParameter("customers.NAME"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsCustomer()); + +report.addField("DATENEW", com.unicenta.data.loader.Datas.TIMESTAMP); +report.addField("TICKETID", com.unicenta.data.loader.Datas.STRING); +report.addField("PAYMENT", com.unicenta.data.loader.Datas.STRING); +report.addField("TOTAL", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("TAXID", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/customers_diary.jrxml b/src/main/resources/com/unicenta/reports/customers_diary.jrxml new file mode 100644 index 0000000..a424be4 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_diary.jrxml @@ -0,0 +1,360 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/customers_export.bs b/src/main/resources/com/unicenta/reports/customers_export.bs new file mode 100644 index 0000000..9db42f0 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_export.bs @@ -0,0 +1,47 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.Customers.Reports.Export"); +report.setReport("/com/unicenta/reports/customers_export"); +report.setResourceBundle("com/unicenta/reports/customers_messages"); + +report.setSentence("SELECT ID,TAXID, NAME,FIRSTNAME,LASTNAME,ADDRESS,ADDRESS2,CITY,POSTAL,PHONE,EMAIL " + + "FROM customers " + + "WHERE VISIBLE = " + app.getSession().DB.TRUE() + " AND ?(QBF_FILTER)" + + "ORDER BY NAME "); + +report.addParameter("ID"); +report.addParameter("NAME"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsCustomer()); + +report.addField("ID", com.unicenta.data.loader.Datas.STRING); +report.addField("TAXID", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("FIRSTNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("LASTNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("ADDRESS", com.unicenta.data.loader.Datas.STRING); +report.addField("ADDRESS2", com.unicenta.data.loader.Datas.STRING); +report.addField("CITY", com.unicenta.data.loader.Datas.STRING); +report.addField("POSTAL", com.unicenta.data.loader.Datas.STRING); +report.addField("PHONE", com.unicenta.data.loader.Datas.STRING); +report.addField("EMAIL", com.unicenta.data.loader.Datas.STRING); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/customers_export.jrxml b/src/main/resources/com/unicenta/reports/customers_export.jrxml new file mode 100644 index 0000000..037b836 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_export.jrxml @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/customers_list.bs b/src/main/resources/com/unicenta/reports/customers_list.bs new file mode 100644 index 0000000..09acf46 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_list.bs @@ -0,0 +1,46 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.Customers.Reports.List"); +report.setReport("/com/unicenta/reports/customers_list"); +report.setResourceBundle("com/unicenta/reports/customers_messages"); + +report.setSentence("SELECT TAXID, NAME, FIRSTNAME, LASTNAME,ADDRESS,ADDRESS2,CITY,POSTAL,PHONE,EMAIL " + + "FROM customers " + + "WHERE VISIBLE = " + app.getSession().DB.TRUE() + " AND ?(QBF_FILTER)" + + "ORDER BY NAME "); + +report.addParameter("TAXID"); +report.addParameter("NAME"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsCustomer()); + +report.addField("TAXID", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("FIRSTNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("LASTNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("ADDRESS", com.unicenta.data.loader.Datas.STRING); +report.addField("ADDRESS2", com.unicenta.data.loader.Datas.STRING); +report.addField("CITY", com.unicenta.data.loader.Datas.STRING); +report.addField("POSTAL", com.unicenta.data.loader.Datas.STRING); +report.addField("PHONE", com.unicenta.data.loader.Datas.STRING); +report.addField("EMAIL", com.unicenta.data.loader.Datas.STRING); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/customers_list.jrxml b/src/main/resources/com/unicenta/reports/customers_list.jrxml new file mode 100644 index 0000000..65d4086 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_list.jrxml @@ -0,0 +1,315 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/customers_messages.properties b/src/main/resources/com/unicenta/reports/customers_messages.properties new file mode 100644 index 0000000..701e302 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_messages.properties @@ -0,0 +1,44 @@ +label.account=Account : +label.accountname = Acc' Name : +label.address=Address +label.address2=Address2 +label.city=City +label.contact=Contact +label.curdate=Date +label.curdebt=Owing +label.customer=Customer +label.date=Date +label.email=eMail +label.firstname=First Name +label.fulladdress = Address : +label.fullname = Holder : +label.lastname=Last Name +label.maxdebt=Max Debt +label.name=Name +label.notes=Notes +label.payment=Payment +label.period=Period: +label.postal=PCode +label.printed=Printed +label.product=Product +label.sales=Sales +label.taxid=Account +label.telephone=Telephone +label.ticket=Ticket +label.title.Customers=Customers +label.title.Debtors=Customer Debtors +label.title.Diary=Customers Diary +label.title.List=Customer List +label.title.Sales=Customer Sales +label.title.Vouchers=Customer Vouchers +label.total=Total +label.totalG=Grand Total +label.totalP=Amount +label.ttype=Type +label.units=Qty +label.vamount=Value +label.vnum=Number +label.vouchers=Vouchers +label.vstatus=Status +reason.A=Valid +reason.D=Redeemed diff --git a/src/main/resources/com/unicenta/reports/customers_messages_al_SQ.properties b/src/main/resources/com/unicenta/reports/customers_messages_al_SQ.properties new file mode 100644 index 0000000..39edf53 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_messages_al_SQ.properties @@ -0,0 +1,9 @@ +label.address=Adresa +label.curdebt=Borxhi aktual +label.curdate=Data e borxhit +label.maxdebt=Borxhi maximal i lejuar +label.name=Emri +label.notes=Shenim +label.printed=Printuar +label.taxid=Numeri Fiskal +label.title=Klienti \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/customers_messages_ar.properties b/src/main/resources/com/unicenta/reports/customers_messages_ar.properties new file mode 100644 index 0000000..8a1d926 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_messages_ar.properties @@ -0,0 +1,7 @@ +label.curdate=\u062a\u0627\u0631\u064a\u062e \u0627\u0644\u0627\u064a\u062f\u0627\u0639 +label.curdebt=\u0627\u064a\u062f\u0627\u0639 \u0627\u0644\u062d\u0627\u0644\u064a +label.maxdebt=\u0627\u0642\u0635\u0649 \u0627\u064a\u062f\u0627\u0639 +label.notes=\u0645\u0644\u0627\u062d\u0638\u0627\u062a +label.printed=\u0645\u0637\u0628\u0648\u0639 +label.taxid=\u0631\u0642\u0645 \u0627\u0644\u062d\u0633\u0627\u0628 +label.title=\u0627\u0644\u0639\u0645\u0644\u0627\u0621 diff --git a/src/main/resources/com/unicenta/reports/customers_messages_de.properties b/src/main/resources/com/unicenta/reports/customers_messages_de.properties new file mode 100644 index 0000000..7482471 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_messages_de.properties @@ -0,0 +1,18 @@ +label.address=Adresse +label.address2=Adresse2 +label.city=Stadt +label.contact=Kontakt +label.curdate=Forderung Datum +label.curdebt=Forderung jetzt +label.email=e-Mail +label.firstname=Vorname +label.lastname=Nachname +label.maxdebt=Forderung max +label.name=Name +label.notes=Gutscheine +label.phone=Telefon +label.postal=PLZ +label.printed=Gedruckt am: +label.taxid=Steuer ID +label.telephone=Telefon +label.title=Kunden \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/customers_messages_el.properties b/src/main/resources/com/unicenta/reports/customers_messages_el.properties new file mode 100644 index 0000000..8c058df --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_messages_el.properties @@ -0,0 +1,7 @@ +label.curdate=\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03a7\u03c1\u03ad\u03bf\u03c5\u03c2 +label.curdebt=\u03a4\u03c1\u03ad\u03c7\u03bf\u03bd \u03a7\u03c1\u03ad\u03bf\u03c2 +label.maxdebt=\u039c\u03ad\u03b3\u03b9\u03c3\u03c4\u03bf \u03a7\u03c1\u03ad\u03bf\u03c2 +label.notes=\u03a3\u03b7\u03bc\u03b5\u03b9\u03ce\u03c3\u03b5\u03b9\u03c2 +label.printed=Printed +label.taxid=ID \u039b\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03bf\u03cd +label.title=\u03a0\u03b5\u03bb\u03ac\u03c4\u03b5\u03c2 \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/customers_messages_en_US.properties b/src/main/resources/com/unicenta/reports/customers_messages_en_US.properties new file mode 100644 index 0000000..60f49a2 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_messages_en_US.properties @@ -0,0 +1,37 @@ +label.account=Account : +label.accountname = Acc' Name : +label.address=Address +label.address2=Address2 +label.city=City +label.contact=Contact +label.curdate=Date +label.curdebt=Owing +label.customer=Customer +label.date=Date +label.email=eMail +label.firstname=First Name +label.fulladdress = Address : +label.fullname = Holder : +label.lastname=Last Name +label.maxdebt=Max Debt +label.name=Name +label.notes=Notes +label.payment=Payment +label.period=Period: +label.postal=PCode +label.printed=Printed +label.product=Product +label.sales=Sales +label.taxid=Account +label.telephone=Telephone +label.ticket=Ticket +label.title.Customers=Customers +label.title.Debtors=Customer Debtors +label.title.Diary=Customers Diary +label.title.List=Customer List +label.title.Sales=Customer Sales +label.total=Total +label.totalG=Grand Total +label.totalP=Amount +label.ttype=Type +label.units=Qty diff --git a/src/main/resources/com/unicenta/reports/customers_messages_es.properties b/src/main/resources/com/unicenta/reports/customers_messages_es.properties new file mode 100644 index 0000000..b3b6246 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_messages_es.properties @@ -0,0 +1,40 @@ +label.account=Cuente : +label.accountname=Nombre : +label.address=Domicilio +label.address2=Domicilio 2 +label.barcode=C\u00f3digo de barras +label.city=Ciudad +label.contact=Contacto +label.curdate=Fecha de d\u00e9bito +label.curdebt=A cuenta +label.customer=Cliente +label.date=Fecha +label.email=eMail +label.firstname=Nombre de pila +label.fulladdress=Domicilio : +label.fullname=Poseedor : +label.lastname=Apellido : +label.maxdebt=M\u00e1ximo a cuenta +label.name=Nombre +label.notes=Notas +label.payment=Pago +label.period=Per\u00edodo +label.phone=Tel\u00e9fono +label.postal=C\u00f3digo postal +label.printed=Imprimir +label.product=Producto +label.sales=Ventas +label.taxid=CIF / NIF +label.telephone=Tel\u00e9fono +label.ticket=Recibo +label.title.Customers=Clientes +label.title.Debtors=Deudores del cliente +label.title.Diary=Diario del cliente +label.title.List=Lista de clientes +label.title.Sales=Ventas al cliente +label.title=Clientes +label.total=Total +label.totalG=Gran total +label.totalP=Cantidad +label.ttype=Tipo +label.units=Qty \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/customers_messages_es_AR.properties b/src/main/resources/com/unicenta/reports/customers_messages_es_AR.properties new file mode 100644 index 0000000..98bddf6 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_messages_es_AR.properties @@ -0,0 +1,6 @@ +label.curdate=Fecha de d\u00E9bito +label.curdebt=A cuenta +label.maxdebt=M\u00E1ximo a cuenta +label.notes=Notas +label.taxid=CUIT / CUIL +label.title=Clientes diff --git a/src/main/resources/com/unicenta/reports/customers_messages_es_MX.properties b/src/main/resources/com/unicenta/reports/customers_messages_es_MX.properties new file mode 100644 index 0000000..0e00f58 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_messages_es_MX.properties @@ -0,0 +1,6 @@ +label.curdate=Fecha del crdito +label.curdebt=Crdito actual +label.maxdebt=Crdito mximo +label.notes=Notas +label.taxid=ID de impuesto +label.title=Clientes diff --git a/src/main/resources/com/unicenta/reports/customers_messages_et.properties b/src/main/resources/com/unicenta/reports/customers_messages_et.properties new file mode 100644 index 0000000..fdd40ea --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_messages_et.properties @@ -0,0 +1,7 @@ +label.curdate=V\u00f5la kuup\u00e4ev +label.curdebt=Hetke v\u00f5lg +label.maxdebt=Krediidipiir +label.notes=M\u00e4rkmed +label.printed=Tr\u00fckitud +label.taxid=Konto ID +label.title=Kliendid \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/customers_messages_fr.properties b/src/main/resources/com/unicenta/reports/customers_messages_fr.properties new file mode 100644 index 0000000..ef9c3e9 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_messages_fr.properties @@ -0,0 +1,40 @@ +label.account=Compte : +label.accountname = Nom Compte : +label.address=Adresse +label.address2=Adresse2 +label.barcode=Code-barres +label.city=Ville +label.contact=Contact +label.curdate=Date du cr\u00e9dit +label.curdebt=Cr\u00e9dit actuel +label.customer=Client +label.date=Date +label.email=eMail +label.firstname=Pr\u00e9nom +label.fulladdress = Addresse : +label.fullname = Membre : +label.lastname=Nom de famille +label.maxdebt=Cr\u00e9dit maximum +label.name=Nom +label.notes=Notes +label.payment=Paiement +label.period=P\u00e9riod: +label.phone=T\u00e9l\u00e9phone +label.postal=Code Postal +label.printed=Imprim\u00e9 +label.product=Produit +label.sales=Ventes +label.taxid=N\u00b0 client +label.telephone=T\u00e9l\u00e9phone +label.ticket=Ticket +label.title.Customers=Clients +label.title.Debtors=Client d\u00e9biteurs +label.title.Diary=Journal clients +label.title.List=Liste Clients +label.title.Sales=Ventes par Client +label.title=Clientes +label.total=Total +label.totalG=Grande Total +label.totalP=Valeur +label.ttype=Type +label.units=Qt\u00e9 \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/customers_messages_hr.properties b/src/main/resources/com/unicenta/reports/customers_messages_hr.properties new file mode 100644 index 0000000..29819c0 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_messages_hr.properties @@ -0,0 +1,7 @@ +label.curdate=Datum duga +label.curdebt=Trenutni dug +label.maxdebt=Max dug +label.notes=Bilje\u009ake +label.printed=Ispisano +label.taxid=Klijent +label.title=Kupac diff --git a/src/main/resources/com/unicenta/reports/customers_messages_it.properties b/src/main/resources/com/unicenta/reports/customers_messages_it.properties new file mode 100644 index 0000000..5de79b9 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_messages_it.properties @@ -0,0 +1,18 @@ +label.address=Indirizzo +label.address2=Indirizzo2 +label.city=Citta +label.contact=Contatto +label.curdate=Data Debito +label.curdebt=Debito Corrente +label.email=eMail +label.firstname=Nome +label.lastname=Cognome +label.maxdebt=Debito Massimo +label.name=Nome +label.notes=Note +label.phone=Telefono +label.postal=C.A.P. +label.printed=Stampato +label.taxid=ID Account +label.telephone=Telefono +label.title=Clienti \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/customers_messages_nl.properties b/src/main/resources/com/unicenta/reports/customers_messages_nl.properties new file mode 100644 index 0000000..49b995e --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_messages_nl.properties @@ -0,0 +1,8 @@ +label.curdate=Datum krediet +label.curdebt=Huidig krediet +label.maxdebt=Maximum krediet +label.name=Naam +label.notes=Biljetten +label.printed=Afgedrukt +label.taxid=BTW ID +label.title=Klanten diff --git a/src/main/resources/com/unicenta/reports/customers_sales.bs b/src/main/resources/com/unicenta/reports/customers_sales.bs new file mode 100644 index 0000000..175af67 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_sales.bs @@ -0,0 +1,61 @@ +// uniCenta oPOS - touch friendly EPoS +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.Customers.Reports.Sales"); +report.setReport("/com/unicenta/reports/customers_sales"); +report.setResourceBundle("com/unicenta/reports/customers_messages"); + +report.setSentence("SELECT " + + "customers.NAME AS CNAME, " + + "receipts.DATENEW, " + + "tickets.TICKETID, " + + "products.NAME AS PNAME, " + + "tickets.TICKETTYPE, " + + "SUM(ticketlines.UNITS) AS UNITS, " + + "SUM(ticketlines.UNITS * ticketlines.PRICE) AS TOTAL " + + "FROM receipts, customers, tickets, ticketlines LEFT OUTER JOIN products ON ticketlines.PRODUCT = products.ID " + + "WHERE customers.ID = tickets.CUSTOMER AND ticketlines.PRODUCT = products.ID AND receipts.ID = tickets.ID AND tickets.ID = ticketlines.TICKET AND ?(QBF_FILTER) " + + "GROUP BY customers.NAME, receipts.DATENEW, tickets.TICKETID, products.NAME, tickets.TICKETTYPE " + + "ORDER BY customers.NAME, products.NAME, receipts.DATENEW"); + +report.addParameter("receipts.DATENEW"); +report.addParameter("receipts.DATENEW"); + +paramdates = new com.unicenta.pos.reports.JParamsDatesInterval(); + +paramdates.setStartDate(com.unicenta.beans.DateUtils.getToday()); +// JG - 8 Jan 14 paramdates.setEndDate(com.unicenta.beans.DateUtils.getToday()); +paramdates.setEndDate(com.unicenta.beans.DateUtils.getTodayMinutes()); +report.addQBFFilter(paramdates); + +report.addParameter("customers.ID"); +report.addParameter("customers.NAME"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsCustomer()); + +report.addField("CNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("DATENEW", com.unicenta.data.loader.Datas.TIMESTAMP); +report.addField("TICKETID", com.unicenta.data.loader.Datas.STRING); +report.addField("PNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("TICKETTYPE", com.unicenta.data.loader.Datas.INT); +report.addField("UNITS", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("TOTAL", com.unicenta.data.loader.Datas.DOUBLE); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/customers_sales.jrxml b/src/main/resources/com/unicenta/reports/customers_sales.jrxml new file mode 100644 index 0000000..7872a46 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_sales.jrxml @@ -0,0 +1,471 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band height="52" splitType="Stretch"> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-5" mode="Transparent" x="50" y="33" width="110" height="15" uuid="5f5ae0a5-05ea-4f83-9cea-56f8eb5405d9"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.TIMESTAMP.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[1])]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-6" mode="Transparent" x="170" y="33" width="110" height="15" uuid="22773f2d-3be7-4fb0-a178-ccb224688745"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.TIMESTAMP.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[3])]]></textFieldExpression> + </textField> + <staticText> + <reportElement key="staticText-1" mode="Transparent" x="160" y="33" width="10" height="15" uuid="cb10ac3c-8836-43cb-8e5f-84a4f031dd27"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Center" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <text><![CDATA[- +]]></text> + </staticText> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-1" mode="Transparent" x="0" y="0" width="375" height="30" forecolor="#33CCFF" backcolor="#000000" uuid="36787551-14c1-4de0-a4bb-1d69f617e95b"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="14" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.title.Sales}]]></textFieldExpression> + </textField> + <rectangle radius="5"> + <reportElement key="rectangle-1" mode="Opaque" x="0" y="50" width="535" height="2" forecolor="#33CCFF" backcolor="#33CCFF" uuid="d5616e40-441d-4c33-bf12-6bb75dd29c19"/> + <graphicElement fill="Solid"> + <pen lineWidth="0.25" lineStyle="Solid"/> + </graphicElement> + </rectangle> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-2" mode="Opaque" x="435" y="1" width="100" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="f1ebdeba-707c-4452-aac2-453ffaa466df"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.printed}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report" pattern="dd/MM/yyyy h.mm a" isBlankWhenNull="false"> + <reportElement key="textField-3" x="435" y="15" width="100" height="15" uuid="491b1df9-4e20-46d9-aa2c-97b445839e31"/> + <textElement textAlignment="Right"> + <font fontName="SansSerif" size="10"/> + </textElement> + <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-4" mode="Opaque" x="0" y="33" width="50" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="86677afa-9925-4fbb-8dd8-29a2823cea73"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.period}]]></textFieldExpression> + </textField> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/customers_vouchers.bs b/src/main/resources/com/unicenta/reports/customers_vouchers.bs new file mode 100644 index 0000000..6a4e9f4 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_vouchers.bs @@ -0,0 +1,58 @@ +// uniCenta oPOS - touch friendly EPoS +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.Customers.Reports.Vouchers"); +report.setReport("/com/unicenta/reports/customers_vouchers"); +report.setResourceBundle("com/unicenta/reports/customers_messages"); + +report.setSentence("SELECT customers.name AS CNAME, " + + "vouchers.voucher_number AS VNUM, " + + "vouchers.amount AS VAMOUNT, " + + "vouchers.status AS VSTATUS, " + + "payments.total AS TOTAL, " + + "tickets.ticketid AS TICKETID, " + + "receipts.datenew AS TDATE " + +"FROM (((tickets tickets " + + "INNER JOIN receipts receipts " + + "ON (tickets.id = receipts.id)) " + + "INNER JOIN payments payments " + + "ON (payments.receipt = receipts.id) " + + "AND (tickets.id = payments.receipt)) " + + "INNER JOIN vouchers vouchers " + + "ON (payments.voucher = vouchers.voucher_number)) " + + "INNER JOIN customers customers " + + "ON (tickets.customer = customers.id) " + +"WHERE ?(QBF_FILTER) " + +"ORDER BY customers.name "); + +report.addParameter("ID"); +report.addParameter("NAME"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsCustomer()); + +report.addField("CNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("VNUM", com.unicenta.data.loader.Datas.STRING); +report.addField("VAMOUNT", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("VSTATUS", com.unicenta.data.loader.Datas.STRING); +report.addField("TOTAL", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("TICKETID", com.unicenta.data.loader.Datas.STRING); +report.addField("TDATE", com.unicenta.data.loader.Datas.TIMESTAMP); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/customers_vouchers.jrxml b/src/main/resources/com/unicenta/reports/customers_vouchers.jrxml new file mode 100644 index 0000000..bb9bd09 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/customers_vouchers.jrxml @@ -0,0 +1,282 @@ + + + + + + + + + + + + + + + + + + + + + + + + + <band height="52" splitType="Stretch"> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-1" mode="Transparent" x="0" y="0" width="375" height="30" forecolor="#33CCFF" backcolor="#000000" uuid="36787551-14c1-4de0-a4bb-1d69f617e95b"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="14" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.title.Vouchers}]]></textFieldExpression> + </textField> + <rectangle radius="5"> + <reportElement key="rectangle-1" mode="Opaque" x="0" y="50" width="535" height="2" forecolor="#33CCFF" backcolor="#33CCFF" uuid="d5616e40-441d-4c33-bf12-6bb75dd29c19"/> + <graphicElement fill="Solid"> + <pen lineWidth="0.25" lineStyle="Solid"/> + </graphicElement> + </rectangle> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-2" mode="Opaque" x="435" y="1" width="100" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="f1ebdeba-707c-4452-aac2-453ffaa466df"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.printed}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report" pattern="dd/MM/yyyy h.mm a" isBlankWhenNull="false"> + <reportElement key="textField-3" x="435" y="15" width="100" height="15" uuid="491b1df9-4e20-46d9-aa2c-97b445839e31"/> + <textElement textAlignment="Right"> + <font fontName="SansSerif" size="10"/> + </textElement> + <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-8" mode="Opaque" x="0" y="35" width="135" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="f5375ab7-2803-4c79-8e90-4e131ede4a81"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="11" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.customer}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-8" mode="Opaque" x="135" y="34" width="100" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="501c9103-6848-46b8-8439-d04294ee692e"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="11" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.vnum}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-9" mode="Opaque" x="235" y="34" width="89" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="eca6fd58-3893-496b-89e7-c924d310b067"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="11" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.vamount}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-10" mode="Opaque" x="324" y="34" width="52" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="59ae8cbf-43c1-4691-894e-ce92fb2424f6"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="11" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.vstatus}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-10" mode="Opaque" x="383" y="34" width="52" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="55b7a888-c5a0-4eda-97cd-81673a2a4db9"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="11" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.ticket}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-10" mode="Opaque" x="435" y="34" width="52" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="bc35bc02-0baa-4d4c-880c-310fc4907c95"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="11" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.curdate}]]></textFieldExpression> + </textField> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/epm_dailypresence.bs b/src/main/resources/com/unicenta/reports/epm_dailypresence.bs new file mode 100644 index 0000000..8db912a --- /dev/null +++ b/src/main/resources/com/unicenta/reports/epm_dailypresence.bs @@ -0,0 +1,53 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// Copyright (C) 2011 Gjergj Sheldija +// http://www.acme-tech.net// +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.EPM.DailyPresenceReport"); +report.setReport("/com/unicenta/reports/epm_dailypresence"); +report.setResourceBundle("com/unicenta/reports/epm_messages"); + +report.setSentence("SELECT " + + "people.NAME, " + + "shifts.STARTSHIFT, " + + "shifts.ENDSHIFT, " + + "CONCAT('',TIMEDIFF(shifts.ENDSHIFT, shifts.STARTSHIFT)) AS TOTAL " + + "FROM people LEFT JOIN shifts ON shifts.PPLID = people.ID " + + "WHERE ?(QBF_FILTER) " + + "ORDER BY people.NAME "); + +report.addParameter("shifts.STARTSHIFT"); +report.addParameter("shifts.ENDSHIFT"); + +paramdates = new com.unicenta.pos.reports.JParamsDatesInterval(); + +paramdates.setStartDate(com.unicenta.beans.DateUtils.getToday()); +// JG - 8 Jan 14 paramdates.setEndDate(com.unicenta.beans.DateUtils.getToday()); +paramdates.setEndDate(com.unicenta.beans.DateUtils.getTodayMinutes()); + +report.addQBFFilter(paramdates); + +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("STARTSHIFT", com.unicenta.data.loader.Datas.TIMESTAMP); +report.addField("ENDSHIFT", com.unicenta.data.loader.Datas.TIMESTAMP); +report.addField("TOTAL", com.unicenta.data.loader.Datas.STRING); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/epm_dailypresence.jrxml b/src/main/resources/com/unicenta/reports/epm_dailypresence.jrxml new file mode 100644 index 0000000..873726f --- /dev/null +++ b/src/main/resources/com/unicenta/reports/epm_dailypresence.jrxml @@ -0,0 +1,325 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band height="74"> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-21" mode="Transparent" x="0" y="0" width="375" height="30" forecolor="#33CCFF" backcolor="#FFFFFF" uuid="58913b3a-3a74-4ff0-bb6c-152118f55e3a"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="14" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.title}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-2" mode="Opaque" x="400" y="0" width="135" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="491b731e-32bf-4577-b242-f6a3cd696569"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.printed}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report" pattern="dd/MM/yyyy h.mm a" isBlankWhenNull="false"> + <reportElement key="textField-3" x="400" y="15" width="135" height="15" uuid="ebc727d5-39f8-4d0e-9fa0-b1c66e9e86e4"/> + <textElement textAlignment="Right"> + <font fontName="SansSerif" size="10"/> + </textElement> + <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-10" mode="Opaque" x="0" y="33" width="50" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="93d41967-fa99-4dc3-9bb9-42937bf1ac4a"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.period}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-2" mode="Transparent" x="50" y="33" width="110" height="15" uuid="08faefff-0b38-49d8-aa07-f17b78c0428f"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.DATE.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[1])]]></textFieldExpression> + </textField> + <staticText> + <reportElement key="staticText-1" mode="Transparent" x="160" y="33" width="10" height="15" uuid="d61227ca-520e-4248-8eac-5e68d52f9f2b"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Center" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <text><![CDATA[-]]></text> + </staticText> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-3" mode="Transparent" x="170" y="33" width="110" height="15" uuid="ec266a5c-b5fa-4311-aa52-511d5b7b4144"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.DATE.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[3])]]></textFieldExpression> + </textField> + <rectangle radius="5"> + <reportElement key="rectangle-1" mode="Opaque" x="0" y="50" width="535" height="2" forecolor="#33CCFF" backcolor="#33CCFF" uuid="722cd55b-fc92-47f9-8e80-0b29773690dc"/> + <graphicElement fill="Solid"> + <pen lineWidth="0.25" lineStyle="Solid"/> + </graphicElement> + </rectangle> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-23" mode="Opaque" x="0" y="55" width="115" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="4d0d585f-031a-4e69-8ee8-bf1e3be63ec2"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="11" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.name}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-23" mode="Opaque" x="138" y="55" width="122" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="ae7b535b-8c14-4f2f-83e8-444045d379a0"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="11" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.start}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-23" mode="Opaque" x="280" y="55" width="130" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="304fb745-4d53-4fc5-962e-ca7884405ad1"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="11" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.end}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-23" mode="Opaque" x="435" y="55" width="100" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="7c97deba-f19c-4a87-befd-9135b79ff3eb"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="11" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.total}]]></textFieldExpression> + </textField> + <line> + <reportElement key="line-4" mode="Opaque" x="0" y="70" width="535" height="1" forecolor="#000000" backcolor="#FFFFFF" uuid="5dd2c504-c533-4184-8dac-e6074c364892"/> + <graphicElement fill="Solid"> + <pen lineWidth="0.25" lineStyle="Solid"/> + </graphicElement> + </line> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/epm_dailyschedule.bs b/src/main/resources/com/unicenta/reports/epm_dailyschedule.bs new file mode 100644 index 0000000..31ce19e --- /dev/null +++ b/src/main/resources/com/unicenta/reports/epm_dailyschedule.bs @@ -0,0 +1,53 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// Copyright (C) 2011 Gjergj Sheldija +// http://www.acme-tech.net// +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.EPM.DailyScheduleReport"); +report.setReport("/com/unicenta/reports/epm_dailyschedule"); +report.setResourceBundle("com/unicenta/reports/epm_messages"); + +report.setSentence("SELECT " + + "people.NAME, " + + "leaves.STARTDATE, " + + "leaves.ENDDATE, " + + "CONCAT('',DATEDIFF(leaves.ENDDATE, leaves.STARTDATE)) AS TOTAL " + + "FROM people LEFT JOIN leaves ON leaves.PPLID = people.ID " + + "WHERE ?(QBF_FILTER) " + + "ORDER BY leaves.STARTDATE DESC "); + +report.addParameter("leaves.STARTDATE"); +report.addParameter("leaves.ENDDATE"); + +paramdates = new com.unicenta.pos.reports.JParamsDatesInterval(); + +paramdates.setStartDate(com.unicenta.beans.DateUtils.getToday()); +// JG - 8 Jan 14 paramdates.setEndDate(com.unicenta.beans.DateUtils.getToday()); +paramdates.setEndDate(com.unicenta.beans.DateUtils.getTodayMinutes()); + +report.addQBFFilter(paramdates); + +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("STARTDATE", com.unicenta.data.loader.Datas.TIMESTAMP); +report.addField("ENDDATE", com.unicenta.data.loader.Datas.TIMESTAMP); +report.addField("TOTAL", com.unicenta.data.loader.Datas.STRING); + +report; diff --git a/src/main/resources/com/unicenta/reports/epm_dailyschedule.jrxml b/src/main/resources/com/unicenta/reports/epm_dailyschedule.jrxml new file mode 100644 index 0000000..c320591 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/epm_dailyschedule.jrxml @@ -0,0 +1,325 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band height="74"> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-21" mode="Transparent" x="0" y="0" width="375" height="30" forecolor="#33CCFF" backcolor="#FFFFFF" uuid="e5fe9f87-96f1-49fe-a57b-0df532b21172"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="14" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.title}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-23" mode="Opaque" x="0" y="55" width="115" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="81c434ac-428c-46b6-9087-88017033572d"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="11" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.name}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-23" mode="Opaque" x="138" y="55" width="122" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="b8260953-bd0a-4e0e-9b0e-c2eff170eec5"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="11" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.start}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-23" mode="Opaque" x="280" y="55" width="130" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="22455dcb-bb99-4806-bc03-67c9e56c7524"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="11" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.end}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-23" mode="Opaque" x="435" y="55" width="100" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="c15c7c6b-d2cd-4bd2-8f80-a1220123374f"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="11" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.total}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-2" mode="Opaque" x="400" y="0" width="135" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="fef16531-7fbf-40e9-a93a-b1be737e360f"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.printed}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report" pattern="dd/MM/yyyy h.mm a" isBlankWhenNull="false"> + <reportElement key="textField-3" x="400" y="15" width="135" height="15" uuid="daa7df66-2c71-465b-9254-57d272322778"/> + <textElement textAlignment="Right"> + <font fontName="SansSerif" size="10"/> + </textElement> + <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-10" mode="Opaque" x="0" y="33" width="50" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="a3d2d7f3-d14b-4429-8f95-cf63c6a485ff"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.period}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-2" mode="Transparent" x="50" y="33" width="110" height="15" uuid="d042401e-df76-45eb-abee-fd71d6f39dcb"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.DATE.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[1])]]></textFieldExpression> + </textField> + <staticText> + <reportElement key="staticText-1" mode="Transparent" x="160" y="33" width="10" height="15" uuid="8ea26690-46db-4d3b-9ded-b6f163ee5a41"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Center" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <text><![CDATA[-]]></text> + </staticText> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-3" mode="Transparent" x="170" y="33" width="110" height="15" uuid="24091254-ee66-446c-a887-376129d95058"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.DATE.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[3])]]></textFieldExpression> + </textField> + <rectangle radius="5"> + <reportElement key="rectangle-1" mode="Opaque" x="0" y="50" width="535" height="2" forecolor="#33CCFF" backcolor="#33CCFF" uuid="02335135-98a2-410c-b26a-82b3377d2308"/> + <graphicElement fill="Solid"> + <pen lineWidth="0.25" lineStyle="Solid"/> + </graphicElement> + </rectangle> + <line> + <reportElement key="line-4" mode="Opaque" x="0" y="70" width="535" height="1" forecolor="#000000" backcolor="#FFFFFF" uuid="e05c23ce-acdf-430d-91be-0f13cff3ebd1"/> + <graphicElement fill="Solid"> + <pen lineWidth="0.25" lineStyle="Solid"/> + </graphicElement> + </line> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/epm_messages.properties b/src/main/resources/com/unicenta/reports/epm_messages.properties new file mode 100644 index 0000000..6c2154f --- /dev/null +++ b/src/main/resources/com/unicenta/reports/epm_messages.properties @@ -0,0 +1,17 @@ +label.cash=Cash Value +label.end=End Leave +label.end=End Shift +label.enddate=End Date +label.name=Name +label.period=Period: +label.printed=Printed +label.start=Start Leave +label.start=Start Shift +label.startdate=Start Date +label.title=Daily Presence +label.title=Daily Schedule +label.title=Performance Report +label.total=Total Days +label.total=Total Hours +label.total=Total: +label.user=User diff --git a/src/main/resources/com/unicenta/reports/epm_messages_al_SQ.properties b/src/main/resources/com/unicenta/reports/epm_messages_al_SQ.properties new file mode 100644 index 0000000..b8e1ace --- /dev/null +++ b/src/main/resources/com/unicenta/reports/epm_messages_al_SQ.properties @@ -0,0 +1,46 @@ +# uniCenta oPOS - touch friendly EPoS +# Copyright (c) 2013 uniCenta oPOS +# https://unicenta.com/projects/unicentaopos +# Copyright (C) 2011 Gjergj Sheldija +# http:#www.acme-tech.net +# +# This file is part of uniCenta oPOS. +# +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see . + + +label.end=Fundi i Orarit +label.name=Emri +label.period=Periudha: +label.printed=Printuar +label.start=Fillimi i Orarit +label.title=Paraqitja Ditore +label.total=Totali i oreve + +label.end=Perfundimi i pushimit +label.name=Emri +label.period=Periudha: +label.printed=Printuar +label.start=Fillimi i Pushimit +label.title=Orari Ditor +label.total=Totali i Diteve + +label.title=Raporti i Permbushjes +label.printed=Printuar +label.period=Periudha +label.user=Perdorues +label.startdate=Data e Fillimit +label.enddate=Data e Mbarimit +label.cash=Vlera ne te Gatshme +label.total=Total: diff --git a/src/main/resources/com/unicenta/reports/epm_messages_de.properties b/src/main/resources/com/unicenta/reports/epm_messages_de.properties new file mode 100644 index 0000000..8d9a177 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/epm_messages_de.properties @@ -0,0 +1,46 @@ +# uniCenta oPOS - touch friendly EPoS +# Copyright (c) 2013 uniCenta oPOS +# https://unicenta.com/projects/unicentaopos +# Copyright (C) 2011 Gjergj Sheldija +# http:#www.acme-tech.net +# +# This file is part of uniCenta oPOS. +# +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see . + + +label.end=Arbeitsende +label.name=Name +label.period=Zeitraum: +label.printed=Ausgedruckt am: +label.start=Arbeitsbeginn +label.title=T\u00e4gliche Anwesenheit +label.total=Summe Stunden + +label.end=Ende Unterbrechung +label.name=Name +label.period=Zeitraum: +label.printed=Ausgedruckt am: +label.start=Beginn Unterbrechung +label.title=Daily Schedule +label.total=Summe Tage + +label.title=Performance Report +label.printed=Erstellt am: +label.period=Zeitraum +label.user=Benutzer +label.startdate=Beginn +label.enddate=Ende +label.cash=Cash Value +label.total=Summe: diff --git a/src/main/resources/com/unicenta/reports/epm_messages_en_US.properties b/src/main/resources/com/unicenta/reports/epm_messages_en_US.properties new file mode 100644 index 0000000..0af2e82 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/epm_messages_en_US.properties @@ -0,0 +1,46 @@ +# uniCenta oPOS - touch friendly EPoS +# Copyright (c) 2013 uniCenta oPOS +# https://unicenta.com/projects/unicentaopos +# Copyright (C) 2011 Gjergj Sheldija +# http:#www.acme-tech.net +# +# This file is part of uniCenta oPOS. +# +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see . + + +label.end=End Shift +label.name=Name +label.period=Period: +label.printed=Printed +label.start=Start Shift +label.title=Daily Presence +label.total=Total Hours + +label.end=End Leave +label.name=Name +label.period=Period: +label.printed=Printed +label.start=Start Leave +label.title=Daily Schedule +label.total=Total Days + +label.title=Performance Report +label.printed=Printed +label.period=Period +label.user=User +label.startdate=Start Date +label.enddate=End Date +label.cash=Cash Value +label.total=Total: \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/epm_messages_es.properties b/src/main/resources/com/unicenta/reports/epm_messages_es.properties new file mode 100644 index 0000000..039a355 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/epm_messages_es.properties @@ -0,0 +1,46 @@ +# uniCenta oPOS - touch friendly EPoS +# Copyright (c) 2013 uniCenta oPOS +# https://unicenta.com/projects/unicentaopos +# Copyright (C) 2011 Gjergj Sheldija +# http:#www.acme-tech.net +# +# This file is part of uniCenta oPOS. +# +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see . + + +label.end=Fin +label.name=Nombre +label.period=Per\u00edodo: +label.printed=Imprimir +label.start=Inicio +label.title=Presencia Diaria +label.total=Horas Totales + +label.end=Ausencia Final +label.name=Nombre +label.period=Per\u00edodo: +label.printed=Imprimir +label.start=Inicio de la Ausencia +label.title=Agenda Diaria +label.total=Total D\u00edas + +label.title=Informe de Prestaciones +label.printed=Imprimir +label.period=Per\u00edodo +label.user=Usuario +label.startdate=Fecha Inicio +label.enddate=Fecha Final +label.cash=Efectivo +label.total=Total: \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/epm_messages_fr.properties b/src/main/resources/com/unicenta/reports/epm_messages_fr.properties new file mode 100644 index 0000000..54ce7c9 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/epm_messages_fr.properties @@ -0,0 +1,46 @@ +# uniCenta oPOS - touch friendly EPoS +# Copyright (c) 2013 uniCenta oPOS +# https://unicenta.com/projects/unicentaopos +# Copyright (C) 2011 Gjergj Sheldija +# http:#www.acme-tech.net +# +# This file is part of uniCenta oPOS. +# +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see . + + +label.end=Fin +label.name=Nom +label.period=P\u00e9riode: +label.printed=Imprim\u00e9 +label.start=D\u00e9but +label.title=Pr\u00e9sence quotidienne +label.total=Total des heures + +label.end=Fin +label.name=Nom +label.period=P\u00e9riode: +label.printed=Imprim\u00e9 +label.start=D\u00e9but +label.title=Programme de la journ\u00e9e +label.total=Total jours + +label.title=Performance +label.printed=Imprim\u00e9 +label.period=P\u00e9riode +label.user=Utilisateur +label.startdate=Date d\u00e9but +label.enddate=Date Fin +label.cash=Valeur rachat +label.total=Total: diff --git a/src/main/resources/com/unicenta/reports/epm_messages_it.properties b/src/main/resources/com/unicenta/reports/epm_messages_it.properties new file mode 100644 index 0000000..617b384 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/epm_messages_it.properties @@ -0,0 +1,46 @@ +# uniCenta oPOS - touch friendly EPoS +# Copyright (c) 2013 uniCenta oPOS +# https://unicenta.com/projects/unicentaopos +# Copyright (C) 2011 Gjergj Sheldija +# http:#www.acme-tech.net +# +# This file is part of uniCenta oPOS. +# +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see . + + +label.end=Fine Turno +label.name=Nome +label.period=Periodo: +label.printed=Stampato +label.start=Inizio Turno +label.title=Presenza Giornaliera +label.total=Totale Ore + +label.title=Rapporto Prestazioni +label.printed=Stampato +label.period=Periodo +label.user=Utente +label.startdate=Data Inizio +label.enddate=Data Fine +label.cash=valore in cassa +label.total=Totale: + +label.end=Fine Permesso +label.name=Nome +label.period=Periodo: +label.printed=Stampato +label.start=Inizio Permesso +label.title=Programma Giornaliero +label.total=Totale Giorni diff --git a/src/main/resources/com/unicenta/reports/epm_messages_nl.properties b/src/main/resources/com/unicenta/reports/epm_messages_nl.properties new file mode 100644 index 0000000..ca2cb18 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/epm_messages_nl.properties @@ -0,0 +1,30 @@ +# uniCenta oPOS - TRanslation File +# Copyright (c) 2014 J.SNijder +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see . + + +label.end=Einde Dienst +label.name=Naam +label.period=Periode: +label.printed=Afgedrukt +label.start=Start Dienst +label.title=Dagelijkse aanwezigheid +label.total=Totaal Uren + +label.title=Prestatie Rapport +label.printed=Afgedrukt +label.period=Periode +label.user=Gebruiker +label.startdate=Start Datum +label.enddate=End Datum +label.cash=Contant Waarde +label.total=Totaal: + +label.end=Eind Verlof +label.name=Naam +label.period=Periode: +label.printed=Afgedrukt +label.start=Start Verlof +label.title=Werk Rooster +label.total=Totaal aantal Dagen diff --git a/src/main/resources/com/unicenta/reports/epm_performance.bs b/src/main/resources/com/unicenta/reports/epm_performance.bs new file mode 100644 index 0000000..a4490b1 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/epm_performance.bs @@ -0,0 +1,44 @@ +// uniCenta oPOS - Touch Friendly POS +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.EPM.PerformanceReport"); +report.setReport("/com/unicenta/reports/epm_performance"); +report.setResourceBundle("com/unicenta/reports/epm_messages"); + +report.setSentence("SELECT people.NAME, MIN(receipts.DATENEW) AS STARTDATE, MAX(receipts.DATENEW) AS ENDDATE, SUM(ticketlines.UNITS * ticketlines.PRICE) AS TOTAL " + + "FROM people, receipts, tickets, ticketlines WHERE people.ID = tickets.PERSON AND receipts.ID = tickets.ID AND tickets.ID = ticketlines.TICKET AND ?(QBF_FILTER) " + + "GROUP BY people.NAME ORDER BY people.NAME"); + +report.addParameter("receipts.DATENEW"); +report.addParameter("receipts.DATENEW"); + +paramdates = new com.unicenta.pos.reports.JParamsDatesInterval(); +paramdates.setStartDate(com.unicenta.beans.DateUtils.getToday()); +// JG - 8 Jan 14 paramdates.setEndDate(com.unicenta.beans.DateUtils.getToday()); +paramdates.setEndDate(com.unicenta.beans.DateUtils.getTodayMinutes()); + +report.addQBFFilter(paramdates); + +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("STARTDATE", com.unicenta.data.loader.Datas.TIMESTAMP); +report.addField("ENDDATE", com.unicenta.data.loader.Datas.TIMESTAMP); +report.addField("TOTAL", com.unicenta.data.loader.Datas.DOUBLE); + +report; diff --git a/src/main/resources/com/unicenta/reports/epm_performance.jrxml b/src/main/resources/com/unicenta/reports/epm_performance.jrxml new file mode 100644 index 0000000..c0c0f30 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/epm_performance.jrxml @@ -0,0 +1,361 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band height="52"> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-8" mode="Transparent" x="50" y="33" width="110" height="15" uuid="2c9296a7-ebdd-492e-8a76-eb4b3b2cd07e"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Middle" rotation="None"> + <font fontName="Arial" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.DATE.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[1])]]></textFieldExpression> + </textField> + <staticText> + <reportElement key="staticText-6" mode="Transparent" x="160" y="33" width="10" height="15" uuid="b1ca7940-fceb-4a3b-8fb3-de237d55f7b4"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Center" verticalAlignment="Middle" rotation="None"> + <font fontName="Arial" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <text><![CDATA[- +]]></text> + </staticText> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-9" mode="Transparent" x="170" y="33" width="110" height="15" uuid="333a6770-21f8-4a9c-a8ac-3b0af581877c"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="Arial" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.DATE.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[3])]]></textFieldExpression> + </textField> + <rectangle radius="5"> + <reportElement key="rectangle-1" mode="Opaque" x="0" y="50" width="535" height="2" forecolor="#33CCFF" backcolor="#33CCFF" uuid="b8dec4ad-1d69-4477-94e1-8e79b418b516"/> + <graphicElement fill="Solid"> + <pen lineWidth="0.25" lineStyle="Solid"/> + </graphicElement> + </rectangle> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-18" mode="Transparent" x="0" y="0" width="375" height="30" forecolor="#33CCFF" backcolor="#FFFFFF" uuid="c6a3b9a4-5ece-4c85-85ea-f62565581587"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Top" rotation="None"> + <font fontName="Arial" size="14" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.title}]]></textFieldExpression> + </textField> + <textField pattern="dd/MM/yyyy h.mm a" isBlankWhenNull="false"> + <reportElement key="textField" x="400" y="15" width="135" height="15" uuid="395d9440-b276-4529-a69c-9163965ef98e"/> + <textElement textAlignment="Right"> + <font fontName="Arial" size="10"/> + </textElement> + <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-10" mode="Opaque" x="400" y="0" width="135" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="6dee7c66-1ef2-40db-bec4-f089a72d5ade"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Top" rotation="None"> + <font fontName="Arial" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.printed}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-19" mode="Opaque" x="0" y="33" width="50" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="8db2f46b-1f2e-436c-a1df-1aa21272ac15"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="Arial" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.period}]]></textFieldExpression> + </textField> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/inventory.bs b/src/main/resources/com/unicenta/reports/inventory.bs new file mode 100644 index 0000000..41d9c41 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory.bs @@ -0,0 +1,77 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.Inventory"); +report.setReport("/com/unicenta/reports/inventory"); +report.setResourceBundle("com/unicenta/reports/inventory_messages"); + +report.setSentence("SELECT " + + "stockcurrent.LOCATION AS LOCATIONID, " + + "locations.NAME AS LOCATIONNAME, " + + "products.REFERENCE, " + + "products.NAME AS PRODUCTNAME, " + + "products.CATEGORY, " + + "categories.NAME AS CATEGORYNAME, " + + "SUM(stockcurrent.UNITS) AS UNITS, " + + "products.PRICEBUY, " + + "products.PRICESELL, " + + "COALESCE(products.STOCKVOLUME, 0) AS STOCKVOLUME, " + + "COALESCE(products.STOCKCOST, 0) AS STOCKCOST, " + + "COALESCE(stocklevel.STOCKSECURITY, 0) AS STOCKSECURITY, " + + "COALESCE(stocklevel.STOCKMAXIMUM, 0) AS STOCKMAXIMUM " + + "FROM stockcurrent " + + "JOIN locations ON stockcurrent.LOCATION = locations.ID " + + "JOIN products ON stockcurrent.PRODUCT = products.ID " + + "JOIN categories ON products.CATEGORY = categories.ID " + + "LEFT OUTER JOIN stocklevel ON stockcurrent.LOCATION = " + + "stocklevel.LOCATION AND stockcurrent.PRODUCT = stocklevel.PRODUCT " + + "WHERE ?(QBF_FILTER) " + + "GROUP BY stockcurrent.LOCATION, locations.NAME, products.REFERENCE, " + + "products.NAME, products.CATEGORY, categories.NAME, products.PRICEBUY, " + + "products.PRICESELL, products.STOCKVOLUME, products.STOCKCOST, " + + "stocklevel.STOCKSECURITY, stocklevel.STOCKMAXIMUM " + + "ORDER BY stockcurrent.LOCATION, categories.NAME, products.NAME"); + +report.addParameter("stockcurrent.LOCATION"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsLocationWithFirst()); + +report.addParameter("products.NAME"); +report.addParameter("products.PRICEBUY"); +report.addParameter("products.PRICESELL"); +report.addParameter("products.CATEGORY"); +report.addParameter("products.CODE"); +report.addQBFFilter(new com.unicenta.pos.ticket.ProductFilter()); + +report.addField("LOCATIONID", com.unicenta.data.loader.Datas.STRING); +report.addField("LOCATIONNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("REFERENCE", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("CATEGORY", com.unicenta.data.loader.Datas.STRING); +report.addField("CATEGORYNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("UNITS", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("PRICEBUY", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("PRICESELL", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("STOCKVOLUME", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("STOCKCOST", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("STOCKSECURITY", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("STOCKMAXIMUM", com.unicenta.data.loader.Datas.DOUBLE); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/inventory.jrxml b/src/main/resources/com/unicenta/reports/inventory.jrxml new file mode 100644 index 0000000..a092048 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory.jrxml @@ -0,0 +1,789 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band height="54"> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-13" mode="Transparent" x="0" y="0" width="375" height="30" forecolor="#33CCFF" backcolor="#FFFFFF" uuid="6e227e7f-ac25-420b-9b5e-116f8186a57d"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="14" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.title.inventory}]]></textFieldExpression> + </textField> + <rectangle radius="5"> + <reportElement key="rectangle-4" mode="Opaque" x="0" y="53" width="782" height="1" forecolor="#33CCFF" backcolor="#33CCFF" uuid="a9c6cfd0-90b1-4e74-a1d4-b42b8c0db50c"> + <property name="com.jaspersoft.studio.unit.width" value="pixel"/> + </reportElement> + <graphicElement fill="Solid"> + <pen lineWidth="0.25" lineStyle="Solid"/> + </graphicElement> + </rectangle> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-10" mode="Opaque" x="647" y="0" width="135" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="dbde2926-d2c6-4853-8c5b-13fa47b3ca0d"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.printed}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report" pattern="dd/MM/yyyy h.mm a" isBlankWhenNull="false"> + <reportElement key="textField" x="647" y="15" width="135" height="15" uuid="110c2083-6cb6-4e0e-a07c-e99e74cad044"/> + <textElement textAlignment="Right"> + <font fontName="SansSerif" size="10"/> + </textElement> + <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression> + </textField> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = $F{STOCKSECURITY}.doubleValue())]]> + + + + + + + + + + + + + + + + $F{STOCKMAXIMUM}.doubleValue())]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $F{STOCKMAXIMUM}.doubleValue())]]> + + + + + + + + + + + + + + + + + = $F{STOCKSECURITY}.doubleValue() + && $F{UNITS}.doubleValue()<= $F{STOCKMAXIMUM}.doubleValue())]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/inventory_b.bs b/src/main/resources/com/unicenta/reports/inventory_b.bs new file mode 100644 index 0000000..dc79c1d --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_b.bs @@ -0,0 +1,82 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.Inventory"); +report.setReport("/com/unicenta/reports/inventory_b"); +report.setResourceBundle("com/unicenta/reports/inventory_messages"); + +report.setSentence("SELECT " + + "stockcurrent.LOCATION AS LOCATIONID, locations.NAME AS LOCATIONNAME, " + + "products.REFERENCE, products.NAME AS PRODUCTNAME, " + + "products.CATEGORY, categories.NAME AS CATEGORYNAME, " + + "MIN(products.SUPPLIER), " + + "SUM(stockcurrent.UNITS) AS UNITS, " + + "products.PRICEBUY, products.PRICESELL, " + + "COALESCE(products.STOCKVOLUME, 0) AS STOCKVOLUME, " + + "COALESCE(products.STOCKCOST, 0) AS STOCKCOST, " + + "COALESCE(stocklevel.STOCKSECURITY, 0) AS STOCKSECURITY, " + + "COALESCE(stocklevel.STOCKMAXIMUM, 0) AS STOCKMAXIMUM, " + + "MIN(suppliers.NAME) AS SUPPLIERNAME, MIN(uom.NAME) AS UOM " + + "FROM (((((stockcurrent stockcurrent INNER JOIN locations locations " + + "ON (stockcurrent.LOCATION = locations.id)) " + + "INNER JOIN products products ON (stockcurrent.PRODUCT = products.ID)) " + + "INNER JOIN categories categories ON (products.CATEGORY = categories.ID)) " + + "RIGHT OUTER JOIN suppliers suppliers ON (suppliers.id = products.SUPPLIER)) " + + "INNER JOIN uom uom ON (uom.id = products.UOM)) " + + "LEFT OUTER JOIN stocklevel stocklevel ON (stockcurrent.LOCATION = stocklevel.LOCATION) " + + "AND (stockcurrent.PRODUCT = stocklevel.PRODUCT) " + + "WHERE ?(QBF_FILTER)" + + "GROUP BY stockcurrent.LOCATION, locations.NAME, products.REFERENCE, products.NAME, " + + "products.CATEGORY, categories.NAME, products.PRICEBUY, products.PRICESELL, " + + "products.STOCKVOLUME, products.STOCKCOST, stocklevel.STOCKSECURITY, stocklevel.STOCKMAXIMUM " + + "ORDER BY LOCATIONID ASC, CATEGORYNAME ASC, PRODUCTNAME ASC"); + +report.addParameter("stockcurrent.LOCATION"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsLocationWithFirst()); + +report.addParameter("suppliers.ID"); +report.addParameter("suppliers.NAME"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsSuppliers()); + +report.addParameter("products.NAME"); +report.addParameter("products.CATEGORY"); +report.addParameter("products.CODE"); +report.addParameter("stockcurrent.UNITS"); +report.addQBFFilter(new com.unicenta.pos.ticket.ProductFilter1()); + +report.addField("LOCATIONID", com.unicenta.data.loader.Datas.STRING); +report.addField("LOCATIONNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("REFERENCE", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("CATEGORY", com.unicenta.data.loader.Datas.STRING); +report.addField("CATEGORYNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("SUPPLIER", com.unicenta.data.loader.Datas.STRING); +report.addField("UNITS", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("PRICEBUY", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("PRICESELL", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("STOCKVOLUME", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("STOCKCOST", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("STOCKSECURITY", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("STOCKMAXIMUM", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("SUPPLIERNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("UOM", com.unicenta.data.loader.Datas.STRING); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/inventory_b.jrxml b/src/main/resources/com/unicenta/reports/inventory_b.jrxml new file mode 100644 index 0000000..1068c9c --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_b.jrxml @@ -0,0 +1,477 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band height="52"> + <rectangle radius="5"> + <reportElement key="rectangle-1" mode="Opaque" x="0" y="50" width="535" height="2" forecolor="#33CCFF" backcolor="#33CCFF" uuid="5ec53e75-a3c3-460e-ad26-e3bf449a9f75"/> + <graphicElement fill="Solid"> + <pen lineWidth="0.25" lineStyle="Solid"/> + </graphicElement> + </rectangle> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-13" mode="Transparent" x="0" y="0" width="375" height="30" forecolor="#33CCFF" backcolor="#FFFFFF" uuid="1eb923ea-a85a-4bb0-b5c7-1d6730afc788"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="14" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.title.current}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-10" mode="Opaque" x="400" y="0" width="135" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="7a7b157a-c985-461a-81a5-31142de08fe2"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.printed}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report" pattern="dd/MM/yyyy h.mm a" isBlankWhenNull="false"> + <reportElement key="textField" x="400" y="15" width="135" height="15" uuid="d7d2c13e-a98f-4c08-9728-cb8890b31eb6"/> + <textElement textAlignment="Right"> + <font fontName="SansSerif" size="10"/> + </textElement> + <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression> + </textField> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = $F{STOCKSECURITY}.doubleValue() + && $F{UNITS}.doubleValue()<= $F{STOCKMAXIMUM}.doubleValue())]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $F{STOCKMAXIMUM}.doubleValue())]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/inventory_broken.bs b/src/main/resources/com/unicenta/reports/inventory_broken.bs new file mode 100644 index 0000000..93bfebd --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_broken.bs @@ -0,0 +1,83 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.InventoryBroken"); +report.setReport("/com/unicenta/reports/inventory_b"); +report.setResourceBundle("com/unicenta/reports/inventory_messages"); + +report.setSentence("SELECT " + + "stockcurrent.LOCATION AS LOCATIONID, locations.NAME AS LOCATIONNAME, " + + "products.REFERENCE, products.NAME AS PRODUCTNAME, " + + "products.CATEGORY, categories.NAME AS CATEGORYNAME, " + + "MIN(products.SUPPLIER), " + + "SUM(stockcurrent.UNITS) AS UNITS, " + + "products.PRICEBUY, products.PRICESELL, " + + "COALESCE(products.STOCKVOLUME, 0) AS STOCKVOLUME, " + + "COALESCE(products.STOCKCOST, 0) AS STOCKCOST, " + + "COALESCE(stocklevel.STOCKSECURITY, 0) AS STOCKSECURITY, " + + "COALESCE(stocklevel.STOCKMAXIMUM, 0) AS STOCKMAXIMUM, " + + "MIN(suppliers.NAME) AS SUPPLIERNAME, MIN(uom.NAME) AS UOM " + + "FROM (((((stockcurrent stockcurrent JOIN locations locations " + + "ON (stockcurrent.LOCATION = locations.id)) " + + "JOIN products products ON (stockcurrent.PRODUCT = products.ID)) " + + "JOIN categories categories ON (products.CATEGORY = categories.ID)) " + + "RIGHT OUTER JOIN suppliers suppliers ON (suppliers.id = products.SUPPLIER)) " + + "INNER JOIN uom uom ON (uom.id = products.UOM)) " + + "LEFT OUTER JOIN stocklevel stocklevel ON (stockcurrent.LOCATION = stocklevel.LOCATION) " + + "AND (stockcurrent.PRODUCT = stocklevel.PRODUCT) " + + "WHERE ?(QBF_FILTER)" + + "GROUP BY stockcurrent.LOCATION, locations.NAME, products.REFERENCE, products.NAME, " + + "products.CATEGORY, categories.NAME, products.PRICEBUY, products.PRICESELL, " + + "products.STOCKVOLUME, products.STOCKCOST, stocklevel.STOCKSECURITY, stocklevel.STOCKMAXIMUM " + + "HAVING stocklevel.STOCKSECURITY IS NOT NULL AND stocklevel.STOCKSECURITY >= SUM(stockcurrent.UNITS) " + + "ORDER BY CATEGORYNAME ASC, PRODUCTNAME ASC, LOCATIONID ASC"); + +report.addParameter("stockcurrent.LOCATION"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsLocationWithFirst()); + +report.addParameter("suppliers.ID"); +report.addParameter("suppliers.NAME"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsSuppliers()); + +report.addParameter("products.NAME"); +report.addParameter("products.CATEGORY"); +report.addParameter("products.CODE"); +report.addParameter("stockcurrent.UNITS"); +report.addQBFFilter(new com.unicenta.pos.ticket.ProductFilter1()); + +report.addField("LOCATIONID", com.unicenta.data.loader.Datas.STRING); +report.addField("LOCATIONNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("REFERENCE", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("CATEGORY", com.unicenta.data.loader.Datas.STRING); +report.addField("CATEGORYNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("SUPPLIER", com.unicenta.data.loader.Datas.STRING); +report.addField("UNITS", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("PRICEBUY", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("PRICESELL", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("STOCKVOLUME", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("STOCKCOST", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("STOCKSECURITY", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("STOCKMAXIMUM", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("SUPPLIERNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("UOM", com.unicenta.data.loader.Datas.STRING); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/inventory_diary.bs b/src/main/resources/com/unicenta/reports/inventory_diary.bs new file mode 100644 index 0000000..3b9fc2f --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_diary.bs @@ -0,0 +1,69 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2018 uniCenta +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.Inventory.Reports.Diary"); +report.setReport("/com/unicenta/reports/inventory_diary"); +report.setResourceBundle("com/unicenta/reports/inventory_messages"); + +report.setSentence("SELECT " + + "TIMESTAMP(stockdiary.datenew), stockdiary.reason, MIN(stockdiary.supplierdoc), " + + "sum(stockdiary.units), MIN(stockdiary.price), " + + "sum(stockdiary.UNITS * stockdiary.PRICE) AS TOTALP, " + + "MIN(suppliers.name) AS SUPPLIERNAME, " + + "products.name, MIN(products.reference), MIN(products.code), " + + "locations.name " + + "FROM ((stockdiary stockdiary " + + "INNER JOIN locations locations " + + "ON (stockdiary.location = locations.id)) " + + "INNER JOIN products products " + + "ON (stockdiary.product = products.id)) " + + "LEFT OUTER JOIN suppliers suppliers " + + "ON (products.supplier = suppliers.id) " + + "WHERE VISIBLE = " + app.getSession().DB.TRUE() + " AND ?(QBF_FILTER) " + + "GROUP BY locations.name, stockdiary.reason, stockdiary.datenew, products.name"); + +report.addParameter("stockdiary.DATENEW"); +report.addParameter("stockdiary.DATENEW"); +paramdates = new com.unicenta.pos.reports.JParamsDatesInterval(); +paramdates.setStartDate(com.unicenta.beans.DateUtils.getToday()); +paramdates.setEndDate(com.unicenta.beans.DateUtils.getTodayMinutes()); +report.addQBFFilter(paramdates); + +report.addParameter("stockdiary.REASON"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsReason()); + +report.addParameter("suppliers.ID"); +report.addParameter("suppliers.NAME"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsSuppliers()); + +report.addField("DATENEW", com.unicenta.data.loader.Datas.TIMESTAMP); +report.addField("REASON", com.unicenta.data.loader.Datas.INT); +report.addField("SUPPLIERDOC", com.unicenta.data.loader.Datas.STRING); +report.addField("UNITS", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("PRICE", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("TOTALP", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("SUPPLIERNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("PRODUCTNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("REFERENCE", com.unicenta.data.loader.Datas.STRING); +report.addField("CODE", com.unicenta.data.loader.Datas.STRING); +report.addField("LOCATION", com.unicenta.data.loader.Datas.STRING); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/inventory_diary.jrxml b/src/main/resources/com/unicenta/reports/inventory_diary.jrxml new file mode 100644 index 0000000..d8249fd --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_diary.jrxml @@ -0,0 +1,438 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/inventory_diff.bs b/src/main/resources/com/unicenta/reports/inventory_diff.bs new file mode 100644 index 0000000..05f3907 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_diff.bs @@ -0,0 +1,74 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.InventoryDiff"); +report.setReport("/com/unicenta/reports/inventory_diff"); +report.setResourceBundle("com/unicenta/reports/inventory_messages"); + +report.setSentence("SELECT " + + "locations.ID AS LOCATIONID, locations.NAME AS LOCATIONNAME, " + + "products.REFERENCE, products.NAME, " + + "products.CATEGORY, categories.NAME AS CATEGORYNAME, " + + "MIN(products.SUPPLIER), " + + "SUM(CASE WHEN stockdiary.UNITS <0 THEN stockdiary.UNITS ELSE 0 END) AS UNITSOUT, " + + "SUM(CASE WHEN stockdiary.UNITS <0 THEN stockdiary.UNITS * stockdiary.PRICE ELSE 0 END) AS TOTALOUT, " + + "SUM(CASE WHEN stockdiary.UNITS >=0 THEN stockdiary.UNITS ELSE 0 END) AS UNITSIN, " + + "SUM(CASE WHEN stockdiary.UNITS >=0 THEN stockdiary.UNITS * stockdiary.PRICE ELSE 0 END) AS TOTALIN, " + + "SUM(stockdiary.UNITS) AS UNITSDIFF, " + + "SUM(stockdiary.UNITS * stockdiary.PRICE) AS TOTALDIFF " + + "FROM stockdiary JOIN locations ON stockdiary.LOCATION = locations.ID, " + + "products LEFT OUTER JOIN categories ON products.CATEGORY = categories.ID " + + "WHERE products.ID = stockdiary.PRODUCT " + + "AND ?(QBF_FILTER) " + + "GROUP BY locations.ID, locations.NAME, products.REFERENCE, products.NAME, products.CATEGORY, categories.NAME " + + "ORDER BY locations.ID, categories.NAME, products.NAME"); + +report.addParameter("stockdiary.DATENEW"); +report.addParameter("stockdiary.DATENEW"); + +paramdates = new com.unicenta.pos.reports.JParamsDatesInterval(); +paramdates.setStartDate(com.unicenta.beans.DateUtils.getToday()); +// JG - 8 Jan 14 paramdates.setEndDate(com.unicenta.beans.DateUtils.getToday()); +paramdates.setEndDate(com.unicenta.beans.DateUtils.getTodayMinutes()); +report.addQBFFilter(paramdates); + +report.addParameter("locations.ID"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsLocationWithFirst()); + +report.addParameter("stockdiary.REASON"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsReason()); + +report.addField("LOCATIONID", com.unicenta.data.loader.Datas.STRING); +report.addField("LOCATIONNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("REFERENCE", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("CATEGORY", com.unicenta.data.loader.Datas.STRING); +report.addField("CATEGORYNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("SUPPLIER", com.unicenta.data.loader.Datas.STRING); +report.addField("UNITSOUT", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("TOTALOUT", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("UNITSIN", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("TOTALIN", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("UNITSDIFF", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("TOTALDIFF", com.unicenta.data.loader.Datas.DOUBLE); + +report; + diff --git a/src/main/resources/com/unicenta/reports/inventory_diff.jrxml b/src/main/resources/com/unicenta/reports/inventory_diff.jrxml new file mode 100644 index 0000000..14e28b3 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_diff.jrxml @@ -0,0 +1,607 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/inventory_diffdetail.bs b/src/main/resources/com/unicenta/reports/inventory_diffdetail.bs new file mode 100644 index 0000000..ea1afc3 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_diffdetail.bs @@ -0,0 +1,76 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.InventoryDiffDetail"); +report.setReport("/com/unicenta/reports/inventory_diffdetail"); +report.setResourceBundle("com/unicenta/reports/inventory_messages"); + +report.setSentence("SELECT " + + "locations.ID AS LOCATIONID, MIN(locations.NAME) AS LOCATIONNAME, " + + "products.REFERENCE, MIN(products.NAME), " + + "MIN(stockdiary.ATTRIBUTESETINSTANCE_ID), attributesetinstance.DESCRIPTION, " + + "products.CATEGORY, MIN(categories.NAME) AS CATEGORYNAME, " + + "SUM(CASE WHEN stockdiary.UNITS <0 THEN stockdiary.UNITS ELSE 0 END) AS UNITSOUT, " + + "SUM(CASE WHEN stockdiary.UNITS <0 THEN stockdiary.UNITS * stockdiary.PRICE ELSE 0 END) AS TOTALOUT, " + + "SUM(CASE WHEN stockdiary.UNITS >=0 THEN stockdiary.UNITS ELSE 0 END) AS UNITSIN, " + + "SUM(CASE WHEN stockdiary.UNITS >=0 THEN stockdiary.UNITS * stockdiary.PRICE ELSE 0 END) AS TOTALIN, " + + "SUM(stockdiary.UNITS) AS UNITSDIFF, " + + "SUM(stockdiary.UNITS * stockdiary.PRICE) AS TOTALDIFF " + + "FROM stockdiary " + + "JOIN locations ON stockdiary.LOCATION = locations.ID " + + "JOIN products ON products.ID = stockdiary.PRODUCT " + + "LEFT OUTER JOIN categories ON products.CATEGORY = categories.ID " + + "LEFT OUTER JOIN attributesetinstance ON stockdiary.ATTRIBUTESETINSTANCE_ID = attributesetinstance.ID " + + "WHERE ?(QBF_FILTER) " + + "GROUP BY locations.ID, products.CATEGORY, products.REFERENCE, DESCRIPTION " + + "ORDER BY locations.ID, MIN(categories.NAME), MIN(products.NAME)"); + +report.addParameter("stockdiary.DATENEW"); +report.addParameter("stockdiary.DATENEW"); +paramdates = new com.unicenta.pos.reports.JParamsDatesInterval(); + +paramdates.setStartDate(com.unicenta.beans.DateUtils.getToday()); +// JG - 8 Jan 14 paramdates.setEndDate(com.unicenta.beans.DateUtils.getToday()); +paramdates.setEndDate(com.unicenta.beans.DateUtils.getTodayMinutes()); +report.addQBFFilter(paramdates); + +report.addParameter("locations.ID"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsLocationWithFirst()); + +report.addParameter("stockdiary.REASON"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsReason()); + +report.addField("LOCATIONID", com.unicenta.data.loader.Datas.STRING); +report.addField("LOCATIONNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("REFERENCE", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("ATTINSTANCEID", com.unicenta.data.loader.Datas.STRING); +report.addField("ATTINSTANCEDESC", com.unicenta.data.loader.Datas.STRING); +report.addField("CATEGORY", com.unicenta.data.loader.Datas.STRING); +report.addField("CATEGORYNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("UNITSOUT", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("TOTALOUT", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("UNITSIN", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("TOTALIN", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("UNITSDIFF", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("TOTALDIFF", com.unicenta.data.loader.Datas.DOUBLE); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/inventory_diffdetail.jrxml b/src/main/resources/com/unicenta/reports/inventory_diffdetail.jrxml new file mode 100644 index 0000000..53f4a70 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_diffdetail.jrxml @@ -0,0 +1,637 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/inventory_listdetail.bs b/src/main/resources/com/unicenta/reports/inventory_listdetail.bs new file mode 100644 index 0000000..595af21 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_listdetail.bs @@ -0,0 +1,78 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.InventoryListDetail"); +report.setReport("/com/unicenta/reports/inventory_listdetail"); +report.setResourceBundle("com/unicenta/reports/inventory_messages"); + +report.setSentence("SELECT " + + "MIN(stockcurrent.LOCATION) AS LOCATIONID, " + + "MIN(locations.NAME) AS LOCATIONNAME, " + + "products.REFERENCE, " + + "MIN(products.NAME) AS NAME, " + + "MIN(stockcurrent.ATTRIBUTESETINSTANCE_ID), " + + "attributesetinstance.DESCRIPTION, " + + "products.CATEGORY, " + + "MIN(categories.NAME) AS CATEGORYNAME, " + + "MIN(products.SUPPLIER), " + + "MIN(stockcurrent.UNITS), " + + "COALESCE(MIN(stocklevel.STOCKSECURITY), 0) AS STOCKSECURITY, " + + "COALESCE(MIN(stocklevel.STOCKMAXIMUM), 0) AS STOCKMAXIMUM, " + + "MIN(suppliers.NAME) " + + "FROM stockcurrent " + + "JOIN locations ON stockcurrent.LOCATION = locations.ID " + + "JOIN products ON stockcurrent.PRODUCT = products.ID " + + "JOIN categories ON products.CATEGORY = categories.ID " + + "LEFT OUTER JOIN stocklevel ON stockcurrent.LOCATION = stocklevel.LOCATION AND stockcurrent.PRODUCT = stocklevel.PRODUCT " + + "LEFT OUTER JOIN attributesetinstance ON stockcurrent.ATTRIBUTESETINSTANCE_ID = attributesetinstance.ID " + + "LEFT OUTER JOIN suppliers suppliers ON (suppliers.ID = products.SUPPLIER) " + + "WHERE ?(QBF_FILTER) " + + "GROUP BY locations.ID, products.CATEGORY, products.REFERENCE, DESCRIPTION " + + "ORDER BY MIN(categories.NAME), MIN(products.NAME), MIN(stockcurrent.LOCATION)"); + +report.addParameter("stockcurrent.LOCATION"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsLocationWithFirst()); + +report.addParameter("suppliers.ID"); +report.addParameter("suppliers.NAME"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsSuppliers()); + + +report.addParameter("products.NAME"); +report.addParameter("products.CATEGORY"); +report.addParameter("products.CODE"); +report.addParameter("stockcurrent.UNITS"); +report.addQBFFilter(new com.unicenta.pos.ticket.ProductFilter1()); + +report.addField("LOCATIONID", com.unicenta.data.loader.Datas.STRING); +report.addField("LOCATIONNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("REFERENCE", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("ATTINSTANCEID", com.unicenta.data.loader.Datas.STRING); +report.addField("ATTINSTANCEDESC", com.unicenta.data.loader.Datas.STRING); +report.addField("CATEGORY", com.unicenta.data.loader.Datas.STRING); +report.addField("CATEGORYNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("SUPPLIER", com.unicenta.data.loader.Datas.STRING); +report.addField("UNITS", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("STOCKSECURITY", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("STOCKMAXIMUM", com.unicenta.data.loader.Datas.DOUBLE); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/inventory_listdetail.jrxml b/src/main/resources/com/unicenta/reports/inventory_listdetail.jrxml new file mode 100644 index 0000000..0f1ea6c --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_listdetail.jrxml @@ -0,0 +1,452 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $F{STOCKMAXIMUM}.doubleValue() +? com.unicenta.format.Formats.DOUBLE.formatValue($V{UNITSTOTALWAREHOUSE}) +: ""]]> + + + + + + + + + + + + + + = $F{STOCKSECURITY}.doubleValue() + && $V{UNITSTOTALWAREHOUSE}.doubleValue()<= $F{STOCKMAXIMUM}.doubleValue() +? com.unicenta.format.Formats.DOUBLE.formatValue($V{UNITSTOTALWAREHOUSE}) +: ""]]> + + + + + + + + + + + + <band height="52"> + <rectangle radius="5"> + <reportElement key="rectangle-1" mode="Opaque" x="0" y="50" width="535" height="2" forecolor="#33CCFF" backcolor="#33CCFF" uuid="89d02ae2-c5a6-455f-843f-f20b531f0be7"/> + <graphicElement fill="Solid"> + <pen lineWidth="0.25" lineStyle="Solid"/> + </graphicElement> + </rectangle> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-13" mode="Transparent" x="0" y="0" width="375" height="30" forecolor="#33CCFF" backcolor="#FFFFFF" uuid="83297b75-6a33-4643-82ec-123284c1e7a6"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="14" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.title.listdetail}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-10" mode="Opaque" x="400" y="0" width="135" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="2ad49871-ae6f-4fbb-9b3d-40867e979a79"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.printed}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report" pattern="dd/MM/yyyy h.mm a" isBlankWhenNull="false"> + <reportElement key="textField" x="400" y="15" width="135" height="15" uuid="c80a320f-6f9e-4743-a527-65289f62b6a9"/> + <textElement textAlignment="Right"> + <font fontName="SansSerif" size="10"/> + </textElement> + <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression> + </textField> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/inventory_messages.properties b/src/main/resources/com/unicenta/reports/inventory_messages.properties new file mode 100644 index 0000000..08482dc --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_messages.properties @@ -0,0 +1,61 @@ +label.account=Account : +label.accountname = Acc' Name : +label.category = Category : +label.code=Code +label.date=Date +label.diff=Difference +label.in=In +label.location=Location : +label.max=Max. +label.min=Min. +label.name=Name +label.out=Out +label.period=Period: +label.price=Unit Value +label.pricebuy=Price Buy +label.pricesell=Price Sell +label.printed=Printed +label.product=Product +label.productname=Prod.Name +label.qty=Qty +label.reason=Reason +label.ref=Ref. +label.reference=Reference +label.sec=Min. +label.sumdiff=Total Difference +label.sumin=Total In +label.sumout=Total Out +label.supplier=Supplier +label.supplierdoc=Doc. Ref. +label.suppliername=Supplier Name +label.taxid=Account ID +label.title.broken=Inventory: Broken +label.title.current=Inventory: Current +label.title.diary=Inventory Diary +label.title.diffdetail=Inventory: Difference Detail +label.title.difference=Inventory: Difference +label.title.inventory=Inventory: Location and Category +label.title.listdetail= Inventory: List Detail +label.total=Total +label.totalG=Grand Total +label.totalP=Amount +label.ttype=Type +label.units.instock=In Stock +label.units=Units +label.uom=UOM +label.valuebuy=Buy Value +label.valuecost=St. Cost +label.valuesell=Sell Value +label.valuevolume=Storage +reason.1=Purchase Supplier +reason.-1=Sales +reason.1000=Transfer +reason.-2=Return - Supplier +reason.2=Return Customer +reason.-3=Breakage +reason.4=Adjust - Add +reason.-4=Adjust - Minus +reason.-5=Sample - Out +reason.-6=Free +reason.-7=Used +reason.-8=Rectify - Subtract diff --git a/src/main/resources/com/unicenta/reports/inventory_messages_al_SQ.properties b/src/main/resources/com/unicenta/reports/inventory_messages_al_SQ.properties new file mode 100644 index 0000000..d0c635b --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_messages_al_SQ.properties @@ -0,0 +1,11 @@ +label.max=Maksimum +label.name=Emri +label.printed=Printuar +label.ref=Ref. +label.sec=Minimum +label.title=Inventari: Lokacioni dhe Kategorit +label.units=njesi +label.valuebuy=Vlera e Blerjes +label.valuecost=Cmimi +label.valuesell=Vlera e shitjes +label.valuevolume=Sasia \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/inventory_messages_ar.properties b/src/main/resources/com/unicenta/reports/inventory_messages_ar.properties new file mode 100644 index 0000000..f1e8c20 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_messages_ar.properties @@ -0,0 +1,12 @@ +label.account=\u0645\u062d\u0627\u0633\u0628\u0629 +label.max=\u0627\u0644\u0627\u0639\u0644\u0649 +label.name=\u0627\u0644\u0627\u0633\u0645 +label.printed=\u0645\u0637\u0628\u0648\u0639 +label.ref=\u0627\u0644\u0645\u0631\u062c\u0639. +label.sec=\u0627\u0644\u0627\u062f\u0646\u0649 +label.title=\u0627\u0644\u062c\u0631\u062f: \u0627\u0644\u0645\u0648\u0642\u0639 \u0648\u0627\u0644\u062a\u0635\u0646\u064a\u0641 +label.units=\u0627\u0644\u0648\u062d\u062f\u0627\u062a +label.valuebuy=\u0627\u062c\u0645\u0627\u0644\u064a \u0627\u0644\u062a\u0643\u0644\u0641\u0629 +label.valuecost=\u0627\u0644\u062a\u0643\u0644\u0641\u0629 +label.valuesell=\u0642\u064a\u0645\u0629 \u0627\u0644\u0628\u064a\u0639 \u0628\u0627\u0644\u062a\u062c\u0632\u0626\u0629 +label.valuevolume=\u0627\u0644\u0643\u0645\u064a\u0629 \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/inventory_messages_de.properties b/src/main/resources/com/unicenta/reports/inventory_messages_de.properties new file mode 100644 index 0000000..c3a6a91 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_messages_de.properties @@ -0,0 +1,15 @@ +label.account=Konto : +label.accountname=Kontobezeichnung +label.location=Platz : +label.max=Max. +label.min=Min. +label.name=Name +label.printed=Erstellt am: +label.ref=Ref. +label.sec=Minimum +label.title=Inventar: Lagerplatz & Kategorie +label.units=St\u00fcckzahl +label.valuebuy=Einkaufspreis (EK) +label.valuecost=Kosten +label.valuesell=Verkaufspreis (VK) +label.valuevolume=Anzahl \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/inventory_messages_el.properties b/src/main/resources/com/unicenta/reports/inventory_messages_el.properties new file mode 100644 index 0000000..e46434e --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_messages_el.properties @@ -0,0 +1,12 @@ +label.account=\u039b\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc\u03c2 +label.max=\u039c\u03ad\u03b3\u03b9\u03c3\u03c4\u03bf +label.name=\u038c\u03bd\u03bf\u03bc\u03b1 +label.printed=Printed +label.ref=\u0391\u03bd\u03b1\u03c6. +label.sec=\u039a\u03b1\u03c4\u03ce\u03c4\u03b5\u03c1\u03bf +label.title=\u039a\u03b1\u03c4\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae: \u03a4\u03bf\u03c0\u03bf\u03b8\u03b5\u03c3\u03af\u03b1 \u039a\u03b1\u03b9 \u039a\u03b1\u03c4\u03b7\u03b3\u03bf\u03c1\u03af\u03b1 +label.units=\u039c\u03bf\u03bd\u03ac\u03b4\u03b5\u03c2 +label.valuebuy=\u0391\u03be\u03af\u03b1 \u039a\u03cc\u03c3\u03c4\u03bf\u03c5\u03c2 +label.valuecost=\u039a\u03cc\u03c3\u03c4\u03bf\u03c2 +label.valuesell=\u0391\u03be\u03af\u03b1 \u039b\u03b9\u03b1\u03bd\u03b9\u03ba\u03ae\u03c2 +label.valuevolume=\u038c\u03b3\u03ba\u03bf\u03c2 \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/inventory_messages_en_US.properties b/src/main/resources/com/unicenta/reports/inventory_messages_en_US.properties new file mode 100644 index 0000000..10aab0b --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_messages_en_US.properties @@ -0,0 +1,61 @@ +label.account=Account : +label.accountname = Acc' Name : +label.category = Category : +label.code=Code +label.date=Date +label.diff=Difference +label.in=In +label.location=Location : +label.max=Max. +label.min=Min. +label.name=Name +label.out=Out +label.period=Period: +label.price=Unit Value +label.pricebuy=Price Buy +label.pricesell=Price Sell +label.printed=Printed +label.product=Product +label.productname=Prod.Name +label.qty=Qty +label.reason=Reason +label.ref=Ref. +label.reference=Reference +label.sec=Min. +label.sumdiff=Total Difference +label.sumin=Total In +label.sumout=Total Out +label.supplier=Supplier +label.supplierdoc=Doc. Ref. +label.suppliername=Supplier Name +label.taxid=Account ID +label.title.broken=Inventory: Broken +label.title.current=Inventory: Current +label.title.diary=Inventory Diary +label.title.diffdetail=Inventory: Difference Detail +label.title.difference=Inventory: Difference +label.title.inventory=Inventory: Location and Category +label.title.listdetail= Inventory: List Detail +label.total=Total +label.totalG=Grand Total +label.totalP=Amount +label.ttype=Type +label.units.instock=In Stock +label.units=Units +label.uom=UOM +label.valuebuy=Buy Value +label.valuecost=St. Cost +label.valuesell=Sell Value +label.valuevolume=Storage +reason.1=Purchase Supplier +reason.-1=Sales +reason.1000=Transfer +reason.-2=Return - Supplier +reason.2=Return Customer +reason.-3=Breakage +reason.4=Adjust - Add +reason.-4=Adjust - Minus +reason.-5=Sample - Out +reason.-6=Free +reason.-7=Used +reason.-8=Rectify Error- Minus \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/inventory_messages_es.properties b/src/main/resources/com/unicenta/reports/inventory_messages_es.properties new file mode 100644 index 0000000..30b1430 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_messages_es.properties @@ -0,0 +1,62 @@ +label.account=Cuenta +label.accountname=Nombre de la cuenta : +label.category=Categor\u00eda : +label.code=C\u00f3digo +label.date=Fecha +label.diff=Diferencia +label.in=En +label.location=Almac\u00e9n : +label.max=M\u00e1ximo +label.min=M\u00ednimo +label.name=Nombre +label.out=Fuera +label.period=Per\u00edodo +label.price=Valor unitario +label.pricebuy=Precio de compra +label.pricesell=Precio de venta +label.printed=Imprimir +label.product=Productos +label.productname=Prod. Nombre +label.qty=Cantidad +label.reason=Raz\u00f3n +label.ref=Ref. +label.reference=Referencia +label.sec=M\u00ednimo +label.sumdiff=Diferencia Total +label.sumin=Total En +label.sumout=Total Fuera +label.supplier=Proveedor +label.supplierdoc=Doc. Ref. +label.suppliername=Nombre del proveedor +label.taxid=ID Cuenta +label.title.broken=Inventario : Roto +label.title.current=Inventario : Actual +label.title.diary=Diario de Inventario +label.title.diffdetail=Inventario: Detalle de la diferencia +label.title.difference=Inventario:Diferencia +label.title.inventory=Inventario: Almac\u00e9n y categor\u00eda +label.title.listdetail=Inventario: Lista detalle +label.title=Almacenes +label.total=Total +label.totalG=Gran Total +label.totalP=Cantidad +label.ttype=Tipo +label.units.instock=En Stock +label.units=Unidades +label.uom=UOM +label.valuebuy=Valor compra +label.valuecost=Costo +label.valuesell=Valor venta +label.valuevolume=Volumen +reason.1=Proveedor de compras +reason.-1=Ventas +reason.1000=Transferir +reason.-2=Retorno - Proveedor +reason.2=Retorno Cliente +reason.-3=Rotura +reason.4=Ajustar - A\u00f1adir +reason.-4=Ajustar - Menos +reason.-5=Ejemplo - salida +reason.-6=Gratis +reason.-7=Usado +reason.-8=Rectificar - Restar \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/inventory_messages_es_AR.properties b/src/main/resources/com/unicenta/reports/inventory_messages_es_AR.properties new file mode 100644 index 0000000..8dde015 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_messages_es_AR.properties @@ -0,0 +1,11 @@ +label.account=Cuenta +label.max=M\u00e1ximo +label.name=Nombre +label.ref=Ref. +label.sec=M\u00ednimo +label.title=Almacenes +label.units=Unidades +label.valuebuy=Valor de compra +label.valuecost=Costo +label.valuesell=Valor de venta +label.valuevolume=Volumen diff --git a/src/main/resources/com/unicenta/reports/inventory_messages_es_MX.properties b/src/main/resources/com/unicenta/reports/inventory_messages_es_MX.properties new file mode 100644 index 0000000..6f2f5a7 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_messages_es_MX.properties @@ -0,0 +1,10 @@ +label.max=Mximo +label.name=Nombre +label.ref=Ref. +label.sec=Seguridad +label.title=Almacenes +label.units=Unidades +label.valuebuy=Valor de compra +label.valuecost=Costo +label.valuesell=Valor de venta +label.valuevolume=Volumen \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/inventory_messages_et.properties b/src/main/resources/com/unicenta/reports/inventory_messages_et.properties new file mode 100644 index 0000000..f64a152 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_messages_et.properties @@ -0,0 +1,11 @@ +label.max=Maksimum +label.name=Nimetus +label.printed=Tr\u00fckitud +label.ref=Kood +label.sec=Miinimum +label.title=Kaubaj\u00e4\u00e4k: ladu ja tooter\u00fchm +label.units=Kogus +label.valuebuy=Omahind +label.valuecost=Kulud +label.valuesell=M\u00fc\u00fcgihind +label.valuevolume=Kogus \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/inventory_messages_fr.properties b/src/main/resources/com/unicenta/reports/inventory_messages_fr.properties new file mode 100644 index 0000000..b85145c --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_messages_fr.properties @@ -0,0 +1,61 @@ +label.account=Compte : +label.accountname=Nom de compte +label.category = Categori\u00e9 : +label.code=Code barre +label.date=Date +label.diff=Stock Final +label.in=Entr\u00e9e +label.location=Entrepot +label.max=Max. +label.min=Min. +label.name=Nom +label.out=Sortie +label.period=P\u00e9riode: +label.price=Valeur Unit\u00e9 +label.pricebuy=Prix d'achat +label.pricesell=Prix Vente HT +label.printed=Imprim\u00e9 +label.product=Produit +label.productname=Produit +label.qty=Qt\u00e9 +label.reason=Raison +label.ref=R\u00e9f. +label.reference=R\u00e9f\u00e9rence +label.sec=Min. +label.sumdiff=Total diff\u00e9rence +label.sumin=Total entr\u00e9e +label.sumout=Total sortie +label.supplier=Fournisseur +label.supplierdoc=Doc. R\u00e9f. +label.suppliername=Nom Fournisseur +label.taxid=N\u00b0 Compte +label.title.broken=Inventaire: minimum atteint +label.title.current=Inventaire: actuel +label.title.diary=Inventaire: Journal +label.title.diffdetail=Journal d'inventaire d\u00e9taill\u00e9 +label.title.difference=Journal d'inventaire +label.title.inventory=Inventaire +label.title.listdetail= Inventaire actuel d\u00e9taill\u00e9 +label.total=Total +label.totalG=Total +label.totalP=Valeur +label.ttype=Type +label.units.instock=En Stock +label.units=Unit\u00e9s +label.uom=UOM +label.valuebuy=Valeur achat +label.valuecost=Valeur st. +label.valuesell=Valeur Revente HT +label.valuevolume=Stockage +reason.1=Entr\u00e9e Marchandises +reason.-1=Ventes +reason.1000=Transf\u00e9rer +reason.2=Retour clients +reason.-2=Retour fournisseurs +reason.-3=Casse +reason.-4=Manque - Retrancher +reason.4=Rectifier - Additioner +reason.-5=Echantillon +reason.-6=Offert +reason.-7=Us\u00e9 +reason.-8=Rectifier - Soustraire \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/inventory_messages_hr.properties b/src/main/resources/com/unicenta/reports/inventory_messages_hr.properties new file mode 100644 index 0000000..98c3c53 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_messages_hr.properties @@ -0,0 +1,11 @@ +label.max=Maksimum +label.name=Ime +label.printed=Ispisano +label.ref=\u0160ifra +label.sec=Sigurnost +label.title=Skladi\u0161ta +label.units=Komada +label.valuebuy=Nabavna vrijednost +label.valuecost=Tro\u0161kovi +label.valuesell=Prodajna vrijednost +label.valuevolume=Koli\u010dina diff --git a/src/main/resources/com/unicenta/reports/inventory_messages_it.properties b/src/main/resources/com/unicenta/reports/inventory_messages_it.properties new file mode 100644 index 0000000..65eb01a --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_messages_it.properties @@ -0,0 +1,12 @@ +label.location=Posto : +label.max=Massimo +label.name=Nome +label.printed=Stampato +label.ref=Rif. +label.sec=Minimo +label.title=Inventario: Posizione e Categoria +label.units=Unit\u00e0 +label.valuebuy=Valore di Costo +label.valuecost=Costo +label.valuesell=Valore al Dettaglio +label.valuevolume=Volume \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/inventory_messages_nl.properties b/src/main/resources/com/unicenta/reports/inventory_messages_nl.properties new file mode 100644 index 0000000..e17dfc7 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/inventory_messages_nl.properties @@ -0,0 +1,62 @@ +label.account=Account +label.accountname=Accountnaam +label.category=Categorie : +label.code=Code +label.date=Datum +label.diff=Verschil +label.in=In +label.location=Plaats : +label.max=Max. +label.min=Min. +label.name=Naam +label.out=Uit +label.period=Periode: +label.price=eenheid Waarde +label.pricebuy=Prijs Bestel +label.pricesell=\nPrijs Verkopen +label.printed=Afgedrukt +label.product=Artikel +label.productname=productnaam +label.qty=Qty +label.reason=Aantal stuks +label.ref=Ref. +label.reference=Referentie +label.sec=Min. +label.sumdiff=Totaal Verschil +label.sumin=Total In +label.sumout=Total Uit +label.supplier=Leverancier +label.supplierdoc=Doc. Ref. +label.suppliername=Naam van leverancier +label.taxid=Account ID +label.title.broken=Inventory: Gebroken +label.title.current=Inventory: Actueel +label.title.diary=Inventory Diary +label.title.diffdetail=Inventaris: Verschil Detail +label.title.difference=Inventaris: Verschil +label.title.inventory=Inventaris: Location en categorie +label.title.listdetail=Inventaris: Lijst Detail +label.title=Voorraadlijst: Locatie en Categorie +label.total=Totaal +label.totalG=Eindtotaal\n +label.totalP=Bedrag +label.ttype=Type +label.units.instock=Op voorraad +label.units=Aantal +label.uom=UOM +label.valuebuy=Inkoop waarde +label.valuecost=Kosten +label.valuesell=Verkoop waarde +label.valuevolume=Volume +reason.1=Aankoop Leverancie +reason.-1=Verkoop +reason.1000=Overdracht +reason.2=Keer terug naar de klant +reason.-2=Keer terug naar leverancier +reason.-3=Breken +reason.-4=Aanpassen - minus +reason.4=Aanpassen - toe te voegen +reason.-5=Voorbeeld - Uit +reason.-6=Gratis +reason.-7=Gebruikt +reason.-8=Corrigeren - minus \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/labels_barcode_sheet.bs b/src/main/resources/com/unicenta/reports/labels_barcode_sheet.bs new file mode 100644 index 0000000..6727816 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/labels_barcode_sheet.bs @@ -0,0 +1,26 @@ + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.BarcodeSheet"); +report.setReport("/com/unicenta/reports/labels_barcode_sheet"); +report.setResourceBundle("com/unicenta/reports/labels_messages"); + +report.setSentence("SELECT " + + "products.CODE, products.CODETYPE, products.NAME, " + + "categories.ID AS CATEGORY, " + + "categories.NAME AS CATEGORYNAME " + + "FROM products LEFT OUTER JOIN categories ON products.CATEGORY = categories.ID " + + "WHERE ?(QBF_FILTER) " + + "ORDER BY categories.NAME, products.NAME"); + +report.addParameter("products.NAME"); +report.addParameter("products.CATEGORY"); +report.addParameter("products.CODE"); +report.addQBFFilter(new com.unicenta.pos.ticket.ProductFilter4()); + +report.addField("CODE", com.unicenta.data.loader.Datas.STRING); +report.addField("CODETYPE", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); + +report; + diff --git a/src/main/resources/com/unicenta/reports/labels_barcode_sheet.jrxml b/src/main/resources/com/unicenta/reports/labels_barcode_sheet.jrxml new file mode 100644 index 0000000..144e544 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/labels_barcode_sheet.jrxml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + <band splitType="Stretch"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/labels_barcode_shelfedge.bs b/src/main/resources/com/unicenta/reports/labels_barcode_shelfedge.bs new file mode 100644 index 0000000..6165da9 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/labels_barcode_shelfedge.bs @@ -0,0 +1,57 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.BarcodeSheet"); +report.setReport("/com/unicenta/reports/labels_barcode_shelfedge"); +report.setResourceBundle("com/unicenta/reports/labels_messages"); + +report.setSentence("SELECT " + + "products.ID, products.REFERENCE, " + + "products.CODE, products.CODETYPE, products.NAME, " + + "products.PRICEBUY, products.PRICESELL, " + + "T.ID AS TAX, T.RATE + 1 AS TAXRATE, " + + "categories.ID AS CATEGORY, categories.NAME AS CATEGORYNAME, " + + "products.SUPPLIER " + + "FROM products LEFT OUTER JOIN categories " + + "ON products.CATEGORY = categories.ID " + + "LEFT OUTER JOIN taxes T ON products.TAXCAT = T.ID " + + "WHERE ?(QBF_FILTER) " + + "ORDER BY products.NAME"); + +report.addParameter("products.NAME"); +report.addParameter("products.CATEGORY"); +report.addParameter("products.CODE"); +report.addQBFFilter(new com.unicenta.pos.ticket.ProductFilter4()); + +report.addField("ID", com.unicenta.data.loader.Datas.STRING); +report.addField("REFERENCE", com.unicenta.data.loader.Datas.STRING); +report.addField("CODE", com.unicenta.data.loader.Datas.STRING); +report.addField("CODETYPE", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("PRICEBUY", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("PRICESELL", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("TAX", com.unicenta.data.loader.Datas.STRING); +report.addField("TAXRATE", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("CATEGORY", com.unicenta.data.loader.Datas.STRING); +report.addField("CATEGORYNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("SUPPLIER", com.unicenta.data.loader.Datas.STRING); + +report \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/labels_barcode_shelfedge.jrxml b/src/main/resources/com/unicenta/reports/labels_barcode_shelfedge.jrxml new file mode 100644 index 0000000..d297814 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/labels_barcode_shelfedge.jrxml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/labels_messages.properties b/src/main/resources/com/unicenta/reports/labels_messages.properties new file mode 100644 index 0000000..471c2b5 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/labels_messages.properties @@ -0,0 +1,4 @@ +label.printed=Printed +label.sellprice=Sell Price Net +label.tax=Tax +label.title=Product Labels \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/labels_messages_al_SQ.properties b/src/main/resources/com/unicenta/reports/labels_messages_al_SQ.properties new file mode 100644 index 0000000..fc83e26 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/labels_messages_al_SQ.properties @@ -0,0 +1,3 @@ +label.printed=Printuar +label.tax=Tax +label.title=Etiketa e Produktit \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/labels_messages_ar.properties b/src/main/resources/com/unicenta/reports/labels_messages_ar.properties new file mode 100644 index 0000000..43833b8 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/labels_messages_ar.properties @@ -0,0 +1,3 @@ +label.printed=\u0645\u0637\u0628\u0648\u0639 +label.tax=Tax +label.title=\u0645\u0633\u0645\u064a\u0627\u062a \u0627\u0644\u0645\u0646\u062a\u062c\u0627\u062a \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/labels_messages_de.properties b/src/main/resources/com/unicenta/reports/labels_messages_de.properties new file mode 100644 index 0000000..428139e --- /dev/null +++ b/src/main/resources/com/unicenta/reports/labels_messages_de.properties @@ -0,0 +1,3 @@ +label.printed=Erstellt am: +label.tax=Steuer +label.title=Produkt-Etiketten \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/labels_messages_el.properties b/src/main/resources/com/unicenta/reports/labels_messages_el.properties new file mode 100644 index 0000000..91904fd --- /dev/null +++ b/src/main/resources/com/unicenta/reports/labels_messages_el.properties @@ -0,0 +1,3 @@ +label.printed=Printed +label.tax=\u03a6\u03cc\u03c1\u03bf\u03c2 +label.title=\u0395\u03c4\u03b9\u03ba\u03ad\u03c4\u03b5\u03c2 \u03a0\u03c1\u03bf\u03b9\u03cc\u03bd\u03c4\u03c9\u03bd \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/labels_messages_en_US.properties b/src/main/resources/com/unicenta/reports/labels_messages_en_US.properties new file mode 100644 index 0000000..471c2b5 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/labels_messages_en_US.properties @@ -0,0 +1,4 @@ +label.printed=Printed +label.sellprice=Sell Price Net +label.tax=Tax +label.title=Product Labels \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/labels_messages_es.properties b/src/main/resources/com/unicenta/reports/labels_messages_es.properties new file mode 100644 index 0000000..80b57d4 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/labels_messages_es.properties @@ -0,0 +1,2 @@ +label.printed=Imprimir +label.title=Etiquetas de productos \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/labels_messages_es_AR.properties b/src/main/resources/com/unicenta/reports/labels_messages_es_AR.properties new file mode 100644 index 0000000..4da07e3 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/labels_messages_es_AR.properties @@ -0,0 +1,3 @@ +label.printed=Impreso +label.tax=Impuesto +label.title=Etiquetas de productos \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/labels_messages_es_MX.properties b/src/main/resources/com/unicenta/reports/labels_messages_es_MX.properties new file mode 100644 index 0000000..4da07e3 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/labels_messages_es_MX.properties @@ -0,0 +1,3 @@ +label.printed=Impreso +label.tax=Impuesto +label.title=Etiquetas de productos \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/labels_messages_et.properties b/src/main/resources/com/unicenta/reports/labels_messages_et.properties new file mode 100644 index 0000000..8b1bbfb --- /dev/null +++ b/src/main/resources/com/unicenta/reports/labels_messages_et.properties @@ -0,0 +1,4 @@ +label.printed=Tr\u00fckitud +label.sellprice= +label.tax=KM +label.title=Hinnasildid \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/labels_messages_fr.properties b/src/main/resources/com/unicenta/reports/labels_messages_fr.properties new file mode 100644 index 0000000..4a3b547 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/labels_messages_fr.properties @@ -0,0 +1,3 @@ +label.printed=Imprim\u00e9 +label.tax=TVA +label.title=Etiquettes produits \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/labels_messages_hr.properties b/src/main/resources/com/unicenta/reports/labels_messages_hr.properties new file mode 100644 index 0000000..b13d35a --- /dev/null +++ b/src/main/resources/com/unicenta/reports/labels_messages_hr.properties @@ -0,0 +1,3 @@ +label.printed=Ispisano +label.tax=Porez +label.title=Natpisi artikala \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/labels_messages_it.properties b/src/main/resources/com/unicenta/reports/labels_messages_it.properties new file mode 100644 index 0000000..82576f5 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/labels_messages_it.properties @@ -0,0 +1,4 @@ +label.printed=Stampato +label.sellprice= +label.tax=Tassa +label.title=Etichette Prodotto \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/labels_messages_nl.properties b/src/main/resources/com/unicenta/reports/labels_messages_nl.properties new file mode 100644 index 0000000..fee6472 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/labels_messages_nl.properties @@ -0,0 +1,3 @@ +label.printed=Afgedrukt +label.tax=BTW +label.title=Artikel Etiketten \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/labels_product.bs b/src/main/resources/com/unicenta/reports/labels_product.bs new file mode 100644 index 0000000..696331f --- /dev/null +++ b/src/main/resources/com/unicenta/reports/labels_product.bs @@ -0,0 +1,61 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.ProductLabels"); +report.setReport("/com/unicenta/reports/labels_product"); +report.setResourceBundle("com/unicenta/reports/labels_messages"); + +report.setSentence("SELECT " + + "MIN(products.ID), MIN(products.REFERENCE), MIN(products.CODE), MIN(products.CODETYPE), " + + "MIN(products.NAME), MIN(products.PRICEBUY), " + + "MIN(products.PRICESELL), MIN(T.ID) AS TAX, MIN(T.RATE) + 1 AS TAXRATE, " + + "MIN(categories.ID) AS CATEGORY, MIN(categories.NAME) AS CATEGORYNAME, " + + "MIN(products.SUPPLIER) " + + "FROM ((products products " + + "INNER JOIN stockcurrent stockcurrent " + + "ON (products.ID = stockcurrent.PRODUCT)) " + + "LEFT OUTER JOIN categories categories " + + "ON (products.CATEGORY = categories.ID)) " + + "LEFT OUTER JOIN taxes T " + + "ON (products.TAXCAT = T.ID) " + + "WHERE ?(QBF_FILTER) " + + "GROUP BY products.REFERENCE " + + "ORDER BY MIN(categories.NAME), MIN(products.NAME)"); + +report.addParameter("products.NAME"); +report.addParameter("products.CATEGORY"); +report.addParameter("products.CODE"); +report.addQBFFilter(new com.unicenta.pos.ticket.ProductFilter4()); + +report.addField("ID", com.unicenta.data.loader.Datas.STRING); +report.addField("REFERENCE", com.unicenta.data.loader.Datas.STRING); +report.addField("CODE", com.unicenta.data.loader.Datas.STRING); +report.addField("CODETYPE", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("PRICEBUY", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("PRICESELL", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("TAX", com.unicenta.data.loader.Datas.STRING); +report.addField("TAXRATE", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("CATEGORY", com.unicenta.data.loader.Datas.STRING); +report.addField("CATEGORYNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("SUPPLIER", com.unicenta.data.loader.Datas.STRING); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/labels_product.jrxml b/src/main/resources/com/unicenta/reports/labels_product.jrxml new file mode 100644 index 0000000..14420f7 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/labels_product.jrxml @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band height="52"> + <rectangle radius="5"> + <reportElement key="rectangle-2" mode="Opaque" x="0" y="50" width="535" height="2" forecolor="#33CCFF" backcolor="#33CCFF" uuid="5c281873-3dc7-42c0-8c1b-1ecda14173ee"/> + <graphicElement fill="Solid"> + <pen lineWidth="0.25" lineStyle="Solid"/> + </graphicElement> + </rectangle> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-8" mode="Transparent" x="0" y="0" width="375" height="28" forecolor="#33CCFF" backcolor="#FFFFFF" uuid="fbe1c2be-2e4e-47fe-a698-33db213f1c60"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="14" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.title}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report" pattern="dd/MM/yyyy h.mm a" isBlankWhenNull="false"> + <reportElement key="textField" x="400" y="15" width="135" height="15" uuid="10007690-4424-46f9-926c-58149342cb7f"/> + <textElement textAlignment="Right"> + <font fontName="SansSerif" size="10"/> + </textElement> + <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-10" mode="Opaque" x="400" y="0" width="135" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="0493b45e-04a3-450c-a80b-e41cd6bc5f88"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.printed}]]></textFieldExpression> + </textField> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/logo.png b/src/main/resources/com/unicenta/reports/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..78fd3b894715cd606c403aa5de0f088e77baa543 GIT binary patch literal 3124 zcmeHJ`8(7L7ymN4Bg=#o>N~cw$E7JvC{%VP`%+=Zl){){FuAr8ibC0q-PreK>@@Zz zqM@vbEH`SHv6HTM?!WQA?|DAY`JB&r&QG87oaZ?&O;LKhTxYld0N^#yzhw>pY%o^s z!U)im#KY%MN!SPVrL>mCAVz>{TjQY^BU@rOj?<&TY3)J6qek+B&-5b@pV>ZIkD>sa?Gt-F+QBEcAEv z4X}**fBg43;BTq=@09@rbCku=|8@WtyHF|ChR+amYzY>g4+wrvUKqgC=@FKogwnAT z_eCgOR#H*X+q`iF0H6eeTiTXH2YTAC;89gRDxQ|uHp-BFYLX}7 z(Nf2urb>hD9UVdGs33zn7o+N%^Z;_^lPjw@G1Fk9g9ayEz?}V8YBFC(~@jV=m+)~1C;@Jsy2RTsI<%H zuXX?5W^;QtDhSCxBpJ%`rqhF7U?2^#sxm0%k<0EgbfFus#rfpH*h0XsuEJt(mS($z zC2eylTGj|`4=Q#t`EbcQzQrTXh%)BAjrTa(Xci5rCuG!Bn zuu8gafl>d#Y6!D#8n!zRXF<=jGSw7cMEq+O<$r9yWLFcv6l=~tcHixAqW>B#pBd&9I1SF49P z2o9&(Z}MYqnsN!f+T)y)h~TriUQHVrZv4GpMY}aydX5y&*(y-09!iPwrM949D)LoE z4n1K`hC8RjikDlA60K}PAoMN0{GlWb%+&^=D=$8#7!@s_Flj!yRKXtcn&>iHNCy}V zJ+3N!9)(^RECQt3w|Zf?~X5k60MHVtakjm zTeb6#NRp9cle88)tH++d)uc4qNEUhprg}H`P8aS_+;XuL@%46u)e6# z+2bby!Cc}M1WB-0BBSd>L)gkiv3Zf{!^s4VV#AjUJnHU0_OmLH%xVDxXsgj2&)$J| zfG;jRPSXQaZaWXx@gVFwp4>MK!iek}=cEhmTEU;ce#6^MYV3_9-a7`f>{!p~Nh#$p z5Q64bv9I#Y)J1MfHbit`QI(`e+GQdj!d@&2ZMPqgE))k_hOYd6|88mUE2Df#V+^@= zK4FHdK#*V0;qc_-zizwz<>q)Qf4X8n+KO9I_%E7U#XeH@_eEO{-|OUq25u~%Pbw}~z;iYw zB)~>?!4>`1u|-E}yAI{_LP!>VMY@p_n#X6*N1IB|bPOqCFqh(*kwwbao)iSUk-`;T z(Ug&kAaOx2G&=Q~)9}?}SjrqtBP`EV=ku;JC}^$sXf=2s1=IU%K^CK3gbRU~MBZ#r z^L!2Y*+;(=`%l!&DLsszDPH2OeAFE^v@=g4kN<)Hh`pAk*#x(logk9foco->VUqE? zy5`f}yFWazN93yJvr&YshqBvv4hZ<2VE-(INa!<;6QI5M^LRDOOo=vU$O@H$yl&=V4Vsj@xzbh87u(47{cg;uk{FOsm>y}si% ze&APu)gY1^;u?{62t2j`Vy{k zn9LZJQ$s}C9TQ&UQVJ>NKa^*YE`X{0Jf{}Mr8_m_0MgOojGf?vD#hsLw6 ztGbp*)AP=*L`&hkC+-poI}4rKE1@F@M!cK#NoZh{V<4ybs;=Fl2A26y!4M?Iix$D* zVI4io3p$f}Q9UmqQyLSu*-r__2hK;X1^p~e+W#5R7Q9#Q{!MM?ckSQfyP^GwdG8K6 z5. + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.Products"); +report.setReport("/com/unicenta/reports/products"); +report.setResourceBundle("com/unicenta/reports/products_messages"); + +report.setSentence("SELECT products.ID, " + + "MIN(products.REFERENCE), " + + "MIN(products.CODE), " + + "MIN(products.NAME), " + + "MIN(products.PRICEBUY), " + + "MIN(products.PRICESELL), " + + "MIN(T.ID) AS TAX, " + + "MIN(T.RATE) + 1 AS TAXRATE, " + + "MIN(categories.ID) AS CATEGORY, " + + "MIN(categories.NAME) AS CATEGORYNAME, " + + "MIN(stockcurrent.UNITS) " + + "FROM ((products products " + + "INNER JOIN taxes T " + + "ON (products.taxcat = T.id)) " + + "INNER JOIN categories categories " + + "ON (products.category = categories.id)) " + + "LEFT OUTER JOIN stockcurrent stockcurrent " + + "ON (stockcurrent.product = products.id) " + + "WHERE ?(QBF_FILTER) " + + "GROUP BY products.ID " + + "ORDER BY CATEGORYNAME ASC, MIN(products.NAME) ASC"); + +report.addParameter("stockcurrent.LOCATION"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsLocationWithFirst()); + +report.addParameter("products.NAME"); +report.addParameter("products.CATEGORY"); +report.addParameter("products.CODE"); +report.addParameter("stockcurrent.UNITS"); +report.addQBFFilter(new com.unicenta.pos.ticket.ProductFilter1()); + +report.addField("ID", com.unicenta.data.loader.Datas.STRING); +report.addField("REFERENCE", com.unicenta.data.loader.Datas.STRING); +report.addField("CODE", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("PRICEBUY", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("PRICESELL", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("TAX", com.unicenta.data.loader.Datas.STRING); +report.addField("TAXRATE", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("CATEGORY", com.unicenta.data.loader.Datas.STRING); +report.addField("CATEGORYNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("UNITS", com.unicenta.data.loader.Datas.DOUBLE); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/products.jrxml b/src/main/resources/com/unicenta/reports/products.jrxml new file mode 100644 index 0000000..afbc1f4 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/products.jrxml @@ -0,0 +1,374 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/products_catalog.bs b/src/main/resources/com/unicenta/reports/products_catalog.bs new file mode 100644 index 0000000..1ebafe7 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/products_catalog.bs @@ -0,0 +1,51 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.Catalog"); +report.setReport("/com/unicenta/reports/products"); +report.setResourceBundle("com/unicenta/reports/products_messages"); + +report.setSentence("SELECT " + + "products.ID, MIN(products.REFERENCE), MIN(products.CODE), MIN(products.NAME), " + + "MIN(products.PRICEBUY), MIN(products.PRICESELL), " + + "MIN(TC.ID) AS TAXCAT, MIN(TC.NAME) AS TAXCATNAME, " + + "MIN(categories.ID)AS CATEGORY, MIN(categories.NAME) AS CATEGORYNAME, " + + "MIN(products.UNITS) " + + "FROM products LEFT OUTER JOIN categories ON products.CATEGORY = categories.ID " + + "LEFT OUTER JOIN TAXcategories TC ON products.TAXCAT = TC.ID " + + "WHERE ?(QBF_FILTER) " + + "ORDER BY categories.NAME, MIN(products.NAME)"); + +report.addParameter("categories.ID"); +report.addQBFFilter(new com.unicenta.pos.ticket.CategoryFilter()); + +report.addField("ID", com.unicenta.data.loader.Datas.STRING); +report.addField("REFERENCE", com.unicenta.data.loader.Datas.STRING); +report.addField("CODE", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("PRICEBUY", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("PRICESELL", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("TAXCAT", com.unicenta.data.loader.Datas.STRING); +report.addField("TAXCATNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("CATEGORY", com.unicenta.data.loader.Datas.STRING); +report.addField("CATEGORYNAME", com.unicenta.data.loader.Datas.STRING); + +report; diff --git a/src/main/resources/com/unicenta/reports/products_messages.properties b/src/main/resources/com/unicenta/reports/products_messages.properties new file mode 100644 index 0000000..7c61efc --- /dev/null +++ b/src/main/resources/com/unicenta/reports/products_messages.properties @@ -0,0 +1,40 @@ +# uniCenta oPOS - Touch Friendly Point Of Sale +# Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +# https://unicenta.com/projects/unicentaopos +# +# This file is part of uniCenta oPOS. +# +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see . + +label.title=Product List +label.printed=Printed + +label.ref=Ref. +label.code=Barcode +label.name=Name +label.units=Qty +label.cost=Buy Price +label.pricebuy=Buy Price +label.pricenet=Sell Net +label.pricegross=Sell Gross + +label.title=Product Catalogue +label.printed=Printed +label.ref=Ref. +label.name=Name +label.cost=Cost +label.price=Price Nett +label.taxname=Tax +label.taxrate=(No Tax Rate found) +label.pricetax=Price Gross diff --git a/src/main/resources/com/unicenta/reports/products_messages_al_SQ.properties b/src/main/resources/com/unicenta/reports/products_messages_al_SQ.properties new file mode 100644 index 0000000..8e10543 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/products_messages_al_SQ.properties @@ -0,0 +1,38 @@ +# uniCenta oPOS - Touch Friendly Point Of Sale +# Copyright (c) 2009-2013 uniCenta & previous Openbravo POS works +# https://unicenta.com/projects/unicentaopos +# +# This file is part of uniCenta oPOS. +# +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see . + +label.title=Lista e Produkteve +label.printed=Printuar +label.ref=Ref. +label.name=Emri +label.cost=Kosotoja +label.price=Cmimi Nett +label.taxname=Tatimi +label.taxrate=Shkalla e Tatimit +label.pricetax=Cmimi Bruto + +label.title=Katalogu i Produkteve +label.printed=Printuar +label.ref=Ref. +label.name=Emri +label.cost=Kosotoja +label.price=Cmiimi Neto +label.taxname=Tatimi +label.taxrate=(Ska shkalle Tatimi) +label.pricetax=Cmimi Bruto \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/products_messages_ar.properties b/src/main/resources/com/unicenta/reports/products_messages_ar.properties new file mode 100644 index 0000000..fbbaec1 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/products_messages_ar.properties @@ -0,0 +1,39 @@ +# uniCenta oPOS - touch friendly EPoS +# Copyright (c) 2009 uniCenta oPOS +# https://unicenta.com/projects/unicentaopos +# +# This file is part of uniCenta oPOS. +# +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see . + +label.title=\u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0645\u0646\u062a\u062c\u0627\u062a +label.printed=\u0645\u0637\u0628\u0648\u0639 +label.ref=\u0645\u0631\u062c\u0639. +label.name=\u0627\u0633\u0645 +label.cost=\u062a\u0643\u0644\u0641\u0629 +label.price=\u0635\u0627\u0641\u064a \u0627\u0644\u062a\u0643\u0644\u0641\u0629 +label.taxname=\u0636\u0631\u064a\u0628\u0629 +label.taxrate=\u0646\u0633\u0628\u0629 \u0627\u0644\u0636\u0631\u064a\u0628\u0629 +label.pricetax=\u0627\u0644\u0633\u0639\u0631 \u0627\u0644\u0627\u062c\u0645\u0627\u0644\u064a + +label.title=\u0643\u0627\u062a\u0644\u0648\u062c \u0627\u0644\u0645\u0646\u062a\u062c +label.printed=\u0645\u0637\u0628\u0648\u0639 +label.ref=\u0645\u0631\u062c\u0639. +label.name=\u0627\u0644\u0627\u0633\u0645 +label.cost=\u0627\u0644\u062a\u0643\u0644\u0641\u0629 +label.price=\u0635\u0627\u0641\u0629 \u0627\u0644\u062a\u0643\u0644\u0641\u0629 +label.taxname=\u0636\u0631\u064a\u0628\u0629 +label.taxrate=(\u0644\u0645 \u064a\u062a\u0645 \u0627\u0644\u0639\u062b\u0648\u0631 \u0639\u0644\u0649 \u0646\u0633\u0628\u0629 \u0627\u0644\u0636\u0631\u064a\u0628\u0629) +label.pricetax=\u0627\u062c\u0645\u0627\u0644\u064a \u0627\u0644\u0642\u064a\u0645\u0629 + diff --git a/src/main/resources/com/unicenta/reports/products_messages_de.properties b/src/main/resources/com/unicenta/reports/products_messages_de.properties new file mode 100644 index 0000000..3505568 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/products_messages_de.properties @@ -0,0 +1,49 @@ +# Openbravo POS is a point of sales application designed for touch screens. +# Copyright (C) 2008 Openbravo, S.L. +# http://sourceforge.net/projects/ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Translations by Sebastian Muszytowski S.Muszytowski@googlemail.com +label.title=Produkt Liste + +label.ref=Ref. + +label.name=Name + +label.price=Preis (netto) + +label.taxname=Steuer + +label.taxrate=Steuersatz + +label.pricetax=Preis (Brutto) +label.cost=Kosten +label.printed=Erstellt am: + label.title=Produkt Katalog + +label.ref=Ref. + +label.name=Name + +label.price=Preis (netto) + +label.taxname=Steuer + +label.taxrate=Steuersatz + +label.pricetax=Preis (brutto) +label.printed=Erstellt am: +label.cost=Kosten diff --git a/src/main/resources/com/unicenta/reports/products_messages_el.properties b/src/main/resources/com/unicenta/reports/products_messages_el.properties new file mode 100644 index 0000000..7bdb3f9 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/products_messages_el.properties @@ -0,0 +1,38 @@ +# uniCenta oPOS - touch friendly EPoS +# Copyright (c) 2009 uniCenta oPOS +# https://unicenta.com/projects/unicentaopos +# +# This file is part of uniCenta oPOS. +# +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see . + +label.title=\u039b\u03af\u03c3\u03c4\u03b1 \u03a0\u03c1\u03bf\u03b9\u03cc\u03bd\u03c4\u03c9\u03bd +label.printed=Printed +label.ref=\u0391\u03bd\u03b1\u03c6. +label.name=\u038c\u03bd\u03bf\u03bc\u03b1 +label.cost=\u039a\u03cc\u03c3\u03c4\u03bf\u03c2 +label.price=Nett \u03a4\u03b9\u03bc\u03ae +label.taxname=\u03a6\u03cc\u03c1\u03bf\u03c2 +label.taxrate=\u03a4\u03b9\u03bc\u03ae \u03a6\u03cc\u03c1\u03bf\u03c5 +label.pricetax=\u039c\u03b9\u03ba\u03c4\u03ae \u03a4\u03b9\u03bc\u03ae + +label.title=\u039a\u03b1\u03c4\u03ac\u03bb\u03bf\u03b3\u03bf\u03c2 \u03a0\u03c1\u03bf\u03b9\u03cc\u03bd\u03c4\u03c9\u03bd +label.printed=Printed +label.ref=\u0391\u03bd\u03b1\u03c6. +label.name=\u038c\u03bd\u03bf\u03bc\u03b1 +label.cost=\u039a\u03cc\u03c3\u03c4\u03bf\u03c2 +label.price=Nett \u03a4\u03b9\u03bc\u03ae +label.taxname=\u03a6\u03cc\u03c1\u03bf\u03c2 +label.taxrate=(\u0394\u03b5\u03bd \u0392\u03c1\u03ad\u03b8\u03b7\u03ba\u03b5 \u03a4\u03b9\u03bc\u03ae \u03a6\u03cc\u03c1\u03bf\u03c5) +label.pricetax=\u039c\u03b9\u03ba\u03c4\u03ae \u03a4\u03b9\u03bc\u03ae \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/products_messages_en_US.properties b/src/main/resources/com/unicenta/reports/products_messages_en_US.properties new file mode 100644 index 0000000..b1146b0 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/products_messages_en_US.properties @@ -0,0 +1,39 @@ +# uniCenta oPOS - Touch Friendly Point Of Sale +# Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +# https://unicenta.com/projects/unicentaopos +# +# This file is part of uniCenta oPOS. +# +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see . + +label.title=Product List +label.printed=Printed + +label.ref=Ref. +label.name=Name +label.units=Qty +label.cost=Buy Price +label.pricebuy=Buy Price +label.pricenet=Sell Net +label.pricegross=Sell Gross + +label.title=Product Catalogue +label.printed=Printed +label.ref=Ref. +label.name=Name +label.cost=Cost +label.price=Price Nett +label.taxname=Tax +label.taxrate=(No Tax Rate found) +label.pricetax=Price Gross diff --git a/src/main/resources/com/unicenta/reports/products_messages_es.properties b/src/main/resources/com/unicenta/reports/products_messages_es.properties new file mode 100644 index 0000000..3dbee7f --- /dev/null +++ b/src/main/resources/com/unicenta/reports/products_messages_es.properties @@ -0,0 +1,38 @@ +# uniCenta oPOS - Touch Friendly Point Of Sale +# Copyright (c) 2009-2013 uniCenta & previous Openbravo POS works +# https://unicenta.com/projects/unicentaopos +# +# This file is part of uniCenta oPOS. +# +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see . + +label.cost=Coste +label.printed=Imprimir +label.name=Nombre +label.price=Precio +label.pricetax=Precio + IVA +label.ref=Ref. +label.taxname=Impuesto +label.taxrate=Tasa de IVA +label.title=Listado de productos + +label.name=Nombre +label.printed=Imprimir +label.price=Precio +label.pricetax=Precio+IVA +label.cost=Coste +label.ref=Ref. +label.taxname=Impuesto +label.taxrate=(No se encuentra la Tasa del Impuesto) +label.title=Cat\u00e1logo de productos diff --git a/src/main/resources/com/unicenta/reports/products_messages_es_AR.properties b/src/main/resources/com/unicenta/reports/products_messages_es_AR.properties new file mode 100644 index 0000000..b526883 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/products_messages_es_AR.properties @@ -0,0 +1,52 @@ +# Openbravo POS is a point of sales application designed for touch screens. +# Copyright (C) 2007-2009 Openbravo, S.L. +# http://sourceforge.net/projects/openbravopos +# +# This file is part of Openbravo POS. +# +# Openbravo POS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Openbravo POS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Openbravo POS. If not, see . + +label.title=Listado de productos + +label.ref=Ref. + +label.name=Nombre + +label.price=Precio + +label.taxname=Impuesto + +label.taxrate=Tasa de impuesto + +label.pricetax=Precio + Imp. +label.cost=Costo +label.printed=Impreso +label.units=Unidades +label.pricebuy=Precio de compra +label.pricenet=Precio de Venta +label.pricegross=Precio de Venta Bruto + +label.title=Cat\u00E1logo de productos + +label.ref=Ref. + +label.name=Nombre + +label.price=Precio + +label.taxname=Impuesto + +label.taxrate= + +label.pricetax=Precio + Imp. \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/products_messages_es_MX.properties b/src/main/resources/com/unicenta/reports/products_messages_es_MX.properties new file mode 100644 index 0000000..d26e729 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/products_messages_es_MX.properties @@ -0,0 +1,31 @@ +# Openbravo POS is a point of sales application designed for touch screens. +# Copyright (C) 2007-2009 Openbravo, S.L. +# http://sourceforge.net/projects/openbravopos +# Author: Juan Carlos Gastlum +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with Openbravo POS. If not, see . + +label.cost=Costo +label.name=Nombre +label.price=Precio +label.pricetax=Precio + Impuesto +label.ref=Ref. +label.taxname=Impuesto +label.taxrate=Tasa de impuesto +label.title=Lista de producto + +label.name=Nombre +label.price=Precio +label.pricetax=Precio + Impuesto +label.ref=Ref. +label.taxname=Impuesto +label.taxrate=Tasa de impuesto +label.title=Catlogo de producto diff --git a/src/main/resources/com/unicenta/reports/products_messages_et.properties b/src/main/resources/com/unicenta/reports/products_messages_et.properties new file mode 100644 index 0000000..87900eb --- /dev/null +++ b/src/main/resources/com/unicenta/reports/products_messages_et.properties @@ -0,0 +1,38 @@ +# uniCenta oPOS - touch friendly EPoS +# Copyright (c) 2009 uniCenta oPOS +# https://unicenta.com/projects/unicentaopos +# +# This file is part of uniCenta oPOS. +# +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see . + +label.title=Sortiment +label.printed=Tr\u00fckitud +label.ref=Kood +label.name=Nimetus +label.cost=Ostuhind +label.price=Netohind +label.taxname=KM +label.taxrate=KM % +label.pricetax=Brutohind + +label.title=Product Catalogue +label.printed=Tr\u00fckitud +label.ref=Kood +label.name=Nimetus +label.cost=Omahind +label.price=Netohind +label.taxname=KM +label.taxrate=(maksuvaba) +label.pricetax=Brutohind \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/products_messages_fr.properties b/src/main/resources/com/unicenta/reports/products_messages_fr.properties new file mode 100644 index 0000000..c436956 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/products_messages_fr.properties @@ -0,0 +1,43 @@ +# Openbravo POS is a point of sales application designed for touch screens. +# Copyright (C) 2009 Openbravo, S.L. +# http://sourceforge.net/projects/openbravopos +# +# This file is part of Openbravo POS. +# +# Openbravo POS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Openbravo POS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Openbravo POS. If not, see . + +label.title=Liste des produits +label.printed=Imprim\u00e9 + +label.ref=R\u00e9f. +label.name=Nom +label.units=Unit\u00e9 +label.pricebuy=TVA +label.pricenet=Prix HT +label.pricegross=Prix TTC +label.cost=Prix de revient +label.taxname=Nom de l'imp\u00f4t +label.taxrate=Taux d'imposition +label.pricetax=Prix d'imp\u00f4t +label.price=Prix + +label.title=Catalogue des produits +label.ref=R\u00e9f. +label.name=Nom +label.price=Prix +label.taxname=Taxe +label.taxrate=Taux +label.pricetax=Prix + Taxe +label.printed=P\u00e9riode: +label.cost=Co\u00fbt diff --git a/src/main/resources/com/unicenta/reports/products_messages_hr.properties b/src/main/resources/com/unicenta/reports/products_messages_hr.properties new file mode 100644 index 0000000..a03a3f2 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/products_messages_hr.properties @@ -0,0 +1,53 @@ +# Openbravo POS je PC kasa koja ima podr\u0161ku i za touch screen monitore. +# Copyright (C) 2007-2009 Openbravo, S.L. +# http://sourceforge.net/projects/openbravopos +# +# Preveo na hrvatski: Pro-Sistemi +# +# Ova datoteka je dio Openbravo POS sistema. +# +# Openbravo POS je besplatan software: mo\u017eete ga distribuirati i/ili +# modificirati pod uvjetima GNU General Public Licence koja je objavljena +# od strane Free Software Foundation, bilo licencne verzije 3, ili bilo +# koje kasnije verzije ( mo\u017eda u Va\u0161em slu\u010daju ). +# +# Openbravo POS se distribuira u nadi da \u0107e biti od koristi, ali +# BEZ IKAKVE GARANCIJE; \u010dak i ako je slu\u010daj da je KUPLJEN kao roba ili +# je PREPRAVLJEN radi specifi\u010dnih potreba. Pogledajte +# GNU General Public Licencu za vi\u0161e detalja o tome. +# +# Uz Openbravo POS ste trebali dobiti kopiju GNU General Public Licence. +# Ako niste, pogledajte je na . + +label.title=Popis artikala + +label.ref=\u0160ifra + +label.name=Ime + +label.cost=Tro\u0161kovi + +label.price=Cijena + +label.taxname=Porez + +label.taxrate=Stopa poreza + +label.pricetax=Cijena+PDV +label.printed=Ispisano + +label.title=Katalog + +label.ref=\u0160ifra + +label.name=Ime + +label.price=Cijena + +label.taxname=Naziv poreza + +label.taxrate=Stopa poreza + +label.pricetax=Cijena+PDV +label.printed=Ispisano +label.cost=Ko\u0161tati diff --git a/src/main/resources/com/unicenta/reports/products_messages_it.properties b/src/main/resources/com/unicenta/reports/products_messages_it.properties new file mode 100644 index 0000000..8b327e1 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/products_messages_it.properties @@ -0,0 +1,39 @@ +# uniCenta oPOS - Touch Friendly Point Of Sale +# Copyright (c) 2009-2014 uniCenta & previous Openbravo POS works +# https://unicenta.com/projects/unicentaopos +# +# This file is part of uniCenta oPOS. +# +# uniCenta oPOS is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# uniCenta oPOS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see . + +label.title=Lista Prodotto +label.printed=Stampato +label.ref=Rif. +label.name=Nome +label.cost=Costo +label.price=Prezzo netto +label.taxname=Tassa +label.taxrate=Perc.Tassa +label.pricetax=Prezzo lordo + +label.title=Catalogo Prodotto +label.printed=Stampato +label.ref=Rif. +label.name=Nome +label.cost=Costo +label.price=Prezzo Netto +label.taxname=Tassa +label.taxrate=Perc.Tassa +label.pricetax=Prezzo Lordo + diff --git a/src/main/resources/com/unicenta/reports/products_messages_nl.properties b/src/main/resources/com/unicenta/reports/products_messages_nl.properties new file mode 100644 index 0000000..aa88bfe --- /dev/null +++ b/src/main/resources/com/unicenta/reports/products_messages_nl.properties @@ -0,0 +1,23 @@ +# uniCenta oPOS - Translation File +# Copyright (c) 2014 J.SNijder +# You should have received a copy of the GNU General Public License +# along with uniCenta oPOS. If not, see . +label.price=Prijs +label.pricetax=Prijs + BTW +label.ref=Ref. +label.cost=Kosten +label.name=Naam +label.printed=Afgedrukt +label.taxname=BTW +label.taxrate=BTW Tarief +label.title=Artikel Lijst + +label.title=Product catalogus +label.printed=Afgedrukt +label.ref=Referentie +label.name=Naam +label.price=Prijs +label.pricetax=Prijs + BTW +label.taxname=BTW +label.taxrate=BTW Tarief +label.pricetax=Bruto Prijs \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/salecatalog.bs b/src/main/resources/com/unicenta/reports/salecatalog.bs new file mode 100644 index 0000000..1274f36 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/salecatalog.bs @@ -0,0 +1,70 @@ +// uniCenta oPOS - touch friendly EPoS +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.SaleCatalog"); +report.setReport("/com/unicenta/reports/salecatalog"); +report.setResourceBundle("com/unicenta/reports/sales_messages"); + +report.setSentence("SELECT products.id, " + + "products.reference, products.code, products.codetype, products.name, " + + "products.pricesell, products.image, " + + "T.ID AS TAX, " + + "T.RATE + 1 AS TAXRATE, " + + "categories.name AS CATEGORYNAME, suppliers.name, stockcurrent.location " + + "FROM (((products products " + + "INNER JOIN stockcurrent stockcurrent " + + "ON (products.id = stockcurrent.product)) " + + "LEFT OUTER JOIN taxes T " + + "ON (products.taxcat = T.id)) " + + "LEFT OUTER JOIN categories categories " + + "ON (products.category = categories.id)) " + + "RIGHT OUTER JOIN suppliers suppliers " + + "ON (suppliers.id = products.supplier) " + + "WHERE ?(QBF_FILTER) " + + "GROUP BY products.REFERENCE " + + "ORDER BY CATEGORYNAME ASC, products.name ASC"); + +report.addParameter("products.NAME"); +report.addParameter("products.CATEGORY"); +report.addParameter("products.CODE"); +report.addQBFFilter(new com.unicenta.pos.ticket.ProductFilter4()); + +report.addParameter("suppliers.ID"); +report.addParameter("suppliers.NAME"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsSuppliers()); + +report.addParameter("stockcurrent.LOCATION"); +report.addQBFFilter(new com.unicenta.pos.reports.JParamsLocation()); + +report.addField("ID", com.unicenta.data.loader.Datas.STRING); +report.addField("REFERENCE", com.unicenta.data.loader.Datas.STRING); +report.addField("CODE", com.unicenta.data.loader.Datas.STRING); +report.addField("CODETYPE", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("PRICESELL", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("IMAGE", com.unicenta.data.loader.Datas.IMAGE); +report.addField("TAX", com.unicenta.data.loader.Datas.STRING); +report.addField("TAXRATE", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("CATEGORYNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("SUPPLIER", com.unicenta.data.loader.Datas.STRING); +report.addField("LOCATION", com.unicenta.data.loader.Datas.STRING); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/salecatalog.jrxml b/src/main/resources/com/unicenta/reports/salecatalog.jrxml new file mode 100644 index 0000000..35da71a --- /dev/null +++ b/src/main/resources/com/unicenta/reports/salecatalog.jrxml @@ -0,0 +1,260 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band height="50"> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-8" mode="Transparent" x="0" y="0" width="309" height="28" forecolor="#33CCFF" backcolor="#FFFFFF" uuid="80a1aa76-7184-489b-a478-2b151ad471a4"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="14" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.title.salecatalog}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-10" mode="Opaque" x="400" y="2" width="135" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="dfad5312-1b35-49dc-956c-5df844d460de"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.printed}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report" pattern="dd/MM/yyyy h.mm a" isBlankWhenNull="false"> + <reportElement key="textField" x="400" y="15" width="135" height="15" uuid="0a60fd2f-d9f7-400c-849b-8c5c40fd7023"/> + <textElement textAlignment="Right"> + <font fontName="SansSerif" size="10"/> + </textElement> + <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression> + </textField> + <rectangle radius="5"> + <reportElement key="rectangle-1" positionType="Float" mode="Opaque" x="0" y="48" width="535" height="2" forecolor="#33CCFF" backcolor="#33CCFF" uuid="eb93e8b8-16bd-4449-b38b-46b559122d9a"/> + <graphicElement fill="Solid"> + <pen lineWidth="0.25" lineStyle="Solid"/> + </graphicElement> + </rectangle> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/sales_cashflow.bs b/src/main/resources/com/unicenta/reports/sales_cashflow.bs new file mode 100644 index 0000000..7b65ae5 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/sales_cashflow.bs @@ -0,0 +1,49 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.CashFlow"); +report.setReport("/com/unicenta/reports/sales_cashflow"); +report.setResourceBundle("com/unicenta/reports/sales_messages"); + +report.setSentence("SELECT " + + "payments.payment AS PAYMENT, " + + "SUM(payments.total) AS PAYMENT_TOTAL " + + "FROM payments payments " + + "INNER JOIN receipts receipts " + + "ON (payments.receipt = receipts.id) " + + "WHERE ?(QBF_FILTER) " + + "GROUP BY payments.PAYMENT"); + +report.addParameter("receipts.DATENEW"); +report.addParameter("receipts.DATENEW"); + +paramdates = new com.unicenta.pos.reports.JParamsDatesInterval(); + +paramdates.setStartDate(com.unicenta.beans.DateUtils.getToday()); +// JG - 8 Jan 14 paramdates.setEndDate(com.unicenta.beans.DateUtils.getToday()); +paramdates.setEndDate(com.unicenta.beans.DateUtils.getTodayMinutes()); + +report.addQBFFilter(paramdates); + +report.addField("PAYMENT", com.unicenta.data.loader.Datas.STRING); +report.addField("PAYMENT_TOTAL", com.unicenta.data.loader.Datas.DOUBLE); + +return report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/sales_cashflow.jrxml b/src/main/resources/com/unicenta/reports/sales_cashflow.jrxml new file mode 100644 index 0000000..c8b7a80 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/sales_cashflow.jrxml @@ -0,0 +1,282 @@ + + + + + + + + + + + + + + + + + + + + + + + + <band height="52" splitType="Stretch"> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-18" mode="Transparent" x="0" y="0" width="359" height="30" forecolor="#33CCFF" backcolor="#FFFFFF" uuid="719119ca-6588-42be-8920-ab0ae9dd2af3"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="14" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.title.cashflow}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-19" mode="Opaque" x="400" y="0" width="135" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="cdb8e1d0-d102-411c-9b01-a1d63c0d85dd"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.printed}]]></textFieldExpression> + </textField> + <textField pattern="dd/MM/yyyy h.mm a"> + <reportElement x="400" y="15" width="135" height="15" uuid="65d82e21-0306-4e0e-9602-38fca8f10033"/> + <textElement textAlignment="Right"> + <font fontName="SansSerif"/> + </textElement> + <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-10" mode="Opaque" x="0" y="33" width="50" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="ddeacb3a-15cc-4ed4-9379-be18ee319190"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.period}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-2" mode="Transparent" x="50" y="33" width="110" height="15" uuid="8b68cb01-4410-4a2a-8c44-8893cfa1f002"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.TIMESTAMP.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[1])]]></textFieldExpression> + </textField> + <staticText> + <reportElement key="staticText-1" mode="Transparent" x="160" y="33" width="10" height="15" uuid="75d2ab4b-01a7-45c7-8a38-99539f8f5d70"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Center" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <text><![CDATA[-]]></text> + </staticText> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-3" mode="Transparent" x="170" y="33" width="110" height="15" uuid="dc859b23-1301-496c-a293-06a9daaf3884"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.TIMESTAMP.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[3])]]></textFieldExpression> + </textField> + <rectangle radius="5"> + <reportElement key="rectangle-1" mode="Opaque" x="0" y="50" width="535" height="2" forecolor="#33CCFF" backcolor="#33CCFF" uuid="57c50ea9-42f2-4621-aa78-4b53c1882c54"/> + <graphicElement fill="Solid"> + <pen lineWidth="0.25" lineStyle="Solid"/> + </graphicElement> + </rectangle> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/sales_cashregisterlog.bs b/src/main/resources/com/unicenta/reports/sales_cashregisterlog.bs new file mode 100644 index 0000000..6b0ac6e --- /dev/null +++ b/src/main/resources/com/unicenta/reports/sales_cashregisterlog.bs @@ -0,0 +1,54 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.CashRegisterLog"); +report.setReport("/com/unicenta/reports/sales_cashregisterlog"); +report.setResourceBundle("com/unicenta/reports/sales_messages"); + +report.setSentence("SELECT " + + "receipts.DATENEW, " + + "payments.PAYMENT, " + + "payments.TENDERED, " + + "payments.VOUCHER, " + + "SUM( payments.TOTAL ) AS PAYMENT_TOTAL " + + "FROM receipts " + + "LEFT JOIN payments ON receipts.ID = payments.RECEIPT " + + "WHERE ?(QBF_FILTER) " + + "GROUP BY receipts.DATENEW, payments.PAYMENT, payments.VOUCHER, payments.TENDERED"); + +report.addParameter("receipts.DATENEW"); +report.addParameter("receipts.DATENEW"); + +paramdates = new com.unicenta.pos.reports.JParamsDatesInterval(); + +paramdates.setStartDate(com.unicenta.beans.DateUtils.getToday()); +// JG - 8 Jan 14 paramdates.setEndDate(com.unicenta.beans.DateUtils.getToday()); +paramdates.setEndDate(com.unicenta.beans.DateUtils.getTodayMinutes()); + +report.addQBFFilter(paramdates); + +report.addField("DATENEW", com.unicenta.data.loader.Datas.TIMESTAMP); +report.addField("PAYMENT", com.unicenta.data.loader.Datas.STRING); +report.addField("TENDERED", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("VOUCHER", com.unicenta.data.loader.Datas.STRING); +report.addField("PAYMENT_TOTAL", com.unicenta.data.loader.Datas.DOUBLE); + +return report; diff --git a/src/main/resources/com/unicenta/reports/sales_cashregisterlog.jrxml b/src/main/resources/com/unicenta/reports/sales_cashregisterlog.jrxml new file mode 100644 index 0000000..2e402ba --- /dev/null +++ b/src/main/resources/com/unicenta/reports/sales_cashregisterlog.jrxml @@ -0,0 +1,349 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band height="52"> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-18" mode="Transparent" x="0" y="0" width="375" height="30" forecolor="#33CCFF" backcolor="#FFFFFF" uuid="e3a2ba03-2172-4bbb-a42a-8bf7806711c9"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="14" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.title.log}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-10" mode="Opaque" x="400" y="0" width="135" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="d53e31d3-82c2-4203-bb1f-53bc5386fc8e"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.printed}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report" pattern="dd/MM/yyyy h.mm a" isBlankWhenNull="false"> + <reportElement key="textField" x="400" y="15" width="135" height="15" uuid="46dfb1b5-1e60-480e-9567-610bafc2a6a7"/> + <textElement textAlignment="Right"> + <font fontName="SansSerif" size="10"/> + </textElement> + <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-2" mode="Transparent" x="50" y="33" width="110" height="15" uuid="a6131305-2a85-4bec-bd05-01ae378af777"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.TIMESTAMP.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[1])]]></textFieldExpression> + </textField> + <staticText> + <reportElement key="staticText-1" mode="Transparent" x="160" y="33" width="10" height="15" uuid="6e3621ee-b4ef-4e21-b74b-a889dafe4e03"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Center" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <text><![CDATA[- +]]></text> + </staticText> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-3" mode="Transparent" x="170" y="33" width="110" height="15" uuid="da098e9d-9aa8-4204-b03c-11c8f48fc67a"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.TIMESTAMP.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[3])]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-19" mode="Opaque" x="0" y="33" width="50" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="c0ef4e9f-e8d0-4661-8ca5-d69d16867540"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.period}]]></textFieldExpression> + </textField> + <rectangle radius="5"> + <reportElement key="rectangle-1" mode="Opaque" x="0" y="50" width="535" height="2" forecolor="#33CCFF" backcolor="#33CCFF" uuid="69b5c545-111b-46dd-9096-6534ca869233"/> + <graphicElement fill="Solid"> + <pen lineWidth="0.25" lineStyle="Solid"/> + </graphicElement> + </rectangle> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/sales_categorysales.bs b/src/main/resources/com/unicenta/reports/sales_categorysales.bs new file mode 100644 index 0000000..f39387b --- /dev/null +++ b/src/main/resources/com/unicenta/reports/sales_categorysales.bs @@ -0,0 +1,64 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.CategorySales"); +report.setReport("/com/unicenta/reports/sales_categorysales"); +report.setResourceBundle("com/unicenta/reports/sales_messages"); + +report.setSentence("SELECT " + + "MIN(R.datenew), " + + "C.id, " + + "MIN(C.name) AS CATNAME, " + + "SUM(TL.price * TL.units) AS BASE, " + + "SUM((TL.price * TL.units) * TX.rate) AS AMOUNT," + + "SUM((TL.PRICE+(TL.PRICE*TX.RATE))*TL.units) AS TOTAL, " + + "SUM(TL.units) AS UNITS " + + "FROM (((((products P " + + "INNER JOIN categories C ON (P.category = C.id)) " + + "INNER JOIN ticketlines TL ON (TL.product = P.id)) " + + "INNER JOIN taxes TX ON (TL.taxid = TX.id)) " + + "INNER JOIN tickets T ON (TL.ticket = T.id)) " + + "INNER JOIN receipts R ON (T.id = R.id)) " + + "INNER JOIN taxlines TXL ON (TXL.receipt = R.id) AND (TXL.taxid = TX.id) " + + "WHERE ?(QBF_FILTER) " + + "GROUP BY C.id " + + "ORDER BY CATNAME ASC"); + +report.addParameter("R.DATENEW"); +report.addParameter("R.DATENEW"); + +paramdates = new com.unicenta.pos.reports.JParamsDatesInterval(); +paramdates.setStartDate(com.unicenta.beans.DateUtils.getToday()); +paramdates.setEndDate(com.unicenta.beans.DateUtils.getTodayMinutes()); +report.addQBFFilter(paramdates); + +report.addParameter("C.id"); +report.addQBFFilter(new com.unicenta.pos.ticket.CategoryFilter()); + +report.addField("DATENEW", com.unicenta.data.loader.Datas.TIMESTAMP); +report.addField("ID", com.unicenta.data.loader.Datas.STRING); +report.addField("CATNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("BASE", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("AMOUNT", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("TOTAL", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("UNITS", com.unicenta.data.loader.Datas.DOUBLE); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/sales_categorysales.jrxml b/src/main/resources/com/unicenta/reports/sales_categorysales.jrxml new file mode 100644 index 0000000..a52ba83 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/sales_categorysales.jrxml @@ -0,0 +1,414 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band height="52" splitType="Stretch"> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-18" mode="Transparent" x="0" y="0" width="375" height="30" forecolor="#33CCFF" backcolor="#FFFFFF" uuid="4d32d804-f652-40d0-b010-f8c395891f1f"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="14" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.title.categorysummary}]]></textFieldExpression> + </textField> + <rectangle radius="5"> + <reportElement key="rectangle-1" mode="Opaque" x="0" y="50" width="535" height="2" forecolor="#33CCFF" backcolor="#33CCFF" uuid="f5d49fc0-1c80-40c2-965e-6ff5565d6bc2"/> + <graphicElement fill="Solid"> + <pen lineWidth="0.25" lineStyle="Solid"/> + </graphicElement> + </rectangle> + <staticText> + <reportElement key="staticText-1" mode="Transparent" x="160" y="33" width="10" height="15" uuid="5bd23888-387c-448e-82b0-6ed6e30160d1"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Center" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <text><![CDATA[- +]]></text> + </staticText> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-2" mode="Transparent" x="50" y="33" width="110" height="15" uuid="6e5dda44-dbe4-47ac-93d4-38091d8ac933"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.TIMESTAMP.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[1])]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-3" mode="Transparent" x="170" y="33" width="110" height="15" uuid="7640f4fe-7d8e-4c02-870f-3db1a0968b2e"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.TIMESTAMP.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[3])]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-10" mode="Opaque" x="0" y="33" width="50" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="819abf64-0b00-4f78-90c0-a205f280a4d5"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.period}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-19" mode="Opaque" x="400" y="0" width="135" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="856e5694-73c1-4106-a3fb-33ad751e11c8"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.printed}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report" pattern="dd/MM/yyyy h.mm a" isBlankWhenNull="false"> + <reportElement key="textField" x="400" y="15" width="135" height="15" forecolor="#000000" uuid="aeacadd7-d1ae-4806-a915-4e13fd313442"/> + <textElement textAlignment="Right"> + <font fontName="SansSerif" size="10"/> + </textElement> + <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression> + </textField> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/sales_categorysales_1.bs b/src/main/resources/com/unicenta/reports/sales_categorysales_1.bs new file mode 100644 index 0000000..e5d2bd7 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/sales_categorysales_1.bs @@ -0,0 +1,69 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see +// + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.CategorySales1"); +report.setReport("/com/unicenta/reports/sales_categorysales_1"); +report.setResourceBundle("com/unicenta/reports/sales_messages"); + +report.setSentence("SELECT " + + "MIN(R.datenew), " + + "MIN(C.id) AS CATID, " + + "C.name AS CATNAME, " + + "MIN((CASE WHEN C_1.NAME='' THEN C.NAME ELSE C_1.name END)) AS PARENTCAT, " + + "P.name AS PRODNAME, " + + "SUM(TL.price * TL.units) AS BASE, " + + "SUM((TL.price * TL.units) * TX.rate) AS AMOUNT, " + + "SUM((TL.PRICE + (TL.PRICE * TX.RATE)) * TL.units) AS TOTAL, " + + "SUM(TL.units) AS UNITS " + + "FROM ((((((products P " + + "INNER JOIN categories C ON (P.category = C.id)) " + + "INNER JOIN ticketlines TL ON (TL.product = P.id)) " + + "INNER JOIN taxes TX ON (TL.taxid = TX.id)) " + + "INNER JOIN tickets T ON (TL.ticket = T.id)) " + + "INNER JOIN receipts R ON (T.id = R.id)) " + + "INNER JOIN taxlines TXL ON (TXL.receipt = R.id) AND (TXL.taxid = TX.id)) " + + "INNER JOIN categories C_1 ON (C_1.id = C.id) " + + "WHERE ?(QBF_FILTER) " + + "GROUP BY C.name, P.name"); + +report.addParameter("R.DATENEW"); +report.addParameter("R.DATENEW"); + +paramdates = new com.unicenta.pos.reports.JParamsDatesInterval(); +paramdates.setStartDate(com.unicenta.beans.DateUtils.getToday()); +paramdates.setEndDate(com.unicenta.beans.DateUtils.getTodayMinutes()); +report.addQBFFilter(paramdates); + +report.addParameter("C.id"); +report.addQBFFilter(new com.unicenta.pos.ticket.CategoryFilter()); + +report.addField("DATENEW", com.unicenta.data.loader.Datas.TIMESTAMP); +report.addField("CATID", com.unicenta.data.loader.Datas.STRING); +report.addField("CATNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("PARENTCAT", com.unicenta.data.loader.Datas.STRING); +report.addField("PRODNAME", com.unicenta.data.loader.Datas.STRING); +report.addField("BASE", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("AMOUNT", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("TOTAL", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("UNITS", com.unicenta.data.loader.Datas.DOUBLE); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/sales_categorysales_1.jrxml b/src/main/resources/com/unicenta/reports/sales_categorysales_1.jrxml new file mode 100644 index 0000000..b0b491d --- /dev/null +++ b/src/main/resources/com/unicenta/reports/sales_categorysales_1.jrxml @@ -0,0 +1,541 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <band height="52" splitType="Stretch"> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-18" mode="Transparent" x="0" y="0" width="375" height="30" forecolor="#33CCFF" backcolor="#FFFFFF" uuid="b60f4d62-3352-4d45-8d95-d3fa31792d97"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="14" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.title.categorydetail}]]></textFieldExpression> + </textField> + <rectangle radius="5"> + <reportElement key="rectangle-1" mode="Opaque" x="0" y="50" width="535" height="2" forecolor="#33CCFF" backcolor="#33CCFF" uuid="ee35d675-ffe7-4083-9b97-ce225ed03abe"/> + <graphicElement fill="Solid"> + <pen lineWidth="0.25" lineStyle="Solid"/> + </graphicElement> + </rectangle> + <staticText> + <reportElement key="staticText-1" mode="Transparent" x="160" y="33" width="10" height="15" uuid="6bffc985-5a90-412a-98e0-a3bd5a83cfb1"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Center" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <text><![CDATA[- +]]></text> + </staticText> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-2" mode="Transparent" x="50" y="33" width="110" height="15" uuid="e857b8c5-fb1a-4ade-84e7-86fbc7087dfb"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.TIMESTAMP.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[1])]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-3" mode="Transparent" x="170" y="33" width="110" height="15" uuid="a381929c-e913-4eba-accf-6d9bcd169228"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.TIMESTAMP.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[3])]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-10" mode="Opaque" x="0" y="33" width="50" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="c6a42663-ccab-466b-97a1-1839e7cd27ba"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.period}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-19" mode="Opaque" x="400" y="0" width="135" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="8c3691fc-492a-449c-a813-edbd78f24b5f"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.printed}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report" pattern="dd/MM/yyyy h.mm a" isBlankWhenNull="false"> + <reportElement key="textField" x="400" y="15" width="135" height="15" forecolor="#000000" uuid="3d17baec-27c3-4855-9036-64c1285b135d"/> + <textElement textAlignment="Right"> + <font fontName="SansSerif" size="10"/> + </textElement> + <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression> + </textField> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/sales_categorysalesmysql.bs b/src/main/resources/com/unicenta/reports/sales_categorysalesmysql.bs new file mode 100644 index 0000000..fc5bcff --- /dev/null +++ b/src/main/resources/com/unicenta/reports/sales_categorysalesmysql.bs @@ -0,0 +1,58 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.CategorySales"); +report.setReport("/com/unicenta/reports/sales_categorysales"); +report.setResourceBundle("com/unicenta/reports/sales_messages"); + +// JG - 8 Jan 14 Convert lowercasednname to UPPERCASE for compatability + +report.setSentence("SELECT categories.NAME, " + +"Sum(ticketlines.UNITS) AS QTY, " + +"Sum(ticketlines.PRICE * ticketlines.UNITS) AS CATPRICE, " + +"Sum((products.PRICESELL * ticketlines.UNITS)-((products.ISVPRICE ) * (ticketlines.PRICE * ticketlines.UNITS))) AS DISC, " + +"Sum((ticketlines.PRICE * taxes.RATE)* ticketlines.UNITS) AS CATTAX, " + +"Sum((ticketlines.PRICE * ticketlines.UNITS) + ((ticketlines.PRICE * taxes.RATE)* ticketlines.UNITS)) AS CATTOTAL " + +"FROM (tickets INNER JOIN receipts ON tickets.ID = receipts.ID) INNER JOIN ((categories INNER JOIN products ON categories.ID = products.CATEGORY) INNER JOIN (taxes INNER JOIN ticketlines ON taxes.ID = ticketlines.TAXID) ON products.ID = ticketlines.PRODUCT) ON tickets.ID = ticketlines.TICKET " + +"WHERE ?(QBF_FILTER) " + +"GROUP BY categories.NAME"); + +report.addParameter("receipts.DATENEW"); +report.addParameter("receipts.DATENEW"); + +paramdates = new com.unicenta.pos.reports.JParamsDatesInterval(); + +paramdates.setStartDate(com.unicenta.beans.DateUtils.getToday()); +// JG - 8 Jan 14 paramdates.setEndDate(com.unicenta.beans.DateUtils.getToday()); +paramdates.setEndDate(com.unicenta.beans.DateUtils.getTodayMinutes()); + +report.addQBFFilter(paramdates); + +report.addField("ID", com.unicenta.data.loader.Datas.STRING); +report.addField("PARENTID", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("QTY", com.unicenta.data.loader.Datas.STRING); +report.addField("CATPRICE", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("DISC", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("CATTAX", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("CATTOTAL", com.unicenta.data.loader.Datas.DOUBLE); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/sales_chart_piesalescat.bs b/src/main/resources/com/unicenta/reports/sales_chart_piesalescat.bs new file mode 100644 index 0000000..a54bd7a --- /dev/null +++ b/src/main/resources/com/unicenta/reports/sales_chart_piesalescat.bs @@ -0,0 +1,54 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.CategoryProductSalesChart"); +report.setReport("/com/unicenta/reports/sales_chart_piesalescat"); +report.setResourceBundle("com/unicenta/reports/sales_messages"); + +report.setSentence("SELECT "+ + "categories.NAME AS CAT, " + + "SUM(ticketlines.UNITS) AS UNITS, " + + "SUM(ticketlines.PRICE * ticketlines.UNITS) AS TOTAL " + + "FROM ticketlines " + + "LEFT OUTER JOIN products ON ticketlines.PRODUCT = products.ID " + + "LEFT OUTER JOIN categories ON products.CATEGORY = categories.ID " + + "LEFT OUTER JOIN tickets ON ticketlines.TICKET = tickets.ID " + + "LEFT OUTER JOIN receipts ON tickets.ID = receipts.ID " + + "WHERE LENGTH(categories.NAME) > 1 AND ?(QBF_FILTER) " + + "GROUP BY categories.ID, categories.NAME "+ + "ORDER BY categories.NAME ASC"); + +report.addParameter("receipts.DATENEW"); +report.addParameter("receipts.DATENEW"); + +paramdates = new com.unicenta.pos.reports.JParamsDatesInterval(); + +paramdates.setStartDate(com.unicenta.beans.DateUtils.getToday()); +// JG - 8 Jan 14 paramdates.setEndDate(com.unicenta.beans.DateUtils.getToday()); +paramdates.setEndDate(com.unicenta.beans.DateUtils.getTodayMinutes()); + +report.addQBFFilter(paramdates); + +report.addField("CAT", com.unicenta.data.loader.Datas.STRING); +report.addField("UNITS", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("TOTAL", com.unicenta.data.loader.Datas.DOUBLE); + +report; diff --git a/src/main/resources/com/unicenta/reports/sales_chart_piesalescat.jrxml b/src/main/resources/com/unicenta/reports/sales_chart_piesalescat.jrxml new file mode 100644 index 0000000..ccb1742 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/sales_chart_piesalescat.jrxml @@ -0,0 +1,292 @@ + + + + + + + + + + + + + 1 +GROUP BY + CATEGORIES.ID +ORDER BY + CATEGORIES.NAME ASC]]> + + + + + + <band height="52"> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-25" mode="Transparent" x="0" y="0" width="375" height="30" forecolor="#33CCFF" backcolor="#FFFFFF" uuid="19688817-97de-4b9b-a334-4b8f8625314e"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="14" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.title.pie}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-10" mode="Opaque" x="400" y="0" width="135" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="f33b28ea-36f1-4503-bc8c-3a6b46d66d83"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.printed}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report" pattern="EEEEE dd MMMMM yyyy" isBlankWhenNull="false"> + <reportElement key="textField" x="400" y="19" width="135" height="15" uuid="f410a7e8-5d4b-4448-b007-eb9da73a5402"/> + <textElement textAlignment="Right"> + <font fontName="SansSerif" size="10"/> + </textElement> + <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-19" mode="Opaque" x="0" y="33" width="50" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="b49ae8ea-e94e-4a2d-8101-885c9047a2df"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.period}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-8" mode="Transparent" x="50" y="33" width="110" height="15" uuid="ae1392ff-2cf7-4645-ad5a-4d9ed609aac4"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.DATE.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[1])]]></textFieldExpression> + </textField> + <staticText> + <reportElement key="staticText-1" mode="Transparent" x="160" y="33" width="10" height="15" uuid="89d6c90c-cae6-4cce-b522-567439026d8a"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Center" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <text><![CDATA[- +]]></text> + </staticText> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-9" mode="Transparent" x="170" y="33" width="110" height="15" uuid="0eec4fd4-123f-4443-a2af-92179893c836"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.DATE.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[3])]]></textFieldExpression> + </textField> + <rectangle radius="5"> + <reportElement key="rectangle-2" mode="Opaque" x="0" y="50" width="535" height="2" forecolor="#33CCFF" backcolor="#33CCFF" uuid="dddf65d2-d40f-407d-b1b0-00207c11558b"/> + <graphicElement fill="Solid"> + <pen lineWidth="0.25" lineStyle="Solid"/> + </graphicElement> + </rectangle> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/sales_chart_pro_test.bs b/src/main/resources/com/unicenta/reports/sales_chart_pro_test.bs new file mode 100644 index 0000000..8238058 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/sales_chart_pro_test.bs @@ -0,0 +1,60 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.ProductSales"); +report.setReport("/com/unicenta/reports/sales_chart_pro_test"); +report.setResourceBundle("com/unicenta/reports/sales_messages"); + +report.setSentence( + "SELECT " + + "products.REFERENCE, " + + "products.NAME, " + + "SUM(ticketlines.UNITS) AS UNITS, " + + "SUM(ticketlines.UNITS * ticketlines.PRICE) AS TOTAL " + + "FROM receipts, tickets, ticketlines, products " + + "WHERE receipts.ID = tickets.ID AND tickets.ID = ticketlines.TICKET AND ticketlines.PRODUCT = products.ID AND ?(QBF_FILTER) " + + "GROUP BY products.REFERENCE, products.NAME " + + "ORDER BY products.NAME"); + +report.addParameter("receipts.DATENEW"); +report.addParameter("receipts.DATENEW"); + +paramdates = new com.unicenta.pos.reports.JParamsDatesInterval(); + +paramdates.setStartDate(com.unicenta.beans.DateUtils.getToday()); +// JG - 8 Jan 14 paramdates.setEndDate(com.unicenta.beans.DateUtils.getToday()); +paramdates.setEndDate(com.unicenta.beans.DateUtils.getTodayMinutes()); + +report.addQBFFilter(paramdates); +report.addParameter("products.NAME"); +report.addParameter("products.PRICEBUY"); +report.addParameter("products.PRICESELL"); +report.addParameter("products.CATEGORY"); +report.addParameter("products.CODE"); +report.addQBFFilter(new com.unicenta.pos.ticket.ProductFilter()); + +report.addField("REFERENCE", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("UNITS", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("TOTAL", com.unicenta.data.loader.Datas.DOUBLE); + +report; + diff --git a/src/main/resources/com/unicenta/reports/sales_chart_pro_test.jrxml b/src/main/resources/com/unicenta/reports/sales_chart_pro_test.jrxml new file mode 100644 index 0000000..24e8cbe --- /dev/null +++ b/src/main/resources/com/unicenta/reports/sales_chart_pro_test.jrxml @@ -0,0 +1,259 @@ + + + + + + + + + + + + + + + + + + + + + + + <band height="52"> + <rectangle radius="5"> + <reportElement key="rectangle-1" mode="Opaque" x="0" y="50" width="535" height="2" forecolor="#33CCFF" backcolor="#33CCFF" uuid="09c85ec6-ef9a-41eb-910d-7777c6e487e0"/> + <graphicElement fill="Solid"> + <pen lineWidth="0.25" lineStyle="Solid"/> + </graphicElement> + </rectangle> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-1" mode="Transparent" x="0" y="0" width="375" height="30" forecolor="#33CCFF" backcolor="#FFFFFF" uuid="aaf15cbc-0ac1-4d3c-a061-23234dc784fd"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="14" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.title.product}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-2" mode="Transparent" x="50" y="33" width="110" height="15" uuid="16775a43-7b4c-47b0-8a78-10556ed05255"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.DATE.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[1])]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-3" mode="Transparent" x="170" y="33" width="110" height="15" uuid="b8440b59-f6e6-4367-919e-9eaa6b328261"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.DATE.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[3])]]></textFieldExpression> + </textField> + <staticText> + <reportElement key="staticText-1" mode="Transparent" x="160" y="33" width="10" height="15" uuid="08ce72be-51c1-4d3b-b5d7-3cf6aea719f2"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Center" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <text><![CDATA[- +]]></text> + </staticText> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-10" mode="Opaque" x="0" y="33" width="50" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="f229e5ad-bc57-408c-826d-abcf49b027c2"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.period}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-19" mode="Opaque" x="400" y="0" width="135" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="6c2a1a42-f2db-43e0-894b-85bb761a59be"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.printed}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report" pattern="dd/MM/yyyy h.mm a" isBlankWhenNull="false"> + <reportElement key="textField" x="400" y="20" width="135" height="15" uuid="93925f65-97c8-464a-8338-205be0097ef1"/> + <textElement textAlignment="Right"> + <font fontName="SansSerif" size="10"/> + </textElement> + <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression> + </textField> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/sales_chart_productsales.bs b/src/main/resources/com/unicenta/reports/sales_chart_productsales.bs new file mode 100644 index 0000000..93ef729 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/sales_chart_productsales.bs @@ -0,0 +1,60 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.ProductSales"); +report.setReport("/com/unicenta/reports/sales_chart_productsales"); +report.setResourceBundle("com/unicenta/reports/sales_messages"); + +report.setSentence( + "SELECT " + + "products.REFERENCE, " + + "products.NAME, " + + "SUM(ticketlines.UNITS) AS UNITS, " + + "SUM(ticketlines.UNITS * ticketlines.PRICE) AS TOTAL " + + "FROM receipts, tickets, ticketlines, products " + + "WHERE receipts.ID = tickets.ID AND tickets.ID = ticketlines.TICKET AND ticketlines.PRODUCT = products.ID AND ?(QBF_FILTER) " + + "GROUP BY products.REFERENCE, products.NAME " + + "ORDER BY products.NAME"); + +report.addParameter("receipts.DATENEW"); +report.addParameter("receipts.DATENEW"); + +paramdates = new com.unicenta.pos.reports.JParamsDatesInterval(); + +paramdates.setStartDate(com.unicenta.beans.DateUtils.getToday()); +// JG - 8 Jan 14 paramdates.setEndDate(com.unicenta.beans.DateUtils.getToday()); +paramdates.setEndDate(com.unicenta.beans.DateUtils.getTodayMinutes()); + +report.addQBFFilter(paramdates); +report.addParameter("products.NAME"); +report.addParameter("products.PRICEBUY"); +report.addParameter("products.PRICESELL"); +report.addParameter("products.CATEGORY"); +report.addParameter("products.CODE"); +report.addQBFFilter(new com.unicenta.pos.ticket.ProductFilter()); + +report.addField("REFERENCE", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("UNITS", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("TOTAL", com.unicenta.data.loader.Datas.DOUBLE); + +report; + diff --git a/src/main/resources/com/unicenta/reports/sales_chart_productsales.jrxml b/src/main/resources/com/unicenta/reports/sales_chart_productsales.jrxml new file mode 100644 index 0000000..8489da7 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/sales_chart_productsales.jrxml @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + <band height="52"> + <rectangle radius="5"> + <reportElement key="rectangle-1" mode="Opaque" x="0" y="50" width="535" height="2" forecolor="#33CCFF" backcolor="#33CCFF" uuid="09c85ec6-ef9a-41eb-910d-7777c6e487e0"/> + <graphicElement fill="Solid"> + <pen lineWidth="0.25" lineStyle="Solid"/> + </graphicElement> + </rectangle> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-1" mode="Transparent" x="0" y="0" width="375" height="30" forecolor="#33CCFF" backcolor="#FFFFFF" uuid="aaf15cbc-0ac1-4d3c-a061-23234dc784fd"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="14" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.title.product}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-2" mode="Transparent" x="50" y="33" width="110" height="15" uuid="16775a43-7b4c-47b0-8a78-10556ed05255"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.DATE.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[1])]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-3" mode="Transparent" x="170" y="33" width="110" height="15" uuid="b8440b59-f6e6-4367-919e-9eaa6b328261"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.DATE.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[3])]]></textFieldExpression> + </textField> + <staticText> + <reportElement key="staticText-1" mode="Transparent" x="160" y="33" width="10" height="15" uuid="08ce72be-51c1-4d3b-b5d7-3cf6aea719f2"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Center" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <text><![CDATA[- +]]></text> + </staticText> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-10" mode="Opaque" x="0" y="33" width="50" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="f229e5ad-bc57-408c-826d-abcf49b027c2"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.period}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-19" mode="Opaque" x="400" y="0" width="135" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="6c2a1a42-f2db-43e0-894b-85bb761a59be"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.printed}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report" pattern="dd/MM/yyyy h.mm a" isBlankWhenNull="false"> + <reportElement key="textField" x="400" y="20" width="135" height="15" uuid="93925f65-97c8-464a-8338-205be0097ef1"/> + <textElement textAlignment="Right"> + <font fontName="SansSerif" size="10"/> + </textElement> + <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression> + </textField> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/sales_chart_sales.bs b/src/main/resources/com/unicenta/reports/sales_chart_sales.bs new file mode 100644 index 0000000..4e42855 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/sales_chart_sales.bs @@ -0,0 +1,52 @@ +// uniCenta oPOS - Touch Friendly Point Of Sale +// Copyright (c) 2009-201 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.SalesChart"); +report.setReport("/com/unicenta/reports/sales_chart_sales"); +report.setResourceBundle("com/unicenta/reports/sales_messages"); + +report.setSentence("SELECT categories.ID, categories.NAME, " + + "Sum(ticketlines.UNITS) AS QTY," + + "Sum((ticketlines.PRICE * ticketlines.UNITS) + ((ticketlines.PRICE * taxes.RATE)* ticketlines.UNITS)) AS CATTOTAL " + + "FROM (tickets INNER JOIN receipts ON tickets.ID = receipts.ID) " + + "INNER JOIN ((categories INNER JOIN products ON categories.ID = products.CATEGORY) " + + "INNER JOIN (taxes INNER JOIN ticketlines ON taxes.ID = ticketlines.TAXID) " + + "ON products.ID = ticketlines.PRODUCT) ON tickets.ID = ticketlines.TICKET " + + "WHERE ?(QBF_FILTER) " + + "GROUP BY categories.ID, categories.NAME"); + +report.addParameter("receipts.DATENEW"); +report.addParameter("receipts.DATENEW"); + +paramdates = new com.unicenta.pos.reports.JParamsDatesInterval(); + +paramdates.setStartDate(com.unicenta.beans.DateUtils.getToday()); +// JG - 8 Jan 14 paramdates.setEndDate(com.unicenta.beans.DateUtils.getToday()); +paramdates.setEndDate(com.unicenta.beans.DateUtils.getTodayMinutes()); + +report.addQBFFilter(paramdates); + +report.addField("ID", com.unicenta.data.loader.Datas.STRING); +report.addField("NAME", com.unicenta.data.loader.Datas.STRING); +report.addField("QTY", com.unicenta.data.loader.Datas.DOUBLE); +report.addField("CATTOTAL", com.unicenta.data.loader.Datas.DOUBLE); + +report; diff --git a/src/main/resources/com/unicenta/reports/sales_chart_sales.jrxml b/src/main/resources/com/unicenta/reports/sales_chart_sales.jrxml new file mode 100644 index 0000000..618c8c0 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/sales_chart_sales.jrxml @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + <band height="54"> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-10" mode="Transparent" x="0" y="0" width="375" height="30" forecolor="#33CCFF" backcolor="#FFFFFF" uuid="69e44e6c-86e5-4946-bc7d-81347f487361"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Top" rotation="None"> + <font fontName="SansSerif" size="14" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.title.bycategory}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-19" mode="Opaque" x="647" y="0" width="135" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="e23f830c-8dc9-4980-b64c-ecadac76dc80"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Top" rotation="None"> + <font fontName="Arial" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.printed}]]></textFieldExpression> + </textField> + <textField evaluationTime="Report" pattern="dd/MM/yyyy h.mm a" isBlankWhenNull="false"> + <reportElement key="textField" x="647" y="14" width="135" height="15" uuid="95b8b2fa-9438-4151-83ea-6572050592de"/> + <textElement textAlignment="Right"> + <font fontName="Arial" size="10"/> + </textElement> + <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="false"> + <reportElement key="textField-10" mode="Opaque" x="0" y="33" width="50" height="15" forecolor="#000000" backcolor="#FFFFFF" uuid="bb5128eb-b94e-44cc-ace9-d4db9f47ae91"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[$R{label.period}]]></textFieldExpression> + </textField> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-8" mode="Transparent" x="50" y="33" width="110" height="15" uuid="4fb626d6-608a-4c7c-a4c0-085b9b433e16"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Right" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.TIMESTAMP.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[1])]]></textFieldExpression> + </textField> + <staticText> + <reportElement key="staticText-6" mode="Transparent" x="160" y="33" width="10" height="15" uuid="330aadca-d0f0-4844-962c-68bde20d553b"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Center" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <text><![CDATA[- +]]></text> + </staticText> + <textField pattern="" isBlankWhenNull="true"> + <reportElement key="textField-9" mode="Transparent" x="170" y="33" width="110" height="15" uuid="4bd37982-8136-4a3a-886c-b1f35b6c5d08"/> + <box> + <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> + <bottomPen lineWidth="0.0" lineColor="#000000"/> + <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#FFFFFF"/> + </box> + <textElement textAlignment="Left" verticalAlignment="Middle" rotation="None"> + <font fontName="SansSerif" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> + <paragraph lineSpacing="Single"/> + </textElement> + <textFieldExpression><![CDATA[com.unicenta.format.Formats.TIMESTAMP.formatValue((java.util.Date)((Object[])((Object[])$P{ARG})[0])[3])]]></textFieldExpression> + </textField> + <rectangle radius="5"> + <reportElement key="rectangle-1" mode="Opaque" x="0" y="50" width="782" height="2" forecolor="#33CCFF" backcolor="#33CCFF" uuid="618299eb-99bb-42b7-bd70-53fe43f20329"/> + <graphicElement fill="Solid"> + <pen lineWidth="0.25" lineStyle="Solid"/> + </graphicElement> + </rectangle> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/unicenta/reports/sales_chart_timeseriesproduct.bs b/src/main/resources/com/unicenta/reports/sales_chart_timeseriesproduct.bs new file mode 100644 index 0000000..1e1770b --- /dev/null +++ b/src/main/resources/com/unicenta/reports/sales_chart_timeseriesproduct.bs @@ -0,0 +1,73 @@ +// uniCenta oPOS - touch friendly EPoS +// Copyright (c) 2009-2018 uniCenta & previous Openbravo POS works +// https://unicenta.com +// +// This file is part of uniCenta oPOS +// +// uniCenta oPOS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// uniCenta oPOS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with uniCenta oPOS. If not, see . + +report = new com.unicenta.pos.reports.PanelReportBean(); + +report.setTitleKey("Menu.TimeSeriesProduct"); +report.setReport("/com/unicenta/reports/sales_chart_timeseriesproduct"); +report.setResourceBundle("com/unicenta/reports/sales_messages"); + +report.setSentence("SELECT " + + "MIN(products.code) AS code, " + + "MIN(products.codetype) AS codetype, " + + "MIN(products.reference) AS prodref, " + + "MIN(products.name) AS prodname, " + + "DATE(receipts.datenew) AS datesold, " + + "MIN(receipts.datenew) AS datestamp, " + + "count(ticketlines.UNITS) AS unitssold " + + "FROM ((ticketlines ticketlines " + + "INNER JOIN products products " + + "ON (ticketlines.PRODUCT = products.id)) " + + "INNER JOIN tickets tickets " + + "ON (TICKET = tickets.id)) " + + "INNER JOIN receipts receipts " + + "ON (tickets.id = receipts.id) " + + "WHERE ?(QBF_FILTER) " + + "GROUP BY DATE(receipts.datenew) " + + "ORDER BY 5 ASC"); + +report.addParameter("receipts.DATENEW"); +report.addParameter("receipts.DATENEW"); + +paramdates = new com.unicenta.pos.reports.JParamsDatesInterval(); + +paramdates.setStartDate(com.unicenta.beans.DateUtils.getToday()); +// JG - 8 Jan 14 paramdates.setEndDate(com.unicenta.beans.DateUtils.getToday()); +paramdates.setEndDate(com.unicenta.beans.DateUtils.getTodayMinutes()); + +report.addQBFFilter(paramdates); + +report.addParameter("products.NAME"); +//report.addParameter("products.ID"); +report.addParameter("products.CATEGORY"); +report.addParameter("products.PRICEBUY"); +report.addParameter("products.PRICESELL"); +report.addParameter("products.CODE"); + +report.addQBFFilter(new com.unicenta.pos.ticket.ProductFilter2()); + +report.addField("code", com.unicenta.data.loader.Datas.STRING); +report.addField("codetype", com.unicenta.data.loader.Datas.STRING); +report.addField("prodref", com.unicenta.data.loader.Datas.STRING); +report.addField("prodname", com.unicenta.data.loader.Datas.STRING); +report.addField("datesold", com.unicenta.data.loader.Datas.TIMESTAMP); +report.addField("datestamp", com.unicenta.data.loader.Datas.TIMESTAMP); +report.addField("unitssold", com.unicenta.data.loader.Datas.DOUBLE); + +report; \ No newline at end of file diff --git a/src/main/resources/com/unicenta/reports/sales_chart_timeseriesproduct.jrxml b/src/main/resources/com/unicenta/reports/sales_chart_timeseriesproduct.jrxml new file mode 100644 index 0000000..8a67864 --- /dev/null +++ b/src/main/resources/com/unicenta/reports/sales_chart_timeseriesproduct.jrxml @@ -0,0 +1,292 @@ + + + + + + + + + + +