Auto Invoice Number Generation in Laravel 5.2 - php

I am building an invoice application using laravel 5.2
I want to create automatic invoice numbers incrementing. Meaning,
If i open create invoice page, i should automatically get #0001 so when i save the invoice, under my invoice_number field it will be 0001 then when i am creating another invoice, the controller will check for the last invoice_number in the database and automatically give me #0002.
Any idea on how to do that or something similar??
Thanks

Get the last record from the db in descending order.
$invoice = new Invoice();
$lastInvoiceID = $invoice->orderBy('id', DESC)->pluck('id')->first();
$newInvoiceID = $lastInvoiceID + 1;
This will return the last ID. Then add 1 to it, and display it on the front end {{ $newInvoiceID }}.
Possible issue: What if two users are creating invoices simultaneously? Once they save, the numbers will be different if invoice number is a unique identifier.
One option is to create invoices per user.
$invoice = new Invoice();
$lastInvoiceID = $invoice->where('user_id', '=', Auth::user()->id)->orderBy('invoice_id', DESC)->pluck('invoice_id')->first();
$newInvoiceID = $lastInvoiceID + 1;

Auto-increment the invoice_number field in your MySQL table (or just use the 'ID' as your invoice_number:
CREATE TABLE invoices (
ID int NOT NULL AUTO_INCREMENT,
invoice_number NOT NULL AUTO_INCREMENT
)
Every time you add an invoice to the table, MySQL automatically assigns it the next number. So if the last invoice in the table is 3, the next one you insert will be assigned 4.
If you want to display the numbers like #0003 and #0004, just query the database for the invoice_number and format the number in PHP.

Related

Is creating a new table each time a user logs in a bad practice?

I am developing an online inventory management system. I have one table for the main inventory which consists of the product names, quantity and barcodes etc. I want users to log into the system each morning and log the quantity of each item they take. I then want to store this information for the admin to view. I have developed the system so that a new table gets created each morning based on the users name and date. This is allows the user to input the quantity for each product, i then subtract that column from the main inventory table when the user clicks submit. I want to know if this is a bad practice, is it necessary to create a new table each morning? If not what method should i use?
I think you should maintain a single table for inventory, and then after a create a temporary table to store the list of items the user takes which will contain the user id, inventory id, qty etc, and then update the quantity of inventory in inventory table, whenever user picks the inventory.
In short you should create a single table to store the information of inventory which user takes instead of creating a new table each day.
Insert and fetch data according to date + user.
I wonder if you are creating new table everyday, you should not create new table in any case. In the rarest scenario even if your columns are dynamic then create a table with rows representing as column and use pivot to fetch the record. For your use case you just need to have a table which stores a new record and subtract the count from main table.

MySQL After Update and After Insert Triggers fail when row is entered

I need to create a MySQL trigger that multiplies the values of two columns in one table and saves that result in the column of another table. I have a table called lineitems that gets the product dimensions entered into it. I need to multiply the height and width of each lineitem row and add them together if they are part of the same order number and save that result in a sqft column of a table called invoices. I need this to happen every time the lineitems table gets a new row or an existing row is updated. I also need to do a very similar process for the item quantity of each lineitem row. And last, I need to do a third calculation where the weight of each product is calculated and stored in the lineitems table. However, that weight calculation involves a third table (layup_config) to derive the weight for only the layers used in the specific product ordered.
Code:
I have tried setting this trigger up both on the invoices table AFTER INSERT and AFTER UPDATE as well as on the lineitems table AFTER INSERT and AFTER UPDATE. However, I would prefer that this happens in the lineitems table if possible.
Note: I am using phpmyadmin to access and manipulate my table triggers so that program has a form that generates the correct trigger format for things such as "CREATE TRIGGER 'triggername' ...etc. The program users interact with to enter each row is using PHP to send data to MySQL.
BEGIN
INSERT INTO invoices SET invoices.totalquantity=SUM(lineitems.quantity) WHERE invoices.id=lineitems.invoiceid;
INSERT INTO invoices SET invoices.totalsqft = ((SUM( lineitems.quantity ))*((lineitems.width + lineitmes.widthf)*(lineitems.height+lineitems.heightf))) WHERE invoices.id = lineitems.invoiceid;
INSERT INTO lineitems SET lineitems.unitweight = SUM(layup_config.weight) WHERE layup-config.parentid IN (SELECT lineitems.productid FROM lineitems WHERE lineitems.invoiceid=invoices.id AND lineitems.displayorder=0);
END
I also tried the following code instead of the previous code:
//Inserts new invoice row but not lineitems data
BEGIN
SET #totalqty = (SELECT SUM(lineitems.quantity) FROM lineitems INNER JOIN invoices ON lineitems.invoiceid=invoices.id);
INSERT INTO invoices SET invoices.NEW.totalquantity = #totalqty;
END
I think the problem I'm encountering is that the section to enter data for the lineitems table is on the same page as the code to save invoices table data. But, both are updated when the same "save" button is clicked. I think I'm trying to update the invoices table before the needed lineitems table actually gets saved.
Ex: invoice data gets entered, invoice trigger runs before lineitems data gets entered but needs to use the lineitems data, so it fails.
I think having the trigger on the lineitems table is the correct way to go, but I can't seem to get the trigger to work correctly in that table...
Please Help!!!!!
Thank you!

Using two where clauses in MYSQL UPDATE query using PHP

Working on a lightweight invoicing system and I'm trying to update my 'items' table correctly without fully succeeding.
Once an invoice is saved, I need to mark the items as paid that were purchased so far that day for that buyer.
Right now this is my query:
$markitemspaidquery = "UPDATE solditems SET paidstatus='paid', paidtime='$date' WHERE buyerid='$buyer_id'";
This updates the records for the buyer correctly, but the problem is it will mark EVERY item in the table for that buyer 'paid'; even if it is from 3 days ago.
How can I use a query kind of like this one or achieve this affect?
$markitemspaidquery = "UPDATE solditems SET paidstatus='paid', paidtime='$date' WHERE buyerid='$buyer_id' AND DATE(timesold)=CURDATE() AND paidstatus='unpaid'";
In all reality, everything should be paid by the end of the day anyway because of the way the company works, but I would like to know for future reference since it's just using up unnecessary resources to update every item for the buyer.
Here is an example with order by and limit
update questions
set prepStatus=1,status_bef_change=status,cv_bef_change=closeVotes,max_cv_reached=greatest(max_cv_reached,closeVotes)
where status='O' and prepStatus = 0
order by qId desc
limit 900;
There is a flaw in your datamodel. You have items sold and invoices but no connection between them.
So you muddle your way through be saying: when there is an invoice on a day for a customer it must be an invoice exactly covering all items on that very day bought by that customer. This is a rule you are kind of making up - the database doesn't tell you this.
So have a reference in your sold items table to the invoice table. Once an invoice is entered in the system it must be linked to all items sold it includes. Thus the update is easy, or better not necessary, as it is not the sigle item sold which is paid, but the invoice. So the sold items shouldn't have columns paidstatus and paidtime, but the invoice should.
UPDATE: Here is an example for a working data model. Each item has an invoice number which is null at first. Once the customer checks out an invoice is written and all the customer's items without an invoice number get this new invoice number. The invoice's total amount is the sum of its items. I.e. you don't store the sum redundantly.
auction_item
auction_item_no - primary key
customer_no - not null
description - not null
price - not null
invoice_no - nullalble (null as long as not checked out)
invoice
invoice_no - composite primary key part 1
customer_no - composite primary key part 2
date_time - not null

insert a row with one column value based on last record

I need to insert a newly added product in table. But to do so I need to check SKU of last inserted product and increase it by 1 and insert it with new product details. SKU is something like SKUNXXXXX - X is a digit. Changing table structure is not possible.
Possible solutions that I can think of is
Get last row using order by and limit 1.
replace "SKUN" with empty string and increase the number by 1
Insert record with product details and incremented SKU value
But this situation may create a problem(though I am not sure about it). Problem is - what if just after fetching last record and before inserting the new product details, another request comes in and gets the same last record? In this case both of the products have same SKU.
Please let me know how to solve this situation.
One option would be to create an auto increment id column and then use this to create the SKU for each product as it gets inserted. A trigger, which would fire after an INSERT, could then be used to assign the SKU for the newly inserted product. But alas, MySQL does not allow a trigger to modify the table which fired it.
However, there is a potentially easy workaround here. If your SKU values will really always have the format SKUNXXXXX, where XXXXX is some number, then you can simply add an auto increment column, and create the SKU value on the fly when you query for it. So you might create a table called products with the following columns:
CREATE TABLE products
(
id INT(11) NOT NULL AUTO_INCREMENT,
name VARCHAR(55),
...
);
Everytime you do an INSERT on products, the id column will automatically be incremented by MySQL. When you want to get the SKU out, you can simply do a query like this:
SELECT id, name, CONCAT('SKUN', id) AS `SKU`
FROM products
WHERE name = 'someproduct'
If you want the SKU number to not be forever (i.e. once assigned to a given product, it can be reassigned to another new one), then you might consider resetting the auto increment id column, q.v. this SO post for more information.

How to get last insert id in Yii create page

I have a model called Invoice.I have made necessary CRUD for Invoice model.The attributes for the Invoice model are as like Invoice Title, Invoice No, Invoice Issue Date, Description.Now I want that when a user will redirect to invoice create page,the input field for Invoice No should be automatically filled in the create page with last inserted id +1 and it should have prefix like INV:.So the input field for Invoice No should be like this INV:12.By this a user don't need to fill the invoice no manually in increasing order.Here is the image for the create page.
First of all==>This is not a good idea to store Invoice number dependent on table's unique id
So you should insert last invoice number's number part+1 with text..
Now first get last invoice model then find its invoice number and populate the field..
In controller..
$model = new Invoice;
$last_invoice = Invoice::model()->find(array('order'=>'id DESC'));
$last_invoice_number = str_replace("INV:", "", $last_invoice->invoice_mumber);
$new_invoice_number = $last_invoice_number+1;
$model->invoice_number = "INV:".$new_invoice_number;
$this->render('create',array('model'=>$model));
EDIT:
Reason why Yii::app()->db->lastInsertId) cannot be used..
First as I said in first place its not good to dependent invoice id from unique id of table..second what if somebody inserted sonething in someother table in between..third what if the db connection is closed and started in between..
Just a Suggestion:
If user does not need to fill the invoice number then why don't you just skip it from Display. I mean let not show it while creating. Once the form is submitted, you can show all the submitted value along the invoice number.
Once the form is submitted, you can display the invoice number simply by $model -> id; where id is the invoice number in the database.
You could use invoice number as the primary auto increment bigint value in the database. Then use INV: prefix while display.
Hope it helps!
This is the simple way to get last insert id in Yii.
Yii::app()->db->getLastInsertId();

Categories