# HG changeset patch # User Tomas Zeman # Date 1334903184 -7200 # Node ID b1dc0efd1303e49b72f79d43a07e87f078f1b482 # Parent f8f8cac057a79cbf214ffcef490f0f4de7c4ef06 Company UI diff -r f8f8cac057a7 -r b1dc0efd1303 db/db-schema.sql --- a/db/db-schema.sql Fri Apr 20 08:26:23 2012 +0200 +++ b/db/db-schema.sql Fri Apr 20 08:26:24 2012 +0200 @@ -142,7 +142,7 @@ 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"); alter table "company" add constraint "companyFK3" foreign key ("address_id") references "address"("id"); -alter table "company" add constraint "companyFK4" foreign key ("post_adress_id") references "address"("id"); +alter table "company" add constraint "companyFK4" foreign key ("post_adress_id") references "address"("id") on delete set null; alter table "bank_account" add constraint "bank_accountFK5" foreign key ("company_id") references "company"("id") on delete cascade; -- column group indexes : create index "user_deleted_active_idx" on "user" ("deleted","active"); diff -r f8f8cac057a7 -r b1dc0efd1303 src/main/scala/bootstrap/liftweb/Boot.scala --- a/src/main/scala/bootstrap/liftweb/Boot.scala Fri Apr 20 08:26:23 2012 +0200 +++ b/src/main/scala/bootstrap/liftweb/Boot.scala Fri Apr 20 08:26:24 2012 +0200 @@ -18,7 +18,7 @@ import fis.base.model._ import fis.base.ui._ import fis.aaa.ui.UserSnippet -import fis.crm.ui.ContactSnippet +import fis.crm.ui._ import fis.geo.ui.{CitySnippet, CountrySnippet} import fis.db.SquerylTxMgr import net.liftweb.common._ @@ -43,6 +43,7 @@ val menus = List(Menu("/", "FIS Main page") / "index" >> Hidden, Menu.i("Home") / "" , ContactSnippet.menu, + CompanySnippet.menu, UserSnippet.menu, CountrySnippet.menu, CitySnippet.menu) diff -r f8f8cac057a7 -r b1dc0efd1303 src/main/scala/fis/base/ui/BootstrapScreen.scala --- a/src/main/scala/fis/base/ui/BootstrapScreen.scala Fri Apr 20 08:26:23 2012 +0200 +++ b/src/main/scala/fis/base/ui/BootstrapScreen.scala Fri Apr 20 08:26:24 2012 +0200 @@ -25,10 +25,13 @@ import net.liftweb.http.js.JsCmds._ import net.liftweb.util._ import net.liftweb.util.Helpers._ +import net.tz.lift.snippet._ import scala.xml._ trait BootstrapScreen extends ScreenWizardRendered { + protected def decorateLine(f: ScreenFieldInfo): CssTr = PassThru + protected override def renderAll(currentScreenNumber: Box[NodeSeq], screenCount: Box[NodeSeq], wizardTop: Box[Elem], @@ -99,9 +102,8 @@ } })) - maxNotice map { t => - (".control-group [class+]" #> t.lowerCaseTitle)(line) - } getOrElse line + val out = (".control-group [class+]" #> maxNotice.map(_.lowerCaseTitle))(line) + decorateLine(f)(out) } } diff -r f8f8cac057a7 -r b1dc0efd1303 src/main/scala/fis/crm/model/Company.scala --- a/src/main/scala/fis/crm/model/Company.scala Fri Apr 20 08:26:23 2012 +0200 +++ b/src/main/scala/fis/crm/model/Company.scala Fri Apr 20 08:26:24 2012 +0200 @@ -16,7 +16,7 @@ package fis.crm.model import fis.base.model.Entity -import fis.geo.model.Address +import fis.geo.model._ import net.liftweb.common._ import net.liftweb.record.{MetaRecord, Record} import net.liftweb.record.field._ @@ -32,9 +32,9 @@ val dic = new StringField(this, 40) with FL val pin = new IntField(this) with FL @Column(name="address_id") - val address = new LongField(this) with FL + val address = new LongField(this) with AddressField with FL @Column(name="post_adress_id") - val postAddress = new OptionalLongField(this) with FL + val postAddress = new OptionalLongField(this) with AddressField with FL } object Company extends Company with MetaRecord[Company] diff -r f8f8cac057a7 -r b1dc0efd1303 src/main/scala/fis/crm/model/CompanyCrud.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/fis/crm/model/CompanyCrud.scala Fri Apr 20 08:26:24 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.crm.model + +import fis.base.model.RecordCrud + +trait CompanyCrud extends RecordCrud[Company] { + val table = CrmSchema.companyT +} + +object CompanyCrud extends CompanyCrud + +// vim: set ts=2 sw=2 et: diff -r f8f8cac057a7 -r b1dc0efd1303 src/main/scala/fis/crm/model/CrmSchema.scala --- a/src/main/scala/fis/crm/model/CrmSchema.scala Fri Apr 20 08:26:23 2012 +0200 +++ b/src/main/scala/fis/crm/model/CrmSchema.scala Fri Apr 20 08:26:24 2012 +0200 @@ -47,12 +47,17 @@ 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) + + def allCompanies: Iterable[Company] = from(companyT) (c => + select(c) orderBy(c.name asc)) + } object CrmSchema extends CrmSchema diff -r f8f8cac057a7 -r b1dc0efd1303 src/main/scala/fis/crm/ui/CompanyPanel.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/fis/crm/ui/CompanyPanel.scala Fri Apr 20 08:26:24 2012 +0200 @@ -0,0 +1,31 @@ +/* + * 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.crm.ui + +import fis.crm.model._ +import fis.base.ui.ViewPanel +import net.liftweb.util.BaseField + +object CompanyPanel { + + def fields(c: Company): List[BaseField] = + List(c.name, c.ico, c.dic, c.address) ++ + c.postAddress.get.map{_ => c.postAddress} ++ Seq(c.note) + + def apply(c: Company) = ViewPanel(fields(c)) +} + +// vim: set ts=2 sw=2 et: diff -r f8f8cac057a7 -r b1dc0efd1303 src/main/scala/fis/crm/ui/CompanySnippet.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/fis/crm/ui/CompanySnippet.scala Fri Apr 20 08:26:24 2012 +0200 @@ -0,0 +1,172 @@ +/* + * 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.crm.ui + +import fis.base.ui._ +import fis.crm.model._ +import fis.geo.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 CompanySnippet extends CompanyCrud with EntitySnippet[Company] { + val prefix = "company" + + private val listPre = Menu("company.list", l10n("Companies")) / prefix >> + Title(_ => i18n("Companies")) >> + locTpl("entity/list") >> Snippet("list", list) + + private val createPre = Menu("company.create", l10n("Create")) / prefix / ADD >> + Title(_ => i18n("Create company")) >> + locTpl("company/form") >> Snippet("form", form) >> Hidden + + private val viewPre = Menu.param[Company]("company.view", l10n("Company"), parse, + encode) / prefix / * >> Title(c => i18n("Company %s", c.linkName)) >> + locTpl("entity/view") >> Snippet("panel", panel) >> Hidden + + private val editPre = Menu.param[Company]("company.edit", l10n("Edit"), parse, + encode) / prefix / * / EDIT >> + Title(c => i18n("Edit company %s", c.linkName)) >> + locTpl("company/form") >> Snippet("form", form) >> Hidden + + private val deletePre = Menu.param[Company]("company.delete", l10n("Delete"), + parse, encode) / prefix / * / DELETE >> + Title(c => i18n("Delete company %s", c.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 = { _ => CompanyTable(CrmSchema.allCompanies) } + + private def panel: CssTr = "*" #> cur.map(CompanyPanel(_)) + + object url { + def view: Company => Box[String] = (viewLoc.calcHref _) andThen (Box !! _) + } + + private case class CompanyLink(c: Company) extends EntityLink[Company](c, + url.view) + + EntityLink.register[Company](CompanyLink(_)) + + private object form extends HorizontalScreen with CancelButton with SaveButton { + + private object company extends ScreenVar[Company](Company.createRecord) + private object address extends ScreenVar[Address](Address.createRecord) + private object postAddress extends ScreenVar[Address](Address.createRecord) + + private val hasPostAddr = builder(Company.postAddress.displayName, false, + FormFieldId("has_post_address")). + help(i18n("Post address differs from company address")).make + + override def screenFields: List[BaseField] = + fields(company) flatMap(_.allFields) + + private def labelField(f: BaseField) = new Field { + type ValueType = String + def default = "" + override def name = f.name + override def displayName = f.displayName + override def toForm = Empty + override implicit def manifest = buildIt[String] + } + + private def fields(c: Company): List[FieldContainer] = { + List[FieldContainer](c.name, c.ico, c.dic, labelField(c.address)) ++ + address.formFields ++ + List[FieldContainer](hasPostAddr) ++ + postAddress.formFields.map { f => field(f, + FormFieldId(f.uniqueFieldId.map { "post_" + _} openOr nextFuncName)) } ++ + List(c.note) + } + + protected override def decorateLine(f: ScreenFieldInfo): CssTr = + f.field.uniqueFieldId.filter { _.startsWith("post_") } map { _ => + ".control-group [class+]" #> "post-address" } openOr PassThru + + override def localSetup() { cur.foreach { c => + company(c) + c.address.vend.foreach(address(_)) + c.postAddress.vend.foreach { a => + hasPostAddr.set(true) + postAddress(a) + } + }} + + def finish() { + hasPostAddr.get match { + case true => + company.postAddress(AddressCrud.save(postAddress).$(logF).map(_.id)) + case false => + val p = company.postAddress.vend + company.postAddress(Empty) + p.foreach { AddressCrud.delete _ } + } + AddressCrud.save(address).$(logF).foreach { a => + save(company.address(a.id)).$(logF).foreach { c => + S notice l10n("Company %s saved.", c.linkName) + S.redirectTo(viewLoc.calcHref(c)) + } + } + } + } + + private def logF[T]: Box[T] => Unit = _ match { + case Failure(m, _, _) => S error m + case _ => + } + + private object deleteF extends HorizontalScreen with CancelButton with + DeleteButton { + + val confirm = field(l10n("Really delete this company?"), false) + + def finish() { + for { + c <- deleteLoc.currentValue if confirm + r <- delete(c) + n <- r.box(c.linkName) + } { + c.address.vend.flatMap(AddressCrud.delete _) $ logF + c.postAddress.vend.flatMap(AddressCrud.delete _) $ logF + S notice l10n("Company %s deleted.", n) + S redirectTo listM.loc.calcDefaultHref + } + } + } + +} + +// vim: set ts=2 sw=2 et: diff -r f8f8cac057a7 -r b1dc0efd1303 src/main/scala/fis/crm/ui/CompanyTable.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/fis/crm/ui/CompanyTable.scala Fri Apr 20 08:26:24 2012 +0200 @@ -0,0 +1,27 @@ +/* + * 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.crm.ui + +import fis.crm.model._ +import fis.base.ui._ + +object CompanyTable extends FieldTable[Company] { + def fields(c: Company) = EntityLink(c) ++ Seq(c.ico, c.dic, c.note) + + def apply(l: Iterable[Company]) = build(Company, l) +} + +// vim: set ts=2 sw=2 et: diff -r f8f8cac057a7 -r b1dc0efd1303 src/main/scala/fis/geo/model/Address.scala --- a/src/main/scala/fis/geo/model/Address.scala Fri Apr 20 08:26:23 2012 +0200 +++ b/src/main/scala/fis/geo/model/Address.scala Fri Apr 20 08:26:24 2012 +0200 @@ -30,6 +30,8 @@ @Column(name="city_id") val city = new LongField(this) with CityField with FL val zipCode = new StringField(this, "") with FL + + def formFields = List(streetName, streetNum, zipCode, city) } object Address extends Address with MetaRecord[Address] diff -r f8f8cac057a7 -r b1dc0efd1303 src/main/webapp/company/form.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/webapp/company/form.html Fri Apr 20 08:26:24 2012 +0200 @@ -0,0 +1,29 @@ + + + + + Company form + + +
+ + + + +
+
+ +
+
+
+ + + + diff -r f8f8cac057a7 -r b1dc0efd1303 src/main/webapp/templates-hidden/_resources.html --- a/src/main/webapp/templates-hidden/_resources.html Fri Apr 20 08:26:23 2012 +0200 +++ b/src/main/webapp/templates-hidden/_resources.html Fri Apr 20 08:26:24 2012 +0200 @@ -98,6 +98,34 @@ Country + + + Name + Note + ICO + DIC + Pin + Address + Post address + + + + Street + No. + City + ZIP + diff -r f8f8cac057a7 -r b1dc0efd1303 src/main/webapp/templates-hidden/_resources_cs.html --- a/src/main/webapp/templates-hidden/_resources_cs.html Fri Apr 20 08:26:23 2012 +0200 +++ b/src/main/webapp/templates-hidden/_resources_cs.html Fri Apr 20 08:26:24 2012 +0200 @@ -95,6 +95,35 @@ Stát + + Společnosti + Vytvořit společnost + Společnost %s + Upravit společnost + Smazat společnost + Korespondenční adresa se liší od sídla společnosti + Společnost %s uložena. + Skutečně smazat společnost? + Společnost %s smazána. + + + Název + Poznámka + IČO + DIČ + Pin + Sídlo + Korespondenční adresa + + + + Ulice + Číslo (č.o./č.p.) + Obec + PSČ + + +