Signed-off-by: Adrian Hinz <adhinz@gmail.com>

This commit is contained in:
Adrian Hinz 2016-10-04 23:47:06 +02:00
parent c5fac2a54b
commit 09cfc055ea
31 changed files with 399 additions and 22 deletions

1
.gitignore vendored
View File

@ -19,3 +19,4 @@
# Ignore Byebug command history file.
.byebug_history
Gemfile.lock

View File

@ -5,7 +5,8 @@ source 'https://rubygems.org'
gem 'rails', '~> 5.0.0', '>= 5.0.0.1'
# Use sqlite3 as the database for Active Record
# gem 'sqlite3'
gem 'momentjs-rails', '>= 2.9.0'
gem 'bootstrap3-datetimepicker-rails', '~> 4.14.30'
gem 'devise'
gem 'mysql2'

View File

@ -12,5 +12,8 @@
//
//= require jquery
//= require jquery_ujs
//= require moment
//= require moment/pl
//= require bootstrap-datetimepicker
//= require turbolinks
//= require_tree .

View File

@ -11,5 +11,6 @@
* It is generally better to create a new file per style scope.
*
*= require_tree .
*= require bootstrap-datetimepicker
*= require_self
*/

View File

@ -1,4 +1,53 @@
class InvoicesController < ApplicationController
def index
@invoices = Invoice.where(user_id: current_user.id)
end
def show
@invoice = Invoice.find(params[:id])
end
def new
@invoice = Invoice.new(date: Date.today)
@user_firms = current_user.user_firms
@customers = current_user.customers
end
def create
@invoice = Invoice.new(invoice_params)
@invoice.user_id = current_user.id
if @invoice.save
redirect_to @invoice
else
@user_firms = current_user.user_firms
@customers = current_user.customers
render :new
end
end
def edit
@invoice = Invoice.find(params[:id])
end
def update
@invoice = Invoice.find(params[:id])
if @invoice.update_attributes(invoice_params)
redirect_to @invoice
else
@user_firms = current_user.user_firms
@customers = current_user.customers
render :edit
end
end
def destroy
@invoice = Invoice.find(params[:id])
@invoice.destroy unless @invoice.blank?
redirect_to invoices_path
end
private
def invoice_params
params.require(:invoice).permit(:number, :user_firm_id, :customer_id, :date, :date_of_payment)
end
end

View File

@ -6,6 +6,7 @@ class ProductsController < ApplicationController
def new
@product = Product.new
@vats = Vat.all
end
def create
@ -14,12 +15,14 @@ class ProductsController < ApplicationController
if @product.save
redirect_to products_path
else
@vats = Vat.all
render :new
end
end
def edit
@product = Product.find(params[:id])
@vats = Vat.all
end
def update
@ -27,6 +30,7 @@ class ProductsController < ApplicationController
if @product.update_attributes(product_params)
redirect_to products_path
else
@vats = Vat.all
render :edit
end
end

View File

@ -4,7 +4,7 @@ module ApplicationHelper
def menu
ret = ""
ret += create_menu_li("glyphicon glyphicon-home","Dashboard","/","welcome")
ret += create_menu_li("glyphicon glyphicon-list-alt","Faktury","/invoices/index","invoices")
ret += create_menu_li("glyphicon glyphicon-list-alt","Faktury","/invoices","invoices")
ret += create_menu_li("glyphicon glyphicon-book","Klienci","/customers","customers")
ret += create_menu_li("glyphicon glyphicon-shopping-cart","Produkty","/products","products")
ret += create_menu_li("glyphicon glyphicon-cog","Ustawienia","/settings/index","settings")

11
app/models/invoice.rb Normal file
View File

@ -0,0 +1,11 @@
class Invoice < ApplicationRecord
belongs_to :user
belongs_to :user_firm
belongs_to :customer
has_many :invoice_products
def netto_amount
0.0
end
end

View File

@ -0,0 +1,4 @@
class InvoiceProduct < ApplicationRecord
belongs_to :invoice
belongs_to :product
end

View File

@ -1,4 +1,5 @@
class Product < ApplicationRecord
belongs_to :vat
belongs_to :user
has_many :invoice_products
end

View File

@ -7,4 +7,5 @@ class User < ApplicationRecord
has_many :user_firms
has_many :products
has_many :customers
has_many :invoices
end

View File

@ -1,3 +1,4 @@
class UserFirm < ApplicationRecord
belongs_to :user
has_many :invoices
end

View File

