# HG changeset patch # User Tomas Zeman # Date 1335292318 -7200 # Node ID 25392159b6caa45c36fa8e4f9ecd5666684cbc23 # Parent 7af1b58877596adb5b154dd52065cb1fa83ff1b7 Project diff -r 7af1b5887759 -r 25392159b6ca db/db-data.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/db/db-data.sql Tue Apr 24 20:31:58 2012 +0200 @@ -0,0 +1,37 @@ +-- Project states +INSERT INTO code_list_item +(code_list, id, i18n, name, rank, dflt, i1, +i2, i3, l1, l2, l3, s1, s2, s3, created_at, updated_at, deleted) +VALUES +('project_state', nextval('code_list_item_id_seq'), true, 'project.state.assigned', 10, true, 0, +0, 0, 0, 0, 0, '', '', '', current_timestamp, current_timestamp, false); +INSERT INTO code_list_item +(code_list, id, i18n, name, rank, dflt, i1, +i2, i3, l1, l2, l3, s1, s2, s3, created_at, updated_at, deleted) +VALUES +('project_state', nextval('code_list_item_id_seq'), true, 'project.state.paused', 45, false, 0, +0, 0, 0, 0, 0, '', '', '', current_timestamp, current_timestamp, false); +INSERT INTO code_list_item +(code_list, id, i18n, name, rank, dflt, i1, +i2, i3, l1, l2, l3, s1, s2, s3, created_at, updated_at, deleted) +VALUES +('project_state', nextval('code_list_item_id_seq'), true, 'project.state.in_preparation', 20, false, 0, +0, 0, 0, 0, 0, '', '', '', current_timestamp, current_timestamp, false); +INSERT INTO code_list_item +(code_list, id, i18n, name, rank, dflt, i1, +i2, i3, l1, l2, l3, s1, s2, s3, created_at, updated_at, deleted) +VALUES +('project_state', nextval('code_list_item_id_seq'), true, 'project.state.in_realization', 30, false, 0, +0, 0, 0, 0, 0, '', '', '', current_timestamp, current_timestamp, false); +INSERT INTO code_list_item +(code_list, id, i18n, name, rank, dflt, i1, +i2, i3, l1, l2, l3, s1, s2, s3, created_at, updated_at, deleted) +VALUES +('project_state', nextval('code_list_item_id_seq'), true, 'project.state.cancelled', 50, false, 1, +0, 0, 0, 0, 0, '', '', '', current_timestamp, current_timestamp, false); +INSERT INTO code_list_item +(code_list, id, i18n, name, rank, dflt, i1, +i2, i3, l1, l2, l3, s1, s2, s3, created_at, updated_at, deleted) +VALUES +('project_state', nextval('code_list_item_id_seq'), true, 'project.state.realized', 40, false, 1, +0, 0, 0, 0, 0, '', '', '', current_timestamp, current_timestamp, false); diff -r 7af1b5887759 -r 25392159b6ca db/db-schema.sql --- a/db/db-schema.sql Tue Mar 06 14:07:55 2012 +0100 +++ b/db/db-schema.sql Tue Apr 24 20:31:58 2012 +0200 @@ -159,6 +159,22 @@ "contact" bigint not null, "entity" bigint not null ); +create table "project" ( + "name" varchar(100) not null, + "updated_at" timestamp not null, + "id" bigint primary key not null, + "description" varchar(40960) not null, + "responsible" bigint not null, + "deadline" timestamp not null, + "ident_s" varchar(256) not null, + "state" bigint not null, + "note" varchar(10240), + "product_line" bigint, + "created_at" timestamp not null, + "created_by" bigint, + "updated_by" bigint + ); +create sequence "project_id_seq"; -- 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"); @@ -166,6 +182,9 @@ alter table "company" add constraint "companyFK4" foreign key ("address_id") references "address"("id"); alter table "company" add constraint "companyFK5" foreign key ("post_adress_id") references "address"("id") on delete set null; alter table "bank_account" add constraint "bank_accountFK6" foreign key ("company_id") references "company"("id") on delete cascade; +alter table "project" add constraint "projectFK11" foreign key ("responsible") references "user"("id"); +alter table "project" add constraint "projectFK12" foreign key ("product_line") references "code_list_item"("id") on delete set null; +alter table "project" add constraint "projectFK13" foreign key ("state") references "code_list_item"("id"); alter table "company_contact" add constraint "company_contactFK7" foreign key ("entity") references "company"("id") on delete cascade; 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; diff -r 7af1b5887759 -r 25392159b6ca src/main/scala/bootstrap/liftweb/Boot.scala --- a/src/main/scala/bootstrap/liftweb/Boot.scala Tue Mar 06 14:07:55 2012 +0100 +++ b/src/main/scala/bootstrap/liftweb/Boot.scala Tue Apr 24 20:31:58 2012 +0200 @@ -21,6 +21,7 @@ import fis.aaa.ui._ import fis.crm.ui._ import fis.geo.ui._ +import fis.pm.ui._ import fis.db.SquerylTxMgr import net.datatables.DataTables import net.liftweb.common._ @@ -58,7 +59,9 @@ AuthnSnippet.menu, CountrySnippet.menu, LocationSnippet.menu, - CitySnippet.menu) + CitySnippet.menu, + ProjectSnippet.menu + ) LiftRules.setSiteMap(SiteMap(menus:_*)) diff -r 7af1b5887759 -r 25392159b6ca src/main/scala/fis/pm/model/PmSchema.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/fis/pm/model/PmSchema.scala Tue Apr 24 20:31:58 2012 +0200 @@ -0,0 +1,45 @@ +/* + * 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.model + +import fis.aaa.model.AaaSchema +import fis.base.model.{BaseSchema, Entity} +import fis.cl.model.CodeListSchema +import net.liftweb.squerylrecord.RecordTypeMode._ + +trait PmSchema extends BaseSchema with AaaSchema with CodeListSchema { + + val projectT = tableWithSeq[Project] + + val projectResponsible = oneToManyRelation(userT, projectT). + via((u, p) => (u.id === p.responsible)) + + val projectProductLine = oneToManyRelation(cli, projectT). + via((i, p) => (i.id === p.productLine)) + projectProductLine.foreignKeyDeclaration.constrainReference(onDelete setNull) + + val projectState = oneToManyRelation(cli, projectT). + via((i, p) => (i.id === p.stateFld)) + + Project.users.default.set(activeUsersF) + + def projects: Iterable[Project] = from(projectT)(p => + select(p) orderBy(p.name asc)) +} + +object PmSchema extends PmSchema + +// vim: set ts=2 sw=2 et: diff -r 7af1b5887759 -r 25392159b6ca src/main/scala/fis/pm/model/Project.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/fis/pm/model/Project.scala Tue Apr 24 20:31:58 2012 +0200 @@ -0,0 +1,56 @@ +/* + * 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.model + +import fis.aaa.model._ +import fis.base.model.Entity +import fis.cl.model._ +import net.liftweb.common._ +import net.liftweb.record.{MetaRecord, Record} +import net.liftweb.record.field._ +import net.liftweb.util._ +import net.tz.lift.model._ +import net.tz.lift.model.{FieldLabel => FL} +import org.squeryl.annotations.Column + +class Project private() extends Record[Project] with Entity[Project] { + def meta = Project + + val description = new TextareaField(this, 40960) with FL + val identS = new StringField(this, 256) with FL + val deadline = new JodaDateMidnightField(this) with FL + val productLine = new OptionalCodeListItemField(this, 'product_line) with FL + val responsible = new UserField(this, meta.users, getUserVendor) with + DefaultCurUser with FL + + @Column("state") + protected[pm] val stateFld = new CodeListItemField(this, 'project_state) + with FL + + def state = stateFld.item.map { ProjectState(_) } +} + +object Project extends Project with MetaRecord[Project] with SimpleInjector { + object users extends Inject[Iterable[User]](() => Nil) +} + +case class ProjectState(id: Long, k: String, closed: Boolean) +object ProjectState { + def apply(i: CodeListItem): ProjectState = + ProjectState(i.id, i.name.get, i.i1.get == 1) +} + +// vim: set ts=2 sw=2 et: diff -r 7af1b5887759 -r 25392159b6ca src/main/scala/fis/pm/model/ProjectCrud.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/fis/pm/model/ProjectCrud.scala Tue Apr 24 20:31:58 2012 +0200 @@ -0,0 +1,26 @@ +/* + * 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.model + +import fis.base.model.RecordCrud + +trait ProjectCrud extends RecordCrud[Project] { + val table = PmSchema.projectT +} + +object ProjectCrud extends ProjectCrud + +// vim: set ts=2 sw=2 et: diff -r 7af1b5887759 -r 25392159b6ca src/main/scala/fis/pm/ui/ProjectSnippet.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/fis/pm/ui/ProjectSnippet.scala Tue Apr 24 20:31:58 2012 +0200 @@ -0,0 +1,129 @@ +/* + * 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.base.ui._ +import fis.pm.model._ +import net.liftweb.common._ +import net.liftweb.http._ +import net.liftweb.sitemap._ +import net.liftweb.sitemap.Loc._ +import net.liftweb.util._ +import net.liftweb.util.Helpers._ +import net.tz.lift.model._ +import net.tz.lift.snippet._ +import scala.xml.{Elem, NodeSeq, Text} + +object ProjectSnippet extends ProjectCrud with EntitySnippet[Project] { + val prefix = "project" + + private val listPre = Menu("project.list", l10n("Projects")) / prefix >> + Title(_ => i18n("Projects")) >> + locTpl("entity/list") >> Snippet("list", list) + + private val createPre = Menu("project.create", l10n("Create")) / prefix / ADD >> + Title(_ => i18n("Create project")) >> + locTpl("entity/form") >> Snippet("form", form) >> Hidden + + private val viewPre = Menu.param[Project]("project.view", l10n("Project"), parse, + encode) / prefix / * >> Title(p => i18n("Project %s", p.linkName)) >> + locTpl("entity/view") >> Snippet("panel", panel) >> Hidden + + private val editPre = Menu.param[Project]("project.edit", l10n("Edit"), parse, + encode) / prefix / * / EDIT >> + Title(p => i18n("Edit project %s", p.linkName)) >> + locTpl("entity/form") >> Snippet("form", form) >> Hidden + + private val deletePre = Menu.param[Project]("project.delete", l10n("Delete"), + parse, encode) / prefix / * / DELETE >> + Title(p => i18n("Delete project %s", p.linkName)) >> + locTpl("entity/delete") >> Snippet("form", deleteF) >> Hidden + + private val listM = listPre >> SecNav(createPre).build + private val createM = createPre >> SecNav(listPre).build + private val viewM = viewPre >> (SecNav(editPre) + deletePre).build + private val editM = editPre >> SecNav(viewPre).build + private val deleteM = deletePre >> SecNav(viewPre).build + + private lazy val viewLoc = viewM.toLoc + private lazy val editLoc = editM.toLoc + private lazy val deleteLoc = deleteM.toLoc + + val menu = listM submenus(viewM, editM, createM, deleteM) + + private def cur = viewLoc.currentValue or editLoc.currentValue or + deleteLoc.currentValue + + private def list: CssTr = { _ => ProjectTable(PmSchema.projects) } + + private def panel: CssTr = "*" #> cur.map { c => ViewPanel(fields(c)) } + + object url { + 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 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 object project extends ScreenVar[Project](Project.createRecord) + + override def screenFields: List[BaseField] = formFields(project) + + override def localSetup() { + cur.foreach(project(_)) + } + + def finish() { save(project) foreach { v => + S notice l10n("Project %s saved.", v.linkName) + S.redirectTo(viewLoc.calcHref(v)) + }} + } + + private object deleteF extends HorizontalScreen with CancelButton with + DeleteButton { + + val confirm = field(l10n("Really delete this project?"), false) + + def finish() { + for { + c <- deleteLoc.currentValue if confirm + r <- delete(c) + n <- r.box(c.linkName) + } { + S notice l10n("Project %s deleted.", n) + S redirectTo listM.loc.calcDefaultHref + } + } + } + +} + +// vim: set ts=2 sw=2 et: diff -r 7af1b5887759 -r 25392159b6ca src/main/scala/fis/top/model/FisDbSchema.scala --- a/src/main/scala/fis/top/model/FisDbSchema.scala Tue Mar 06 14:07:55 2012 +0100 +++ b/src/main/scala/fis/top/model/FisDbSchema.scala Tue Apr 24 20:31:58 2012 +0200 @@ -1,5 +1,5 @@ /* - * Copyright 2011 Tomas Zeman + * Copyright 2011-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. @@ -20,12 +20,14 @@ import fis.cl.model.CodeListSchema import fis.crm.model.CrmSchema import fis.geo.model.GeoSchema +import fis.pm.model.PmSchema trait FisDbSchema extends BaseSchema with CodeListSchema with AaaSchema with CrmSchema with GeoSchema + with PmSchema object FisDbSchema extends FisDbSchema diff -r 7af1b5887759 -r 25392159b6ca src/main/webapp/templates-hidden/_resources.html --- a/src/main/webapp/templates-hidden/_resources.html Tue Mar 06 14:07:55 2012 +0100 +++ b/src/main/webapp/templates-hidden/_resources.html Tue Apr 24 20:31:58 2012 +0200 @@ -9,6 +9,10 @@ Add Name GPS + Created at + Created by + Updated at + Updated by + + Name + Note + Description + Identifier + Deadline + Product line + Responsible + State + + Assigned + Paused + In preparation + In realization + Cancelled + Realized + + diff -r 7af1b5887759 -r 25392159b6ca src/main/webapp/templates-hidden/_resources_cs.html --- a/src/main/webapp/templates-hidden/_resources_cs.html Tue Mar 06 14:07:55 2012 +0100 +++ b/src/main/webapp/templates-hidden/_resources_cs.html Tue Apr 24 20:31:58 2012 +0200 @@ -11,6 +11,10 @@ GPS Odebrat Typ + Vytvořeno + Vytvořil + Aktualizováno + Aktualizoval @@ -166,6 +170,34 @@ Adresa + + Projekt + Projekty + Vytvořit projekt + Projekt %s + Upravit projekt %s + Smazat projekt %s + Projekt %s uložen. + Skutečně smazat projekt? + Projekt %s smazán. + + Název + Poznámka + Popis + Identifikátor + Termín + Produktová řada + Odpovědný + Stav + + Přidělen + Pozastaven + V přípravě + V realizaci + Stornován + Realizován + +