src/main/scala/fis/crm/model/CrmSchema.scala
author Tomas Zeman <tzeman@volny.cz>
Tue, 23 Apr 2013 10:36:04 +0200
changeset 108 ef4e3e0ef83f
parent 91 494b3b9db463
permissions -rw-r--r--
84a94fa29a67504b Task/Project notifications

/*
 * Copyright 2011-2012 Tomas Zeman <tzeman@volny.cz>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package fis.crm.model

import fis.base.model.{BaseSchema, Entity}
import fis.cl.model.CodeListSchema
import fis.geo.model.GeoSchema
import net.liftweb.squerylrecord.RecordTypeMode._

trait CrmSchema extends BaseSchema with CodeListSchema with GeoSchema {

  val contactT = tableWithSeq[Contact]

  def allContacts: Iterable[Contact] = from(contactT) (c =>
    select(c) orderBy(c.lastName asc, c.firstName asc)
  )

  /*
  val entityContacts = manyToManyRelation(entities, contacts).
    via[EntityContact]((e, c, ec) => (
      e.id === ec.entityId,
      c.id === ec.contactId
    ))

  entityContacts.leftForeignKeyDeclaration.unConstrainReference

  val contactTypeToEntityContacts = oneToManyRelation(codeListItems,
    entityContacts).via((cli, ec) => cli.id === ec.typeId)
  */

  val companyT = tableWithSeq[Company]

  val companyStatus = oneToManyRelation(cli, companyT).
    via((i, c) => i.id === c.status)

  val companyAddress = oneToManyRelation(addressT, companyT).
    via((a, c) => c.address === a.id)

  val companyPostAddress = oneToManyRelation(addressT, companyT).
    via((a, c) => c.postAddress === a.id)
  companyPostAddress.foreignKeyDeclaration.constrainReference(onDelete setNull)

  val bankAccountT = tableWithSeq[BankAccount]

  val companyBankAccounts = oneToManyRelation(companyT, bankAccountT).
    via((c, a) => c.id === a.company)
  companyBankAccounts.foreignKeyDeclaration.constrainReference(onDelete cascade)

  val companyContacts = manyToManyRelation(companyT, contactT).
    via[CompanyContact]((comp, cnt, cc) => (
      comp.id === cc.entity,
      cnt.id  === cc.contact
    ))
  companyContacts.leftForeignKeyDeclaration.constrainReference(onDelete cascade)
  companyContacts.rightForeignKeyDeclaration.constrainReference(onDelete cascade)
  ContactEntities.register(companyContacts)

  Company.companies.default.set { () => from(companyT)(c =>
    select(c) orderBy(c.name asc)) }

}

object CrmSchema extends CrmSchema

object CompanyContacts {
  def apply(company: Company): Iterable[Contact] =
    from(CrmSchema.companyContacts.left(company)) (c =>
      select(c) orderBy(c.lastName asc, c.firstName asc)
    )
}

import org.squeryl.KeyedEntity
import org.squeryl.dsl._

object ContactEntities {
  type T = ManyToManyRelation[Entity[_], Contact, _]

  import java.util.concurrent.{ConcurrentHashMap => CHash}
  import scala.collection.JavaConversions._
  private val rels = new CHash[String, T]

  def register[L <: Entity[_], A <: KeyedEntity[_]](
    rel: ManyToManyRelation[L, Contact, A])(implicit man:Manifest[L]) {
    rels.put(man.toString, rel.asInstanceOf[T])
  }

  def apply(c: Contact): Iterable[Entity[_]] = rels.values flatMap { _.right(c) }
}

trait EntityContact[T] extends KeyedEntity[CompositeKey2[Long, Long]] {
  def entity: Long
  def contact: Long
  def id = CompositeKey2(entity, contact)
}

case class CompanyContact(entity: Long, contact: Long) extends
  EntityContact[Company]

case class EntityContactWithType[T](val entityId: Long, val contactId: Long,
  val typeId: Long) extends KeyedEntity[CompositeKey3[Long, Long, Long]] {

  def id = CompositeKey3(entityId, contactId, typeId)
}

// vim: set ts=2 sw=2 et: