Merge branch 'master' of uflows.com:/var/git/qwaiter

This commit is contained in:
2015-05-06 11:57:14 +02:00
56 changed files with 372 additions and 12245 deletions
+2
View File
@@ -44,3 +44,5 @@ erl_crash.dump
/.project
# dia
/*.autosave
/db/data
/db/config
+5 -5
View File
@@ -1,6 +1,6 @@
GIT
remote: git://github.com/bterkuile/cmtool.git
revision: e937070277ae7d44e37de85864f91a1fc779f093
revision: 1b82ab178409684e504e70b6403bc4eb8425c432
specs:
cmtool (1.0.0)
bourbon
@@ -101,7 +101,7 @@ GEM
bcrypt (3.1.10)
binding_of_caller (0.7.2)
debug_inspector (>= 0.0.1)
bourbon (4.2.1)
bourbon (4.2.2)
sass (~> 3.4)
thor
builder (3.2.2)
@@ -239,7 +239,7 @@ GEM
ruby-progressbar (~> 1.4)
gherkin (2.12.2)
multi_json (~> 1.3)
globalid (0.3.3)
globalid (0.3.4)
activesupport (>= 4.1.0)
handlebars-source (1.3.0)
hashie (3.4.0)
@@ -341,7 +341,7 @@ GEM
rails-assets-qunit (1.17.1)
rails-deprecated_sanitizer (1.0.3)
activesupport (>= 4.2.0.alpha)
rails-dom-testing (1.0.5)
rails-dom-testing (1.0.6)
activesupport (>= 4.2.0.beta, < 5.0)
nokogiri (~> 1.6.0)
rails-deprecated_sanitizer (>= 1.0.1)
@@ -440,7 +440,7 @@ GEM
eventmachine (~> 1.0)
rack (~> 1.0)
thor (0.19.1)
thread_safe (0.3.4)
thread_safe (0.3.5)
tilt (1.4.1)
timers (4.0.1)
hitimes
@@ -24,8 +24,11 @@ App.MenuProductComponent = Ember.Component.extend
makeEditable: -> @set('editMode', true)
save: ->
return unless @get('product.isValid')
@get('product.product_variants').forEach (product_variant)->
product_variant.save() if product_variant.get('isDirty')
if @get('product.isDirty')
@get('product').save().then((=> @set 'editMode', false), (-> true))
@get('product').save()
@set 'editMode', false
destroyProduct: (product)->
if product.get('isNew')
product.deleteRecord()
@@ -38,8 +41,15 @@ App.MenuProductComponent = Ember.Component.extend
if @get('product.isNew')
@get('product').deleteRecord()
else
@get('product.product_variants').forEach (product_variant)->
product_variant.rollback()
@get('product').rollback()
@set 'editMode', false
addProductVariant: ->
product_variant = @get('targetObject.store').createRecord('product_variant')
@get('product.product_variants').addObject product_variant
removeProductVariant: (product_variant)->
product_variant.destroyRecord()
didInsertElement: ->
@set 'editMode', true if @get('product.isNew')
namePlaceholder: (-> t "attributes.product.name").property()
@@ -34,9 +34,8 @@ App.Order = DS.Model.extend
@get('product_orders').getEach('total').reduce(((sum, total) -> sum + total), 0)
).property('product_orders.@each.total')
display: (->
@get('product_orders').map((po) -> "#{po.get('quantity')} x #{po.get('product.name')}").join(', ')
).property('product_orders.@each.quantity', 'product_orders.@each.product.@each.name')
display: Ember.computed 'product_orders.@each.display', ->
@get('product_orders').map((po) -> po.get('display')).join(', ')
display_with_table: (->
table = t('models.table').toLowerCase()
@@ -10,6 +10,7 @@ App.Product = DS.Model.extend Ember.Validations.Mixin,
image: attr()
product_category: DS.belongsTo('product_category')
product_orders: DS.hasMany('product_order')
product_variants: DS.hasMany('product_variant')
image_src: (->
image = @get('image')
@@ -18,6 +19,12 @@ App.Product = DS.Model.extend Ember.Validations.Mixin,
image
).property('image')
sorted_product_variants: Ember.computed 'product_variants.@each.name', 'product_variants.@each.position', ->
@get('product_variants').sortBy('position')
variantsDisplay: Ember.computed 'sorted_product_variants', ->
@get('sorted_product_variants').mapBy('name').join(', ')
#isValid: (->
#return false unless price = @get('price')
#return false unless "#{price}".match(/^[+-]?\d+(\.?\d?\d)?$/)
@@ -2,8 +2,14 @@ attr = DS.attr
App.ProductOrder = DS.Model.extend
quantity: attr 'number', defaultValue: 1
price: attr 'number'
product_variant: attr('string')
product: DS.belongsTo('product', async: true)
order: DS.belongsTo('order')
increment: ->
@set('quantity', @get('quantity') + 1)
total: (-> @get('quantity') * @get('price')).property('quantity', 'price')
display: Ember.computed 'quantity', 'product_variant', 'product.name', ->
disp = "#{@get('quantity')} x #{@get('product.name')}"
if variant = @get('product_variant')
disp = "#{disp} (#{variant})"
disp.htmlSafe()
@@ -0,0 +1,8 @@
attr = DS.attr
App.ProductVariant = DS.Model.extend Ember.Validations.Mixin,
name: attr 'string'
product: DS.belongsTo 'product'
position: attr 'number', defaultValue: 0
validations:
name:
presence: true
@@ -3,14 +3,14 @@ if editMode
.small-6.medium-3.columns.name
= input value=product.name placeholder=namePlaceholder action="save"
= errors product.errors.name
.small-6.medium-3.columns.actions
a.rollback-product-action{action "rollbackProduct"}: span
a.destroy-product-action{action "destroyProduct" product}: span
a.save-product-action{action "save"}: span
.small-6.medium-3.columns.price
= edit-currency value=product.price action="save"
= errors product.errors.price
.small-6.medium-3.columns.code= input value=product.code placeholder=codePlaceholder
.small-6.medium-3.columns.actions
a.rollback-product-action{action "rollbackProduct"}: span
a.destroy-product-action{action "destroyProduct" product}: span
a.save-product-action{action "save"}: span
.row
.small-3.columns= t 'attributes.product.active'
.small-9.columns: view boolean-switch value=product.active
@@ -21,6 +21,17 @@ if editMode
.small-12.medium-6.columns
= view "upload-file" name="image" accept="image/*" file=product.image
img src=product.image_src
each product_variant in product.product_variants
.row
.small-1.columns &nbsp;
.small-8.medium-5.large-4.columns= input value=product_variant.name
.small-2.medium-6.large-7.columns
button.remove-product-variant{action "removeProductVariant" product_variant}: span
.row
.small-12.columns
button.add-product-variant{ action "addProductVariant"}
span.icon
= t 'product_variant.add_product_variant'
else
if showProduct
.row
@@ -34,3 +45,6 @@ else
.small-3.columns
a.edit-product-action{action "makeEditable"}: span
/img src=product.image_src
if product.product_variants
.row
.small-12.columns= product.variantsDisplay
@@ -13,4 +13,4 @@ form.form-horizontal
.form-field= number-field numericValue=number_end
hr
button.modal-close{action "close"}=t 'section.add_tables.modal.close_button'
button.modal-confirm.right{action "addTables"}=t 'section.add_tables.modal.add_button'
button.modal-confirm.right{action "ok"}=t 'section.add_tables.modal.add_button'
@@ -21,7 +21,6 @@
@ttry = (path, vars={})->
@t(path, $.extend(vars, emptyWhenNotFound: true))
# return translation in the form
# <span data-t="models.table">Tafel</span>
@tspan = (path, vars={}) -> "<span data-t='#{path}' class='translation' data-t-attributes='#{JSON.stringify(vars)}'>#{t(path, vars)}</span>"
@@ -4,11 +4,13 @@ App.MenuProductComponent = Ember.Component.extend
specific_id: (-> "order-product-#{@get('product.id')}").property('product.id')
orderProducts: false
target: -> @get('parentView.targetObject')
showDescriptionIcon: Ember.computed.or 'product.description', 'product.product_variants.length'
actions:
addProduct: (product)->
if existing = @target().store.all('product_order').find((po)-> po.get('product') == product and not po.get('order'))
existing.increment()
if product.get('product_variants.length')
@target().modal 'product_variant_select', model: product
else
@target().store.createRecord 'product_order', product: product, price: product.get('price')
product.addOrderItem()
showProductDescription: (product)->
@target().modal 'product_info', model: product, title: product.get('name')
@@ -0,0 +1,5 @@
@App.modals.ProductVariantSelectController = @App.modals.BaseController.extend
actions:
chooseProductVariant: (product_variant)->
@get('model').addOrderItem(product_variant: product_variant.get('name'))
@send 'close'
@@ -31,10 +31,17 @@ App.ProductOrdersController = Ember.ArrayController.extend
#orders = @store.all('product_order').toArray()
#data = @get('product_orders').map( (po)->po.serialize() )
dataObject = order: {table_id: @get('controllers.table.model.id')}
@get('product_orders').forEach (product_order)-> dataObject['order'][product_order.get('product.id')] = product_order.get('quantity')
Ember.$.post "#{$data_host}/user/orders.json", dataObject, (response) =>
@store.pushPayload('order', response) if response.order
dataObject = {table_id: @get('controllers.table.model.id')}
dataObject.product_orders = @get('product_orders').map( (po) -> po.serialize()).toArray()
#@get('product_orders').forEach (product_order)-> dataObject['order'][product_order.get('product.id')] = product_order.get('quantity')
Ember.$.ajax
type: 'POST'
dataType: 'json'
contentType: 'application/json'
url: "#{$data_host}/user/orders.json"
data: JSON.stringify(dataObject)
success: (response) =>
@store.pushPayload('order', response) if response.order
@transitionToRoute 'active_list'
@get('product_orders').invoke 'unloadRecord'
@@ -0,0 +1,5 @@
attr = DS.attr
App.ProductVariant = DS.Model.extend
name: attr 'string'
product: DS.belongsTo 'product'
position: attr 'number', defaultValue: 0
@@ -6,5 +6,26 @@ App.Product = DS.Model.extend
position: attr('number', defaultValue: 0)
active: attr 'boolean', defaultValue: true
image: attr()
product_category: DS.belongsTo('product_category')
product_orders: DS.hasMany('product_order')
product_category: DS.belongsTo('product-category')
product_orders: DS.hasMany('product-order')
product_variants: DS.hasMany 'product-variant'
sorted_product_variants: Ember.computed 'product_variants.@each.name', 'product_variants.@each.position', ->
@get('product_variants').sortBy('position')
variantsDisplay: Ember.computed 'sorted_product_variants', ->
@get('sorted_product_variants').mapBy('name').join(', ')
addOrderItem: (options = {})->
#if existing = @store.all('product_order').find((po)-> po.get('product') == product and not po.get('order'))
if options.product_variant
existing = @get('product_orders').find( (po)-> !po.get('order') and po.get('product_variant') is options.product_variant )
else
existing = @get('product_orders').find( (po)-> !po.get('order') )
if existing
existing.increment()
else
@store.createRecord 'product_order',
product: this
price: @get('price')
product_variant: options.product_variant
@@ -4,12 +4,17 @@ App.ProductOrder = DS.Model.extend
price: attr 'number'
product_name: attr('string')
product: DS.belongsTo('product')
product_variant: attr('string')
order: DS.belongsTo('order')
placed: attr('boolean', defaultValue: false) # virtual attribute for new orders to be placed, should be more elegant
increment: ->
@set('quantity', @get('quantity') + 1)
total: (-> @get('quantity') * @get('price')).property('quantity', 'price')
display: (-> "#{@get('quantity')} x #{@get('product.name')}").property('quantity', 'product.name')
display: Ember.computed 'quantity', 'product_variant', 'product.name', ->
disp = "#{@get('quantity')} x #{@get('product.name')}"
if variant = @get('product_variant')
disp = "#{disp} (#{variant})"
disp.htmlSafe()
setOrder: (order)->
@set('placed', true)
@set('order', order)
@@ -1,4 +1,4 @@
if product.description
if showDescriptionIcon
button.show-product-description{action "showProductDescription" product}
span
else
@@ -1,5 +1,10 @@
if image
.right: img src=image.small alt=""
p==description
if product_variants
h4= t 'models.plural.product_variant'
ul
each product_variant in product_variants
li= product_variant.name
hr
button{action "close"}= t 'modal.info.close'
@@ -0,0 +1,8 @@
if model.image
.right: img src=model.image.small alt=""
each product_variant in product_variants
.row
.small-8.columns: a{action "chooseProductVariant" product_variant}= product_variant.name
.small-4.columns: a.choose-product-variant-button{action "chooseProductVariant" product_variant}= t 'product_variant.choose'
hr
button.modal-close{action "close"}= t 'modal.info.close'
@@ -90,6 +90,15 @@
@extend .fa
@extend .fa-lg
@extend .fa-trash
.remove-product-variant
+push-button($bg: $alert-color, $padding: 5px)
span
@extend .fa, .fa-trash
.add-product-variant
+button($bg: $success-color, $padding: $button-tny)
.icon
@extend .fa, .fa-plus
margin-right: 6px
.error
color: $alert-color
input
@@ -1,7 +1,8 @@
.modal
margin: auto
margin-top: 90px
width: 300px
width: 90%
max-width: 756px
background-color: #fff
padding: 1em
z-index: 9085
@@ -0,0 +1,4 @@
.choose-product-variant-button
+button($padding: $button-tny)
margin: 0
margin-bottom: 6px
@@ -0,0 +1,66 @@
module Suppliers
class ProductVariantsController < Suppliers::ApplicationController
layout 'tablet'
# GET /product_variants
# GET /product_variants.json
def index
end
# GET /product_variants/1
# GET /product_variants/1.json
def show
end
# GET /product_variants/new
# GET /product_variants/new.json
def new
end
# GET /product_variants/1/edit
def edit
end
# POST /product_variants
# POST /product_variants.json
def create
@product_variant = ProductVariant.new(product_variant_params)
@product_variant.supplier = current_supplier
if @product_variant.save
render json: @product_variant
else
render json: {errors: @product_variant.errors}, status: :unprocessable_entity
end
end
# PUT /product_variants/1
# PUT /product_variants/1.json
def update
@product_variant = ProductVariant.find(params[:id])
head :unprocessable_entity and return unless product_id = product_variant_params[:product_id]
product = Product.find(product_id)
head :forbidden and return unless product.supplier_id == current_supplier.id
if @product_variant.update_attributes(product_variant_params)
render json: @product_variant
else
render json: {errors: @product_variant.errors}, status: :unprocessable_entity
end
end
# DELETE /product_variants/1
# DELETE /product_variants/1.json
def destroy
#@product_variant = ProductVariant.find_by_supplier_id_and_id!(current_supplier.id, params[:id])
@product_variant = ProductVariant.find(params[:id])
@product_variant.destroy
render json: {}
end
private
def product_variant_params
params.require(:product_variant).permit(:name, :product_id)
end
end
end
@@ -5,7 +5,7 @@ module Suppliers
end
def show
[current_supplier].include_relations(sections: :tables, product_categories: :products)
[current_supplier].include_relations(sections: :tables, product_categories: {products: :product_variants})
render json: current_supplier, serializer: Suppliers::SupplierSerializer #.new(current_supplier).as_json
end
+4 -7
View File
@@ -6,9 +6,6 @@ module Users
# POST /user/orders
def create
# render json: {}, status: :unprocessable_entity and return unless params[:order].present? && params[:order][:product_orders].present?
# converted_order = params[:order][:product_orders].each_with_object({}){|po, o| o[po[:product_id]] = po[:quantity] }
converted_order = params[:order]
table_id = params[:order].delete('table_id')
if list = current_user.active_list
render json: {}, status: :not_acceptable and return unless list.supplier.open?
else
@@ -16,8 +13,8 @@ module Users
#NOTE: security bug here!!!!!!
# - supplier.open?
# - etc....
render json: {}, status: :unprocessable_entity and return unless table_id.present?
table = Table.find(table_id)
render json: {}, status: :unprocessable_entity and return unless params[:table_id].present?
table = Table.find(params[:table_id])
render json: {}, status: :not_acceptable and return unless table.supplier.open?
if table.occupied?
@@ -27,8 +24,8 @@ module Users
list = List.from_table( table, current_user )
end
order = list.place_order products: converted_order, user: current_user
render json: order, serializer: OrderSerializer
order = list.place_order product_orders: params[:product_orders], user: current_user
render json: order, serializer: OrderSerializer
#render nothing: true
end
end
+10 -6
View File
@@ -9,7 +9,10 @@ class Employee
}
DEFAULT_SETTINGS.each do |attribute, default_value|
define_method(attribute) { settings.public_send attribute }
define_method("#{attribute}=") { |value| settings.set attribute, value }
define_method("#{attribute}=") do |value|
is_dirty
settings.set attribute, value
end
if default_value == true or default_value == false # boolean
define_method(:"#{attribute}?"){ public_send attribute }
end
@@ -44,11 +47,12 @@ class Employee
end
alias_method :settings=, :enrich_with_settings
alias_method :orig_save, :save
def save(*args)
settings.persist!
orig_save(*args)
end
#alias_method :orig_save, :save
#def save(*args)
#settings.persist!
#orig_save(*args)
#end
before_save { settings.persist! }
def settings
@settings || SupplierEmployeesSettings.new(Supplier.new).for_employee(self)
+20 -7
View File
@@ -17,6 +17,7 @@ class List
belongs_to :table
belongs_to :supplier
belongs_to :section
has_many :list_payments
has_and_belongs_to_many :users, storing_keys: true
has_and_belongs_to_many :employees, storing_keys: true
@@ -274,16 +275,28 @@ class List
state == 'active'
end
def place_order(products: {}, user: nil, employee: nil)
return false unless products.any?
def closed?
state == 'closed'
end
def place_order(product_orders: [], user: nil, employee: nil)
return false unless product_orders.any?
order = Order.create list: self, supplier: supplier, user: user, employee: employee, section_id: section_id, table_id: table_id
return unless order.id
orders_placed_count = supplier.increment_orders_placed_count!
loaded_products = self.class.database.load_document products.keys
products.each do |product_id, quantity|
product = loaded_products.find{|p| p.id == product_id} # to get the price
if quantity.to_i > 0
ProductOrder.create(order: order, product_id: product_id, quantity: quantity, price: product.price, product_name: product.name)
loaded_products = self.class.database.load_document product_orders.map{|po| po['product_id']}
product_orders.each do |product_order|
next unless product = loaded_products.find{|p| p.id == product_order['product_id']} # to get the price
quantity = product_order['quantity'].to_i
if quantity > 0
ProductOrder.create(
order: order,
product_id: product.id,
quantity: quantity,
price: product.price,
product_name: product.name,
product_variant: product_order['product_variant']
)
end
end
set_price
+16
View File
@@ -0,0 +1,16 @@
class ListPayment
include SimplyStored::Couch
include ActiveModel::SerializerSupport
property :amount
property :source # bitcoin, apple_pay, etc...
belongs_to :list
belongs_to :user
after_save :close_list_when_is_paid
validates :list_id, presence: true
def close_list_when_is_paid
amount_paid = list.list_payments.inject(0.0){|sum, payment| sum + payment.amount}
list.close! if amount_paid >= list.price
end
end
+1
View File
@@ -15,6 +15,7 @@ class Product
#has_and_belongs_to_many :product_categories, storing_keys: false
belongs_to :supplier # direct! category is an aid
has_many :product_orders
has_many :product_variants, dependent: :destroy
attr_protected :supplier_id
+3 -1
View File
@@ -5,6 +5,7 @@ class ProductOrder
property :quantity, type: Fixnum
property :price, type: Float
property :product_name
property :product_variant
belongs_to :product
belongs_to :order
@@ -14,7 +15,8 @@ class ProductOrder
# Getter for product name. If a supplier deletes a product, that has product_orders, the product
# will become nil. This method should handle this case.
alias_method :direct_product_name, :product_name
def product_name
product.try(:name) || '[deleted]'
direct_product_name.presence || product.try(:name) || '[deleted]'
end
end
+8
View File
@@ -0,0 +1,8 @@
class ProductVariant
include SimplyStored::Couch
include ActiveModel::SerializerSupport
property :name
property :position, type: Fixnum, default: 0
belongs_to :product
belongs_to :supplier
end
+5
View File
@@ -20,6 +20,10 @@ class Supplier
property :week_starts_on_monday, type: :boolean, default: true
property :employee_settings_storage
# PAYMENT
property :accept_bitpay, type: :boolean, default: false
property :bitpay_number
#LOCATION
property :lat, type: Float #, default: 52.08062426379751
property :lng, type: Float #, default: 4.312562942504883
@@ -35,6 +39,7 @@ class Supplier
#has_many :orders, through: :lists
has_many :products, dependent: :destroy
has_many :product_variants
has_many :product_categories, dependent: :destroy
has_many :tables, dependent: :destroy
has_many :lists, dependent: :destroy
+1
View File
@@ -19,6 +19,7 @@ class User
has_and_belongs_to_many :lists, storing_keys: false
has_many :orders
has_many :list_payments
validates_uniqueness_of :email
before_save :ensure_authentication_token
+1 -1
View File
@@ -1,4 +1,4 @@
# Used for user ember1
class ProductOrderSerializer < Qwaiter::Serializer
attributes :order_id, :product_id, :quantity, :price, :product_name
attributes :order_id, :product_id, :quantity, :price, :product_name, :product_variant
end
+3
View File
@@ -1,6 +1,9 @@
class ProductSerializer < Qwaiter::Serializer
root 'product'
attributes :name, :price, :description, :image, :code, :position, :visible, :active, :product_category_id
has_many :product_variants
def image
if object.image.present?
{small: object.image.url(:small)}
@@ -0,0 +1,4 @@
class ProductVariantSerializer < Qwaiter::Serializer
root 'product_variant'
attributes :name
end
+2
View File
@@ -78,3 +78,5 @@ en:
selected_products:
clear: Clear
order: Order
product_variant:
add_product_variant: Add ${models.product_variant}
+4
View File
@@ -9,6 +9,7 @@ en:
product: Product
order: Order
product_category: Product category
product_variant: Variant
section: Section
join_request: Join request
user_feedback: User feedback
@@ -26,6 +27,7 @@ en:
product: Products
order: Orders
product_category: Product categories
product_variant: Variants
section: Sections
join_request: Join requests
user_feedback: User feedbacks
@@ -52,6 +54,8 @@ en:
visible: Visible?
created_at: Created
image: Image
product_variant:
name: Name
list:
created_at: Created
state: Status
+4
View File
@@ -9,6 +9,7 @@ nl:
product: Product
order: Bestelling
product_category: Product categorie
product_variant: Variant
section: Afdeling
join_request: Deelname verzoek
employee: Werknemer
@@ -25,6 +26,7 @@ nl:
product: Producten
order: Bestellingen
product_category: Product categorieen
product_variant: Varianten
section: Afdelingen
join_request: Deelname verzoeken
employee: Werknemers
@@ -50,6 +52,8 @@ nl:
active: "Actief?"
created_at: Aangemaakt
image: Afbeelding
product_variant:
name: Naam
list:
created_at: Aangemaakt
state: Status
+2
View File
@@ -76,6 +76,8 @@ nl:
selected_products:
clear: Leegmaken
order: Bestellen
product_variant:
add_product_variant: ${models.product_variant} toevoegen
views:
pagination:
first: "&laquo; Eerste"
+1
View File
@@ -139,6 +139,7 @@ Qwaiter::Application.routes.draw do
get :preview_products
end
end
resources :product_variants
resources :lists do
collection do
get :active
-12183
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -1,7 +1,8 @@
db:
image: bterkuile/couchdb
volumes:
- db:/usr/local/var/lib/couchdb
- db/data:/usr/local/var/lib/couchdb
- db/config:/usr/local/etc/couchdb
expose:
- 5984
net: host
+1 -1
View File
@@ -20,5 +20,5 @@ step 'a new order on a table in another section is created' do
# @new_section = create :section, title: 'Terrace', supplier: @supplier
# @new_table = create :table, number: 59, section: @new_section, supplier: @supplier
@new_list = create :list, section: @other_section, table: @other_table, supplier: @supplier, user_ids: [@user.id]
@new_order = @new_list.place_order(products: {@product.id => 3}, user: @user)
@new_order = @new_list.place_order(product_orders: [ {'product_id' => @product.id, 'quantity' => 3}], user: @user)
end
+1 -1
View File
@@ -1,7 +1,7 @@
step "A new order is placed" do
@user ||= create :user
@list = create :list, state: 'active', supplier: @supplier, table: @table, section: @section, user_ids: [@user.id]
@order = @list.place_order products: {@product.id => 2}, user: @user
@order = @list.place_order product_orders: [{ 'product_id' => @product.id, 'quantity' => 2}], user: @user
end
step "an order with :quantity products :product_name should have been created" do |quantity, product_name|
+1 -1
View File
@@ -9,7 +9,7 @@ step "the order should be marked as delivered" do
end
step "another order is placed" do
@new_order = @list.place_order(products: {@product.id => 5}, user: @user)
@new_order = @list.place_order(product_orders: [{ 'product_id' => @product.id, 'quantity' => 5}], user: @user)
end
step "the user order should be created as a new order" do
@@ -43,7 +43,7 @@ step "there is another signed in user on the same list" do
end
step 'the other user orders a product :count times' do |count|
@list.place_order products: {@product.id => count.to_i}, user: @other_user
@list.place_order product_orders: [{'product_id' => @product.id, 'quantity' => count.to_i}], user: @other_user
end
step 'the other user is part of the list' do
+5
View File
@@ -0,0 +1,5 @@
FactoryGirl.define do
factory :list_payment do
end
end
+7
View File
@@ -0,0 +1,7 @@
Logo-bigMozo.bar is een systeem om bestellingen te doen met je smartphone. Als je wel eens op een terras of een afgelegen deel van een horeca gelegenheid hebt gezeten en vond dat het te lang duurde voordat er iemand aan je kwam vragen wat je wil bestellen dan weet je dat er nog veel te verbeteren is.
Om horeca gelegenheden te helpen de vraag van klanten beter te kunnen verwerken is mozo.bar ontstaan. Mozo.bar is een toevoeging voor horeca gelegenheden om klanten met hun smartphone te laten bestellen. Dit is de focus van Mozo.bar! Om het gemak en de sfeer waar mensen aan gewend zijn te handhaven integreert Mozo.bar zo goed mogelijk met de ervaring van mensen. Klanten kunnen gewoon op een lijstje bestellen en bij ondersteunde systemen komt de bestelling gewoon achter de bar of in de keuken uitgeprint.
Mozo.bar is gratis om in gebruik te nemen en in een handomdraai toegevoegd als extra dienst. Maak als horeca gelegenheid een account aan. Richt deze in en je kan aan de slag!
Heb je een ervaring of idee waardoor we de ervaring voor zowel de horeca bezoeker als de horeca gelegenheid kunnen verbeteren mail dit dan naar: experience@mozo.bar dan kunnen wij ervoor zorgen dat het gaan naar een horeca gelegenheid leuk en makkelijk wordt!
+4
View File
@@ -0,0 +1,4 @@
<div style="position: absolute; right: 0; top: -170px; z-index: 2222;"><img src="/assets/site/tablet-phone.png" alt="" width="249" height="166" /></div>
<p><img class="home-qr" src="/assets/qr.png" alt="Qr" width="124" height="124" />Welkom bij de mozo.bar&nbsp;website! Mozo.bar&nbsp;is een mobiele app waarmee je gemakkelijk bestellingen kan doen op terrassen, in bars of restaurants. Scan een Qr code op de tafel, en krijg meteen het menu te zien. Klik aan wat je wilt hebben en bestel. Dat is alles!</p>
<p>Momenteel is mozo.bar&nbsp;in de ontwikkelingsfase. Dit houdt in dat er nog veel moet gebeuren en dat we volledig open staan voor alle input die we kunnen krijgen. Onze missie is om zowel klant als kroegeigenaar blij te maken met de mogelijkheden die deze tijd ons biedt.</p>
<p>Schrijf je in op&nbsp;<a style="color: #7bb459; text-decoration: none;" href="https://www.facebook.com/mozo.bar" target="_blank">Facebook</a>&nbsp;of&nbsp;<a style="color: #7bb459; text-decoration: none;" href="https://www.twitter.com/Qwaiter" target="_blank">Twitter</a>&nbsp;om op de hoogte te worden gehouden.</p>
@@ -0,0 +1,13 @@
moduleForModel 'product', 'Product model',
needs: [
'model:product_variant',
'model:product_category',
'model:section_area',
'model:product_order',
'model:order',
'model:supplier'
]
#test "Nothing yet", ->
#element = @subject()
#assert 2, 2
@@ -1,5 +1,5 @@
moduleForModel 'section-element', 'Section element model',
needs: ['model:section', 'model:table']
needs: ['model:section', 'model:table', 'model:section-area']
test "box_size", ->
element = @subject
+21
View File
@@ -0,0 +1,21 @@
require 'spec_helper'
describe ListPayment do
it "does completes a list if amount is equal to the list amount" do
list = create :list, price: 10.22
create :list_payment, amount: 10.22, list: list
list.should be_closed
end
it "does completes a list if amount is greater than the list amount" do
list = create :list, price: 10.22
create :list_payment, amount: 12, list: list
list.should be_closed
end
it "does completes a list if amount is less than the list amount, but total payments on list bigger" do
list = create :list, price: 10.22
create :list_payment, amount: 7, list: list
list.should be_active
create :list_payment, amount: 7, list: list
list.should be_closed
end
end
+6 -6
View File
@@ -126,30 +126,30 @@ describe List do
describe '#place_order' do
it 'returns an order object' do
list.place_order(products: {product.id => 7}, user: user).should be_a Order
list.place_order(product_orders: [{'product_id' => product.id, 'quantity' => 7}], user: user).should be_a Order
end
it 'creates an order' do
expect{ list.place_order(products: {product.id => 7}, user: user) }.to change{ Order.count }.by(1)
expect{ list.place_order(product_orders: [{'product_id' => product.id, 'quantity' => 7}], user: user) }.to change{ Order.count }.by(1)
end
describe 'broadcasting' do
it 'broadcasts to the user and the supplier the active order counter' do
# create existing order
list.place_order(products: {product.id => 7}, user: user)
list.place_order(product_orders: [{'product_id' => product.id, 'quantity' => 7}], user: user)
# expect{
# list.place_order(products: {product.id => 3}, user: user)
# list.place_order(product_orders: [{product_id: product.id, quantity: 5}], user: user)
# }.to broadcast_to_user(user.id).message('orders_placed_count').with(count: 2)
expect{
list.place_order(products: {product.id => 5}, user: user)
list.place_order(product_orders: [{'product_id' => product.id, 'quantity' => 5}], user: user)
}.to broadcast_to_supplier(supplier.id).message('orders_placed_count').with(count: 2)
end
end
it 'sets the list price as kind of caching' do
list.place_order(products: {product.id => 7}, user: user)
list.place_order(product_orders: [{'product_id' => product.id, 'quantity' => 7}], user: user)
list.reload
list.price.should == 15.54
end
+1
View File
@@ -106,6 +106,7 @@ RSpec.configure do |config|
config.infer_base_class_for_anonymous_controllers = true
config.filter_run_excluding broken: true
config.render_views = true
config.expect_with(:rspec) { |c| c.syntax = [:expect, :should] }
OmniAuth.config.test_mode = true
OmniAuth.config.add_mock :facebook, {
+8
View File
@@ -103,3 +103,11 @@ Integrations
- Bonnetjes machine
- Payleven? Payment
Braindump:
Create blog
Explanation about ordering
The price is the actual price at the restaurant, is different when
waited for a long time