# HG changeset patch # User Tomas Zeman # Date 1335901236 -7200 # Node ID 3ef84ec492faae6232ea40ae15de0de6e9f6ef21 # Parent 43674362ff5e599920063eb101cd40d0a654b8f2 Project - company relation diff -r 43674362ff5e -r 3ef84ec492fa db/db-schema.sql --- a/db/db-schema.sql Fri Apr 27 16:18:28 2012 +0200 +++ b/db/db-schema.sql Tue May 01 21:40:36 2012 +0200 @@ -201,6 +201,10 @@ "updated_by" bigint ); create sequence "comment_id_seq"; +create table "project_company" ( + "project" bigint not null, + "company" bigint not null + ); -- foreign key constraints : alter table "address" add constraint "addressFK1" foreign key ("city_id") references "city"("id"); alter table "city" add constraint "cityFK2" foreign key ("country_id") references "country"("id"); @@ -220,8 +224,11 @@ alter table "company_contact" add constraint "company_contactFK8" foreign key ("contact") references "contact"("id") on delete cascade; alter table "user_contact" add constraint "user_contactFK9" foreign key ("entity") references "user"("id") on delete cascade; alter table "user_contact" add constraint "user_contactFK10" foreign key ("contact") references "contact"("id") on delete cascade; +alter table "project_company" add constraint "project_companyFK19" foreign key ("project") references "project"("id") on delete cascade; +alter table "project_company" add constraint "project_companyFK20" foreign key ("company") references "company"("id") on delete cascade; -- composite key indexes : alter table "company_contact" add constraint "company_contactCPK" unique("entity","contact"); alter table "user_contact" add constraint "user_contactCPK" unique("entity","contact"); +alter table "project_company" add constraint "project_companyCPK" unique("project","company"); -- column group indexes : create index "user_deleted_active_idx" on "user" ("deleted","active"); diff -r 43674362ff5e -r 3ef84ec492fa src/main/scala/fis/crm/ui/CompanySnippet.scala --- a/src/main/scala/fis/crm/ui/CompanySnippet.scala Fri Apr 27 16:18:28 2012 +0200 +++ b/src/main/scala/fis/crm/ui/CompanySnippet.scala Tue May 01 21:40:36 2012 +0200 @@ -19,6 +19,8 @@ import fis.base.ui._ import fis.crm.model._ import fis.geo.model._ +import fis.pm.model.CompanyProjects +import fis.pm.ui.ProjectTable import net.liftweb.common._ import net.liftweb.http._ import net.liftweb.http.js.JsCmds.RedirectTo @@ -44,7 +46,8 @@ private val viewPre = Menu.param[Company]("company.view", l10n("Company"), parse, encode) / prefix / * >> Title(c => i18n("Company %s", c.linkName)) >> locTpl("company/view") >> Snippet("panel", panel) >> - Snippet("contacts", contacts.contacts) >> Hidden + Snippet("contacts", contacts.contacts) >> + Snippet("projects", projects) >> Hidden private val editPre = Menu.param[Company]("company.edit", l10n("Edit"), parse, encode) / prefix / * / EDIT >> @@ -77,6 +80,9 @@ private def panel: CssTr = "*" #> cur.map(CompanyPanel(_)) + private def projects: CssTr = "*" #> cur.map { c => + ProjectTable(CompanyProjects(c)) } + object url { def view: Company => Box[String] = (viewLoc.calcHref _) andThen (Box !! _) } diff -r 43674362ff5e -r 3ef84ec492fa src/main/scala/fis/pm/model/PmSchema.scala --- a/src/main/scala/fis/pm/model/PmSchema.scala Fri Apr 27 16:18:28 2012 +0200 +++ b/src/main/scala/fis/pm/model/PmSchema.scala Tue May 01 21:40:36 2012 +0200 @@ -63,6 +63,15 @@ val commentTask = oneToManyRelation(taskT, commentT). via((t, c) => (t.id === c.task)) commentTask.foreignKeyDeclaration.constrainReference(onDelete cascade) + + /* project - company */ + val projectCompany = manyToManyRelation(projectT, companyT). + via[ProjectCompany]((p, c, pc) => ( + p.id === pc.project, + c.id === pc.company + )) + projectCompany.leftForeignKeyDeclaration.constrainReference(onDelete cascade) + projectCompany.rightForeignKeyDeclaration.constrainReference(onDelete cascade) } object PmSchema extends PmSchema @@ -77,4 +86,20 @@ from(PmSchema.commentTask.left(t))(c => select(c) orderBy(c.createdAt asc)) } +object CompanyProjects { + import fis.crm.model.Company + def apply(c: Company): Iterable[Project] = + from(PmSchema.projectCompany.right(c))(p => select(p) orderBy(p.name asc)) +} + +/* Many-to-many relations */ + +import org.squeryl.KeyedEntity +import org.squeryl.dsl._ + +case class ProjectCompany(val project: Long, val company: Long) + extends KeyedEntity[CompositeKey2[Long, Long]] { + def id = CompositeKey2(project, company) +} + // vim: set ts=2 sw=2 et: diff -r 43674362ff5e -r 3ef84ec492fa src/main/scala/fis/pm/ui/ProjectSnippet.scala --- a/src/main/scala/fis/pm/ui/ProjectSnippet.scala Fri Apr 27 16:18:28 2012 +0200 +++ b/src/main/scala/fis/pm/ui/ProjectSnippet.scala Tue May 01 21:40:36 2012 +0200 @@ -16,9 +16,11 @@ package fis.pm.ui import fis.base.ui._ +import fis.crm.model._ import fis.pm.model._ import net.liftweb.common._ import net.liftweb.http._ +import net.liftweb.record.field._ import net.liftweb.sitemap._ import net.liftweb.sitemap.Loc._ import net.liftweb.util._ @@ -85,36 +87,53 @@ def view: Project => Box[String] = (viewLoc.calcHref _) andThen (Box !! _) } - private def fields(p: Project) = List(p.name, p.identS, p.stateFld, p.createdBy, - p.createdAt, p.deadline, p.responsible, p.productLine, p.description, p.note) - - private def formFields(p: Project) = List(p.name, p.identS, p.stateFld, - p.deadline, p.responsible, p.productLine, p.description, p.note) - - private object ProjectTable extends FieldTable[Project] { - def fields(p: Project) = EntityLink(p) ++ Seq(p.identS, p.deadline, - p.responsible, p.description, p.note) - def apply(l: Iterable[Project]) = build(Project, l) - } + private def fields(p: Project) = List(p.name, p.identS, p.stateFld, + p.createdBy, p.createdAt, p.deadline, p.responsible, p.productLine, + ProjectCompanyField(p), p.description, p.note) private case class ProjectLink(c: Project) extends EntityLink[Project](c, url.view) EntityLink.register[Project](ProjectLink(_)) - private object form extends HorizontalScreen with CancelButton with SaveButton { + private case class ProjectCompanyField(p: Project) extends OptionalLongField(p) + with CompanyField with FieldLabel { + override def name = "company" + override def defaultValueBox = + PmSchema.projectCompany.left(p).headOption.map(_.id) + } + + private object form extends HorizontalScreen with CancelButton with + SaveButton { private object project extends ScreenVar[Project](Project.createRecord) + private object company extends ScreenVar[CompanyField]( + ProjectCompanyField(project)) + + private def formFields(p: Project) = { + List(p.name, p.identS, p.stateFld, p.deadline, p.responsible, + p.productLine, company.get, p.description, p.note) + } override def screenFields: List[BaseField] = formFields(project) override def localSetup() { - cur.foreach(project(_)) + cur.foreach { p => project(p); company(ProjectCompanyField(p)) } } - def finish() { save(project) foreach { v => - S notice l10n("Project %s saved.", v.linkName) - S.redirectTo(viewLoc.calcHref(v)) - }} + def finish() { + save(project) foreach { p => + val fk = PmSchema.projectCompany.left(p) + company.vend match { + case Full(c) if fk.exists(_.id == c.id) => // empty, no update + case Full(c) => + fk.dissociateAll + fk.associate(c) + case _ => fk.dissociateAll + } + S notice l10n("Project %s saved.", p.linkName) + S.redirectTo(viewLoc.calcHref(p)) + } + } } private object deleteF extends HorizontalScreen with CancelButton with diff -r 43674362ff5e -r 3ef84ec492fa src/main/scala/fis/pm/ui/ProjectTable.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/fis/pm/ui/ProjectTable.scala Tue May 01 21:40:36 2012 +0200 @@ -0,0 +1,29 @@ +/* + * Copyright 2012 Tomas Zeman + * + * 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.pm.ui + +import fis.pm.model._ +import fis.base.ui._ + +object ProjectTable extends FieldTable[Project] { + def fields(p: Project) = EntityLink(p) ++ Seq(p.identS, p.deadline, + p.responsible, p.description, p.note) + def apply(l: Iterable[Project]) = build(Project, l) +} + + + +// vim: set ts=2 sw=2 et: diff -r 43674362ff5e -r 3ef84ec492fa src/main/webapp/company/view.html --- a/src/main/webapp/company/view.html Fri Apr 27 16:18:28 2012 +0200 +++ b/src/main/webapp/company/view.html Tue May 01 21:40:36 2012 +0200 @@ -17,6 +17,12 @@ +
+
+

+ +
+
diff -r 43674362ff5e -r 3ef84ec492fa src/main/webapp/templates-hidden/_resources.html --- a/src/main/webapp/templates-hidden/_resources.html Fri Apr 27 16:18:28 2012 +0200 +++ b/src/main/webapp/templates-hidden/_resources.html Tue May 01 21:40:36 2012 +0200 @@ -190,6 +190,7 @@ Really delete this project? Project %s deleted. --> + Projects Name Note @@ -200,6 +201,7 @@ Responsible State Tasks + Company Assigned Paused diff -r 43674362ff5e -r 3ef84ec492fa src/main/webapp/templates-hidden/_resources_cs.html --- a/src/main/webapp/templates-hidden/_resources_cs.html Fri Apr 27 16:18:28 2012 +0200 +++ b/src/main/webapp/templates-hidden/_resources_cs.html Tue May 01 21:40:36 2012 +0200 @@ -190,6 +190,7 @@ Odpovědný Stav Úkoly + Společnost Přidělen Pozastaven