package org.osbp.mysmartshop.dtos;

import java.beans.PropertyChangeListener;
import java.io.Serializable;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import javax.validation.Valid;
import org.eclipse.osbp.dsl.common.datatypes.IDto;
import org.eclipse.osbp.runtime.common.annotations.Dispose;
import org.eclipse.osbp.runtime.common.annotations.DomainKey;
import org.eclipse.osbp.runtime.common.annotations.DomainReference;
import org.eclipse.osbp.runtime.common.annotations.FilterDepth;
import org.osbp.mysmartshop.dtos.BaseIDDto;
import org.osbp.mysmartshop.dtos.CashSlipDto;

@SuppressWarnings("all")
public class McustomerDto extends BaseIDDto implements IDto, Serializable, PropertyChangeListener {
  private long account_num;
  
  private String lname;
  
  private String fname;
  
  private String mi;
  
  private String address1;
  
  private String address2;
  
  private String address3;
  
  private String address4;
  
  private String city;
  
  private String state_province;
  
  private String postal_code;
  
  private String country;
  
  private String phone1;
  
  private String phone2;
  
  @Valid
  private Date birthdate;
  
  private String marital_status;
  
  private String yearly_income;
  
  private String gender;
  
  private int total_children;
  
  private int num_children_at_home;
  
  private String education;
  
  private String date_accnt_opened;
  
  private String member_card;
  
  private String occupation;
  
  private String houseowner;
  
  private int num_cars_owned;
  
  @DomainKey
  private String fullname;
  
  private String test;
  
  @DomainReference
  @FilterDepth(depth = 0)
  private List<CashSlipDto> slips;
  
  private String foo;
  
  public McustomerDto() {
    installLazyCollections();
  }
  
  /**
   * Installs lazy collection resolving for entity {@link Mcustomer} to the dto {@link McustomerDto}.
   * 
   */
  protected void installLazyCollections() {
    super.installLazyCollections();
    slips = new org.eclipse.osbp.dsl.dto.lib.OppositeDtoList<>(
    				org.eclipse.osbp.dsl.dto.lib.MappingContext.getCurrent(),
    				CashSlipDto.class, "customer.id",
    				(java.util.function.Supplier<Object> & Serializable) () -> this.getId(), this);
  }
  
  /**
   * 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;
    }
    super.dispose();
  }
  
  /**
   * Returns the account_num property or <code>null</code> if not present.
   */
  public long getAccount_num() {
    return this.account_num;
  }
  
  /**
   * Sets the <code>account_num</code> property to this instance.
   * 
   * @param account_num - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setAccount_num(final long account_num) {
    firePropertyChange("account_num", this.account_num, this.account_num = account_num );
  }
  
  /**
   * Returns the lname property or <code>null</code> if not present.
   */
  public String getLname() {
    return this.lname;
  }
  
  /**
   * Sets the <code>lname</code> property to this instance.
   * 
   * @param lname - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setLname(final String lname) {
    firePropertyChange("lname", this.lname, this.lname = lname );
  }
  
  /**
   * Returns the fname property or <code>null</code> if not present.
   */
  public String getFname() {
    return this.fname;
  }
  
  /**
   * Sets the <code>fname</code> property to this instance.
   * 
   * @param fname - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setFname(final String fname) {
    firePropertyChange("fname", this.fname, this.fname = fname );
  }
  
  /**
   * Returns the mi property or <code>null</code> if not present.
   */
  public String getMi() {
    return this.mi;
  }
  
  /**
   * Sets the <code>mi</code> property to this instance.
   * 
   * @param mi - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setMi(final String mi) {
    firePropertyChange("mi", this.mi, this.mi = mi );
  }
  
  /**
   * Returns the address1 property or <code>null</code> if not present.
   */
  public String getAddress1() {
    return this.address1;
  }
  
  /**
   * Sets the <code>address1</code> property to this instance.
   * 
   * @param address1 - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setAddress1(final String address1) {
    firePropertyChange("address1", this.address1, this.address1 = address1 );
  }
  
  /**
   * Returns the address2 property or <code>null</code> if not present.
   */
  public String getAddress2() {
    return this.address2;
  }
  
  /**
   * Sets the <code>address2</code> property to this instance.
   * 
   * @param address2 - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setAddress2(final String address2) {
    firePropertyChange("address2", this.address2, this.address2 = address2 );
  }
  
  /**
   * Returns the address3 property or <code>null</code> if not present.
   */
  public String getAddress3() {
    return this.address3;
  }
  
  /**
   * Sets the <code>address3</code> property to this instance.
   * 
   * @param address3 - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setAddress3(final String address3) {
    firePropertyChange("address3", this.address3, this.address3 = address3 );
  }
  
  /**
   * Returns the address4 property or <code>null</code> if not present.
   */
  public String getAddress4() {
    return this.address4;
  }
  
  /**
   * Sets the <code>address4</code> property to this instance.
   * 
   * @param address4 - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setAddress4(final String address4) {
    firePropertyChange("address4", this.address4, this.address4 = address4 );
  }
  
  /**
   * Returns the city property or <code>null</code> if not present.
   */
  public String getCity() {
    return this.city;
  }
  
  /**
   * Sets the <code>city</code> property to this instance.
   * 
   * @param city - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setCity(final String city) {
    firePropertyChange("city", this.city, this.city = city );
  }
  
  /**
   * Returns the state_province property or <code>null</code> if not present.
   */
  public String getState_province() {
    return this.state_province;
  }
  
  /**
   * Sets the <code>state_province</code> property to this instance.
   * 
   * @param state_province - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setState_province(final String state_province) {
    firePropertyChange("state_province", this.state_province, this.state_province = state_province );
  }
  
  /**
   * Returns the postal_code property or <code>null</code> if not present.
   */
  public String getPostal_code() {
    return this.postal_code;
  }
  
  /**
   * Sets the <code>postal_code</code> property to this instance.
   * 
   * @param postal_code - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setPostal_code(final String postal_code) {
    firePropertyChange("postal_code", this.postal_code, this.postal_code = postal_code );
  }
  
  /**
   * Returns the country property or <code>null</code> if not present.
   */
  public String getCountry() {
    return this.country;
  }
  
  /**
   * Sets the <code>country</code> property to this instance.
   * 
   * @param country - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setCountry(final String country) {
    firePropertyChange("country", this.country, this.country = country );
  }
  
  /**
   * Returns the phone1 property or <code>null</code> if not present.
   */
  public String getPhone1() {
    return this.phone1;
  }
  
  /**
   * Sets the <code>phone1</code> property to this instance.
   * 
   * @param phone1 - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setPhone1(final String phone1) {
    firePropertyChange("phone1", this.phone1, this.phone1 = phone1 );
  }
  
  /**
   * Returns the phone2 property or <code>null</code> if not present.
   */
  public String getPhone2() {
    return this.phone2;
  }
  
  /**
   * Sets the <code>phone2</code> property to this instance.
   * 
   * @param phone2 - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setPhone2(final String phone2) {
    firePropertyChange("phone2", this.phone2, this.phone2 = phone2 );
  }
  
  /**
   * Returns the birthdate property or <code>null</code> if not present.
   */
  public Date getBirthdate() {
    return this.birthdate;
  }
  
  /**
   * Sets the <code>birthdate</code> property to this instance.
   * 
   * @param birthdate - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setBirthdate(final Date birthdate) {
    firePropertyChange("birthdate", this.birthdate, this.birthdate = birthdate );
  }
  
  /**
   * Returns the marital_status property or <code>null</code> if not present.
   */
  public String getMarital_status() {
    return this.marital_status;
  }
  
  /**
   * Sets the <code>marital_status</code> property to this instance.
   * 
   * @param marital_status - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setMarital_status(final String marital_status) {
    firePropertyChange("marital_status", this.marital_status, this.marital_status = marital_status );
  }
  
  /**
   * Returns the yearly_income property or <code>null</code> if not present.
   */
  public String getYearly_income() {
    return this.yearly_income;
  }
  
  /**
   * Sets the <code>yearly_income</code> property to this instance.
   * 
   * @param yearly_income - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setYearly_income(final String yearly_income) {
    firePropertyChange("yearly_income", this.yearly_income, this.yearly_income = yearly_income );
  }
  
  /**
   * Returns the gender property or <code>null</code> if not present.
   */
  public String getGender() {
    return this.gender;
  }
  
  /**
   * Sets the <code>gender</code> property to this instance.
   * 
   * @param gender - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setGender(final String gender) {
    firePropertyChange("gender", this.gender, this.gender = gender );
  }
  
  /**
   * Returns the total_children property or <code>null</code> if not present.
   */
  public int getTotal_children() {
    return this.total_children;
  }
  
  /**
   * Sets the <code>total_children</code> property to this instance.
   * 
   * @param total_children - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setTotal_children(final int total_children) {
    firePropertyChange("total_children", this.total_children, this.total_children = total_children );
  }
  
  /**
   * Returns the num_children_at_home property or <code>null</code> if not present.
   */
  public int getNum_children_at_home() {
    return this.num_children_at_home;
  }
  
  /**
   * Sets the <code>num_children_at_home</code> property to this instance.
   * 
   * @param num_children_at_home - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setNum_children_at_home(final int num_children_at_home) {
    firePropertyChange("num_children_at_home", this.num_children_at_home, this.num_children_at_home = num_children_at_home );
  }
  
  /**
   * Returns the education property or <code>null</code> if not present.
   */
  public String getEducation() {
    return this.education;
  }
  
  /**
   * Sets the <code>education</code> property to this instance.
   * 
   * @param education - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setEducation(final String education) {
    firePropertyChange("education", this.education, this.education = education );
  }
  
  /**
   * Returns the date_accnt_opened property or <code>null</code> if not present.
   */
  public String getDate_accnt_opened() {
    return this.date_accnt_opened;
  }
  
  /**
   * Sets the <code>date_accnt_opened</code> property to this instance.
   * 
   * @param date_accnt_opened - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setDate_accnt_opened(final String date_accnt_opened) {
    firePropertyChange("date_accnt_opened", this.date_accnt_opened, this.date_accnt_opened = date_accnt_opened );
  }
  
  /**
   * Returns the member_card property or <code>null</code> if not present.
   */
  public String getMember_card() {
    return this.member_card;
  }
  
  /**
   * Sets the <code>member_card</code> property to this instance.
   * 
   * @param member_card - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setMember_card(final String member_card) {
    firePropertyChange("member_card", this.member_card, this.member_card = member_card );
  }
  
  /**
   * Returns the occupation property or <code>null</code> if not present.
   */
  public String getOccupation() {
    return this.occupation;
  }
  
  /**
   * Sets the <code>occupation</code> property to this instance.
   * 
   * @param occupation - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setOccupation(final String occupation) {
    firePropertyChange("occupation", this.occupation, this.occupation = occupation );
  }
  
  /**
   * Returns the houseowner property or <code>null</code> if not present.
   */
  public String getHouseowner() {
    return this.houseowner;
  }
  
  /**
   * Sets the <code>houseowner</code> property to this instance.
   * 
   * @param houseowner - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setHouseowner(final String houseowner) {
    firePropertyChange("houseowner", this.houseowner, this.houseowner = houseowner );
  }
  
  /**
   * Returns the num_cars_owned property or <code>null</code> if not present.
   */
  public int getNum_cars_owned() {
    return this.num_cars_owned;
  }
  
  /**
   * Sets the <code>num_cars_owned</code> property to this instance.
   * 
   * @param num_cars_owned - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setNum_cars_owned(final int num_cars_owned) {
    firePropertyChange("num_cars_owned", this.num_cars_owned, this.num_cars_owned = num_cars_owned );
  }
  
  /**
   * Returns the fullname property or <code>null</code> if not present.
   */
  public String getFullname() {
    return this.fullname;
  }
  
  /**
   * Sets the <code>fullname</code> property to this instance.
   * 
   * @param fullname - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setFullname(final String fullname) {
    firePropertyChange("fullname", this.fullname, this.fullname = fullname );
  }
  
  /**
   * Returns the test property or <code>null</code> if not present.
   */
  public String getTest() {
    return this.test;
  }
  
  /**
   * Sets the <code>test</code> property to this instance.
   * 
   * @param test - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setTest(final String test) {
    firePropertyChange("test", this.test, this.test = test );
  }
  
  /**
   * Returns an unmodifiable list of slips.
   */
  public List<CashSlipDto> getSlips() {
    return Collections.unmodifiableList(internalGetSlips());
  }
  
  /**
   * Returns the list of <code>CashSlipDto</code>s thereby lazy initializing it. For internal use only!
   * 
   * @return list - the resulting list
   * 
   */
  public List<CashSlipDto> internalGetSlips() {
    if (this.slips == null) {
      this.slips = new java.util.ArrayList<CashSlipDto>();
    }
    return this.slips;
  }
  
  /**
   * Adds the given cashSlipDto to this object. <p>
   * Since the reference is a composition reference, the opposite reference <code>CashSlipDto#customer</code> of the <code>cashSlipDto</code> will be handled automatically and no further coding is required to keep them in sync.<p>
   * See {@link CashSlipDto#setCustomer(CashSlipDto)}.
   * 
   * @param cashSlipDto - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void addToSlips(final CashSlipDto cashSlipDto) {
    checkDisposed();
    
    cashSlipDto.setCustomer(this);
  }
  
  /**
   * Removes the given cashSlipDto from this object. <p>
   * 
   * @param cashSlipDto - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void removeFromSlips(final CashSlipDto cashSlipDto) {
    checkDisposed();
    
    cashSlipDto.setCustomer(null);
  }
  
  /**
   * For internal use only!
   */
  public void internalAddToSlips(final CashSlipDto cashSlipDto) {
    
    if(!org.eclipse.osbp.dsl.dto.lib.MappingContext.isMappingMode()) {
    		List<CashSlipDto> oldList = null;
    		if(internalGetSlips() instanceof org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) {
    			oldList = ((org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) internalGetSlips()).copy();
    		} else {
    			oldList = new java.util.ArrayList<>(internalGetSlips());
    		}
    		internalGetSlips().add(cashSlipDto);
    		firePropertyChange("slips", oldList, internalGetSlips());
    }
  }
  
  /**
   * For internal use only!
   */
  public void internalRemoveFromSlips(final CashSlipDto cashSlipDto) {
    if(!org.eclipse.osbp.dsl.dto.lib.MappingContext.isMappingMode()) {
    	List<CashSlipDto> oldList = null;
    	if(internalGetSlips() instanceof org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) {
    		oldList = ((org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) internalGetSlips()).copy();
    	} else {
    		oldList = new java.util.ArrayList<>(internalGetSlips());
    	}
    	internalGetSlips().remove(cashSlipDto);
    	firePropertyChange("slips", oldList, internalGetSlips());	
    }else{
    	// in mapping mode, we do NOT resolve any collection
    	internalGetSlips().remove(cashSlipDto);
    }
  }
  
  /**
   * Sets the <code>slips</code> property to this instance.
   * Since the reference has an opposite reference, the opposite <code>CashSlipDto#
   * customer</code> of the <code>slips</code> will be handled automatically and no 
   * further coding is required to keep them in sync.<p>
   * See {@link CashSlipDto#setCustomer(CashSlipDto)
   * 
   * @param slips - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setSlips(final List<CashSlipDto> slips) {
    checkDisposed();
    for (CashSlipDto dto : internalGetSlips().toArray(new CashSlipDto[this.slips.size()])) {
    	removeFromSlips(dto);
    }
    
    if(slips == null) {
    	return;
    }
    
    for (CashSlipDto dto : slips) {
    	addToSlips(dto);
    }
  }
  
  /**
   * Returns the foo property or <code>null</code> if not present.
   */
  public String getFoo() {
    return this.foo;
  }
  
  /**
   * Sets the <code>foo</code> property to this instance.
   * 
   * @param foo - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setFoo(final String foo) {
    firePropertyChange("foo", this.foo, this.foo = foo );
  }
  
  public void propertyChange(final java.beans.PropertyChangeEvent event) {
    Object source = event.getSource();
    
    // forward the event from embeddable beans to all listeners. So the parent of the embeddable
    // bean will become notified and its dirty state can be handled properly
    { 
    	super.propertyChange(event);
    }
  }
}
