Menghasilkan Faktur dan Pelacakan

11

Setiap 2 minggu, sistem akan menghasilkan faktur untuk perusahaan.

Perusahaan akan menerima faktur pada tanggal 1 dan 16 setiap bulan. (Ini akan berjalan melalui Cron Job setiap 2 minggu. Memindai melalui tabel pesanan dan kemudian menambahkan ke tabel 'faktur'. Apakah ada alternatif?)

Ada daftar pesanan pelanggan dalam orderstabel dan ini juga menunjukkan perusahaan yang menjadi miliknya ( orders.company_id)

The invoicemeja menghitung total biaya pesanan dari ordersmeja.

Saya mencoba mencari cara untuk merancang pelacakan faktur yang masuk akal. Kadang-kadang perusahaan harus mengirim saya biaya atau kadang saya mengirim mereka biaya ( invoice.amount)

Saya perlu melacak faktur dengan yang berikut:

  • ketika perusahaan telah mengirimi saya jumlahnya
  • kapan saya mengirim jumlahnya ke perusahaan
  • berapa jumlah yang telah diterima dari perusahaan
  • berapa jumlah yang saya kirim ke perusahaan
  • apakah saya menerima jumlah penuh (jika tidak, apa yang harus saya perbarui pada Db?)
  • status faktur (Faktur Terkirim, Dibatalkan, Jumlah Diterima, Jumlah Terkirim)

Berikut adalah desain database yang saya buat:

meja perusahaan

mysql> select * from company;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | Company A |
|  2 | Company B |
+----+-----------+

Pelanggan dapat memilih perusahaan dari situs web saya.

tabel pesanan

mysql> select * from orders;
+----+---------+------------+------------+---------------------+-----------+
| id | user_id | company_id | total_cost | order_date          | status_id |
+----+---------+------------+------------+---------------------+-----------+
|  1 |       5 |          2 |      25.00 | 2012-02-03 23:30:24 |         1 |
|  2 |       7 |          2 |      30.00 | 2012-02-13 18:06:12 |         1 |
+----+---------+------------+------------+---------------------+-----------+

dua pelanggan telah memesan produk dari Perusahaan B ( orders.company_id = 2). Saya tahu bidang pesanan tidak cukup, cukup disederhanakan untuk Anda.

tabel orders_products

mysql> select * from orders_products;
+----+----------+------------+--------------+-------+
| id | order_id | product_id | product_name | cost  |
+----+----------+------------+--------------+-------+
|  1 |        1 |         34 | Chair        | 10.00 |
|  2 |        1 |         25 | TV           | 10.00 |
|  3 |        1 |         27 | Desk         |  2.50 |
|  4 |        1 |         36 | Laptop       |  2.50 |
|  5 |        2 |         75 | PHP Book     | 25.00 |
|  6 |        2 |         74 | MySQL Book   |  5.00 |
+----+----------+------------+--------------+-------+

Daftar produk yang dipesan pelanggan.

tabel faktur

mysql> select * from invoice;
+----+------------+------------+---------------------+--------+-----------+
| id | company_id | invoice_no | invoice_date        | amount | status_id |
+----+------------+------------+---------------------+--------+-----------+
|  7 |          2 |        123 | 2012-02-16 23:59:59 |  55.00 |         1 |
+----+------------+------------+---------------------+--------+-----------+

Di sinilah saya cukup terjebak pada desain tabel faktur. Saya tidak yakin bagaimana itu harus dilakukan. Faktur akan dibuat setiap 2 minggu. Dari hasil contoh invoice.amountadalah 55,00 karena sudah dihitung dari orders.company_id = 2tabel

Jika invoice.amountis -50.00 (minus), itu berarti perusahaan perlu mengirim saya jumlah biaya.

Jika invoice.amount50,00, itu berarti saya harus mengirim biaya kepada perusahaan.

Status_id dapat berupa: (1) Faktur Terkirim, (2) Dibatalkan, (3) Selesai

Apakah saya perlu menambahkan invoice_idbidang dalam orderstabel? Perbarui orders.invoice_idbidang saat baris telah dimasukkan ke tabel 'faktur'.

tabel faktur_pembayaran

mysql> select * from invoice_payment;
+----+------------+-----------------+-------------+---------------------+---------------------+
| id | invoice_id | amount_received | amount_sent | date_received       | date_sent           |
+----+------------+-----------------+-------------+---------------------+---------------------+
|  1 |          1 |            0.00 |       55.00 | 0000-00-00 00:00:00 | 2012-02-18 22:20:53 |
+----+------------+-----------------+-------------+---------------------+---------------------+

Di sinilah saya dapat melacak dan memperbarui transaksi .. pembayaran akan dilakukan melalui BACS.

Apakah ini tabel yang bagus atau apa yang perlu saya tingkatkan? Bidang dan tabel apa yang harus saya tambahkan?

Jika faktur telah dibuat dan kemudian saya perlu membuat perubahan dalam orders_productsatau orderstabel - haruskah ia menghitung ulang invoice.amountbidang? (Saya akan menggunakan PHP / MySQL).

SQL Dump :

CREATE TABLE IF NOT EXISTS `company` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(25) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

INSERT INTO `company` (`id`, `name`) VALUES
(1, 'Company A'),
(2, 'Company B');

CREATE TABLE IF NOT EXISTS `invoice` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `company_id` int(11) NOT NULL,
  `invoice_no` int(11) NOT NULL,
  `invoice_date` datetime NOT NULL,
  `amount` decimal(6,2) NOT NULL,
  `status_id` tinyint(1) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;


INSERT INTO `invoice` (`id`, `company_id`, `invoice_no`, `invoice_date`, `amount`, `status_id`) VALUES
(7, 2, 123, '2012-02-16 23:59:59', '55.00', 1);


CREATE TABLE IF NOT EXISTS `invoice_payment` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `invoice_id` int(11) NOT NULL,
  `amount_received` decimal(6,2) NOT NULL,
  `amount_sent` decimal(6,2) NOT NULL,
  `date_received` datetime NOT NULL,
  `date_sent` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

INSERT INTO `invoice_payment` (`id`, `invoice_id`, `amount_received`, `amount_sent`, `date_received`, `date_sent`) VALUES
(1, 1, '0.00', '55.00', '0000-00-00 00:00:00', '2012-02-18 22:20:53');


