公司将在每月1号和16号收到发票。 (它将通过 Cron Job 每两周运行一次。它扫描订单表,然后添加到“发票”表中。还有其他选择吗?)
orders
表中有客户订单列表,它还表明它属于哪家公司 (orders.company_id
)
invoice
表计算 orders
表中订单的总成本。
我试图弄清楚如何设计合理的发票跟踪。有时公司必须向我发送费用,有时我向他们发送费用 (invoice.amount
)
我需要通过以下方式跟踪发票:
- 当公司发送时我的金额
- 我什么时候向公司发送了金额
- 我从公司收到了多少金额
- 我向公司发送了多少金额
- 我是否收到了全额金额(如果没有,我需要在数据库上更新什么? )
- 发票状态(发票已发送,已取消、已收到金额、已发送金额)
这是我提出的数据库设计:
公司表
mysql> select * from company;
+----+-----------+
| id | name |
+----+-----------+
| 1 | Company A |
| 2 | Company B |
+----+-----------+
客户可以从我的网站上选择一家公司。
订单表
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 |
+----+---------+------------+------------+---------------------+-----------+
两位客户已从公司 B 订购了产品 (orders.company_id = 2
)。我知道订单字段还不够,只是为您简化了。
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 |
+----+----------+------------+--------------+-------+
客户订购的产品列表。
发票表
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 |
+----+------------+------------+---------------------+--------+-----------+
这是我在发票表设计上非常困惑的地方。我不知道应该如何做。发票将每两周生成一次。从结果示例来看,invoice.amount
为 55.00,因为它是根据 orders.company_id = 2
表计算的
如果 invoice.amount
为 -50.00 (减),这意味着公司需要向我发送费用金额。
如果invoice.amount
是50.00,这意味着我需要向公司发送费用。
status_id 可以是:(1)发票已发送、(2)已取消、(3)已完成
我是否需要在 orders
表中添加 invoice_id
字段?将行插入“发票”表后更新 orders.invoice_id
字段。
发票付款表
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 |
+----+------------+-----------------+-------------+---------------------+---------------------+
这是我可以跟踪和更新交易的地方。付款将通过 BACS 进行。
这是好的表格设计还是我需要改进什么?我应该添加哪些字段和表格?
如果发票已生成,稍后我需要在 orders_products
或 orders
表中进行更改 - 是否应该重新计算 invoice.amount
字段? (我将使用 PHP / MySQL)。
SQL 转储:
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');
您可以随意更新/添加表以在此处回答。
谢谢
Company will receive an invoice on the 1st and 16th every month. (It will run via Cron Job every 2 week. It scan through the order table and then add into 'invoice' table. Is there alternative?)
There are list of customers orders in the orders
table and it also indicate which company it belong to (orders.company_id
)
The invoice
table calculate the total cost of the orders from orders
table.
I am trying to figure it out how to design reasonable invoices tracking. Sometime company will have to send me the fees or sometime I send them the fees (invoice.amount
)
I need to track the invoices with the following:
- when the company have sent me the amount
- when did I sent the amount to the company
- how much amount has been received from the company
- how much amount did I sent to the company
- did I receive the full amount (if not, what do I need to update on the Db?)
- invoice status (Invoice Sent, Cancelled, Amount Received, Amount Sent)
Here is the database design I have came up with:
company table
mysql> select * from company;
+----+-----------+
| id | name |
+----+-----------+
| 1 | Company A |
| 2 | Company B |
+----+-----------+
Customers can select a company from my website.
orders table
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 |
+----+---------+------------+------------+---------------------+-----------+
two customers have ordered the products from Company B (orders.company_id = 2
). I know the orders fields is not enough, just simplified for you.
orders_products table
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 |
+----+----------+------------+--------------+-------+
List of products what customers have ordered.
invoice table
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 |
+----+------------+------------+---------------------+--------+-----------+
This is where I am quite stuck on invoice tables design. I am not sure how it should be done. Invoices will be generated every 2 weeks. From the result example invoice.amount
is 55.00 because it has been calculated from orders.company_id = 2
table
If the invoice.amount
is -50.00 (minus), it mean company will need to send me the fees amount.
If the invoice.amount
is 50.00, it mean I need to send the company the fees.
The status_id could be: (1)Invoice Sent, (2)Cancelled, (3)Completed
Do I need to add invoice_id
field in the orders
table? Update the orders.invoice_id
field when row has been inserted into 'invoice' table.
invoice_payment table
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 |
+----+------------+-----------------+-------------+---------------------+---------------------+
This is where I can track and update transaction.. the payment will be made via BACS.
Is this good tables design or what do I need to improve? What fields and tables I should add?
If the invoice has been generated and later I need to make the changes in orders_products
or orders
tables - should it recalculate the invoice.amount
field? (I will be using 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');
Feel free you want to updates/add tables to Answer here.
Thanks
发布评论
评论(1)
看看我的 Gemini 插件 - SimplyFi。它将允许您相应地标记您的发票,可以在生成发票时自动通过电子邮件将其发送给客户,可以记录付款并发送未收到付款的提醒(报表),并且具有完整的基于 REST 的 API,您可以使用它集成到您的系统中。还可以从其定期计费功能中受益。
在您提到负发票金额的地方,这些实际上是“贷方票据”(根据我从您的帖子中了解到的内容)。一般来说,您不应该在向客户开具发票后自行更改发票 - 如果您需要修改金额(即:增加或减少),那么您应该开具新发票(针对增加的金额)或贷方票据,用于扣除金额。
另外,我建议您如果客户将在几周内收到新发票,则不要退还客户资金,只需跟踪他们的帐户余额,并仅在必要时开具发票或贷方票据。转移资金需要花钱,如果没有必要,就不需要这样做。只是我的2分钱
Have a look at my add-on for Gemini - SimplyFi. It will allow you to brand your invoices accordingly, can auto email them to customers when they generated, can log payments and send reminders for payments not received (statements) and has a full REST based API you can use to integrate into your system. Also may be able to benefit off the recurring billing it features.
Where you mention negative invoice amounts, those are effectively "Credit Notes" (from what I've understood from your post). Generally, you should not be changing invoices themselves after they have been issued to a client - if you need to make amendments to an amount (ie: add on, or subtract off) then you should be issuing a new invoice (for added amount), or a credit note, for subtracted amount.
Also, I would suggest you don;t send the customer money back if they are going to receive a new invoice in a few weeks time, simply keep track of their account balance, and only issue invoices or credit notes when necessary. Moving money around costs money, and you don't need to do it if it's not necessary. Just my 2 cents