Merge branch 'master' of https://git.bukova.info/repos/git/isspst
This commit is contained in:
@@ -267,6 +267,17 @@ public class AppInitListener implements ServletContextListener {
|
||||
ns.setNumber(1);
|
||||
nsService.add(ns);
|
||||
}
|
||||
|
||||
ns = nsService.getNumberSerie(Constants.MOD_ORDER);
|
||||
|
||||
if (ns == null)
|
||||
{
|
||||
ns = new NumberSeries();
|
||||
ns.setModule(Constants.MOD_ORDER);
|
||||
ns.setPrefix("");
|
||||
ns.setNumber(1);
|
||||
nsService.add(ns);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkGlobalSettings() {
|
||||
|
||||
@@ -8,6 +8,7 @@ import info.bukova.isspst.reporting.Report;
|
||||
import info.bukova.isspst.reporting.ReportMapping;
|
||||
import info.bukova.isspst.services.addressbook.AdbService;
|
||||
import info.bukova.isspst.services.approved.ApprovedService;
|
||||
import info.bukova.isspst.services.approved.OrderService;
|
||||
import info.bukova.isspst.services.buildings.BuildingService;
|
||||
import info.bukova.isspst.services.munits.MUnitService;
|
||||
import info.bukova.isspst.services.reqsubjects.MaterialService;
|
||||
@@ -69,6 +70,7 @@ public class Constants {
|
||||
public final static String MOD_WORKFLOW = "WORKFLOW";
|
||||
public final static String MOD_TRIPBILL = "TRIPBILL";
|
||||
public final static String MOD_APPROVED = "APPROVED";
|
||||
public final static String MOD_ORDER = "ORDER";
|
||||
public final static Module MODULES[] = {
|
||||
new Module(MOD_USERS, "Uživatelé", UserService.class),
|
||||
new Module(MOD_PERMISSIONS, "Práva", RoleService.class),
|
||||
@@ -82,7 +84,8 @@ public class Constants {
|
||||
new Module(MOD_TRIPREQUIREMENTS, "Požadavky na služební cesty", TripRequirementService.class),
|
||||
new Module(MOD_WORKFLOW, "Procesy schválení", RequirementTypeService.class),
|
||||
new Module(MOD_TRIPBILL, "Cestovní příkazy", TripBillService.class),
|
||||
new Module(MOD_APPROVED, "Schválené položky příkazů", ApprovedService.class) };
|
||||
new Module(MOD_APPROVED, "Schválené položky požadavků", ApprovedService.class),
|
||||
new Module(MOD_ORDER, "Objednávky", OrderService.class) };
|
||||
|
||||
public final static String PERM_APPROVE = "PERM_APPROVE";
|
||||
public final static String PERM_SHOW_WORKGROUP_REQ = "PERM_SHOW_WORKGROUP_REQ";
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package info.bukova.isspst.dao;
|
||||
|
||||
import info.bukova.isspst.data.Order;
|
||||
|
||||
public interface OrderDao extends BaseDao<Order> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package info.bukova.isspst.dao.jpa;
|
||||
|
||||
import info.bukova.isspst.dao.OrderDao;
|
||||
import info.bukova.isspst.data.Order;
|
||||
|
||||
public class OrderDaoJPA extends BaseDaoJPA<Order> implements OrderDao {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
package info.bukova.isspst.data;
|
||||
|
||||
import javax.persistence.Embeddable;
|
||||
|
||||
@Embeddable
|
||||
public class AddressEmb {
|
||||
|
||||
private String company;
|
||||
private String department;
|
||||
private String contactName;
|
||||
private String street;
|
||||
private String houseNumber;
|
||||
private String zipCode;
|
||||
private String city;
|
||||
private String state;
|
||||
private long ic;
|
||||
private String dic;
|
||||
private String phone;
|
||||
private String email;
|
||||
private String web;
|
||||
private String description;
|
||||
|
||||
public AddressEmb() {
|
||||
super();
|
||||
}
|
||||
|
||||
public AddressEmb(Address address) {
|
||||
this.company = address.getCompany();
|
||||
this.department = address.getDepartment();
|
||||
this.contactName = address.getContactName();
|
||||
this.street = address.getStreet();
|
||||
this.houseNumber = address.getHouseNumber();
|
||||
this.zipCode = address.getZipCode();
|
||||
this.city = address.getCity();
|
||||
this.state = address.getState();
|
||||
this.ic = address.getIc();
|
||||
this.dic = address.getDic();
|
||||
this.phone = address.getPhone();
|
||||
this.email = address.getEmail();
|
||||
this.web = address.getWeb();
|
||||
this.description = address.getDescription();
|
||||
}
|
||||
|
||||
public String getCompany() {
|
||||
return company;
|
||||
}
|
||||
|
||||
public void setCompany(String company) {
|
||||
this.company = company;
|
||||
}
|
||||
|
||||
public String getDepartment() {
|
||||
return department;
|
||||
}
|
||||
|
||||
public void setDepartment(String department) {
|
||||
this.department = department;
|
||||
}
|
||||
|
||||
public String getContactName() {
|
||||
return contactName;
|
||||
}
|
||||
|
||||
public void setContactName(String contactName) {
|
||||
this.contactName = contactName;
|
||||
}
|
||||
|
||||
public String getStreet() {
|
||||
return street;
|
||||
}
|
||||
|
||||
public void setStreet(String street) {
|
||||
this.street = street;
|
||||
}
|
||||
|
||||
public String getHouseNumber() {
|
||||
return houseNumber;
|
||||
}
|
||||
|
||||
public void setHouseNumber(String houseNumber) {
|
||||
this.houseNumber = houseNumber;
|
||||
}
|
||||
|
||||
public String getZipCode() {
|
||||
return zipCode;
|
||||
}
|
||||
|
||||
public void setZipCode(String zipCode) {
|
||||
this.zipCode = zipCode;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public long getIc() {
|
||||
return ic;
|
||||
}
|
||||
|
||||
public void setIc(long ic) {
|
||||
this.ic = ic;
|
||||
}
|
||||
|
||||
public String getDic() {
|
||||
return dic;
|
||||
}
|
||||
|
||||
public void setDic(String dic) {
|
||||
this.dic = dic;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getWeb() {
|
||||
return web;
|
||||
}
|
||||
|
||||
public void setWeb(String web) {
|
||||
this.web = web;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
package info.bukova.isspst.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.AttributeOverride;
|
||||
import javax.persistence.AttributeOverrides;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.annotations.LazyCollection;
|
||||
import org.hibernate.annotations.LazyCollectionOption;
|
||||
|
||||
@Entity
|
||||
@Table(name = "ORDERS")
|
||||
public class Order extends BaseData {
|
||||
|
||||
@Column(name = "NUMSER")
|
||||
private String numser;
|
||||
|
||||
@Column(name = "ORDER_DATE")
|
||||
private Date orderDate;
|
||||
|
||||
@Embedded
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(name = "city", column = @Column(name = "SUPPLIER_CITY")),
|
||||
@AttributeOverride(name = "company", column = @Column(name = "SUPPLIER_COMPANY")),
|
||||
@AttributeOverride(name = "contactName", column = @Column(name = "SUPPLIER_CONTACT_NAME")),
|
||||
@AttributeOverride(name = "department", column = @Column(name = "SUPPLIER_DEPARTMENT")),
|
||||
@AttributeOverride(name = "description", column = @Column(name = "SUPPLIER_DESCRIPTION")),
|
||||
@AttributeOverride(name = "dic", column = @Column(name = "SUPPLIER_DIC")),
|
||||
@AttributeOverride(name = "email", column = @Column(name = "SUPPLIER_EMAIL")),
|
||||
@AttributeOverride(name = "houseNumber", column = @Column(name = "SUPPLIER_HOUSENUMBER")),
|
||||
@AttributeOverride(name = "ic", column = @Column(name = "SUPPLIER_IC")),
|
||||
@AttributeOverride(name = "phone", column = @Column(name = "SUPPLIER_PHONE")),
|
||||
@AttributeOverride(name = "state", column = @Column(name = "SUPPLIER_STATE")),
|
||||
@AttributeOverride(name = "street", column = @Column(name = "SUPPLIER_STREET")),
|
||||
@AttributeOverride(name = "web", column = @Column(name = "SUPPLIER_WEB")),
|
||||
@AttributeOverride(name = "zipCode", column = @Column(name = "SUPPLIER_ZIP_CODE"))
|
||||
})
|
||||
private AddressEmb suplier;
|
||||
|
||||
@Embedded
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(name = "city", column = @Column(name = "INVOICE_CITY")),
|
||||
@AttributeOverride(name = "company", column = @Column(name = "INVOICE_COMPANY")),
|
||||
@AttributeOverride(name = "contactName", column = @Column(name = "INVOICE_CONTACT_NAME")),
|
||||
@AttributeOverride(name = "department", column = @Column(name = "INVOICE_DEPARTMENT")),
|
||||
@AttributeOverride(name = "description", column = @Column(name = "INVOICE_DESCRIPTION")),
|
||||
@AttributeOverride(name = "dic", column = @Column(name = "INVOICE_DIC")),
|
||||
@AttributeOverride(name = "email", column = @Column(name = "INVOICE_EMAIL")),
|
||||
@AttributeOverride(name = "houseNumber", column = @Column(name = "INVOICE_HOUSENUMBER")),
|
||||
@AttributeOverride(name = "ic", column = @Column(name = "INVOICE_IC")),
|
||||
@AttributeOverride(name = "phone", column = @Column(name = "INVOICE_PHONE")),
|
||||
@AttributeOverride(name = "state", column = @Column(name = "INVOICE_STATE")),
|
||||
@AttributeOverride(name = "street", column = @Column(name = "INVOICE_STREET")),
|
||||
@AttributeOverride(name = "web", column = @Column(name = "INVOICE_WEB")),
|
||||
@AttributeOverride(name = "zipCode", column = @Column(name = "INVOICE_ZIP_CODE"))
|
||||
})
|
||||
private AddressEmb address;
|
||||
|
||||
@Embedded
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(name = "city", column = @Column(name = "DELIVERY_CITY")),
|
||||
@AttributeOverride(name = "company", column = @Column(name = "DELIVERY_COMPANY")),
|
||||
@AttributeOverride(name = "contactName", column = @Column(name = "DELIVERY_CONTACT_NAME")),
|
||||
@AttributeOverride(name = "department", column = @Column(name = "DELIVERY_DEPARTMENT")),
|
||||
@AttributeOverride(name = "description", column = @Column(name = "DELIVERY_DESCRIPTION")),
|
||||
@AttributeOverride(name = "dic", column = @Column(name = "DELIVERY_DIC")),
|
||||
@AttributeOverride(name = "email", column = @Column(name = "DELIVERY_EMAIL")),
|
||||
@AttributeOverride(name = "houseNumber", column = @Column(name = "DELIVERY_HOUSENUMBER")),
|
||||
@AttributeOverride(name = "ic", column = @Column(name = "DELIVERY_IC")),
|
||||
@AttributeOverride(name = "phone", column = @Column(name = "DELIVERY_PHONE")),
|
||||
@AttributeOverride(name = "state", column = @Column(name = "DELIVERY_STATE")),
|
||||
@AttributeOverride(name = "street", column = @Column(name = "DELIVERY_STREET")),
|
||||
@AttributeOverride(name = "web", column = @Column(name = "DELIVERY_WEB")),
|
||||
@AttributeOverride(name = "zipCode", column = @Column(name = "DELIVERY_ZIP_CODE"))
|
||||
})
|
||||
private AddressEmb deliveryAddress;
|
||||
|
||||
@Column(name = "DELIVERY_DATE")
|
||||
private Date deliveryDate;
|
||||
|
||||
@Column(name = "DELIVERED_DATE")
|
||||
private Date deliveredDate;
|
||||
|
||||
@Column(name = "DELIVERY_TYPE")
|
||||
private String deliveryType;
|
||||
|
||||
@Column(name = "DESCRIPTION")
|
||||
private String description;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "order", orphanRemoval = true)
|
||||
@LazyCollection(LazyCollectionOption.TRUE)
|
||||
private List<OrderItem> items;
|
||||
|
||||
@Column(name = "TOTAL", precision=15, scale=4)
|
||||
private BigDecimal total;
|
||||
|
||||
@Column(name = "ORDERED")
|
||||
private boolean ordered;
|
||||
|
||||
@Column(name = "DELIVERED")
|
||||
private boolean delivered;
|
||||
|
||||
@Column(name = "INVOICED")
|
||||
private boolean invoiced;
|
||||
|
||||
@Column(name = "INVOICE_NUMBER")
|
||||
private String invoiceNumber;
|
||||
|
||||
public Order() {
|
||||
items = new ArrayList<OrderItem>();
|
||||
}
|
||||
|
||||
public String getNumser() {
|
||||
return numser;
|
||||
}
|
||||
|
||||
public void setNumser(String numser) {
|
||||
this.numser = numser;
|
||||
}
|
||||
|
||||
public AddressEmb getSuplier() {
|
||||
return suplier;
|
||||
}
|
||||
|
||||
public void setSuplier(AddressEmb suplier) {
|
||||
this.suplier = suplier;
|
||||
}
|
||||
|
||||
public AddressEmb getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(AddressEmb address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public Date getDeliveryDate() {
|
||||
return deliveryDate;
|
||||
}
|
||||
|
||||
public void setDeliveryDate(Date deliveryDate) {
|
||||
this.deliveryDate = deliveryDate;
|
||||
}
|
||||
|
||||
public String getDeliveryType() {
|
||||
return deliveryType;
|
||||
}
|
||||
|
||||
public void setDeliveryType(String deliveryType) {
|
||||
this.deliveryType = deliveryType;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public AddressEmb getDeliveryAddress() {
|
||||
return deliveryAddress;
|
||||
}
|
||||
|
||||
public void setDeliveryAddress(AddressEmb deliveryAddress) {
|
||||
this.deliveryAddress = deliveryAddress;
|
||||
}
|
||||
|
||||
public Date getDeliveredDate() {
|
||||
return deliveredDate;
|
||||
}
|
||||
|
||||
public void setDeliveredDate(Date deliveredDate) {
|
||||
this.deliveredDate = deliveredDate;
|
||||
}
|
||||
|
||||
public List<OrderItem> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public void addItem(OrderItem item) {
|
||||
item.setOrder(this);
|
||||
items.add(item);
|
||||
}
|
||||
|
||||
public void setItems(List<OrderItem> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
public boolean isDelivered() {
|
||||
return delivered;
|
||||
}
|
||||
|
||||
public void setDelivered(boolean delivered) {
|
||||
this.delivered = delivered;
|
||||
}
|
||||
|
||||
public boolean isInvoiced() {
|
||||
return invoiced;
|
||||
}
|
||||
|
||||
public void setInvoiced(boolean invoiced) {
|
||||
this.invoiced = invoiced;
|
||||
}
|
||||
|
||||
public String getInvoiceNumber() {
|
||||
return invoiceNumber;
|
||||
}
|
||||
|
||||
public void setInvoiceNumber(String invoiceNumber) {
|
||||
this.invoiceNumber = invoiceNumber;
|
||||
}
|
||||
|
||||
public boolean isOrdered() {
|
||||
return ordered;
|
||||
}
|
||||
|
||||
public void setOrdered(boolean ordered) {
|
||||
this.ordered = ordered;
|
||||
}
|
||||
|
||||
public Date getOrderDate() {
|
||||
return orderDate;
|
||||
}
|
||||
|
||||
public void setOrderDate(Date orderDate) {
|
||||
this.orderDate = orderDate;
|
||||
}
|
||||
|
||||
public BigDecimal getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(BigDecimal total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package info.bukova.isspst.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "ORDER_ITEM")
|
||||
public class OrderItem {
|
||||
|
||||
@Id
|
||||
@Column(name="ID")
|
||||
@GeneratedValue
|
||||
private int id;
|
||||
|
||||
@Column(name = "CODE")
|
||||
private String code;
|
||||
|
||||
@Column(name = "NAME")
|
||||
private String name;
|
||||
|
||||
@Column(name = "TEXTITEM")
|
||||
private String textItem;
|
||||
|
||||
@Column(name = "QUANTITY", precision=15, scale=4)
|
||||
private BigDecimal quantity;
|
||||
|
||||
@Embedded
|
||||
private MUnitEmb munit;
|
||||
|
||||
@Column(name = "UNITPRICE", precision=15, scale=4)
|
||||
private BigDecimal unitPrice;
|
||||
|
||||
@Column(name = "TOTAL", precision=15, scale=4)
|
||||
private BigDecimal total;
|
||||
|
||||
@Column(name = "DESCRIPTION")
|
||||
private String description;
|
||||
|
||||
@ManyToOne(fetch = FetchType.EAGER)
|
||||
@JoinColumn(name = "REQUIREMENT_ITEM_ID")
|
||||
private RequirementItem reqItem;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "ORDER_ID")
|
||||
private Order order;
|
||||
|
||||
public OrderItem() {
|
||||
super();
|
||||
}
|
||||
|
||||
public OrderItem(RequirementItem reqItem) {
|
||||
super();
|
||||
this.reqItem = reqItem;
|
||||
this.code = reqItem.getCode();
|
||||
this.name = reqItem.getName();
|
||||
this.textItem = reqItem.getTextItem();
|
||||
this.quantity = reqItem.getQuantity();
|
||||
this.unitPrice = reqItem.getUnitPrice();
|
||||
this.munit = reqItem.getMunit();
|
||||
this.total = reqItem.getTotal();
|
||||
this.description = reqItem.getDescription();
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getTextItem() {
|
||||
return textItem;
|
||||
}
|
||||
|
||||
public void setTextItem(String textItem) {
|
||||
this.textItem = textItem;
|
||||
}
|
||||
|
||||
public BigDecimal getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public void setQuantity(BigDecimal quantity) {
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
public MUnitEmb getMunit() {
|
||||
return munit;
|
||||
}
|
||||
|
||||
public void setMunit(MUnitEmb munit) {
|
||||
this.munit = munit;
|
||||
}
|
||||
|
||||
public BigDecimal getUnitPrice() {
|
||||
return unitPrice;
|
||||
}
|
||||
|
||||
public void setUnitPrice(BigDecimal unitPrice) {
|
||||
this.unitPrice = unitPrice;
|
||||
}
|
||||
|
||||
public BigDecimal getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(BigDecimal total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public RequirementItem getReqItem() {
|
||||
return reqItem;
|
||||
}
|
||||
|
||||
public void setReqItem(RequirementItem reqItem) {
|
||||
this.reqItem = reqItem;
|
||||
}
|
||||
|
||||
public Order getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
public void setOrder(Order order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,7 +16,7 @@ import javax.persistence.Table;
|
||||
@Table(name = "REQUIREMENT")
|
||||
public class Requirement extends RequirementBase
|
||||
{
|
||||
@OneToMany(fetch = FetchType.EAGER, mappedBy = "requirement", cascade = CascadeType.ALL)
|
||||
@OneToMany(fetch = FetchType.EAGER, mappedBy = "requirement", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||
private List<RequirementItem> items;
|
||||
|
||||
@Column(name = "DELIVERYDATE")
|
||||
@@ -38,6 +38,12 @@ public class Requirement extends RequirementBase
|
||||
return items;
|
||||
}
|
||||
|
||||
public void addItem(RequirementItem item)
|
||||
{
|
||||
item.setRequirement(this); // nutné nastavit kvůli obousměrné vazbě. Na položce v DB se jinak nenastaví ID hlavního záznamu
|
||||
items.add(item);
|
||||
}
|
||||
|
||||
public void setItems(List<RequirementItem> items)
|
||||
{
|
||||
this.items = items;
|
||||
|
||||
@@ -53,6 +53,9 @@ public class RequirementItem
|
||||
@Column(name = "DESCRIPTION")
|
||||
private String description;
|
||||
|
||||
@Column(name = "DELIVERED")
|
||||
private Boolean delivered;
|
||||
|
||||
public int getId()
|
||||
{
|
||||
return id;
|
||||
@@ -176,4 +179,12 @@ public class RequirementItem
|
||||
{
|
||||
this.requirement = requirement;
|
||||
}
|
||||
|
||||
public Boolean getDelivered() {
|
||||
return delivered;
|
||||
}
|
||||
|
||||
public void setDelivered(Boolean delivered) {
|
||||
this.delivered = delivered;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,13 @@ package info.bukova.isspst.mail;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.InputStreamSource;
|
||||
import org.springframework.mail.MailAuthenticationException;
|
||||
import org.springframework.mail.MailParseException;
|
||||
import org.springframework.mail.MailSendException;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
@@ -14,6 +18,8 @@ public class MailerWithAttachement implements Mailer {
|
||||
|
||||
private JavaMailSender sender;
|
||||
private String from;
|
||||
private boolean overrideFrom = false;
|
||||
private static final Logger logger = LoggerFactory.getLogger(MailerWithAttachement.class);
|
||||
|
||||
public MailerWithAttachement(JavaMailSender sender) {
|
||||
this.sender = sender;
|
||||
@@ -27,7 +33,9 @@ public class MailerWithAttachement implements Mailer {
|
||||
try {
|
||||
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
|
||||
|
||||
if (message.getFrom() == null || message.getFrom().isEmpty()) {
|
||||
message.setReplyTo(message.getFrom());
|
||||
|
||||
if (message.getFrom() == null || message.getFrom().isEmpty() || overrideFrom) {
|
||||
if (from == null || from.isEmpty()) {
|
||||
message.setFrom("tomcat@is.bukova.info");
|
||||
} else {
|
||||
@@ -36,9 +44,15 @@ public class MailerWithAttachement implements Mailer {
|
||||
}
|
||||
|
||||
helper.setFrom(message.getFrom());
|
||||
helper.setReplyTo(message.getReplyTo());
|
||||
helper.setTo(message.getTo());
|
||||
helper.setSubject(message.getSubject());
|
||||
|
||||
if (message.getText() != null) {
|
||||
helper.setText(message.getText(), message.isHtml());
|
||||
} else {
|
||||
helper.setText("", message.isHtml());
|
||||
}
|
||||
|
||||
if (message.getAttachementData() != null) {
|
||||
InputStreamSource source = new ByteArrayResource(message.getAttachementData());
|
||||
@@ -47,11 +61,22 @@ public class MailerWithAttachement implements Mailer {
|
||||
} catch (MessagingException e) {
|
||||
throw new MailParseException(e);
|
||||
}
|
||||
try {
|
||||
sender.send(mimeMessage);
|
||||
} catch (MailAuthenticationException e) {
|
||||
logger.error("Authentication error");
|
||||
} catch (MailSendException e) {
|
||||
logger.error("Mail send error: " + e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setFrom(String from) {
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
public void setOverrideFrom(boolean override) {
|
||||
this.overrideFrom = override;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package info.bukova.isspst.services.approved;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import info.bukova.isspst.data.JoinedItem;
|
||||
import info.bukova.isspst.data.Order;
|
||||
import info.bukova.isspst.services.Service;
|
||||
|
||||
public interface OrderService extends Service<Order> {
|
||||
|
||||
public Order createOrder(List<JoinedItem> items);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package info.bukova.isspst.services.approved;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import info.bukova.isspst.data.AddressEmb;
|
||||
import info.bukova.isspst.data.JoinedItem;
|
||||
import info.bukova.isspst.data.Order;
|
||||
import info.bukova.isspst.data.OrderItem;
|
||||
import info.bukova.isspst.services.AbstractOwnedService;
|
||||
import info.bukova.isspst.services.settings.GlobalSettingsService;
|
||||
|
||||
public class OrderServiceImpl extends AbstractOwnedService<Order> implements
|
||||
OrderService {
|
||||
|
||||
@Autowired
|
||||
private GlobalSettingsService globalSettings;
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasPermission(this, 'PERM_ADD')")
|
||||
public Order createOrder(List<JoinedItem> items) {
|
||||
Order order = new Order();
|
||||
|
||||
order.setAddress(new AddressEmb(globalSettings.getSettings().getMainAddress()));
|
||||
order.setDeliveryAddress(new AddressEmb(globalSettings.getSettings().getMainAddress()));
|
||||
order.setOrderDate(new Date());
|
||||
|
||||
BigDecimal total = BigDecimal.ZERO;
|
||||
|
||||
for (JoinedItem item : items) {
|
||||
total = total.add(item.getTotal());
|
||||
order.addItem(new OrderItem(item.getItem()));
|
||||
}
|
||||
|
||||
order.setTotal(total);
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@PreAuthorize("hasPermission(this, 'PERM_ADD')")
|
||||
public void add(Order order) {
|
||||
order.setNumser(getNumberSerie());
|
||||
super.add(order);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -232,6 +232,7 @@ public abstract class RequirementBaseServiceImpl<T extends RequirementBase> exte
|
||||
}
|
||||
|
||||
if (message != null) {
|
||||
message.setFrom(getLoggedInUser().getEmail());
|
||||
message.setTo(e.getOwnedBy().getEmail());
|
||||
mailer.send(message);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,29 @@
|
||||
package info.bukova.isspst.ui.mail;
|
||||
|
||||
import static ch.lambdaj.Lambda.filter;
|
||||
import static ch.lambdaj.Lambda.having;
|
||||
import static ch.lambdaj.Lambda.on;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import info.bukova.isspst.data.Address;
|
||||
import info.bukova.isspst.data.Member;
|
||||
import info.bukova.isspst.data.User;
|
||||
import info.bukova.isspst.mail.MailMessage;
|
||||
import info.bukova.isspst.mail.Mailer;
|
||||
import info.bukova.isspst.reporting.Generator;
|
||||
import info.bukova.isspst.reporting.GeneratorFactory;
|
||||
import info.bukova.isspst.reporting.ReportDefinition;
|
||||
import info.bukova.isspst.services.addressbook.AdbService;
|
||||
import info.bukova.isspst.services.users.UserService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.zkoss.bind.annotation.BindingParam;
|
||||
import org.zkoss.bind.annotation.Command;
|
||||
import org.zkoss.bind.annotation.ExecutionArgParam;
|
||||
import org.zkoss.bind.annotation.Init;
|
||||
import org.zkoss.bind.annotation.NotifyChange;
|
||||
import org.zkoss.zk.ui.select.annotation.WireVariable;
|
||||
import org.zkoss.zul.Window;
|
||||
|
||||
@@ -21,10 +35,22 @@ public class MailForm {
|
||||
private ReportDefinition reportDefinition;
|
||||
@WireVariable
|
||||
private GeneratorFactory genFactory;
|
||||
@WireVariable
|
||||
private UserService userService;
|
||||
@WireVariable
|
||||
private AdbService adbService;
|
||||
private MailMessage message;
|
||||
private String to;
|
||||
private String cc;
|
||||
private String bcc;
|
||||
private String attachement;
|
||||
private boolean report;
|
||||
private List<Address> addressbook;
|
||||
private List<User> users;
|
||||
private List<Address> selectedAddresses;
|
||||
private List<User> selectedUsers;
|
||||
private int adbType;
|
||||
private String findAddress;
|
||||
|
||||
@Init
|
||||
public void init(@ExecutionArgParam("report") Boolean report) {
|
||||
@@ -34,11 +60,37 @@ public class MailForm {
|
||||
if (report) {
|
||||
attachement = "report.pdf";
|
||||
}
|
||||
|
||||
try {
|
||||
addressbook = adbService.getAll();
|
||||
} catch (AccessDeniedException e) {
|
||||
addressbook = new ArrayList<Address>();
|
||||
}
|
||||
|
||||
users = userService.getAll();
|
||||
|
||||
selectedAddresses = new ArrayList<Address>();
|
||||
selectedUsers = new ArrayList<User>();
|
||||
|
||||
to = "";
|
||||
cc = "";
|
||||
bcc = "";
|
||||
}
|
||||
|
||||
@Command
|
||||
public void send(@BindingParam("window") Window window) {
|
||||
message.setTo(to);
|
||||
message.setTo(to.split(";"));
|
||||
|
||||
if (cc != null && !cc.isEmpty()) {
|
||||
message.setCc(cc.split(";"));
|
||||
}
|
||||
|
||||
if (bcc != null && !bcc.isEmpty()) {
|
||||
message.setCc(bcc.split(";"));
|
||||
}
|
||||
|
||||
message.setFrom(userService.getCurrent().getEmail());
|
||||
|
||||
if (report) {
|
||||
Generator generator = genFactory.createGenerator(reportDefinition);
|
||||
message.setAttachementData(generator.generate());
|
||||
@@ -50,6 +102,76 @@ public class MailForm {
|
||||
window.detach();
|
||||
}
|
||||
|
||||
@Command
|
||||
@NotifyChange("to")
|
||||
public void addTo() {
|
||||
to = appendAddress(to, selAddrs());
|
||||
}
|
||||
|
||||
@Command
|
||||
@NotifyChange("cc")
|
||||
public void addCc() {
|
||||
cc = appendAddress(cc, selAddrs());
|
||||
}
|
||||
|
||||
@Command
|
||||
@NotifyChange("bcc")
|
||||
public void addBcc() {
|
||||
bcc = appendAddress(bcc, selAddrs());
|
||||
}
|
||||
|
||||
@Command
|
||||
@NotifyChange({"selectedAddresses", "selectedUsers"})
|
||||
public void find() {
|
||||
if (adbType == 0) {
|
||||
List<User> found = filter(having(on(Member.class).getFullName(), startsWith(findAddress)), users);
|
||||
|
||||
if (!found.isEmpty()) {
|
||||
selectedUsers.clear();
|
||||
if (!findAddress.isEmpty() && found.get(0).getEmail() != null && !found.get(0).getEmail().isEmpty()) {
|
||||
selectedUsers.add(found.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
List<Address> found = filter(having(on(Address.class).getCompany(), startsWith(findAddress)), addressbook);
|
||||
|
||||
if (!found.isEmpty()) {
|
||||
selectedAddresses.clear();
|
||||
if (!findAddress.isEmpty() && found.get(0).getEmail() != null && !found.get(0).getEmail().isEmpty()) {
|
||||
selectedAddresses.add(found.get(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String appendAddress(String field, List<String> addrs) {
|
||||
for (String addr : addrs) {
|
||||
if (field.isEmpty()) {
|
||||
field = addr;
|
||||
} else {
|
||||
field += "; " + addr;
|
||||
}
|
||||
}
|
||||
|
||||
return field;
|
||||
}
|
||||
|
||||
private List<String> selAddrs() {
|
||||
List<String> ret = new ArrayList<String>();
|
||||
|
||||
if (adbType == 1) {
|
||||
for (Address addr : selectedAddresses) {
|
||||
ret.add(addr.getCompany() + " <" + addr.getEmail() + ">");
|
||||
}
|
||||
} else {
|
||||
for (User u : selectedUsers) {
|
||||
ret.add(u.getFullName() + " <" + u.getEmail() + ">");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public MailMessage getMessage() {
|
||||
return message;
|
||||
}
|
||||
@@ -70,4 +192,60 @@ public class MailForm {
|
||||
return attachement;
|
||||
}
|
||||
|
||||
public String getCc() {
|
||||
return cc;
|
||||
}
|
||||
|
||||
public void setCc(String cc) {
|
||||
this.cc = cc;
|
||||
}
|
||||
|
||||
public String getBcc() {
|
||||
return bcc;
|
||||
}
|
||||
|
||||
public void setBcc(String bcc) {
|
||||
this.bcc = bcc;
|
||||
}
|
||||
|
||||
public List<Address> getAddressbook() {
|
||||
return addressbook;
|
||||
}
|
||||
|
||||
public List<User> getUsers() {
|
||||
return users;
|
||||
}
|
||||
|
||||
public int getAdbType() {
|
||||
return adbType;
|
||||
}
|
||||
|
||||
public void setAdbType(int adbType) {
|
||||
this.adbType = adbType;
|
||||
}
|
||||
|
||||
public List<Address> getSelectedAddresses() {
|
||||
return selectedAddresses;
|
||||
}
|
||||
|
||||
public void setSelectedAddresses(List<Address> selectedAddresses) {
|
||||
this.selectedAddresses = selectedAddresses;
|
||||
}
|
||||
|
||||
public List<User> getSelectedUsers() {
|
||||
return selectedUsers;
|
||||
}
|
||||
|
||||
public void setSelectedUsers(List<User> selectedUsers) {
|
||||
this.selectedUsers = selectedUsers;
|
||||
}
|
||||
|
||||
public String getFindAddress() {
|
||||
return findAddress;
|
||||
}
|
||||
|
||||
public void setFindAddress(String findAddress) {
|
||||
this.findAddress = findAddress;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ public class RequirementForm extends FormViewModel<Requirement>
|
||||
}
|
||||
|
||||
this.setSelectedItem(item);
|
||||
this.getDataBean().getItems().add(item);
|
||||
this.getDataBean().addItem(item);
|
||||
this.setSelItemIndex(this.getDataBean().getItems().indexOf(item));
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ public class RequirementForm extends FormViewModel<Requirement>
|
||||
item.setMunit(null);
|
||||
|
||||
this.setSelectedItem(item);
|
||||
this.getDataBean().getItems().add(item);
|
||||
this.getDataBean().addItem(item);
|
||||
this.setSelItemIndex(this.getDataBean().getItems().indexOf(item));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,5 +28,7 @@
|
||||
<mapping class="info.bukova.isspst.data.GlobalSettings"></mapping>
|
||||
<mapping class="info.bukova.isspst.data.TripBill"></mapping>
|
||||
<mapping class="info.bukova.isspst.data.TripBillItem"></mapping>
|
||||
<mapping class="info.bukova.isspst.data.Order"></mapping>
|
||||
<mapping class="info.bukova.isspst.data.OrderItem"></mapping>
|
||||
</session-factory>
|
||||
</hibernate-configuration>
|
||||
@@ -237,9 +237,20 @@ ReportNoOptions=Žádná nestavení
|
||||
|
||||
MailForm=Odeslání e-mailu
|
||||
MailFor=Komu:
|
||||
MailCc=Kopie:
|
||||
MailBcc=Skrytá:
|
||||
MailSubject=Předmět:
|
||||
MailSend=Odeslat
|
||||
MailAttachement=Příloha:
|
||||
MailAddressBook=Adresář:
|
||||
MailUsers=Uživatelé
|
||||
MailSuppliers=Dodavatelé
|
||||
MailName=Jméno
|
||||
MailCompany=Firma
|
||||
MailToButton=Komu ->
|
||||
MailCcButton=Kopie ->
|
||||
MailBccButton=Skrytá ->
|
||||
|
||||
|
||||
Error=Chyba
|
||||
ErrorRights=K vykobání této operace nemáte dostatečná oprávnění
|
||||
@@ -258,7 +269,6 @@ false=Ne
|
||||
|
||||
|
||||
Information=Informace
|
||||
Requirements=Požadavky
|
||||
Orders=Objednávky
|
||||
|
||||
MaterialRequirement=Požadavek na materiál
|
||||
@@ -270,7 +280,6 @@ ApprovedRequirementItems=Schválené položky požadavků
|
||||
CurrentRequirements=Aktuální požadavky
|
||||
ApprovedOrders=Schválené objednávky
|
||||
BussinessTrips=Služební cesty
|
||||
TravelOrders=Cestovní příkazy
|
||||
Lists=Seznamy
|
||||
Settings=Nastavení
|
||||
Administration=Administrace
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
mail.from=kosef.rokos@gmail.com
|
||||
mail.from=josef.rokos@gmail.com
|
||||
mail.host=smtp.gmail.com
|
||||
mail.port=587
|
||||
mail.useauth=true
|
||||
mail.usessl=true
|
||||
mail.username=josef.rokos@gmail.com
|
||||
mail.password=XXXXXX
|
||||
mail.password=XXXXXXXX
|
||||
mail.overrideFrom=false
|
||||
@@ -20,6 +20,7 @@
|
||||
<bean id="mailer" class="info.bukova.isspst.mail.MailerWithAttachement">
|
||||
<constructor-arg ref="mailSender"/>
|
||||
<property name="from" value="${mail.from}"/>
|
||||
<property name="overrideFrom" value="${mail.overrideFrom}"/>
|
||||
</bean>
|
||||
|
||||
<bean id="simpleMailer" class="info.bukova.isspst.mail.SimpleMailer">
|
||||
|
||||
@@ -243,6 +243,10 @@
|
||||
<property name="sessionFactory" ref="sessionFactory"/>
|
||||
</bean>
|
||||
|
||||
<bean id="orderDao" class="info.bukova.isspst.dao.jpa.OrderDaoJPA">
|
||||
<property name="sessionFactory" ref="sessionFactory"/>
|
||||
</bean>
|
||||
|
||||
<!-- Business logic -->
|
||||
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
|
||||
|
||||
@@ -400,4 +404,10 @@
|
||||
<property name="validator" ref="validator"/>
|
||||
</bean>
|
||||
|
||||
<bean id="orderService" class="info.bukova.isspst.services.approved.OrderServiceImpl">
|
||||
<property name="dao" ref="orderDao"/>
|
||||
<property name="validator" ref="validator"/>
|
||||
<property name="numberSeriesService" ref="numericSeriesService"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -2,8 +2,51 @@
|
||||
<zk>
|
||||
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
|
||||
<window id="mailWin" border="normal" apply="org.zkoss.bind.BindComposer"
|
||||
viewModel="@id('vm') @init('info.bukova.isspst.ui.mail.MailForm')" width="500px" closable="true">
|
||||
viewModel="@id('vm') @init('info.bukova.isspst.ui.mail.MailForm')" width="800px" closable="true">
|
||||
<caption zclass="form-caption" label="${labels.MailForm}" />
|
||||
<hbox>
|
||||
<vbox hflex="2">
|
||||
<hbox>
|
||||
<label value="${labels.MailAddressBook}"/>
|
||||
<combobox selectedIndex="@bind(vm.adbType)" readonly="true">
|
||||
<comboitem label="${labels.MailUsers}"/>
|
||||
<comboitem label="${labels.MailSuppliers}"/>
|
||||
</combobox>
|
||||
</hbox>
|
||||
<textbox value="@bind(vm.findAddress)" instant="true" onChange="@command('find')" width="100%"/>
|
||||
<listbox model="@load(vm.users)"
|
||||
visible="@load(vm.adbType eq 0)"
|
||||
multiple="true"
|
||||
selectedItems="@bind(vm.selectedUsers)"
|
||||
height="350px">
|
||||
<listhead>
|
||||
<listheader label="${labels.MailName}"/>
|
||||
</listhead>
|
||||
<template name="model">
|
||||
<listitem disabled="@load(empty each.email)" draggable="true">
|
||||
<listcell label="@load(each.fullName)"/>
|
||||
</listitem>
|
||||
</template>
|
||||
</listbox>
|
||||
<listbox model="@load(vm.addressbook)"
|
||||
visible="@load(vm.adbType eq 1)"
|
||||
multiple="true"
|
||||
selectedItems="@bind(vm.selectedAddresses)"
|
||||
height="350px">
|
||||
<listhead>
|
||||
<listheader label="${labels.MailCompany}"/>
|
||||
</listhead>
|
||||
<template name="model">
|
||||
<listitem disabled="@load(empty each.email)" draggable="true">
|
||||
<listcell label="@load(each.company)"/>
|
||||
</listitem>
|
||||
</template>
|
||||
</listbox>
|
||||
<button label="${labels.MailToButton}" width="90%" sclass="nicebutton" onClick="@command('addTo')"/>
|
||||
<button label="${labels.MailCcButton}" width="90%" sclass="nicebutton" onClick="@command('addCc')"/>
|
||||
<button label="${labels.MailBccButton}" width="90%" sclass="nicebutton" onClick="@command('addBcc')"/>
|
||||
</vbox>
|
||||
<vbox hflex="5">
|
||||
<grid>
|
||||
<columns>
|
||||
<column hflex="min"/>
|
||||
@@ -11,7 +54,13 @@ viewModel="@id('vm') @init('info.bukova.isspst.ui.mail.MailForm')" width="500px"
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<label value="${labels.MailFor}"/> <textbox value="@bind(vm.to)" width="100%"/>
|
||||
<label value="${labels.MailFor}"/> <textbox value="@bind(vm.to)" width="100%" droppable="true" onDrop="@command('addTo')"/>
|
||||
</row>
|
||||
<row>
|
||||
<label value="${labels.MailCc}"/> <textbox value="@bind(vm.cc)" width="100%" droppable="true" onDrop="@command('addCc')"/>
|
||||
</row>
|
||||
<row>
|
||||
<label value="${labels.MailBcc}"/> <textbox value="@bind(vm.bcc)" width="100%" droppable="true" onDrop="@command('addBcc')"/>
|
||||
</row>
|
||||
<row>
|
||||
<label value="${labels.MailSubject }"/> <textbox value="@bind(vm.message.subject)" width="100%"/>
|
||||
@@ -22,10 +71,12 @@ viewModel="@id('vm') @init('info.bukova.isspst.ui.mail.MailForm')" width="500px"
|
||||
</rows>
|
||||
</grid>
|
||||
<vbox>
|
||||
<ckeditor width="470px" height="200px" value="@bind(vm.message.text)" toolbar="Basic"/>
|
||||
<ckeditor width="540px" height="250px" value="@bind(vm.message.text)" toolbar="Basic"/>
|
||||
<hbox>
|
||||
<button label="${labels.MailSend}" onClick="@command('send', window=mailWin)"/> <button label="${labels.ButtonStorno}" onClick="mailWin.detach()"/>
|
||||
<button label="${labels.MailSend}" onClick="@command('send', window=mailWin)" disabled="@load(empty vm.to)" sclass="nicebutton"/> <button label="${labels.ButtonStorno}" onClick="mailWin.detach()" sclass="nicebutton"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</window>
|
||||
</zk>
|
||||
Reference in New Issue
Block a user