/**
 * Copyright (C) - Loetz GmbH&Co.KG, 69115 Heidelberg, Germany
 * 
 *  This source was created by OSBP Softwarefactory Wizard!
 * 
 *  OSBP is (C) - Loetz GmbH&Co.KG, 69115 Heidelberg, Germany
 * 
 * ================================================================
 * 
 *  @file           $HeadURL$
 *  @version        $Revision$
 *  @date           $Date$
 *  @author         $Author$
 */
package org.osbp.mysmartshop.entities;

import com.google.common.base.Objects;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.PreRemove;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.Valid;
import org.eclipse.osbp.dsl.common.datatypes.IEntity;
import org.eclipse.osbp.runtime.common.annotations.Dispose;
import org.eclipse.osbp.runtime.common.annotations.Properties;
import org.eclipse.osbp.runtime.common.annotations.Property;
import org.eclipse.persistence.annotations.Noncacheable;
import org.osbp.mysmartshop.entities.BaseUUID;
import org.osbp.mysmartshop.entities.CashPayment;
import org.osbp.mysmartshop.entities.CashPosition;
import org.osbp.mysmartshop.entities.CashRegister;
import org.osbp.mysmartshop.entities.Mcustomer;

@Entity
@Table(name = "CASH_SLIP", indexes = { @Index(name = "CURRENT_DAY_INDEX", columnList = "CURRENT_DAY"), @Index(name = "SERIAL_INDEX", columnList = "CURRENT_DAY, SERIAL") })
@SuppressWarnings("all")
public class CashSlip extends BaseUUID implements IEntity {
  @Column(name = "CURRENT_DAY")
  private String currentDay;
  
  @Column(name = "NOW")
  @Temporal(value = TemporalType.TIMESTAMP)
  @Valid
  private Date now;
  
  @Column(name = "CASHIER")
  private String cashier;
  
  @Column(name = "TOTAL")
  @Properties(properties = @Property(key = "decimalformat", value = "###,##0.00 &curren"))
  private Double total;
  
  @GeneratedValue
  @Column(name = "SERIAL")
  private long serial;
  
  @Column(name = "PAYED")
  private boolean payed;
  