@ -1,9 +1,9 @@
<div class="col-lg-8 col-md-12 panel-default">
<div class="content-box-header panel-heading">
<div class="panel-title">Nowy klient</div>
<div class="panel-options">
<%= link_to raw("<i class=\"glyphicon glyphicon-arrow-left text-success\"></i> " + I18n.t('back')), customers_path, title: I18n.t('back'), class: "text-primary" %>
</div>
<div class="panel-title">Nowy klient</div>
<div class="panel-options">
<%= link_to raw("<i class=\"glyphicon glyphicon-arrow-left text-success\"></i> " + I18n.t('back')), customers_path, title: I18n.t('back'), class: "text-primary" %>
</div>
</div>
<div class="content-box-large box-with-header">
<%= render 'form' %>

View File

@ -0,0 +1,52 @@
<%= form_for @invoice, html: {class: "form-horizontal"} do |f| %>
<% if @invoice.errors.any? %>
<%= raw errors_to_html(@invoice.errors) %>
<% end %>
<div class="form-group">
<%= f.label :number, class: "col-sm-2 control-label" %>
<div class="col-sm-10">
<%= f.text_field :number, class: "form-control", placeholder: 'Numer faktury' %>
</div>
</div>
<div class="form-group">
<%= f.label :user_firm, class: "col-sm-2 control-label" %>
<div class="col-sm-10">
<%= f.select :user_firm_id, @user_firms.collect {|uf| [ uf.name, uf.id ] }, {}, {class: "form-control"} %>
</div>
</div>
<div class="form-group">
<%= f.label :customer, class: "col-sm-2 control-label" %>
<div class="col-sm-10">
<%= f.select :customer_id, @customers.collect {|c| [ c.name, c.id ] }, {include_blank: true}, {class: "form-control"} %>
</div>
</div>
<div class="form-group">
<%= f.label :date, class: "col-sm-2 control-label" %>
<div class="col-sm-10">
<div class="input-group date">
<%= f.text_field :date, class: "form-control datepicker", placeholder: 'Data wystawienia' %>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar">
</span>
</span>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<%= f.submit 'Zapisz', class: "btn btn-primary" %>
</div>
</div>
<script type="text/javascript">
$(function() {
// Bootstrap DateTimePicker v4
$('.datepicker').datetimepicker({
useCurrent: true,
locale: 'pl',
format: 'YYYY-MM-DD'
});
});
</script>
<% end %>

View File

@ -0,0 +1,17 @@
<div class="row">
<div class="col-md-12">
<div class="content-box-large">
<div class="panel-heading">
<div class="panel-title">Faktura VAT</div>
</div>
<div class="panel-body">
Ut tristique adipiscing mauris, sit amet suscipit metus porta quis. Donec dictum tincidunt erat, eu blandit ligula. Nam sit amet dolor sapien. Quisque velit erat, congue sed suscipit vel, feugiat sit amet enim. Suspendisse interdum enim at mi tempor commodo. Sed tincidunt sed tortor eu scelerisque. Donec luctus malesuada vulputate. Nunc vel auctor metus, vel adipiscing odio. Aliquam aliquet rhoncus libero, at varius nisi pulvinar nec. Aliquam erat volutpat. Donec ut neque mi. Praesent enim nisl, bibendum vitae ante et, placerat pharetra magna. Donec facilisis nisl turpis, eget facilisis turpis semper non. Maecenas luctus ligula tincidunt iasdsd vitae ante et,
<br><br>
Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque sed consectetur erat. Maecenas in elementum libero. Sed consequat pellentesque ultricies. Ut laoreet vehicula nisl sed placerat. Duis posuere lectus n, eros et hendrerit pellentesque, ante magna condimentum sapien, eget ultrices eros libero non orci. Etiam varius diam lectus.
<br><br>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,12 @@
<div class="col-lg-8 col-md-12 panel-default">
<div class="content-box-header panel-heading">
<div class="panel-title">Edycja faktury</div>
<div class="panel-options">
<%= link_to raw("<i class=\"glyphicon glyphicon-arrow-left text-success\"></i> " + I18n.t('back')), invoices_path, title: I18n.t('back'), class: "text-primary" %>
</div>
</div>
<div class="content-box-large box-with-header">
<%= render 'form' %>
</div>
</div>
</div>

View File