CREATE TABLE IF NOT EXISTS `orders` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `company_id` int(11) NOT NULL,
  `total_cost` decimal(6,2) NOT NULL,
  `order_date` datetime NOT NULL,
  `status_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;


INSERT INTO `orders` (`id`, `user_id`, `company_id`, `total_cost`, `order_date`, `status_id`) VALUES
(1, 5, 2, '25.00', '2012-02-03 23:30:24', 1),
(2, 7, 2, '30.00', '2012-02-13 18:06:12', 1);


CREATE TABLE IF NOT EXISTS `orders_products` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `order_id` int(11) NOT NULL,
  `product_id` int(11) NOT NULL,
  `product_name` varchar(100) NOT NULL,
  `cost` decimal(6,2) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;

INSERT INTO `orders_products` (`id`, `order_id`, `product_id`, `product_name`, `cost`) VALUES
(1, 1, 34, 'Chair', '10.00'),
(2, 1, 25, 'TV', '10.00'),
(3, 1, 27, 'Desk', '2.50'),
(4, 1, 36, 'Laptop', '2.50'),
(5, 2, 75, 'PHP Book', '25.00'),
(6, 2, 74, 'MySQL Book', '5.00');

Jangan ragu untuk memperbarui / menambahkan tabel ke Jawab di sini.

Terima kasih

Aku akan kembali
sumber

Jawaban:

8

Pencocokan uang tunai

Ini adalah masalah pencocokan uang tunai. Anda dapat melacak ini di salah satu dari dua level:

  • Bandingkan ditagih dengan angka tunai (agak ceroboh tapi ini sebenarnya cara itu dilakukan untuk bisnis dalam oleh sebagian besar Lloyd's Syndicates, sering disebut laporan 'tertulis vs. ditandatangani').

  • Pertahankan alokasi kas eksplisit dari pembayaran tunai yang dikelompokkan berdasarkan faktur.

Dari pertanyaan Anda, saya pikir Anda ingin melakukan yang terakhir.

Biasanya ini dilakukan dengan memiliki satu set transaksi tunai yang terpisah, dan tabel bridging yang memiliki alokasi pembayaran tunai untuk faktur. Jika nilainya sama atau pembayaran tunai disertai dengan satu faktur referensi, Anda dapat melakukan alokasi secara otomatis. Jika ada hubungan M: M antara faktur dan pembayaran, Anda harus melakukan proses pencocokan manual (melakukan ini secara otomatis sebenarnya merupakan varian dari masalah ransel ).

Sistem pencocokan uang tunai dasar

Bayangkan Anda memiliki tabel faktur, tabel pembayaran tunai, dan tabel alokasi. Ketika Anda mengeluarkan faktur maka Anda mengatur catatan faktur di tabel faktur dan catatan 'piutang' atau 'hutang' di tabel alokasi.

  • Faktur # 1, $ 100

  • Alokasi: catatan dengan referensi ke faktur # 1, jenis transaksi 'piutang' dan $ 100 terutang. Tidak ada referensi untuk pembayaran tunai pada catatan ini.

Sekarang, Anda mendapatkan pembayaran tunai sebesar $ 100

  • Pembayaran tunai (chq # 12345): $ 100

  • Alokasi: catatan dengan referensi ke faktur # 1 dan chq # 12345, jenis transaksi 'tunai' dan -100 berhutang (dibayar $ 100).

Anda dapat menggeneralisasi ini ke hubungan M: M di mana Anda menerima beberapa pembayaran terhadap satu faktur atau pembayaran yang mencakup banyak faktur. Struktur ini juga memudahkan pembuatan laporan kontrol kredit. Laporan hanya perlu menemukan faktur yang lebih lama dari (katakanlah) 180 hari yang masih memiliki saldo terutang.

Berikut adalah contoh skema ditambah beberapa skenario dan permintaan utang yang sudah tua. Sayangnya saya tidak memiliki instance mysql yang sedang berjalan, jadi yang ini untuk SQL Server.

-- ==============================================================
-- === CashMatch.sql ============================================
-- ==============================================================
--


-- === Invoices =================================================
--
create table Invoice (
       InvoiceID        int identity (1,1) not null
      ,InvoiceRef       varchar (20)
      ,Amount           money
      ,InvoiceDate      datetime
)
go

alter table Invoice
  add constraint PK_Invoice 
      primary key nonclustered (InvoiceID)
go


-- === Cash Payments ============================================
--
create table CashPayment (
       CashPaymentID    int identity (1,1) not null
      ,CashPaymentRef   varchar (20)
      ,Amount           money
      ,PaidDate         datetime
)
go

alter table CashPayment
  add constraint PK_CashPayment
      primary key nonclustered (CashPaymentID)
go




-- === Allocations ==============================================
--
create table Allocation (
       AllocationID       int identity (1,1) not null
      ,CashPaymentID      int  -- Note that some records are not
      ,InvoiceID          int  -- on one side.
      ,AllocatedAmount    money
      ,AllocationType     varchar (20)
      ,TransactionDate    datetime
)
go

alter table Allocation
  add constraint PK_Allocation
      primary key nonclustered (AllocationID)
go


-- ==============================================================
-- === Scenarios ================================================
-- ==============================================================
--
declare @Invoice1ID int
       ,@Invoice2ID int
       ,@PaymentID int


-- === Raise a new invoice ======================================
--
insert Invoice (InvoiceRef, Amount, InvoiceDate)
values ('001', 100, '2012-01-01')

set @Invoice1ID = @@identity

insert Allocation (
       InvoiceID
      ,AllocatedAmount
      ,TransactionDate
      ,AllocationType
) values (@Invoice1ID, 100, '2012-01-01', 'receivable')


-- === Receive a payment ========================================
--
insert CashPayment (CashPaymentRef, Amount, PaidDate)
values ('12345', 100, getdate())

set @PaymentID = @@identity

insert Allocation (
       InvoiceID
      ,CashPaymentID
      ,AllocatedAmount
      ,TransactionDate
      ,AllocationType
) values (@Invoice1ID, @PaymentID, -100, getdate(), 'paid')



-- === Raise two invoices =======================================
--
insert Invoice (InvoiceRef, Amount, InvoiceDate)
values ('002', 75, '2012-01-01')

set @Invoice1ID = @@identity

insert Allocation (
       InvoiceID
      ,AllocatedAmount
      ,TransactionDate
      ,AllocationType
) values (@Invoice1ID, 75, '2012-01-01', 'receivable')


insert Invoice (InvoiceRef, Amount, InvoiceDate)
values ('003', 75, '2012-01-01')

set @Invoice2ID = @@identity

insert Allocation (
       InvoiceID
      ,AllocatedAmount
      ,TransactionDate
      ,AllocationType
) values (@Invoice2ID, 75, '2012-01-01', 'receivable')


-- === Receive a payment ========================================
-- The payment covers one invoice in full and part of the other.
--
insert CashPayment (CashPaymentRef, Amount, PaidDate)
values ('23456', 120, getdate()) 

set @PaymentID = @@identity

insert Allocation (
       InvoiceID
      ,CashPaymentID
      ,AllocatedAmount
      ,TransactionDate
      ,AllocationType
) values (@Invoice1ID, @PaymentID, -75, getdate(), 'paid')

insert Allocation (
       InvoiceID
      ,CashPaymentID
      ,AllocatedAmount
      ,TransactionDate
      ,AllocationType
) values (@Invoice2ID, @PaymentID, -45, getdate(), 'paid')



-- === Aged debt report ========================================
--
select i.InvoiceRef
      ,sum (a.AllocatedAmount)                 as Owing
      ,datediff (dd, i.InvoiceDate, getdate()) as Age
  from Invoice i
  join Allocation a
    on a.InvoiceID = i.InvoiceID
 group by i.InvoiceRef
         ,datediff (dd, i.InvoiceDate, getdate())
having sum (a.AllocatedAmount) > 0
ConcernedOfTunbridgeWells
sumber
Milik saya memiliki tabel terpisah untuk faktur dan pembayaran. Anda bisa menggunakan tabel umum dengan tautan internal. Pencocokan uang tunai sering diterapkan seperti itu dalam sistem akuntansi.
ConcernedOfTunbridgeWells
Saya telah berhasil menerjemahkan contoh SQL Server Anda ke MySQL. Saya telah melalui dan saya mengerti dengan baik sekarang. Apa yang akan AllocationTypeterjadi jika saya ingin mengirim uang klien? Apakah saya perlu memasukkan ke dalam CashPaymenttabel juga (misalkan membayar mereka melalui BACS)?
I'll-Be-Back
1
Ya, Anda ingin catatan pembayaran tunai untuk pembayaran masuk dan keluar. Jenis transaksi aktual untuk transaksi pencocokan tunai terserah Anda.
ConcernedOfTunbridgeWells
1
Anda dapat mencocokkan transaksi dari faktur di kedua arah dengan satu pembayaran penyelesaian jika Anda mau. Misalnya: Faktur keluar sebesar $ 100, faktur masuk sebesar $ 50 (-50) dan menyeimbangkan pembayaran masuk sebesar $ 50 cocok dengan kedua faktur.
ConcernedOfTunbridgeWells