  @JoinColumn(name = "POSITIONS_ID")
  @OneToMany(mappedBy = "slip", cascade = CascadeType.ALL, orphanRemoval = true)
  @Noncacheable
  private List<CashPosition> positions;
  
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "CUSTOMER_ID")
  private Mcustomer customer;
  
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "REGISTER_ID")
  private CashRegister register;
  
  @JoinColumn(name = "PAYMENTS_ID")
  @OneToMany(mappedBy = "slip", cascade = CascadeType.ALL, orphanRemoval = true)
  @Noncacheable
  private List<CashPayment> payments;
  
  /**
   * Checks whether the object is disposed.
   * @throws RuntimeException if the object is disposed.
   */
  private void checkDisposed() {
    if (isDisposed()) {
      throw new RuntimeException("Object already disposed: " + this);
    }
  }
  
  /**
   * Calling dispose will destroy that instance. The internal state will be 
   * set to 'disposed' and methods of that object must not be used anymore. 
   * Each call will result in runtime exceptions.<br>
   * If this object keeps composition containments, these will be disposed too. 
   * So the whole composition containment tree will be disposed on calling this method.
   */
  @Dispose
  public void dispose() {
    if (isDisposed()) {
      return;
    }
    try {
      // Dispose all the composition references.
      if (this.positions != null) {
        for (CashPosition cashPosition : this.positions) {
          cashPosition.dispose();
        }
        this.positions = null;
      }
      if (this.payments != null) {
        for (CashPayment cashPayment : this.payments) {
          cashPayment.dispose();
        }
        this.payments = null;
      }
      
    }
    finally {
      super.dispose();
    }
    
  }
  
  /**
   * @return Returns the currentDay property or <code>null</code> if not present.
   */
  public String getCurrentDay() {
    checkDisposed();
    return this.currentDay;
  }
  
  /**
   * Sets the currentDay property to this instance.
   */
  public void setCurrentDay(final String currentDay) {
    checkDisposed();
    this.currentDay = currentDay;
  }
  
  /**
   * @return Returns the now property or <code>null</code> if not present.
   */
  public Date getNow() {
    checkDisposed();
    return this.now;
  }
  
  /**
   * Sets the now property to this instance.
   */
  public void setNow(final Date now) {
    checkDisposed();
    this.now = now;
  }
  
  /**
   * @return Returns the cashier property or <code>null</code> if not present.
   */
  public String getCashier() {
    checkDisposed();
    return this.cashier;
  }
  
  /**
   * Sets the cashier property to this instance.
   */
  public void setCashier(final String cashier) {
    checkDisposed();
    this.cashier = cashier;
  }
  
  /**
   * @return Returns the total property or <code>null</code> if not present.
   */
  public Double getTotal() {
    checkDisposed();
    return this.total;
  }
  
  /**
   * Sets the total property to this instance.
   */
  public void setTotal(final Double total) {
    checkDisposed();
    this.total = total;
  }
  
  /**
   * @return Returns the serial property or <code>null</code> if not present.
   */
  public long getSerial() {
    checkDisposed();
    return this.serial;
  }
  
  /**
   * Sets the serial property to this instance.
   */
  public void setSerial(final long serial) {
    checkDisposed();
    this.serial = serial;
  }
  
  /**
   * @return Returns the payed property or <code>null</code> if not present.
   */
  public boolean getPayed() {
    checkDisposed();
    return this.payed;
  }
  
  /**
   * Sets the payed property to this instance.
   */
  public void setPayed(final boolean payed) {
    checkDisposed();
    this.payed = payed;
  }
  
  /**
   * @return Returns an unmodifiable list of positions.
   */
  public List<CashPosition> getPositions() {
    checkDisposed();
    return Collections.unmodifiableList(internalGetPositions());
  }
  
  /**
   * Sets the given positions to the object. Currently contained positions instances will be removed.
   * 
   * @param positions the list of new instances
   */
  public void setPositions(final List<CashPosition> positions) {
    // remove the old cashPosition
    for(CashPosition oldElement : new ArrayList<CashPosition>(this.internalGetPositions())){
      removeFromPositions(oldElement);
    }
    
    // add the new cashPosition
    for(CashPosition newElement : positions){
      addToPositions(newElement);
    }
  }
  
  /**
   * For internal use only! Returns the list of <code>CashPosition</code>s thereby lazy initializing it.
   */
  public List<CashPosition> internalGetPositions() {
    if (this.positions == null) {
      this.positions = new ArrayList<CashPosition>();
    }
    return this.positions;
  }
  
  /**
   * Adds the given cashPosition to this object. <p>
   * Since the reference is a composition reference, the opposite reference (CashPosition.slip)
   * of the cashPosition will be handled automatically and no further coding is required to keep them in sync. 
   * See {@link CashPosition#setSlip(CashPosition)}.
   * 
   */
  public void addToPositions(final CashPosition cashPosition) {
    checkDisposed();
    cashPosition.setSlip(this);
  }
  
  /**
   * Removes the given cashPosition from this object. <p>
   * Since the reference is a cascading reference, the opposite reference (CashPosition.slip)
   * of the cashPosition will be handled automatically and no further coding is required to keep them in sync. 
   * See {@link CashPosition#setSlip(CashPosition)}.
   * 
   */
  public void removeFromPositions(final CashPosition cashPosition) {
    checkDisposed();
    cashPosition.setSlip(null);
  }
  
  /**
   * For internal use only!
   */
  public void internalAddToPositions(final CashPosition cashPosition) {
    if(cashPosition == null) {
    	return;
    }
    
    if(!internalGetPositions().contains(cashPosition)) {
    	internalGetPositions().add(cashPosition);
    }
  }
  
  /**
   * For internal use only!
   */
  public void internalRemoveFromPositions(final CashPosition cashPosition) {
    internalGetPositions().remove(cashPosition);
  }
  
  /**
   * @return Returns the customer property or <code>null</code> if not present.
   */
  public Mcustomer getCustomer() {
    checkDisposed();
    return this.customer;
  }
  
  /**
   * Sets the customer property to this instance.
   * Since the reference is a container reference, the opposite reference (Mcustomer.slips)
   * of the customer will be handled automatically and no further coding is required to keep them in sync.
   * See {@link Mcustomer#setSlips(Mcustomer)}.
   */
  public void setCustomer(final Mcustomer customer) {
    checkDisposed();
    if (this.customer != null) {
      this.customer.internalRemoveFromSlips(this);
    }
    internalSetCustomer(customer);
    if (this.customer != null) {
      this.customer.internalAddToSlips(this);
    }
    
  }
  
  /**
   * For internal use only!
   */
  public void internalSetCustomer(final Mcustomer customer) {
    this.customer = customer;
  }
  
  /**
   * @return Returns the register property or <code>null</code> if not present.
   */
  public CashRegister getRegister() {
    checkDisposed();
    return this.register;
  }
  
  /**
   * Sets the register property to this instance.
   * Since the reference is a container reference, the opposite reference (CashRegister.slips)
   * of the register will be handled automatically and no further coding is required to keep them in sync.
   * See {@link CashRegister#setSlips(CashRegister)}.
   */
  public void setRegister(final CashRegister register) {
    checkDisposed();
    if (this.register != null) {
      this.register.internalRemoveFromSlips(this);
    }
    internalSetRegister(register);
    if (this.register != null) {
      this.register.internalAddToSlips(this);
    }
    
  }
  
  /**
   * For internal use only!
   */
  public void internalSetRegister(final CashRegister register) {
    this.register = register;
  }
  
  /**
   * @return Returns an unmodifiable list of payments.
   */
  public List<CashPayment> getPayments() {
    checkDisposed();
    return Collections.unmodifiableList(internalGetPayments());
  }
  
  /**
   * Sets the given payments to the object. Currently contained payments instances will be removed.
   * 
   * @param payments the list of new instances
   */
  public void setPayments(final List<CashPayment> payments) {
    // remove the old cashPayment
    for(CashPayment oldElement : new ArrayList<CashPayment>(this.internalGetPayments())){
      removeFromPayments(oldElement);
    }
    
    // add the new cashPayment
    for(CashPayment newElement : payments){
      addToPayments(newElement);
    }
  }
  
  /**
   * For internal use only! Returns the list of <code>CashPayment</code>s thereby lazy initializing it.
   */
  public List<CashPayment> internalGetPayments() {
    if (this.payments == null) {
      this.payments = new ArrayList<CashPayment>();
    }
    return this.payments;
  }
  
  /**
   * Adds the given cashPayment to this object. <p>
   * Since the reference is a composition reference, the opposite reference (CashPayment.slip)
   * of the cashPayment will be handled automatically and no further coding is required to keep them in sync. 
   * See {@link CashPayment#setSlip(CashPayment)}.
   * 
   */
  public void addToPayments(final CashPayment cashPayment) {
    checkDisposed();
    cashPayment.setSlip(this);
  }
  
  /**
   * Removes the given cashPayment from this object. <p>
   * Since the reference is a cascading reference, the opposite reference (CashPayment.slip)
   * of the cashPayment will be handled automatically and no further coding is required to keep them in sync. 
   * See {@link CashPayment#setSlip(CashPayment)}.
   * 
   */
  public void removeFromPayments(final CashPayment cashPayment) {
    checkDisposed();
    cashPayment.setSlip(null);
  }
  
  /**
   * For internal use only!
   */
  public void internalAddToPayments(final CashPayment cashPayment) {
    if(cashPayment == null) {
    	return;
    }
    
    if(!internalGetPayments().contains(cashPayment)) {
    	internalGetPayments().add(cashPayment);
    }
  }
  
  /**
   * For internal use only!
   */
  public void internalRemoveFromPayments(final CashPayment cashPayment) {
    internalGetPayments().remove(cashPayment);
  }
  
  public String when() {
    boolean _notEquals = (!Objects.equal(this.now, null));
    if (_notEquals) {
      return SimpleDateFormat.getDateInstance(DateFormat.SHORT).format(this.now);
    }
    return "";
  }
  
  /**
   * Iterates all cross references and removes them from the parent to avoid ConstraintViolationException
   */
  @PreRemove
  protected void preRemove() {
    
  }
}