@ -1,15 +1,35 @@
<div class="col-md-12">
<div class="content-box-large">
<div class="panel-heading">
<div class="col-md-12 panel-default">
<div class="content-box-header panel-heading">
<div class="panel-title">Faktury</div>
<div class="panel-options">
<%= link_to raw('<i class="glyphicon glyphicon-file text-success"></i> Nowa faktura'), new_invoice_path, class: "text-primary" %><br/>
</div>
</div>
<div class="panel-body">
<div class="content-box-large box-with-header">
<table class="table table-striped table-bordered">
<tr>
<th>Numer</th>
<th>Klient</th>
<th>Kwota netto</th>
<th>Data wystawienia</th>
<th>Termin płatności</th>
<th>Akcje</th>
</tr>
<% @invoices.each do |invoice| %>
<tr>
<td><%= invoice.number %></td>
<td><%= invoice.customer.name %></td>
<td><%= number_with_precision(invoice.netto_amount, precision: 2) %></td>
<td><%= invoice.date %></td>
<td><%= invoice.date_of_payment %></td>
<td>
<%= link_to raw('<i class="glyphicon glyphicon-pencil"></i> Edycja'), edit_invoice_path(invoice), class: "btn btn-primary btn-xs" %>
<%= link_to raw('<i class="glyphicon glyphicon-trash"></i> Usuń'), invoice_path(invoice), class: "btn btn-danger btn-xs", method: :delete, data: { confirm: 'Czy na pewno usunąć?' } %>
</td>
</tr>
<% end %>
</table>
</div>
</div>
</div>

View File

@ -0,0 +1,11 @@
<div class="col-lg-8 col-md-12 panel-default">
<div class="content-box-header panel-heading">
<div class="panel-title">Nowa faktura</div>
<div class="panel-options">
<%= link_to raw("<i class=\"glyphicon glyphicon-arrow-left text-success\"></i> " + I18n.t('back')), invoices_path, title: I18n.t('back'), class: "text-primary" %>
</div>
</div>
<div class="content-box-large box-with-header">
<%= render 'form' %>
</div>
</div>

View File

@ -0,0 +1,12 @@
<div class="col-lg-12 col-md-12 panel-default">
<div class="content-box-header panel-heading">
<div class="panel-title">Faktura: <%= @invoice.number %></div>
<div class="panel-options">
<%= link_to raw("<i class=\"glyphicon glyphicon-arrow-left text-success\"></i> " + I18n.t('back')), invoices_path, title: I18n.t('back'), class: "text-primary" %>
</div>
</div>
<div class="content-box-large box-with-header" style="background:#dddddd">
<%= render 'show' %>
</div>
</div>
</div>

View File

@ -0,0 +1,35 @@
<%= form_for @product, html: {class: "form-horizontal"} do |f| %>
<% if @product.errors.any? %>
<%= raw errors_to_html(@product.errors) %>
<% end %>
<div class="form-group">
<%= f.label :name, class: "col-sm-2 control-label" %>
<div class="col-sm-10">
<%= f.text_field :name, class: "form-control", placeholder: 'Nazwa' %>
</div>
</div>
<div class="form-group">
<%= f.label :netto_price, class: "col-sm-2 control-label" %>
<div class="col-sm-10">
<%= f.text_field :netto_price, class: "form-control", placeholder: 'Wartość netto' %>
</div>
</div>
<div class="form-group">
<%= f.label :qnt_name, class: "col-sm-2 control-label" %>
<div class="col-sm-10">
<%= f.text_field :qnt_name, class: "form-control", placeholder: 'Jednostka miary' %>
</div>
</div>
<div class="form-group">
<%= f.label :vat, class: "col-sm-2 control-label" %>
<div class="col-sm-10">
<%= f.select :vat_id, @vats.collect {|v| [ v.name, v.id ] }, {}, {class: "form-control"} %>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<%= f.submit 'Zapisz', class: "btn btn-primary" %>
</div>
</div>
<% end %>

View File

@ -0,0 +1,12 @@
<div class="col-lg-8 col-md-12 panel-default">
<div class="content-box-header panel-heading">
<div class="panel-title">Edycja produktu</div>
<div class="panel-options">
<%= link_to raw("<i class=\"glyphicon glyphicon-arrow-left text-success\"></i> " + I18n.t('back')), products_path, title: I18n.t('back'), class: "text-primary" %>
</div>
</div>
<div class="content-box-large box-with-header">
<%= render 'form' %>
</div>
</div>
</div>

View File

@ -1,15 +1,33 @@
<div class="col-md-12">
<div class="content-box-large">
<div class="panel-heading">
<div class="col-md-12 panel-default">
<div class="content-box-header panel-heading">
<div class="panel-title">Produkty</div>
<div class="panel-options">
<%= link_to raw('<i class="glyphicon glyphicon-file text-success"></i> Nowy produkt'), new_product_path, class: "text-primary" %><br/>
</div>
</div>
<div class="panel-body">
<div class="content-box-large box-with-header">
<table class="table table-striped table-bordered">
<tr>
<th>Nazwa</th>
<th>Wartość netto</th>
<th>VAT</th>
<th>Jednostka miary</th>
<th>Akcje</th>
</tr>
<% @products.each do |product| %>
<tr>
<td><%= product.name %></td>
<td><%= number_with_precision(product.netto_price, precision: 2) %></td>
<td><%= product.vat.name %></td>
<td><%= product.qnt_name %></td>
<td>
<%= link_to raw('<i class="glyphicon glyphicon-pencil"></i> Edycja'), edit_product_path(product), class: "btn btn-primary btn-xs" %>
<%= link_to raw('<i class="glyphicon glyphicon-trash"></i> Usuń'), product_path(product), class: "btn btn-danger btn-xs", method: :delete, data: { confirm: 'Czy na pewno usunąć?' } %>
</td>
</tr>
<% end %>
</table>
</div>
</div>
</div>

