package com.yourcompany.invoicing.model;
import java.time.*;
import javax.persistence.*;
import javax.persistence.Entity;
import org.hibernate.annotations.*;
import org.openxava.annotations.*;
import org.openxava.calculators.*;
import lombok.*;
@Entity
@Getter
@Setter
public class Invoice {
@Id
@GeneratedValue(generator = "system-uuid")
@Hidden
@GenericGenerator(name = "system-uuid", strategy = "uuid")
@Column(length = 32)
String oid;
@Column(length = 4)
@DefaultValueCalculator(CurrentYearCalculator.class) // 今年
int year;
@Column(length = 6)
int number;
@Required
@DefaultValueCalculator(CurrentLocalDateCalculator.class) // 当前的日期
LocalDate date;
@TextArea
String remarks;
}
package com.yourcompany.invoicing.calculators;
import javax.persistence.*;
import org.openxava.calculators.*;
import org.openxava.jpa.*;
import lombok.*;
public class NextNumberForYearCalculator implements ICalculator { // 计算器必须实现 ICalculator
@Getter // 可公开访问
@Setter // 可公开访问
int year; // 这个值会在计算之前被注入
public Object calculate() throws Exception { // 它进行计算
Query query = XPersistence.getManager() // 一个 JPA 查询
.createQuery("select max(i.number) from Invoice i where i.year = :year"); // 查询的返回
// 指定年份的最大发票编号
query.setParameter("year", year); // 我们使用注入的年份作为查询的参数
Integer lastNumber = (Integer) query.getSingleResult();
return lastNumber == null ? 1 : lastNumber + 1; // 返回最后一个发票号码
// 並+1或是1(如果今年还没有号码的话)
}
}
public class Invoice {
...
@Column(length=6)
@DefaultValueCalculator(value=NextNumberForYearCalculator.class,
properties=@PropertyValue(name="year") // 调用calculate()之前将 Invoice 中的年份值注入到计算器
)
int number;
...
}
@ManyToOne(fetch=FetchType.LAZY, optional=false) // Customer 为必须的
Customer customer;
@ElementCollection
Collection<Detail> details;
package com.yourcompany.invoicing.model;
import javax.persistence.*;
import lombok.*;
@Embeddable @Getter @Setter
public class Detail {
int quantity;
@ManyToOne(fetch = FetchType.LAZY, optional = true)
Product product;
}
@ElementCollection
@ListProperties("product.number, product.description, quantity")
Collection<Detail> details;
product.number = 产品编号
// 在本应用程序我们将使用上一个标签,而不是以下这个
Invoice.details.product.number= 产品编号