diff --git a/client/pom.xml b/client/pom.xml index 28831e4..1356444 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -6,12 +6,12 @@ com.ecep.contract Contract-Manager - 0.0.102-SNAPSHOT + 0.0.122-SNAPSHOT com.ecep.contract client - 0.0.102-SNAPSHOT + 0.0.122-SNAPSHOT ${java.version} @@ -22,7 +22,7 @@ com.ecep.contract common - 0.0.102-SNAPSHOT + 0.0.122-SNAPSHOT org.springframework.boot diff --git a/client/src/main/java/com/ecep/contract/controller/contract/ContractInvoiceManagerSkin.java b/client/src/main/java/com/ecep/contract/controller/contract/ContractInvoiceManagerSkin.java new file mode 100644 index 0000000..7afe183 --- /dev/null +++ b/client/src/main/java/com/ecep/contract/controller/contract/ContractInvoiceManagerSkin.java @@ -0,0 +1,24 @@ +package com.ecep.contract.controller.contract; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.ecep.contract.controller.AbstEntityManagerSkin; +import com.ecep.contract.vm.ContractInvoiceViewModel; +import com.ecep.contract.vo.ContractInvoiceVo; + +public class ContractInvoiceManagerSkin extends + AbstEntityManagerSkin { + + private static final Logger logger = LoggerFactory.getLogger(ContractInvoiceManagerSkin.class); + + public ContractInvoiceManagerSkin(ContractInvoiceManagerWindowController controller) { + super(controller); + } + + @Override + public void initializeTable() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'initializeTable'"); + } +} \ No newline at end of file diff --git a/client/src/main/java/com/ecep/contract/controller/contract/ContractInvoiceManagerWindowController.java b/client/src/main/java/com/ecep/contract/controller/contract/ContractInvoiceManagerWindowController.java new file mode 100644 index 0000000..ae73187 --- /dev/null +++ b/client/src/main/java/com/ecep/contract/controller/contract/ContractInvoiceManagerWindowController.java @@ -0,0 +1,48 @@ +package com.ecep.contract.controller.contract; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import com.ecep.contract.controller.AbstManagerWindowController; +import com.ecep.contract.service.ContractInvoiceService; +import com.ecep.contract.util.FxmlPath; +import com.ecep.contract.vm.ContractInvoiceViewModel; +import com.ecep.contract.vo.ContractInvoiceVo; + +import javafx.scene.control.TableColumn; +import javafx.stage.Stage; + +@Lazy +@Scope("prototype") +@Component +@FxmlPath("/ui/contract/contract-invoice-manager.fxml") +public class ContractInvoiceManagerWindowController extends AbstManagerWindowController { + + public TableColumn idColumn; + public TableColumn codeColumn; + public TableColumn nameColumn; + public TableColumn contractColumn; + public TableColumn contractItemColumn; + + @Autowired + private ContractInvoiceService contractInvoiceService; + + @Override + public ContractInvoiceService getViewModelService() { + return contractInvoiceService; + } + + @Override + protected ContractInvoiceManagerSkin createDefaultSkin() { + ContractInvoiceManagerSkin skin = new ContractInvoiceManagerSkin(this); + return skin; + } + + @Override + public void show(Stage stage) { + super.show(stage); + getTitle().set("合同发票管理"); + } +} \ No newline at end of file diff --git a/client/src/main/java/com/ecep/contract/controller/contract/ContractInvoiceWindowController.java b/client/src/main/java/com/ecep/contract/controller/contract/ContractInvoiceWindowController.java new file mode 100644 index 0000000..0728685 --- /dev/null +++ b/client/src/main/java/com/ecep/contract/controller/contract/ContractInvoiceWindowController.java @@ -0,0 +1,50 @@ +package com.ecep.contract.controller.contract; + +import org.springframework.stereotype.Component; + +import com.ecep.contract.controller.AbstEntityController; +import com.ecep.contract.controller.tab.ContractInvoiceTabSkinBase; +import com.ecep.contract.service.ContractInvoiceService; +import com.ecep.contract.util.FxmlPath; +import com.ecep.contract.vm.ContractInvoiceViewModel; +import com.ecep.contract.vo.ContractInvoiceVo; + +import javafx.collections.ObservableList; +import javafx.scene.control.Button; +import javafx.scene.control.Tab; +import javafx.scene.control.TabPane; +import javafx.scene.control.TextArea; +import javafx.scene.control.TextField; +import javafx.stage.Window; + +@FxmlPath("/ui/contract/contract-invoice.fxml") +@Component +public class ContractInvoiceWindowController + extends AbstEntityController { + + public static void show(ContractInvoiceViewModel viewModel, Window owner) { + show(ContractInvoiceWindowController.class, viewModel, owner); + } + + public Tab baseInfoTab; + public TextField codeField; + public TextField nameField; + public TextField invoiceField; + public TextField amountField; + public TextArea remarkField; + public Button saveBtn; + public Button cancelBtn; + + @Override + public ContractInvoiceService getViewModelService() { + return getBean(ContractInvoiceService.class); + } + + @Override + protected void registerTabSkins() { + TabPane tabPane = baseInfoTab.getTabPane(); + ObservableList tabs = tabPane.getTabs(); + registerTabSkin(baseInfoTab, tab -> new ContractInvoiceTabSkinBase(this)); + } + +} \ No newline at end of file diff --git a/client/src/main/java/com/ecep/contract/controller/contract/ContractTabSkinSaleOrders.java b/client/src/main/java/com/ecep/contract/controller/contract/ContractTabSkinSaleOrders.java index 015e8e2..9980df2 100644 --- a/client/src/main/java/com/ecep/contract/controller/contract/ContractTabSkinSaleOrders.java +++ b/client/src/main/java/com/ecep/contract/controller/contract/ContractTabSkinSaleOrders.java @@ -3,24 +3,21 @@ package com.ecep.contract.controller.contract; import java.time.LocalDate; import com.ecep.contract.ContractPayWay; +import com.ecep.contract.controller.contract.sale_order.SalesOrderWindowController; import com.ecep.contract.controller.tab.TabSkin; import com.ecep.contract.controller.table.cell.CompanyTableCell; import com.ecep.contract.controller.table.cell.EmployeeTableCell; -import com.ecep.contract.util.FxmlPath; -import com.ecep.contract.controller.contract.sale_order.SalesOrderWindowController; import com.ecep.contract.controller.table.cell.LocalDateFieldTableCell; import com.ecep.contract.converter.EmployeeStringConverter; import com.ecep.contract.service.CompanyService; import com.ecep.contract.service.SaleOrdersService; +import com.ecep.contract.util.FxmlPath; import com.ecep.contract.vm.SalesOrderViewModel; - import com.ecep.contract.vo.SalesOrderVo; -import javafx.scene.control.Button; + import javafx.scene.control.MenuItem; import javafx.scene.control.Tab; import javafx.scene.control.TableColumn; -import javafx.scene.control.TextField; -import javafx.scene.input.KeyCode; import lombok.Setter; /** @@ -56,7 +53,6 @@ public class ContractTabSkinSaleOrders public TableColumn verifierDateColumn; public TableColumn refIdColumn; public TableColumn taxRateColumn; - public TableColumn customerColumn; public TableColumn customerAddressColumn; /** * 修改人, Employee @@ -70,8 +66,6 @@ public class ContractTabSkinSaleOrders public TableColumn closerDateColumn; public TableColumn descriptionColumn; public MenuItem subContractTable_menu_refresh; - public TextField contractSearchKeyField; - public Button searchBtn; private Tab tab; public ContractTabSkinSaleOrders(ContractWindowController controller, Tab tab) { @@ -98,13 +92,7 @@ public class ContractTabSkinSaleOrders @Override public void initializeTab() { - contractSearchKeyField.setOnKeyReleased(event -> { - if (event.getCode() == KeyCode.ENTER) { - searchBtn.fire(); - } - }); - - searchBtn.setOnAction(this::onTableRefreshAction); + super.initializeTab(); subContractTable_menu_refresh.setOnAction(this::onTableRefreshAction); idColumn.setCellValueFactory(param -> param.getValue().getId()); @@ -123,8 +111,6 @@ public class ContractTabSkinSaleOrders // 设置新增字段的单元格值工厂和工厂类 refIdColumn.setCellValueFactory(param -> param.getValue().getRefId()); taxRateColumn.setCellValueFactory(param -> param.getValue().getTaxRate()); - customerColumn.setCellValueFactory(param -> param.getValue().getCustomer()); - customerColumn.setCellFactory(CompanyTableCell.forTableColumn(getCompanyService())); customerAddressColumn.setCellValueFactory(param -> param.getValue().getCustomerAddress()); modifierColumn.setCellValueFactory(param -> param.getValue().getModifier()); modifierColumn.setCellFactory(EmployeeTableCell.forTableColumn(getEmployeeService())); @@ -136,7 +122,7 @@ public class ContractTabSkinSaleOrders closerDateColumn.setCellFactory(LocalDateFieldTableCell.forTableColumn()); descriptionColumn.setCellValueFactory(param -> param.getValue().getDescription()); - super.initializeTab(); + } @Override diff --git a/client/src/main/java/com/ecep/contract/controller/contract/ContractWindowController.java b/client/src/main/java/com/ecep/contract/controller/contract/ContractWindowController.java index f38e16d..53e981d 100644 --- a/client/src/main/java/com/ecep/contract/controller/contract/ContractWindowController.java +++ b/client/src/main/java/com/ecep/contract/controller/contract/ContractWindowController.java @@ -13,6 +13,7 @@ import com.ecep.contract.controller.AbstEntityController; import com.ecep.contract.controller.company.CompanyWindowController; import com.ecep.contract.controller.tab.ContractTabSkinBase; import com.ecep.contract.controller.tab.ContractTabSkinFiles; +import com.ecep.contract.controller.tab.ContractTabSkinInvoices; import com.ecep.contract.controller.tab.ContractTabSkinItemsV2; import com.ecep.contract.controller.tab.ContractTabSkinPayPlan; import com.ecep.contract.controller.tab.ContractTabSkinSubContract; @@ -154,7 +155,7 @@ public class ContractWindowController registerTabSkin(saleOrderTab, tab -> new ContractTabSkinSaleOrders(this, tab)); Tab invoiceTab = new Tab("发票"); tabs.add(invoiceTab); - // registerTabSkin(invoiceTab, tab -> new ContractTabSkinInvoices(this, tab)); + registerTabSkin(invoiceTab, tab -> new ContractTabSkinInvoices(this, tab)); tabs.add(new Tab("出库单")); tabs.add(new Tab("发货单")); tabs.add(new Tab("签收单")); diff --git a/client/src/main/java/com/ecep/contract/controller/tab/ContractInvoiceTabSkinBase.java b/client/src/main/java/com/ecep/contract/controller/tab/ContractInvoiceTabSkinBase.java new file mode 100644 index 0000000..ace0895 --- /dev/null +++ b/client/src/main/java/com/ecep/contract/controller/tab/ContractInvoiceTabSkinBase.java @@ -0,0 +1,31 @@ +package com.ecep.contract.controller.tab; + +import com.ecep.contract.controller.contract.ContractInvoiceWindowController; +import com.ecep.contract.vm.ContractInvoiceViewModel; +import com.ecep.contract.vo.ContractInvoiceVo; +import javafx.scene.control.Tab; + +/** + * 合同发票基础信息标签页皮肤 + */ +public class ContractInvoiceTabSkinBase + extends AbstEntityBasedTabSkin + implements TabSkin { + + public ContractInvoiceTabSkinBase(ContractInvoiceWindowController controller) { + super(controller); + } + + @Override + public Tab getTab() { + return controller.baseInfoTab; + } + + @Override + public void initializeTab() { + // 可以在这里进行标签页的初始化工作 + controller.codeField.textProperty().bindBidirectional(viewModel.getCode()); + controller.nameField.textProperty().bindBidirectional(viewModel.getName()); + controller.remarkField.textProperty().bindBidirectional(viewModel.getRemark()); + } +} \ No newline at end of file diff --git a/client/src/main/java/com/ecep/contract/controller/tab/ContractTabSkinInvoices.java b/client/src/main/java/com/ecep/contract/controller/tab/ContractTabSkinInvoices.java new file mode 100644 index 0000000..c0be320 --- /dev/null +++ b/client/src/main/java/com/ecep/contract/controller/tab/ContractTabSkinInvoices.java @@ -0,0 +1,124 @@ +package com.ecep.contract.controller.tab; + +import java.time.LocalDate; +import java.util.Objects; + +import org.controlsfx.glyphfont.Glyph; +import org.springframework.stereotype.Component; + +import com.ecep.contract.controller.contract.AbstContractTableTabSkin; +import com.ecep.contract.controller.contract.ContractInvoiceWindowController; +import com.ecep.contract.controller.contract.ContractWindowController; +import com.ecep.contract.controller.table.EditableEntityTableTabSkin; +import com.ecep.contract.controller.table.cell.ContractInvoiceTableCell; +import com.ecep.contract.controller.table.cell.EmployeeTableCell; +import com.ecep.contract.controller.table.cell.NumberTableCell; +import com.ecep.contract.model.IdentityEntity; +import com.ecep.contract.service.ContractInvoiceService; +import com.ecep.contract.service.ContractService; +import com.ecep.contract.service.InvoiceService; +import com.ecep.contract.util.FxmlPath; +import com.ecep.contract.util.UITools; +import com.ecep.contract.vm.ContractInvoiceViewModel; +import com.ecep.contract.vo.ContractInvoiceVo; + +import javafx.beans.binding.Bindings; +import javafx.beans.property.SimpleStringProperty; +import javafx.event.ActionEvent; +import javafx.scene.control.Label; +import javafx.scene.control.MenuItem; +import javafx.scene.control.Tab; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.TextField; +import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.control.cell.TextFieldTableCell; +import javafx.scene.layout.Region; +import javafx.util.StringConverter; +import javafx.util.converter.CurrencyStringConverter; + +@FxmlPath("/ui/contract/contract-tab-invoices.fxml") +public class ContractTabSkinInvoices + extends AbstContractTableTabSkin + implements TabSkin, EditableEntityTableTabSkin { + + private Tab tab; + + + public TableColumn idColumn; + public TableColumn codeColumn; + public TableColumn nameColumn; + public TableColumn invoiceColumn; + public TableColumn amountColumn; + public TableColumn remarkColumn; + public TableColumn creatorColumn; + public TableColumn createDateColumn; + public TableColumn updaterColumn; + public TableColumn updateDateColumn; + + public Label totalAmountLabel; + + public ContractTabSkinInvoices(ContractWindowController controller, Tab tab) { + super(controller); + this.tab = tab; + } + + @Override + public Tab getTab() { + return tab; + } + + @Override + protected ContractInvoiceService getViewModelService() { + return getBean(ContractInvoiceService.class); + } + + @Override + public void initializeTable() { + super.initializeTable(); + getTableView().setEditable(true); + + // 初始化列 + idColumn.setCellValueFactory(new PropertyValueFactory<>("id")); + idColumn.setPrefWidth(50); + + codeColumn.setCellValueFactory(new PropertyValueFactory<>("code")); + codeColumn.setPrefWidth(120); + codeColumn.setCellFactory(TextFieldTableCell.forTableColumn()); + + nameColumn.setCellValueFactory(new PropertyValueFactory<>("name")); + nameColumn.setPrefWidth(200); + nameColumn.setCellFactory(TextFieldTableCell.forTableColumn()); + + // 发票列 + invoiceColumn.setCellValueFactory(new PropertyValueFactory<>("invoice")); + invoiceColumn.setPrefWidth(100); + invoiceColumn.setCellFactory(ContractInvoiceTableCell.forTableColumn(getCachedBean(InvoiceService.class))); + + // 金额列 + amountColumn.setCellValueFactory(new PropertyValueFactory<>("amount")); + amountColumn.setPrefWidth(100); + amountColumn.setCellFactory(NumberTableCell.forTableColumn(new CurrencyStringConverter(getLocale()))); + + remarkColumn.setCellValueFactory(new PropertyValueFactory<>("remark")); + remarkColumn.setPrefWidth(150); + remarkColumn.setCellFactory(TextFieldTableCell.forTableColumn()); + + // 创建人列 + creatorColumn.setCellValueFactory(new PropertyValueFactory<>("creator")); + creatorColumn.setPrefWidth(80); + creatorColumn.setCellFactory(EmployeeTableCell.forTableColumn(getEmployeeService())); + + createDateColumn.setCellValueFactory(new PropertyValueFactory<>("createDate")); + createDateColumn.setPrefWidth(120); + + // 更新人列 + updaterColumn.setCellValueFactory(new PropertyValueFactory<>("updater")); + updaterColumn.setPrefWidth(80); + updaterColumn.setCellFactory(EmployeeTableCell.forTableColumn(getEmployeeService())); + + updateDateColumn.setCellValueFactory(new PropertyValueFactory<>("updateDate")); + updateDateColumn.setPrefWidth(120); + } + +} \ No newline at end of file diff --git a/client/src/main/java/com/ecep/contract/controller/tab/ContractTabSkinItemsV2.java b/client/src/main/java/com/ecep/contract/controller/tab/ContractTabSkinItemsV2.java index 66a3765..4575d2f 100644 --- a/client/src/main/java/com/ecep/contract/controller/tab/ContractTabSkinItemsV2.java +++ b/client/src/main/java/com/ecep/contract/controller/tab/ContractTabSkinItemsV2.java @@ -4,6 +4,8 @@ import java.text.NumberFormat; import java.time.LocalDate; import java.time.LocalDateTime; +import javax.naming.Binding; + import org.springframework.data.domain.Pageable; import com.ecep.contract.ContractPayWay; @@ -28,6 +30,7 @@ import com.ecep.contract.vo.InventoryVo; import com.ecep.contract.vo.PurchaseOrderItemVo; import javafx.application.Platform; +import javafx.beans.binding.Bindings; import javafx.scene.control.ContextMenu; import javafx.scene.control.MenuItem; import javafx.scene.control.Tab; @@ -196,6 +199,8 @@ public class ContractTabSkinItemsV2 } showInOwner(InventoryWindowController.class, InventoryViewModel.from(inventory)); }); + showInventory.visibleProperty().bind( + Bindings.select(getTableView().getSelectionModel().selectedItemProperty(), "inventory", "value").isNotNull()); contextMenu.getItems().addAll(showInventory); } diff --git a/client/src/main/java/com/ecep/contract/controller/table/cell/ContractInvoiceTableCell.java b/client/src/main/java/com/ecep/contract/controller/table/cell/ContractInvoiceTableCell.java new file mode 100644 index 0000000..730db38 --- /dev/null +++ b/client/src/main/java/com/ecep/contract/controller/table/cell/ContractInvoiceTableCell.java @@ -0,0 +1,59 @@ +package com.ecep.contract.controller.table.cell; + +import static com.ecep.contract.SpringApp.getBean; + +import com.ecep.contract.service.InvoiceService; +import com.ecep.contract.vo.InvoiceVo; + +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.util.Callback; +import lombok.NoArgsConstructor; + +/** + * 合同发票表格单元格 + * 用于在表格中显示合同发票信息 + */ +@NoArgsConstructor +public class ContractInvoiceTableCell extends AsyncUpdateTableCell { + + /** + * 创建一个ContractInvoiceTableCell的TableCell工厂,自动获取InvoiceService实例 + * + * @param 表格行类型 + * @return TableCell工厂回调 + */ + public static Callback, TableCell> forTableColumn() { + return forTableColumn(getBean(InvoiceService.class)); + } + + /** + * 创建一个ContractInvoiceTableCell的TableCell工厂,使用提供的InvoiceService实例 + * + * @param 表格行类型 + * @param service InvoiceService实例 + * @return TableCell工厂回调 + */ + public static Callback, TableCell> forTableColumn(InvoiceService service) { + return param -> new ContractInvoiceTableCell(service); + } + + /** + * 使用指定的InvoiceService创建ContractInvoiceTableCell + * + * @param invoiceService InvoiceService实例 + */ + public ContractInvoiceTableCell(InvoiceService invoiceService) { + setService(invoiceService); + } + + @Override + protected InvoiceService getServiceBean() { + return getBean(InvoiceService.class); + } + + @Override + public String format(InvoiceVo entity) { + return entity.getCode(); + } +} \ No newline at end of file diff --git a/client/src/main/java/com/ecep/contract/service/ContractInvoiceService.java b/client/src/main/java/com/ecep/contract/service/ContractInvoiceService.java new file mode 100644 index 0000000..83bf4d2 --- /dev/null +++ b/client/src/main/java/com/ecep/contract/service/ContractInvoiceService.java @@ -0,0 +1,67 @@ +package com.ecep.contract.service; + +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.cache.annotation.Caching; +import org.springframework.stereotype.Service; + +import com.ecep.contract.vm.ContractInvoiceViewModel; +import com.ecep.contract.vo.ContractInvoiceVo; + +@Service +@CacheConfig(cacheNames = "contract-invoice") +public class ContractInvoiceService extends QueryService { + + @Cacheable(key = "#p0") + @Override + public ContractInvoiceVo findById(Integer id) { + return super.findById(id); + } + + @Caching(evict = { + @CacheEvict(key = "#p0.id"), + @CacheEvict(key = "'code-'+#p0.code") + }) + public ContractInvoiceVo save(ContractInvoiceVo invoice) { + return super.save(invoice); + } + + @Caching(evict = { + @CacheEvict(key = "#p0.id"), + @CacheEvict(key = "'code-'+#p0.code") + }) + public void delete(ContractInvoiceVo invoice) { + super.delete(invoice); + } + + @Cacheable(key = "'code-'+#p0") + public ContractInvoiceVo findByCode(String code) { + try { + return async("findByCode", code, String.class).handle((response, ex) -> { + if (ex != null) { + throw new RuntimeException("远程方法+findByCode+调用失败", ex); + } + if (response != null) { + return updateValue(createNewEntity(), response); + } + return null; + }).get(); + } catch (Exception e) { + throw new RuntimeException("查找合同发票 " + code + " 时发生错误", e); + } + } + + public ContractInvoiceVo findByContractId(Integer contractId) { + try { + return async("findByContractId", contractId, Integer.class).handle((response, ex) -> { + if (response != null) { + return updateValue(createNewEntity(), response); + } + return null; + }).get(); + } catch (Exception e) { + throw new RuntimeException("查找合同ID为 " + contractId + " 的发票时发生错误", e); + } + } +} \ No newline at end of file diff --git a/client/src/main/java/com/ecep/contract/service/EmployeeService.java b/client/src/main/java/com/ecep/contract/service/EmployeeService.java index d4f5aa8..5ab33f7 100644 --- a/client/src/main/java/com/ecep/contract/service/EmployeeService.java +++ b/client/src/main/java/com/ecep/contract/service/EmployeeService.java @@ -10,7 +10,6 @@ import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Caching; import org.springframework.stereotype.Service; -import com.ecep.contract.model.EmployeeRole; import com.ecep.contract.vm.EmployeeViewModel; import com.ecep.contract.vo.EmployeeRoleVo; import com.ecep.contract.vo.EmployeeVo; diff --git a/client/src/main/java/com/ecep/contract/vm/ContractInvoiceViewModel.java b/client/src/main/java/com/ecep/contract/vm/ContractInvoiceViewModel.java new file mode 100644 index 0000000..0f33a68 --- /dev/null +++ b/client/src/main/java/com/ecep/contract/vm/ContractInvoiceViewModel.java @@ -0,0 +1,119 @@ +package com.ecep.contract.vm; + +import java.time.LocalDate; +import java.util.Objects; + +import com.ecep.contract.util.NumberUtils; +import com.ecep.contract.vo.ContractInvoiceVo; + +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.property.SimpleStringProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = false) +public class ContractInvoiceViewModel extends IdentityViewModel { + private final SimpleStringProperty code = new SimpleStringProperty(); + private final SimpleStringProperty name = new SimpleStringProperty(); + /** + * 关联的合同对象, Contract + */ + private final SimpleObjectProperty contract = new SimpleObjectProperty<>(); + /** + * 关联的发票对象, Invoice + */ + private final SimpleObjectProperty invoice = new SimpleObjectProperty<>(); + /** + * 发票金额 + */ + private final SimpleObjectProperty amount = new SimpleObjectProperty<>(); + /** + * 备注 + */ + private final SimpleStringProperty remark = new SimpleStringProperty(); + private final SimpleObjectProperty createDate = new SimpleObjectProperty<>(); + private final SimpleObjectProperty updateDate = new SimpleObjectProperty<>(); + private final SimpleObjectProperty creator = new SimpleObjectProperty<>(); + private final SimpleObjectProperty updater = new SimpleObjectProperty<>(); + + @Override + protected void updateFrom(ContractInvoiceVo v) { + super.updateFrom(v); + code.set(v.getCode()); + name.set(v.getName()); + contract.set(v.getContractId()); + invoice.set(v.getInvoiceId()); + amount.set(v.getAmount() != null ? v.getAmount() : 0.0); + remark.set(v.getRemark()); + + updateDate.set(v.getUpdateDate()); + creator.set(v.getSetupPersonId()); + updater.set(v.getUpdatePersonId()); + } + + @Override + public boolean copyTo(ContractInvoiceVo v) { + boolean modified = super.copyTo(v); + + if (!Objects.equals(code.get(), v.getCode())) { + v.setCode(code.get()); + modified = true; + } + + if (!Objects.equals(name.get(), v.getName())) { + v.setName(name.get()); + modified = true; + } + + if (!Objects.equals(contract.get(), v.getContractId())) { + v.setContractId(contract.get()); + modified = true; + } + + if (!Objects.equals(invoice.get(), v.getInvoiceId())) { + v.setInvoiceId(invoice.get()); + modified = true; + } + + if (!NumberUtils.equals(amount.get(), v.getAmount())) { + v.setAmount(amount.get()); + modified = true; + } + + if (!Objects.equals(remark.get(), v.getRemark())) { + v.setRemark(remark.get()); + modified = true; + } + if (!Objects.equals(creator.get(), v.getSetupPersonId())) { + v.setSetupPersonId(creator.get()); + modified = true; + } + if (!Objects.equals(updater.get(), v.getUpdatePersonId())) { + v.setUpdatePersonId(updater.get()); + modified = true; + } + if (!Objects.equals(createDate.get(), v.getSetupDate())) { + v.setSetupDate(createDate.get()); + modified = true; + } + if (!Objects.equals(updateDate.get(), v.getUpdateDate())) { + v.setUpdateDate(updateDate.get()); + modified = true; + } + + return modified; + } + + /** + * 从VO对象创建ViewModel实例 + * + * @param vo 发票VO对象 + * @return 发票ViewModel实例 + */ + public static ContractInvoiceViewModel from(ContractInvoiceVo vo) { + ContractInvoiceViewModel viewModel = new ContractInvoiceViewModel(); + viewModel.updateFrom(vo); + return viewModel; + } +} \ No newline at end of file diff --git a/client/src/main/resources/ui/contract/contract-invoice-manager.fxml b/client/src/main/resources/ui/contract/contract-invoice-manager.fxml new file mode 100644 index 0000000..811b0a7 --- /dev/null +++ b/client/src/main/resources/ui/contract/contract-invoice-manager.fxml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + +