import java.text.DateFormat
import java.text.SimpleDateFormat
import javax.persistence.GeneratedValue
import ns org.osbp.mysmartshop.datatypes.Boolean
import ns org.osbp.mysmartshop.datatypes.Date
import ns org.osbp.mysmartshop.datatypes.PaymentMethod
import ns org.osbp.mysmartshop.datatypes.Price
import ns org.osbp.mysmartshop.datatypes.String
import ns org.osbp.mysmartshop.datatypes.Timestamp
import ns org.osbp.mysmartshop.datatypes.boolean
import ns org.osbp.mysmartshop.datatypes.double
import ns org.osbp.mysmartshop.datatypes.int
import ns org.osbp.mysmartshop.datatypes.long

/******************************************************************
 *                                                                *
 *  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 {

	mappedSuperclass BaseID {
		id int ^id
		version long version
	}

	mappedSuperclass BaseUUID {
		uuid String ^id
		version long version
	}

	entity Bar extends BaseUUID {
		var String fooxxx
	}

	entity DtoTestParent extends BaseUUID {

		var String string

		ref cascade DtoTestChildContainment[ * ]containmentChilds opposite container

		ref DtoTestChildCrossRef[ * ]crossRefChilds opposite container
		ref DtoTestChildCrossRef crossRefChild

		var DtoTestBean beanx
	}

	entity DtoTestChildContainment extends BaseUUID {
		ref DtoTestParent container opposite containmentChilds
	}

	entity DtoTestChildCrossRef extends BaseUUID {
		ref DtoTestParent container opposite crossRefChilds
	}

	bean DtoTestBean {
		var String foo
		ref DtoTestChildCrossRef crossRefChild
	}

	entity Mcustomer extends BaseID {
		var long account_num
		var String lname
		var String fname
		var String mi
		var String address1
		var String address2
		var String address3
		var String address4
		var String city
		var String state_province
		var String postal_code
		var String country
		var String phone1
		var String phone2
		var Date birthdate
		var String marital_status
		var String yearly_income
		var String gender
		var int total_children
		var int num_children_at_home
		var String education
		var String date_accnt_opened
		var String member_card
		var String occupation
		var String houseowner
		var int num_cars_owned
		domainKey String fullname
		var String test
		ref CashSlip[ * ]slips opposite customer

		derived String foo {
			return country + "_" + city
		}

	}

	cacheable entity CashRegister extends BaseUUID {
		domainKey String num
		var String ip
		var String location
		var String currentDay
		ref CashSlip[ * ]slips opposite register

		unique index cashIpIndex {
			ip
		}

		unique index cashNumIndex {
			num
		}

	}

	entity CashSlip extends BaseUUID {
		var String currentDay
		var Timestamp now
		var String cashier
		var Price total
		@ javax.persistence.GeneratedValue var long serial
		var boolean payed
		ref cascade CashPosition[ * ]positions opposite slip
		ref Mcustomer customer opposite slips
		ref CashRegister register opposite slips
		ref cascade CashPayment[ * ]payments opposite slip
		def String when( ) {
			if( now != null ) {
				return java.text.SimpleDateFormat.getDateInstance( java.text.DateFormat.SHORT ).format( now )
			}
			return ""
		}

		index currentDay_index {
			currentDay
		}

		index serial_index {
			currentDay, serial
		}

	}

	entity CashPosition extends BaseUUID {
		ref CashSlip slip opposite positions

		var Timestamp now
		var double quantity
		var Price price
		var Price amount
		
		ref cascade CashSubPosition[*] subPositions opposite parent
	}

	entity CashSubPosition extends BaseUUID {
		var double quantity
		var Price price
		ref CashPosition parent opposite subPositions
	}

	entity CashPayment extends BaseUUID {
		var Timestamp now
		var Price payed
		ref CashSlip slip opposite payments
		ref CashPaymentMethod methodOfPayment opposite payments
	}

	entity CashPaymentMethod extends BaseUUID {
		domainKey String num
		domainDescription String name
		var Boolean credit
		var PaymentMethod imageName
		var double lowerLimit
		ref CashPayment[ * ]payments opposite methodOfPayment

		unique index paymentNumIndex {
			num
		}

	}

	/** relation of the company to the owner - not the user - of this personal information manager */
	entity CompanyRelationType extends BaseUUID {
	/** short name for this relation type */
		domainKey String name
		/** more detailed description */
		var String description
	}

	/** a company group consisting of a group of companies, from one is defined as the main company */
	entity CompanyGroup extends BaseUUID {
	/** name of the company group */
		domainKey String name
		/** more detailed description with usable information for the PIM owner */
		var String description
		/** the main company */
		ref Company main_company
		/** group of companies */
		ref Company[ * ]companies opposite company_group
	}

	/** a company */
	entity Company extends BaseUUID {
	/** the company group if any */
		ref CompanyGroup company_group opposite companies
		/** name of the company */
		domainKey String name
		/** more detailed description with usable information for the PIM owner */
		var String description
		/** relation of the company to the PIM owner */
		ref CompanyRelationType relation_type
		/** any number of addresses */
		ref cascade Address[ * ]address opposite company
		/** departments of this company */
		ref cascade Department[ * ]departments opposite company
	}

	/** an address */
	entity Address extends BaseUUID {
	/** if address for a company, the company is given */
		ref Company company opposite address
		/** if address for a department, the address is given */
		ref Department department opposite address
		/** if address for a person, the person is given */
		//        ref cascade PostalAddress[*] postal_adresses opposite address
		/** address field 1 */
		var String address1
		/** address field 2 */
		var String address2
		/** city */
		var String city
		/** state province */
		var String state_province
		/** postal code */
		var String postal_code
		/** country */
		var String country
		//        ref cascade Email[*] emails opposite address
		/** email */
		var String email
		//        ref cascade Phone[*] phones opposite address
		/** landline (Festnetznummer) */
		var String landline
		/** mobile */
		var String mobile
	}

	/** a companies department */
	entity Department extends BaseUUID {
	/** the company */
		ref Company company opposite departments
		/** name of the department */
		domainKey String name
		/** more detailed description with usable information for the PIM owner */
		var String description
		/** any number of addresses */
		ref cascade Address[ * ]address opposite department
		/** any number of employees */
		var double default_yearly_income
	}

	entity Test extends BaseUUID {

	}

}