diff --git a/shopapi/src/main/scala/net/shop/api/Model.scala b/shopapi/src/main/scala/net/shop/api/Model.scala
index 7f1e400..70836c9 100644
--- a/shopapi/src/main/scala/net/shop/api/Model.scala
+++ b/shopapi/src/main/scala/net/shop/api/Model.scala
@@ -6,6 +6,8 @@ import scala.util.Failure
import net.shift.security.User
import net.shift.security.Permissions
import net.shift.security.Permission
+import net.shift.loc.Language
+import net.shift.io.FileSystem
case class UserInfo(firstName: String, lastName: String, cnp: String, phone: String)
case class CompanyInfo(name: String, cif: String, regCom: String, bank: String, bankAccount: String, phone: String)
@@ -124,18 +126,18 @@ case class ServiceHit(year: Int, month: Int, day: Int, service: String)
case class ServiceStat(hit: ServiceHit, count: Long)
object Formatter {
- def format[T: Formatter](v: T)(implicit lang: String): String = {
+ def format[T: Formatter](v: T)(implicit lang: Language, fs: FileSystem): String = {
implicitly[Formatter[T]].write(v)
}
}
trait Formatter[T] {
- def write(value: T)(implicit lang: String): String
+ def write(value: T)(implicit lang: Language, fs: FileSystem): String
}
object ShopError {
def fail(msg: String) = Failure(new ShopError(msg))
- def fail(e: Throwable) = Failure(new ShopError(e))
+ def fail(msg: String, e: Throwable) = Failure(new ShopError(msg, e))
}
case class ShopError(msg: String, e: Throwable) extends RuntimeException(msg, e) {
diff --git a/shopdatabase/src/main/scala/net/shop/mongodb/MongoDBPersistence.scala b/shopdatabase/src/main/scala/net/shop/mongodb/MongoDBPersistence.scala
index c0582e4..7761c9d 100644
--- a/shopdatabase/src/main/scala/net/shop/mongodb/MongoDBPersistence.scala
+++ b/shopdatabase/src/main/scala/net/shop/mongodb/MongoDBPersistence.scala
@@ -26,10 +26,10 @@ object MongoDBPersistence extends Persistence with MongoConversions {
def productById(id: String): Try[ProductDetail] = try {
db("products").findOne(MongoDBObject("_id" -> new ObjectId(id))) match {
case Some(obj) => Success(mongoToProduct(obj))
- case _ => fail("Item " + id + " not found")
+ case _ => fail("no.product")
}
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error", e)
}
def allProducts: Try[Iterator[ProductDetail]] = try {
@@ -37,7 +37,7 @@ object MongoDBPersistence extends Persistence with MongoConversions {
mongoToProduct(p)
})
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error", e)
}
def categoryProducts(cat: String, spec: SortSpec = NoSort): Try[Iterator[ProductDetail]] = try {
@@ -54,7 +54,7 @@ object MongoDBPersistence extends Persistence with MongoConversions {
mongoToProduct(p)
})
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error", e)
}
def searchProducts(text: String, spec: SortSpec = NoSort): Try[Iterator[ProductDetail]] = try {
@@ -65,16 +65,16 @@ object MongoDBPersistence extends Persistence with MongoConversions {
mongoToProduct(p)
})
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error", e)
}
def categoryById(id: String): Try[Category] = try {
db("categories").findOne(MongoDBObject("_id" -> new ObjectId(id))) match {
case Some(obj) => Success(mongoToCategory(obj))
- case _ => fail("Item " + id + " not found")
+ case _ => fail("no.category")
}
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error", e)
}
def allCategories: Try[Iterator[Category]] = try {
@@ -82,14 +82,14 @@ object MongoDBPersistence extends Persistence with MongoConversions {
mongoToCategory(p)
})
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error")
}
def deleteProducts(ids: String*): Try[Int] = try {
val num = (0 /: ids)((acc, id) => db("products").remove(MongoDBObject("_id" -> new ObjectId(id))).getN)
Success(num)
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error")
}
def createProducts(prod: ProductDetail*): Try[Seq[String]] = try {
@@ -97,7 +97,7 @@ object MongoDBPersistence extends Persistence with MongoConversions {
db("products").insert(mongos: _*)
Success(mongos map { p => p.get("_id").getOrElse("?").toString() })
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error")
}
def updateProducts(prod: ProductDetail*): Try[Seq[String]] = try {
@@ -116,7 +116,7 @@ object MongoDBPersistence extends Persistence with MongoConversions {
builder.execute()
Success(ids)
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error")
}
def createCategories(cats: Category*): Try[Seq[String]] = try {
@@ -124,7 +124,7 @@ object MongoDBPersistence extends Persistence with MongoConversions {
db("categories").insert(mongos: _*)
Success(mongos map { p => p.getOrElse("_id", "?").toString })
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error")
}
def updateCategories(c: Category*): Try[Seq[String]] = try {
@@ -143,14 +143,14 @@ object MongoDBPersistence extends Persistence with MongoConversions {
builder.execute()
Success(ids)
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error")
}
def deleteCategories(ids: String*): Try[Int] = try {
val num = (0 /: ids)((acc, id) => db("categories").remove(MongoDBObject("_id" -> new ObjectId(id))).getN)
Success(num)
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error")
}
def createUsers(user: UserDetail*): Try[Seq[String]] = try {
@@ -158,7 +158,7 @@ object MongoDBPersistence extends Persistence with MongoConversions {
db("users").insert(mongos: _*)
Success(mongos map { p => p.getOrElse("_id", "?").toString })
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error")
}
def updateUsers(user: UserDetail*): Try[Seq[String]] = try {
@@ -177,14 +177,14 @@ object MongoDBPersistence extends Persistence with MongoConversions {
builder.execute()
Success(ids)
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error")
}
def deleteUsers(ids: String*): Try[Int] = try {
val num = (0 /: ids)((acc, id) => db("users").remove(MongoDBObject("_id" -> new ObjectId(id))).getN)
Success(num)
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error")
}
def allUsers: Try[Iterator[UserDetail]] = try {
@@ -192,7 +192,7 @@ object MongoDBPersistence extends Persistence with MongoConversions {
mongoToUser(p)
})
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error")
}
def userByEmail(email: String): Try[Option[UserDetail]] = try {
@@ -201,7 +201,7 @@ object MongoDBPersistence extends Persistence with MongoConversions {
case _ => Success(None)
}
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error", e)
}
def createOrder(order: OrderLog*): Try[Seq[String]] = {
@@ -218,7 +218,7 @@ object MongoDBPersistence extends Persistence with MongoConversions {
Success(mongos map { _.getOrElse("_id", "?").toString })
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error", e)
}
}
@@ -226,21 +226,21 @@ object MongoDBPersistence extends Persistence with MongoConversions {
val update = db("orders").update(MongoDBObject("id" -> orderId), $set(("status" -> status.index)))
Success(update.getN == 1)
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error", e)
}
def ordersByEmail(email: String): Try[Iterator[OrderLog]] = try {
Success(
db("orders").find(MongoDBObject("email" -> email)) map mongoToOrder)
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error", e)
}
def ordersByProduct(productId: String): Try[Iterator[OrderLog]] = try {
Success(
db("orders").find("items.id" $in List(productId)) map mongoToOrder)
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error", e)
}
def storeServiceHit(h: ServiceHit): Try[String] = try {
@@ -250,7 +250,7 @@ object MongoDBPersistence extends Persistence with MongoConversions {
Success(mongo.get("_id").getOrElse("?").toString())
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error", e)
}
def allServiceStats(): Try[Iterator[ServiceStat]] = try {
@@ -258,7 +258,7 @@ object MongoDBPersistence extends Persistence with MongoConversions {
mongoToServiceStat(p)
})
} catch {
- case e: Exception => fail(e)
+ case e: Exception => fail("internal.error", e)
}
}
diff --git a/shopweb/localization/ro.json b/shopweb/localization/ro.json
index f72b141..91894a1 100644
--- a/shopweb/localization/ro.json
+++ b/shopweb/localization/ro.json
@@ -1,24 +1,24 @@
[
{
"code" : "100",
- "name" : "no_categories",
+ "name" : "internal.error",
+ "text" : "Eroare interna"
+ },
+ {
+ "code" : "100",
+ "name" : "no.categories",
"text" : "Categoriile nu pot fi obtinute"
},
{
"code" : "101",
- "name" : "no_category",
+ "name" : "no.category",
"text" : "Categorie inexistenta"
},
{
"code" : "102",
- "name" : "no_product",
+ "name" : "no.product",
"text" : "Produs inexistent"
},
- {
- "code" : "103",
- "name" : "add_to_cart",
- "text" : "Adauga in cos"
- },
{
"code" : "104",
"name" : "categories",
diff --git a/shopweb/src/main/scala/net/shop/model/Formatters.scala b/shopweb/src/main/scala/net/shop/model/Formatters.scala
index 4916c67..3cb776f 100644
--- a/shopweb/src/main/scala/net/shop/model/Formatters.scala
+++ b/shopweb/src/main/scala/net/shop/model/Formatters.scala
@@ -2,8 +2,10 @@ package net.shop
package model
import api._
-import net.shift.loc.Language
import net.shop.api.ShopError
+import net.shift.loc.Loc
+import net.shift.loc.Language
+import net.shift.io.FileSystem
object Formatters {
@@ -15,9 +17,9 @@ object Formatters {
override def dateFormatter = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss'Z'")
}
- def write(err: ShopError)(implicit lang: String): String = {
+ def write(err: ShopError)(implicit lang: Language, fs: FileSystem): String = {
import org.json4s.native.Serialization.writePretty
- writePretty(Err(err.msg))
+ writePretty(Err(Loc.loc0(lang)(err.msg).text))
}
case class Err(msg: String)
@@ -32,7 +34,7 @@ object Formatters {
override def dateFormatter = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss'Z'")
}
- def write(orders: List[OrderLog])(implicit lang: String): String = {
+ def write(orders: List[OrderLog])(implicit lang: Language, fs: FileSystem): String = {
import org.json4s.native.Serialization.writePretty
writePretty(orders)
}
@@ -47,7 +49,7 @@ object Formatters {
override def dateFormatter = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss'Z'")
}
- def write(user: UserDetail)(implicit lang: String): String = {
+ def write(user: UserDetail)(implicit lang: Language, fs: FileSystem): String = {
import org.json4s.native.Serialization.writePretty
writePretty(UserSummary(user.userInfo, user.companyInfo, user.email, user.addresses))
}
@@ -63,7 +65,7 @@ object Formatters {
override def dateFormatter = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss'Z'")
}
- def write(err: ValidationFail)(implicit lang: String): String = {
+ def write(err: ValidationFail)(implicit lang: Language, fs: FileSystem): String = {
import org.json4s.native.Serialization.writePretty
writePretty(err)
}
@@ -77,7 +79,7 @@ object Formatters {
override def dateFormatter = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss'Z'")
}
- def write(err: FieldError)(implicit lang: String): String = {
+ def write(err: FieldError)(implicit lang: Language, fs: FileSystem): String = {
import org.json4s.native.Serialization.writePretty
writePretty(err)
}
@@ -91,9 +93,9 @@ object Formatters {
override def dateFormatter = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss'Z'")
}
- def write(c: Category)(implicit lang: String): String = {
+ def write(c: Category)(implicit lang: Language, fs: FileSystem): String = {
import org.json4s.native.Serialization.writePretty
- writePretty(CategoryJson(c.id, c.title.getOrElse(lang, "ro"), c.position))
+ writePretty(CategoryJson(c.id, c.title.getOrElse(lang.name, "ro"), c.position))
}
case class CategoryJson(id: Option[String], title: String, position: Int)
diff --git a/shopweb/src/main/scala/net/shop/utils/ShopUtils.scala b/shopweb/src/main/scala/net/shop/utils/ShopUtils.scala
index c050c70..60d02c3 100644
--- a/shopweb/src/main/scala/net/shop/utils/ShopUtils.scala
+++ b/shopweb/src/main/scala/net/shop/utils/ShopUtils.scala
@@ -18,7 +18,7 @@ object ShopUtils {
def imagePath(variant: String, prod: ProductDetail): String =
prod.images match {
case h :: _ => s"/data/products/${prod.stringId}/$variant/${h}"
- case Nil => "/static/images/noimage.png"
+ case Nil => ""
}
def errorTag(text: String) =
diff --git a/shopweb/src/main/scala/net/shop/web/pages/CategoryPage.scala b/shopweb/src/main/scala/net/shop/web/pages/CategoryPage.scala
index dc5a21e..f3e9613 100644
--- a/shopweb/src/main/scala/net/shop/web/pages/CategoryPage.scala
+++ b/shopweb/src/main/scala/net/shop/web/pages/CategoryPage.scala
@@ -5,7 +5,6 @@ import scala.util.Failure
import scala.util.Success
import scala.xml._
import scala.xml._
-
import net.shift._
import net.shift._
import net.shift.engine.http._
@@ -17,6 +16,7 @@ import net.shift.template.Binds._
import net.shift.template.Snippet._
import net.shop.utils.ShopUtils._
import net.shop.web.ShopApplication
+import net.shop.api.ShopError
object CategoryPage extends Cart[Request] { self =>
@@ -36,10 +36,11 @@ object CategoryPage extends Cart[Request] { self =>
case "div" attributes HasClasses("info_tag_text" :: _, a) / _ => { cat.title_?(s.state.lang.name) }
% a
}) match {
case Success(n) => n
+ case Failure(ShopError(msg, _)) => errorTag(Loc.loc0(s.state.lang)(msg).text)
case Failure(f) => errorTag(f toString)
}
}
- case Failure(t) => { Loc.loc0(s.state.lang)("no_categories").text }
+ case Failure(t) => { Loc.loc0(s.state.lang)("no.categories").text }
}
Success(s.state.initialState, prods.toSeq)
diff --git a/shopweb/src/main/scala/net/shop/web/pages/OrderPage.scala b/shopweb/src/main/scala/net/shop/web/pages/OrderPage.scala
index 581020b..24a2cf1 100644
--- a/shopweb/src/main/scala/net/shop/web/pages/OrderPage.scala
+++ b/shopweb/src/main/scala/net/shop/web/pages/OrderPage.scala
@@ -23,6 +23,8 @@ import net.shop.api.Person
import net.shop.api.Company
import net.shop.api.Address
import net.shift.io.IODefaults
+import net.shift.loc.Loc
+import net.shop.api.ShopError
object OrderPage extends DynamicContent[OrderState] with Selectors with IODefaults {
@@ -99,6 +101,7 @@ object OrderPage extends DynamicContent[OrderState] with Selectors with IODefaul
case "td" attributes HasClass("c4", a) / _ => { prod.userOptions.flatMap { o => - { o._1 + " : " + o._2 }
} } | % a
}) match {
case Success(n) => acc ++ n
+ case Failure(ShopError(msg, _)) => acc ++ errorTag(Loc.loc0(s.state.lang)(msg).text)
case Failure(f) => acc ++ errorTag(f toString)
}
case Failure(f) => errorTag(f getMessage)
diff --git a/shopweb/src/main/scala/net/shop/web/pages/ProductDetailPage.scala b/shopweb/src/main/scala/net/shop/web/pages/ProductDetailPage.scala
index f4806de..42a2f96 100644
--- a/shopweb/src/main/scala/net/shop/web/pages/ProductDetailPage.scala
+++ b/shopweb/src/main/scala/net/shop/web/pages/ProductDetailPage.scala
@@ -22,11 +22,10 @@ import net.shift.loc.Language
import net.shift.common.ShiftFailure
import net.shift.security.User
import net.shift.common.Config
+import net.shop.api.ShopError
object ProductDetailPage extends Cart[ProductPageState] {
- val noImage = "/static/images/noimage.png"
-
override def snippets = List(meta, catlink, productLink, images, detailPrice, stock, details, specs, customize, edit) ++ super.snippets
val meta = reqSnip("fb_meta") {
@@ -45,17 +44,18 @@ object ProductDetailPage extends Cart[ProductPageState] {
for { n <- fb } yield {
(ProductPageState(s.state.initialState.req, Success(prod), s.state.user), n)
}
+ case Failure(ShopError(msg, _)) => ShiftFailure(Loc.loc0(s.state.lang)(msg).text).toTry
case Failure(t) =>
- Success(s.state.initialState, errorTag(Loc.loc0(s.state.lang)("no_product").text))
+ ShiftFailure(Loc.loc0(s.state.lang)("no.product").text).toTry
}
- case _ => Success(s.state.initialState, errorTag(Loc.loc0(s.state.lang)("no_product").text))
+ case _ => ShiftFailure(Loc.loc0(s.state.lang)("no.product").text).toTry
}
}
}
def pageTitle(s: PageState[ProductPageState]) =
s.initialState.product match {
case Success(prod) => prod.title_?(s.lang.name)
- case Failure(t) => Loc.loc0(s.lang)("no_product").text
+ case Failure(t) => ""
}
val catlink = reqSnip("catlink") {
@@ -87,28 +87,33 @@ object ProductDetailPage extends Cart[ProductPageState] {
val images = reqSnip("images") {
s =>
(s.state.initialState.product flatMap { prod =>
- bind(s.node) {
+ prod.images match {
+ case Nil => Success(s.state.initialState, NodeSeq.Empty)
+ case images =>
+ bind(s.node) {
+
+ case "b:img" attributes a =>
- case "b:img" attributes a =>
+ val p = imagePath(prod.stringId, "normal", prod.images.head)
+ val large = imagePath(prod.stringId, "large", prod.images.head)
- val p = if (prod.images.isEmpty) noImage else imagePath(prod.stringId, "normal", prod.images.head)
- val large = if (prod.images.isEmpty) noImage else imagePath(prod.stringId, "large", prod.images.head)
+ node("img", a.attrs.attrs + ("src" -> p) + ("title" -> prod.title_?(s.state.lang.name)) + ("data-zoom-image" -> large))
- node("img", a.attrs.attrs + ("src" -> p) + ("title" -> prod.title_?(s.state.lang.name)) + ("data-zoom-image" -> large))
+ case e attributes HasId("thumb", a) =>
+ NodeSeq.fromSeq(for {
+ p <- prod.images zipWithIndex
+ } yield {
+ val normal = imagePath(prod.stringId, "normal", p._1)
+ val large = imagePath(prod.stringId, "large", p._1)
+ val thumb = imagePath(prod.stringId, "thumb", p._1)
+ (node(e, a.attrs - "id") /
+
+ ).e
+ })
- case e attributes HasId("thumb", a) =>
- NodeSeq.fromSeq(for {
- p <- prod.images zipWithIndex
- } yield {
- val normal = imagePath(prod.stringId, "normal", p._1)
- val large = imagePath(prod.stringId, "large", p._1)
- val thumb = imagePath(prod.stringId, "thumb", p._1)
- (node(e, a.attrs - "id") /
-
- ).e
- })
+ } map { b => (ProductPageState(s.state.initialState.req, Success(prod), s.state.user), b) }
+ }
- } map { b => (ProductPageState(s.state.initialState.req, Success(prod), s.state.user), b) }
}).recover { case _ => (s.state.initialState, NodeSeq.Empty) }
}
diff --git a/shopweb/src/main/scala/net/shop/web/pages/ProductsPage.scala b/shopweb/src/main/scala/net/shop/web/pages/ProductsPage.scala
index f489835..d7c5909 100644
--- a/shopweb/src/main/scala/net/shop/web/pages/ProductsPage.scala
+++ b/shopweb/src/main/scala/net/shop/web/pages/ProductsPage.scala
@@ -29,6 +29,7 @@ import net.shift.common.XmlUtils._
import net.shift.common.NodeOps._
import net.shift.engine.page.Html5
import net.shift.common.Path
+import net.shop.api.ShopError
object ProductsPage extends Cart[Request] {
@@ -77,7 +78,7 @@ object ProductsPage extends Cart[Request] {
case Failure(f) => errorTag(f toString)
}
}
- case Failure(t) => errorTag(Loc.loc0(s.state.lang)("no_category").text)
+ case Failure(t) => errorTag(Loc.loc0(s.state.lang)("no.category").text)
}
Success((s.state.initialState, prods.toSeq))
}
@@ -93,7 +94,8 @@ object ProductsPage extends Cart[Request] {
Success((s.state.initialState, e / NodeSeq.fromSeq(v)))
case _ => Success((s.state.initialState, NodeSeq.Empty))
}
- case Failure(t) => Success((s.state.initialState, errorTag(Loc.loc0(s.state.lang)("no_category").text)))
+ case Failure(ShopError(msg, _)) => Success((s.state.initialState, errorTag(Loc.loc0(s.state.lang)(msg).text)))
+ case Failure(t) => Success((s.state.initialState, errorTag(Loc.loc0(s.state.lang)("no.category").text)))
}
}
diff --git a/shopweb/src/main/scala/net/shop/web/services/CategoryService.scala b/shopweb/src/main/scala/net/shop/web/services/CategoryService.scala
index da94f1d..8a36af9 100644
--- a/shopweb/src/main/scala/net/shop/web/services/CategoryService.scala
+++ b/shopweb/src/main/scala/net/shop/web/services/CategoryService.scala
@@ -37,6 +37,7 @@ import net.shift.io.IO
import net.shift.io.FileSystem
import net.shift.io.FileOps
import net.shop.utils.ShopUtils._
+import net.shop.api.ShopError
object CategoryService extends Selectors
with TraversingSpec
@@ -53,9 +54,10 @@ object CategoryService extends Selectors
ShopApplication.persistence.categoryById(id) match {
case scala.util.Success(cat) =>
fs.deletePath(Path(s"${dataPath}/categories/$id"))
- implicit val l = r.language.name
+ implicit val l = r.language
service(_(JsonResponse(Formatter.format(cat))))
- case scala.util.Failure(t) => service(_(Resp.notFound))
+ case scala.util.Failure(ShopError(msg, _)) => service(_(Resp.ok.asText.withBody(Loc.loc0(r.language)(msg).text)))
+ case scala.util.Failure(t) => service(_(Resp.notFound))
}
}
@@ -68,7 +70,8 @@ object CategoryService extends Selectors
case scala.util.Success(num) =>
fs.deletePath(Path(s"${dataPath}/categories/$id"));
service(_(Resp.ok))
- case scala.util.Failure(t) => service(_(Resp.notFound))
+ case scala.util.Failure(ShopError(msg, _)) => service(_(Resp.ok.asText.withBody(Loc.loc0(r.language)(msg).text)))
+ case scala.util.Failure(t) => service(_(Resp.notFound))
}
}
@@ -88,11 +91,14 @@ object CategoryService extends Selectors
}
service(_(Resp.created))
+ case scala.util.Failure(ShopError(msg, _)) => service(_(Resp.ok.asText.withBody(Loc.loc0(r.language)(msg).text)))
case scala.util.Failure(t) =>
service(_(Resp.serverError.asText.withBody("category.create.fail")))
}
- case (_, Invalid(msgs)) => validationFail(msgs)(r.language.name)
+ case (_, Invalid(msgs)) =>
+ implicit val l = r.language
+ validationFail(msgs)
}
@@ -113,13 +119,16 @@ object CategoryService extends Selectors
IO.arrayProducer(f._2)(FileOps.writer(Path(s"${dataPath}/categories/${p.head}.png")))
}
service(_(Resp.created))
+
+ case scala.util.Failure(ShopError(msg, _)) => service(_(Resp.ok.asText.withBody(Loc.loc0(r.language)(msg).text)))
case scala.util.Failure(t) =>
error("Cannot create category ", t)
service(_(Resp.serverError))
}
- case (_, Invalid(msgs)) => validationFail(msgs)(r.language.name)
-
+ case (_, Invalid(msgs)) =>
+ implicit val l = r.language
+ validationFail(msgs)
}
}
diff --git a/shopweb/src/main/scala/net/shop/web/services/FormValidation.scala b/shopweb/src/main/scala/net/shop/web/services/FormValidation.scala
index adc15b7..58926c0 100644
--- a/shopweb/src/main/scala/net/shop/web/services/FormValidation.scala
+++ b/shopweb/src/main/scala/net/shop/web/services/FormValidation.scala
@@ -20,6 +20,7 @@ import net.shop.model.FieldError
import net.shop.model.Formatters.ValidationErrorWriter
import net.shop.model.ValidationFail
import net.shop.web.ShopApplication
+import net.shift.io.FileSystem
object FormImplicits extends IODefaults {
implicit val o = new Ordering[Double] {
@@ -171,12 +172,12 @@ trait FormValidation extends IODefaults {
case _ => None
}
- def validationFail(msgs: ValidationFail)(implicit lang: String) =
+ def validationFail(msgs: ValidationFail)(implicit lang: Language, fs: FileSystem) =
service(r => {
r(JsonResponse(Formatter.format(msgs)).code(403))
})
- def respValidationFail(resp: net.shift.engine.http.AsyncResponse, msgs: ValidationFail)(implicit lang: String) =
+ def respValidationFail(resp: net.shift.engine.http.AsyncResponse, msgs: ValidationFail)(implicit lang: Language, fs: FileSystem) =
resp(JsonResponse(Formatter.format(msgs)).code(403))
}
diff --git a/shopweb/src/main/scala/net/shop/web/services/OrderService.scala b/shopweb/src/main/scala/net/shop/web/services/OrderService.scala
index 48a2894..39f328a 100644
--- a/shopweb/src/main/scala/net/shop/web/services/OrderService.scala
+++ b/shopweb/src/main/scala/net/shop/web/services/OrderService.scala
@@ -126,7 +126,8 @@ object OrderService extends HttpPredicates with FormValidation with TraversingSp
}
}
case Invalid(msgs) =>
- respValidationFail(resp, msgs)(r.language.name)
+ implicit val l = r.language
+ respValidationFail(resp, msgs)
}
case Failure(t) =>
@@ -152,7 +153,7 @@ object OrderService extends HttpPredicates with FormValidation with TraversingSp
import model.Formatters._
- implicit val l = r.language.name
+ implicit val l = r.language
ShopApplication.persistence.ordersByEmail(email) match {
case Success(orders) =>
resp(JsonResponse(Formatter.format(orders.toList)))
@@ -168,7 +169,7 @@ object OrderService extends HttpPredicates with FormValidation with TraversingSp
id <- param("productid")
} yield service(resp => {
import model.Formatters._
- implicit val l = r.language.name
+ implicit val l = r.language
ShopApplication.persistence.ordersByProduct(id) match {
case Success(orders) =>
resp(JsonResponse(Formatter.format(orders.toList)))
diff --git a/shopweb/src/main/scala/net/shop/web/services/ProductService.scala b/shopweb/src/main/scala/net/shop/web/services/ProductService.scala
index d391f3a..85ce286 100644
--- a/shopweb/src/main/scala/net/shop/web/services/ProductService.scala
+++ b/shopweb/src/main/scala/net/shop/web/services/ProductService.scala
@@ -38,6 +38,7 @@ import net.shift.io.FileSystem
import net.shift.io.FileOps
import net.shift.io.IO
import utils.ShopUtils._
+import net.shop.api.ShopError
object ProductService extends ShiftUtils
with Selectors
@@ -55,7 +56,8 @@ object ProductService extends ShiftUtils
case scala.util.Success(num) =>
fs.deletePath(Path(s"${dataPath}/products/$id"))
service(_(Resp.ok))
- case scala.util.Failure(t) => service(_(Resp.notFound))
+ case scala.util.Failure(ShopError(msg, _)) => service(_(Resp.ok.asText.withBody(Loc.loc0(r.language)(msg).text)))
+ case scala.util.Failure(t) => service(_(Resp.notFound))
}
}
@@ -69,25 +71,23 @@ object ProductService extends ShiftUtils
case (files, Valid(o)) =>
val cpy = o.copy(images = Set(files.map(f => f._2): _*).toList)
- ShopApplication.persistence.productById(pid) match {
- case scala.util.Success(p) =>
- val merged = cpy.copy(images = p.images ++ cpy.images)
-
- ShopApplication.persistence.updateProducts(merged) match {
- case scala.util.Success(p) =>
- files.map { f =>
- IO.arrayProducer(f._3)(FileOps.writer(Path(s"${dataPath}/products/${p.head}/${f._1}")))
- }
- service(_(Resp.created))
- case scala.util.Failure(t) =>
- error("Cannot create product ", t)
- service(_(Resp.serverError))
- }
-
- case scala.util.Failure(f) => service(_(Resp.notFound))
+ (for {
+ p <- ShopApplication.persistence.productById(pid)
+ u <- ShopApplication.persistence.updateProducts(cpy.copy(images = p.images ++ cpy.images))
+ } yield {
+ files.map { f =>
+ IO.arrayProducer(f._3)(FileOps.writer(Path(s"${dataPath}/products/${u.head}/${f._1}")))
+ }
+ service(_(Resp.created))
+ }) match {
+ case scala.util.Success(s) => s
+ case scala.util.Failure(ShopError(msg, _)) => service(_(Resp.ok.asText.withBody(Loc.loc0(r.language)(msg).text)))
+ case scala.util.Failure(t) => service(_(Resp.serverError))
}
- case (_, Invalid(msgs)) => validationFail(msgs)(r.language.name)
+ case (_, Invalid(msgs)) =>
+ implicit val l = r.language
+ validationFail(msgs)
}
}
@@ -116,17 +116,17 @@ object ProductService extends ShiftUtils
IO.arrayProducer(f._3)(FileOps.writer(Path(s"${dataPath}/products/${p.head}/${f._1}")))
}) { d => log.debug("Write files: " + d) }
}
- log.debug("Send OK")
service(_(Resp.created))
+ case scala.util.Failure(ShopError(msg, _)) => service(_(Resp.ok.asText.withBody(Loc.loc0(r.language)(msg).text)))
case scala.util.Failure(t) =>
error("Cannot create product ", t)
- log.debug("Send ERROR")
service(_(Resp.serverError))
}
case (_, Invalid(msgs)) =>
log.debug("Send FAIL")
- validationFail(msgs)(r.language.name)
+ implicit val l = r.language
+ validationFail(msgs)
}
@@ -181,8 +181,9 @@ object ProductService extends ShiftUtils
case p => Valid(p)
})
} catch {
- case e: Exception => e.printStackTrace()
- (Nil, Invalid(ValidationFail(FieldError("edit_discount_price", Loc.loc0(loc)("field.discount.smaller").text))))
+ case e: Exception =>
+ e.printStackTrace()
+ (Nil, Invalid(ValidationFail(FieldError("edit_discount_price", Loc.loc0(loc)("field.discount.smaller").text))))
}
}
diff --git a/shopweb/src/main/scala/net/shop/web/services/SettingsService.scala b/shopweb/src/main/scala/net/shop/web/services/SettingsService.scala
index 14ef60b..eadb36e 100644
--- a/shopweb/src/main/scala/net/shop/web/services/SettingsService.scala
+++ b/shopweb/src/main/scala/net/shop/web/services/SettingsService.scala
@@ -29,6 +29,7 @@ import net.shop.api.OrderStatus
import scala.util.Success
import scala.util.Failure
import net.shift.security.Permission
+import net.shop.api.ShopError
object SettingsService extends Selectors
with TraversingSpec
@@ -42,8 +43,9 @@ object SettingsService extends Selectors
u <- permissions(Loc.loc0(r.language)("user.not.found").text, Permission("write"))
} yield {
ShopApplication.persistence.updateOrderStatus(orderId, OrderStatus.fromIndex(status.toInt)) match {
- case Success(_) => service(_(Resp.ok))
- case Failure(msg) => service(_(Resp.notFound.asText.withBody(Loc.loc(r.language)("order.not.found", List(orderId)).text)))
+ case Success(_) => service(_(Resp.ok))
+ case scala.util.Failure(ShopError(msg, _)) => service(_(Resp.ok.asText.withBody(Loc.loc0(r.language)(msg).text)))
+ case Failure(msg) => service(_(Resp.notFound.asText.withBody(Loc.loc(r.language)("order.not.found", List(orderId)).text)))
}
}
@@ -68,7 +70,8 @@ object SettingsService extends Selectors
case _ => service(_(Resp.serverError.asText.withBody(Loc.loc0(r.language)("login.fail").text)))
}
service(_(Resp.created.asText.withBody(Loc.loc0(r.language)("settings.saved").text)))
- case Invalid(e) => validationFail(e)(r.language.name)
+ case Invalid(e) =>
+ validationFail(e)
}
case None => service(_(Resp.forbidden.asText.withBody(Loc.loc0(r.language)("login.fail").text)))
}
diff --git a/shopweb/src/main/scala/net/shop/web/services/ShopServices.scala b/shopweb/src/main/scala/net/shop/web/services/ShopServices.scala
index bb5f038..ba3f62f 100644
--- a/shopweb/src/main/scala/net/shop/web/services/ShopServices.scala
+++ b/shopweb/src/main/scala/net/shop/web/services/ShopServices.scala
@@ -50,6 +50,7 @@ import net.shift.common.State
import net.shift.engine.http.Header
import net.shift.common.Config
import utils.ShopUtils._
+import net.shop.api.ShopError
trait ShopServices extends ShiftUtils with Selectors with TraversingSpec with DefaultLog with SecuredService with IODefaults {
@@ -151,7 +152,9 @@ trait ShopServices extends ShiftUtils with Selectors with TraversingSpec with De
u <- user
} yield {
val logout = !r.param("logout").isEmpty
- Html5.pageFromFile(PageState(f(r, u), r.language, if (logout) None else u), filePath, snipets)(bySnippetAttr[T], fs)
+ val p = Html5.pageFromFile(PageState(f(r, u), r.language, if (logout) None else u), filePath, snipets)(bySnippetAttr[T], fs)
+
+ p
}
def productsVariantImages = for {
@@ -183,6 +186,7 @@ trait ShopServices extends ShiftUtils with Selectors with TraversingSpec with De
Html5.runPageFromFile(PageState(CartState(index, item, prod), r.language), Path("web/templates/cartitem.html"), CartItemNode).map(_._2 toString)
}) match {
case Success(list) => resp(JsonResponse(write(list)))
+ case scala.util.Failure(ShopError(msg, _)) => service(_(Resp.ok.asText.withBody(Loc.loc0(r.language)(msg).text)))
case Failure(t) =>
log.error("Failed processing cart ", t)
resp(JsonResponse(write(Nil)))
diff --git a/shopweb/src/main/scala/net/shop/web/services/UserService.scala b/shopweb/src/main/scala/net/shop/web/services/UserService.scala
index ffd13fb..d76bcac 100644
--- a/shopweb/src/main/scala/net/shop/web/services/UserService.scala
+++ b/shopweb/src/main/scala/net/shop/web/services/UserService.scala
@@ -34,6 +34,7 @@ import net.shop.model.FieldError
import net.shift.html.Valid
import net.shift.html.Invalid
import net.shift.common.Config
+import net.shop.api.ShopError
object UserService extends Selectors
with TraversingSpec
@@ -50,8 +51,9 @@ object UserService extends Selectors
} yield {
ShopApplication.persistence.userByEmail(user.name) match {
case Success(Some(ud)) =>
- implicit val l = r.language.name
+ implicit val l = r.language
service(_(JsonResponse(Formatter.format(ud))))
+ case scala.util.Failure(ShopError(msg, _)) => service(_(Resp.ok.asText.withBody(Loc.loc0(r.language)(msg).text)))
case _ =>
service(_(Resp.notFound.asText.withBody(Loc.loc(r.language)("user.not.found", Seq(user.name)).text)))
}
@@ -88,8 +90,8 @@ object UserService extends Selectors
cnp = u.cnp,
phone = u.phone)
- val perms = List("read") ++ (if (Config.string("admin.user") == u.email) List("write") else Nil )
-
+ val perms = List("read") ++ (if (Config.string("admin.user") == u.email) List("write") else Nil)
+
val usr = UserDetail(id = None,
userInfo = ui,
companyInfo = CompanyInfo("", "", "", "", "", ""),
@@ -101,12 +103,14 @@ object UserService extends Selectors
ShopApplication.persistence.createUsers(usr) match {
case scala.util.Success(ids) =>
service(_(Resp.created))
+ case scala.util.Failure(ShopError(msg, _)) => service(_(Resp.ok.asText.withBody(Loc.loc0(r.language)(msg).text)))
case scala.util.Failure(t) =>
error("Cannot create user ", t)
service(_(Resp.serverError.withBody(Loc.loc0(r.language)("user.cannot.create").text)))
}
- case Invalid(msgs) => validationFail(msgs)(r.language.name)
+ case Invalid(msgs) =>
+ validationFail(msgs)
}
}
diff --git a/shopweb/web/static/css/style.css b/shopweb/web/static/css/style.css
index c374cb2..21b2884 100755
--- a/shopweb/web/static/css/style.css
+++ b/shopweb/web/static/css/style.css
@@ -562,6 +562,7 @@ h1 {
float: left;
margin-left: 20px;
margin-top: 20px;
+ margin-right: 10px;
font-size: 18px;
}
diff --git a/shopweb/web/templates/productquickview.html b/shopweb/web/templates/productquickview.html
index 95146c1..8bd18e2 100644
--- a/shopweb/web/templates/productquickview.html
+++ b/shopweb/web/templates/productquickview.html
@@ -26,7 +26,6 @@
-