| author | Tomas Zeman <tzeman@volny.cz> |
| Thu, 24 May 2012 11:19:26 +0200 | |
| changeset 99 | 49eb72a46208 |
| parent 91 | 494b3b9db463 |
| permissions | -rw-r--r-- |
| 69 | 1 |
/* |
2 |
* Copyright 2012 Tomas Zeman <tzeman@volny.cz> |
|
3 |
* |
|
4 |
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
5 |
* you may not use this file except in compliance with the License. |
|
6 |
* You may obtain a copy of the License at |
|
7 |
* |
|
8 |
* http://www.apache.org/licenses/LICENSE-2.0 |
|
9 |
* |
|
10 |
* Unless required by applicable law or agreed to in writing, software |
|
11 |
* distributed under the License is distributed on an "AS IS" BASIS, |
|
12 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
13 |
* See the License for the specific language governing permissions and |
|
14 |
* limitations under the License. |
|
15 |
*/ |
|
16 |
package fis.crm.ui |
|
17 |
||
|
89
fd364bae9c49
Basic authorization: only logged in user can change entities
Tomas Zeman <tzeman@volny.cz>
parents:
85
diff
changeset
|
18 |
import fis.aaa.model.User |
|
fd364bae9c49
Basic authorization: only logged in user can change entities
Tomas Zeman <tzeman@volny.cz>
parents:
85
diff
changeset
|
19 |
import fis.aaa.ui.IfLoggedIn |
| 72 | 20 |
import fis.base.model._ |
| 69 | 21 |
import fis.base.ui._ |
22 |
import fis.crm.model._ |
|
23 |
import fis.geo.model._ |
|
| 85 | 24 |
import fis.pm.model.CompanyProjects |
25 |
import fis.pm.ui.ProjectTable |
|
| 99 | 26 |
import fis.sr.model.{CompanyServices, Service}
|
27 |
import fis.sr.ui.{ServiceForm, ServiceSnippet, ServiceTable}
|
|
| 69 | 28 |
import net.liftweb.common._ |
29 |
import net.liftweb.http._ |
|
| 72 | 30 |
import net.liftweb.http.js.JsCmds.RedirectTo |
| 69 | 31 |
import net.liftweb.sitemap._ |
32 |
import net.liftweb.sitemap.Loc._ |
|
33 |
import net.liftweb.util._ |
|
34 |
import net.liftweb.util.Helpers._ |
|
35 |
import net.tz.lift.model._ |
|
36 |
import net.tz.lift.snippet._ |
|
37 |
import scala.xml.{Elem, NodeSeq, Text}
|
|
38 |
||
39 |
object CompanySnippet extends CompanyCrud with EntitySnippet[Company] {
|
|
40 |
val prefix = "company" |
|
41 |
||
42 |
private val listPre = Menu("company.list", l10n("Companies")) / prefix >>
|
|
43 |
Title(_ => i18n("Companies")) >>
|
|
44 |
locTpl("entity/list") >> Snippet("list", list)
|
|
45 |
||
46 |
private val createPre = Menu("company.create", l10n("Create")) / prefix / ADD >>
|
|
|
89
fd364bae9c49
Basic authorization: only logged in user can change entities
Tomas Zeman <tzeman@volny.cz>
parents:
85
diff
changeset
|
47 |
Title(_ => i18n("Create company")) >> IfLoggedIn.test >>
|
| 69 | 48 |
locTpl("company/form") >> Snippet("form", form) >> Hidden
|
49 |
||
50 |
private val viewPre = Menu.param[Company]("company.view", l10n("Company"), parse,
|
|
51 |
encode) / prefix / * >> Title(c => i18n("Company %s", c.linkName)) >>
|
|
| 72 | 52 |
locTpl("company/view") >> Snippet("panel", panel) >>
|
| 99 | 53 |
Snippet("services", services) >> Snippet("contacts", contacts.contacts) >>
|
| 85 | 54 |
Snippet("projects", projects) >> Hidden
|
| 69 | 55 |
|
56 |
private val editPre = Menu.param[Company]("company.edit", l10n("Edit"), parse,
|
|
57 |
encode) / prefix / * / EDIT >> |
|
|
89
fd364bae9c49
Basic authorization: only logged in user can change entities
Tomas Zeman <tzeman@volny.cz>
parents:
85
diff
changeset
|
58 |
Title(c => i18n("Edit company %s", c.linkName)) >> IfLoggedIn.testVal >>
|
| 69 | 59 |
locTpl("company/form") >> Snippet("form", form) >> Hidden
|
60 |
||
61 |
private val deletePre = Menu.param[Company]("company.delete", l10n("Delete"),
|
|
62 |
parse, encode) / prefix / * / DELETE >> |
|
|
89
fd364bae9c49
Basic authorization: only logged in user can change entities
Tomas Zeman <tzeman@volny.cz>
parents:
85
diff
changeset
|
63 |
Title(c => i18n("Delete company %s", c.linkName)) >> IfLoggedIn.testVal >>
|
| 69 | 64 |
locTpl("entity/delete") >> Snippet("form", deleteF) >> Hidden
|
65 |
||
| 99 | 66 |
private val createServicePre = Menu.param[Company]("company.create-service",
|
67 |
l10n("Create service"), parse, encode) / prefix / * / "create-service" >>
|
|
68 |
Title(c => i18n("Create service for company %s", c.linkName)) >>
|
|
69 |
IfLoggedIn.testVal >> |
|
70 |
locTpl("entity/form") >> Snippet("form", createServiceForm) >> Hidden
|
|
71 |
||
| 69 | 72 |
private val listM = listPre >> SecNav(createPre).build |
73 |
private val createM = createPre >> SecNav(listPre).build |
|
| 72 | 74 |
private val viewM = viewPre >> |
| 99 | 75 |
(SecNav(editPre) + deletePre + createServicePre + contacts.chooseM).build |
| 69 | 76 |
private val editM = editPre >> SecNav(viewPre).build |
77 |
private val deleteM = deletePre >> SecNav(viewPre).build |
|
| 99 | 78 |
private val createServiceM = createServicePre >> SecNav(viewPre).build |
| 69 | 79 |
|
80 |
private lazy val viewLoc = viewM.toLoc |
|
81 |
private lazy val editLoc = editM.toLoc |
|
82 |
private lazy val deleteLoc = deleteM.toLoc |
|
83 |
||
| 99 | 84 |
val menu = listM submenus(viewM, editM, createM, deleteM, createServiceM, |
| 72 | 85 |
contacts.chooseM, contacts.confirmM) |
| 69 | 86 |
|
87 |
private def cur = viewLoc.currentValue or editLoc.currentValue or |
|
88 |
deleteLoc.currentValue |
|
89 |
||
| 84 | 90 |
private def list: CssTr = { _ => CompanyTable(Company.companies()) }
|
| 69 | 91 |
|
92 |
private def panel: CssTr = "*" #> cur.map(CompanyPanel(_)) |
|
93 |
||
| 85 | 94 |
private def projects: CssTr = "*" #> cur.map { c =>
|
95 |
ProjectTable(CompanyProjects(c)) } |
|
96 |
||
| 99 | 97 |
private def services: CssTr = "*" #> cur.map { c =>
|
98 |
ServiceTable(CompanyServices(c)) } |
|
99 |
||
| 69 | 100 |
object url {
|
101 |
def view: Company => Box[String] = (viewLoc.calcHref _) andThen (Box !! _) |
|
102 |
} |
|
103 |
||
104 |
private case class CompanyLink(c: Company) extends EntityLink[Company](c, |
|
105 |
url.view) |
|
106 |
||
107 |
EntityLink.register[Company](CompanyLink(_)) |
|
108 |
||
109 |
private object form extends HorizontalScreen with CancelButton with SaveButton {
|
|
110 |
||
111 |
private object company extends ScreenVar[Company](Company.createRecord) |
|
112 |
private object address extends ScreenVar[Address](Address.createRecord) |
|
113 |
private object postAddress extends ScreenVar[Address](Address.createRecord) |
|
114 |
||
115 |
private val hasPostAddr = builder(Company.postAddress.displayName, false, |
|
116 |
FormFieldId("has_post_address")).
|
|
117 |
help(i18n("Post address differs from company address")).make
|
|
118 |
||
119 |
override def screenFields: List[BaseField] = |
|
120 |
fields(company) flatMap(_.allFields) |
|
121 |
||
122 |
private def fields(c: Company): List[FieldContainer] = {
|
|
| 91 | 123 |
List[FieldContainer](c.name, c.ico, c.dic, c.status, |
| 72 | 124 |
ReadOnlyField.labelOnly(c.address)) ++ |
| 69 | 125 |
address.formFields ++ |
126 |
List[FieldContainer](hasPostAddr) ++ |
|
127 |
postAddress.formFields.map { f => field(f,
|
|
128 |
FormFieldId(f.uniqueFieldId.map { "post_" + _} openOr nextFuncName)) } ++
|
|
129 |
List(c.note) |
|
130 |
} |
|
131 |
||
132 |
protected override def decorateLine(f: ScreenFieldInfo): CssTr = |
|
133 |
f.field.uniqueFieldId.filter { _.startsWith("post_") } map { _ =>
|
|
134 |
".control-group [class+]" #> "post-address" } openOr PassThru |
|
135 |
||
136 |
override def localSetup() { cur.foreach { c =>
|
|
137 |
company(c) |
|
138 |
c.address.vend.foreach(address(_)) |
|
139 |
c.postAddress.vend.foreach { a =>
|
|
140 |
hasPostAddr.set(true) |
|
141 |
postAddress(a) |
|
142 |
} |
|
143 |
}} |
|
144 |
||
145 |
def finish() {
|
|
146 |
hasPostAddr.get match {
|
|
147 |
case true => |
|
148 |
company.postAddress(AddressCrud.save(postAddress).$(logF).map(_.id)) |
|
149 |
case false => |
|
150 |
val p = company.postAddress.vend |
|
151 |
company.postAddress(Empty) |
|
152 |
p.foreach { AddressCrud.delete _ }
|
|
153 |
} |
|
154 |
AddressCrud.save(address).$(logF).foreach { a =>
|
|
155 |
save(company.address(a.id)).$(logF).foreach { c =>
|
|
156 |
S notice l10n("Company %s saved.", c.linkName)
|
|
157 |
S.redirectTo(viewLoc.calcHref(c)) |
|
158 |
} |
|
159 |
} |
|
160 |
} |
|
161 |
} |
|
162 |
||
163 |
private def logF[T]: Box[T] => Unit = _ match {
|
|
164 |
case Failure(m, _, _) => S error m |
|
165 |
case _ => |
|
166 |
} |
|
167 |
||
168 |
private object deleteF extends HorizontalScreen with CancelButton with |
|
169 |
DeleteButton {
|
|
170 |
||
171 |
val confirm = field(l10n("Really delete this company?"), false)
|
|
172 |
||
173 |
def finish() {
|
|
174 |
for {
|
|
175 |
c <- deleteLoc.currentValue if confirm |
|
176 |
r <- delete(c) |
|
177 |
n <- r.box(c.linkName) |
|
178 |
} {
|
|
179 |
c.address.vend.flatMap(AddressCrud.delete _) $ logF |
|
180 |
c.postAddress.vend.flatMap(AddressCrud.delete _) $ logF |
|
181 |
S notice l10n("Company %s deleted.", n)
|
|
182 |
S redirectTo listM.loc.calcDefaultHref |
|
183 |
} |
|
184 |
} |
|
185 |
} |
|
186 |
||
| 72 | 187 |
/* Contacts view + add contact op. */ |
188 |
private object contacts {
|
|
189 |
||
190 |
private val choosePreM = Menu.param[Company]("company.addContact",
|
|
191 |
l10n("Add contact"), parse, encode) / prefix / * / "add-contact" >>
|
|
192 |
Title(c => i18n("Add contact to %s", c.linkName)) >>
|
|
|
89
fd364bae9c49
Basic authorization: only logged in user can change entities
Tomas Zeman <tzeman@volny.cz>
parents:
85
diff
changeset
|
193 |
IfLoggedIn.testVal >> |
| 72 | 194 |
locTpl("company/add-contact") >> Snippet("panel", chooseContact) >> Hidden
|
195 |
||
196 |
val confirmM = Menu.params[(Company, Contact)]( |
|
197 |
"company.addContactId", l10n("Add contact"), { _ match {
|
|
198 |
case AsLong(cmpId) :: AsLong(cntId) :: Nil => for {
|
|
199 |
comp <- get(cmpId) |
|
200 |
cnt <- ContactCrud.get(cntId) |
|
201 |
} yield (comp, cnt) |
|
202 |
case _ => Empty |
|
203 |
}}, |
|
204 |
{ p => List(p._1, p._2) map(_.id.toString) }) / prefix /
|
|
205 |
* / "add-contact" / * >> |
|
206 |
Title(p => i18n("Add contact %s to %s", p._2.linkName, p._1.linkName)) >>
|
|
|
89
fd364bae9c49
Basic authorization: only logged in user can change entities
Tomas Zeman <tzeman@volny.cz>
parents:
85
diff
changeset
|
207 |
IfLoggedIn.testVal >> |
| 72 | 208 |
locTpl("entity/form") >> Snippet("form", addContact) >> Hidden
|
209 |
||
210 |
val chooseM = choosePreM >> SecNav(viewPre).build |
|
211 |
||
212 |
private case class RemoveContactLink(comp: Company, cnt: Contact) extends |
|
213 |
ReadOnlyField("actions", "", ConfirmationLink(i18n("Remove"),
|
|
214 |
l10n("Really remove contact?"), {
|
|
215 |
CrmSchema.companyContacts.left(comp).dissociate(cnt) |
|
216 |
RedirectTo(viewLoc.calcHref(comp)) |
|
217 |
}), Empty) |
|
218 |
||
219 |
def contacts: CssTr = "*" #> cur.map { c =>
|
|
|
89
fd364bae9c49
Basic authorization: only logged in user can change entities
Tomas Zeman <tzeman@volny.cz>
parents:
85
diff
changeset
|
220 |
FieldTable[Contact]({ cnt => ContactTable.fields(cnt).toSeq ++
|
|
fd364bae9c49
Basic authorization: only logged in user can change entities
Tomas Zeman <tzeman@volny.cz>
parents:
85
diff
changeset
|
221 |
(User.get.map { _ => RemoveContactLink(c, cnt) }) }, Contact)(
|
|
fd364bae9c49
Basic authorization: only logged in user can change entities
Tomas Zeman <tzeman@volny.cz>
parents:
85
diff
changeset
|
222 |
CompanyContacts(c)) } |
| 72 | 223 |
|
224 |
private case class AddContactLink(comp: Company, cnt: Contact) extends |
|
225 |
EntityLink[Contact](cnt, |
|
226 |
{ c => Full(confirmM.toLoc.calcHref((comp, cnt))) })
|
|
227 |
||
228 |
private def chooseContact: CssTr = "*" #> chooseM.toLoc.currentValue.map {
|
|
229 |
comp => |
|
230 |
FieldTable[Contact]({ c =>
|
|
231 |
List(AddContactLink(comp, c)) }, Contact)(CrmSchema.allContacts) |
|
232 |
} |
|
233 |
||
234 |
private object addContact extends HorizontalScreen with CancelButton |
|
235 |
with SaveButton {
|
|
236 |
||
237 |
override def screenFields: List[BaseField] = (for {
|
|
238 |
(comp, cnt) <- confirmM.toLoc.currentValue |
|
239 |
cl <- EntityLink(comp) |
|
240 |
cntl <- EntityLink(cnt) |
|
241 |
} yield {
|
|
242 |
List(ReadOnlyField(l10n("Company"), cl),
|
|
243 |
ReadOnlyField(l10n("Contact"), cntl)) flatMap(_.allFields)
|
|
244 |
}) openOr Nil |
|
245 |
||
246 |
def finish() { for {
|
|
247 |
(comp, cnt) <- confirmM.toLoc.currentValue |
|
248 |
} {
|
|
249 |
val fk = CrmSchema.companyContacts.left(comp) |
|
250 |
fk.exists(_.id == cnt.id) match {
|
|
251 |
case true => |
|
252 |
S notice l10n("Contact %s is already associated with %s",
|
|
253 |
cnt.linkName, comp.linkName) |
|
254 |
case false => |
|
255 |
fk.associate(cnt) |
|
256 |
S notice l10n("Added contact %s", cnt.linkName)
|
|
257 |
} |
|
258 |
S redirectTo viewLoc.calcHref(comp) |
|
259 |
}} |
|
260 |
} |
|
261 |
} |
|
262 |
||
| 99 | 263 |
private object createServiceForm extends ServiceForm {
|
264 |
override def localSetup() {
|
|
265 |
createServiceM.currentValue.foreach { c => service.company(c.id) }
|
|
266 |
} |
|
267 |
||
268 |
protected def onSuccess(s: Service) {
|
|
269 |
ServiceSnippet.url.view(s).foreach { u => S redirectTo u }
|
|
270 |
} |
|
271 |
} |
|
272 |
||
| 69 | 273 |
} |
274 |
||
275 |
// vim: set ts=2 sw=2 et: |