View File

@ -0,0 +1,11 @@
<div class="col-lg-8 col-md-12 panel-default">
<div class="content-box-header panel-heading">
<div class="panel-title">Nowy produkt</div>
<div class="panel-options">
<%= link_to raw("<i class=\"glyphicon glyphicon-arrow-left text-success\"></i> " + I18n.t('back')), products_path, title: I18n.t('back'), class: "text-primary" %>
</div>
</div>
<div class="content-box-large box-with-header">
<%= render 'form' %>
</div>
</div>

View File

@ -1,10 +1,10 @@
Rails.application.routes.draw do
get 'invoices/index'
get 'settings/index'
devise_for :users
resources :products
resources :invoices
resources :customers

View File

@ -0,0 +1,14 @@
class CreateInvoices < ActiveRecord::Migration[5.0]
def change
create_table :invoices do |t|
t.references :user, foreign_key: true
t.references :user_firm, foreign_key: true
t.references :customer, foreign_key: true
t.string :number
t.date :date
t.date :date_of_payment
t.timestamps
end
end
end

View File

@ -0,0 +1,12 @@
class CreateInvoiceProducts < ActiveRecord::Migration[5.0]
def change
create_table :invoice_products do |t|
t.references :invoice, foreign_key: true
t.references :product, foreign_key: true
t.decimal :netto_price, { precision: 18, scale: 2 }
t.decimal :qty, { precision: 18, scale: 3 }
t.timestamps
end
end
end

View File

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20161003103325) do
ActiveRecord::Schema.define(version: 20161004200042) do
create_table "customers", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci" do |t|
t.string "name"
@ -25,6 +25,31 @@ ActiveRecord::Schema.define(version: 20161003103325) do
t.index ["user_id"], name: "index_customers_on_user_id", using: :btree
end
create_table "invoice_products", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci" do |t|
t.integer "invoice_id"
t.integer "product_id"
t.decimal "netto_price", precision: 18, scale: 2
t.decimal "qty", precision: 18, scale: 3
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["invoice_id"], name: "index_invoice_products_on_invoice_id", using: :btree
t.index ["product_id"], name: "index_invoice_products_on_product_id", using: :btree
end
create_table "invoices", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci" do |t|
t.integer "user_id"
t.integer "user_firm_id"
t.integer "customer_id"
t.string "number"
t.date "date"
t.date "date_of_payment"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["customer_id"], name: "index_invoices_on_customer_id", using: :btree
t.index ["user_firm_id"], name: "index_invoices_on_user_firm_id", using: :btree
t.index ["user_id"], name: "index_invoices_on_user_id", using: :btree
end
create_table "products", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci" do |t|
t.string "name"
t.integer "vat_id"
@ -80,6 +105,11 @@ ActiveRecord::Schema.define(version: 20161003103325) do
end
add_foreign_key "customers", "users"
add_foreign_key "invoice_products", "invoices"
add_foreign_key "invoice_products", "products"
add_foreign_key "invoices", "customers"
add_foreign_key "invoices", "user_firms"
add_foreign_key "invoices", "users"
add_foreign_key "products", "users"
add_foreign_key "products", "vats"
add_foreign_key "user_firms", "users"

13
test/fixtures/invoice_products.yml vendored Normal file
View File

@ -0,0 +1,13 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
one:
invoice: one
product: one
netto_price:
qty:
two:
invoice: two
product: two
netto_price:
qty:

17
test/fixtures/invoices.yml vendored Normal file
View File

@ -0,0 +1,17 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
one:
user: one
user_firm: one
customer: one
number: MyString
date: 2016-10-04
date_of_payment: 2016-10-04
two:
user: two
user_firm: two
customer: two
number: MyString
date: 2016-10-04
date_of_payment: 2016-10-04

View File

@ -0,0 +1,7 @@
require 'test_helper'
class InvoiceProductTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end

View File

@ -0,0 +1,7 @@
require 'test_helper'
class InvoiceTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end