CakePHP Invoicing App & Deleting Data From Another Controller/Model - mysql

I'm new to CakePHP and I could do with some newbie advice please.
I'm creating an invoicing application and the way I have it set up is with seperate tables (and so Models and Controlllers) for Invoices and Items. The Invoice table holds the data such as 'Invoice Number', 'Date' and 'Client ID' for example, and the Items table stores individual records/items that make up each invoice with 'Quantity', 'Unit Price' etc. The two are associated correctly.
When I call the 'edit' view for Invoices, obviously passing an ID, I retrieve the record and then also loop through the all associated records returned from the Items table to - all works as planned and are retrieved and displayed correctly.
What I want to be able to do from this view though, is to be able to delete individual items from the invoice by clicking on a delete button next to each - ideally with a confirmation box. How would this be acheived exactly? What would be the best method? Would I use a function in the Items controller to do this without leaving the page? How would I call the function in that controller from the Invoice controller/view? Or would another method such as the CakePHP query() function be used for this?
I hope I've explained this setup clearly enough for someone to offer any help and/or advice for which I would be very thankful.
Thanks in advance

The simple way:
In your Invoice/view.ctp
Inside your foreach loop you would do something like this:
//this is loose code since you have not pasted any in your question
<?php echo $this->Html->link('Delete', array('controller'=>'Item', 'action'=>'delete', $item['Item']['id'])); ?>
then create the function in your ItemController.php
function delete($id=NULL){
if($id){
$this->Item->delete($id);
$this->Session->setFlash(__('Invoice item deleted', true));
$this->redirect($this->referer());
}
}

Related

How do I insert data from a reference table to the corresponding field

I'm sorry if my question sounds confusing.I just started learning web2py recently,in this exercise I'm trying to make a simple users management webpage with the admin can assign the users theirs work lists,note and deadline
db.define_table('auth_manager',Field('name','string',requires=IS_NOT_EMPTY()))
db.define_table('manager',Field('user','string','reference user.name'),
Field('workname','text',requires=IS_NOT_EMPTY()),
Field('deadline','date'),)
db.manager.deadline.requires=IS_DATE_IN_RANGE(format=T('%Y-%m-%d'),
minimum=now,maximum=now+datetime.timedelta(60))
I thought of adding the manager's username in auth_manager table using appadmin's new record function.This is my user table
db.define_table('user',Field('name','string',requires=IS_NOT_EMPTY()),
Field('password','password'),
Field('workname','text'),
Field('deadline','date'),
format='%(name)s')
I wanted to insert workname and deadline into user table right after I add those form on manager but I couldn't find any other methods except the update or update_or_insert functions but both don't work because those fields can't be empty and their ids aren't the same value and multiple references to a single table don't work .
One last question,I want to use web2py's RBAC but the first & last name fields are often unnecessary if I want to use a full name field is there other way to do it?
Sorry for the long post,I hope I made my question clear.
You can use the tables from auth and let web2py to handle everything in between.
The following code should resolve your problem:
db.define_table('manager', 'reference auth_user'),
Field('workname', 'text', requires=IS_NOT_EMPTY()),
Field('deadline', 'date'))

Passing Model sub-tables to HTTPPOST Controller for Model Editing

I have created a MVC 5 application where I am creating a custom purchasing system.
My View model is generated based on the contents of an SQL Database. The database uses a Single Primary Key for a Purchase Order with some basic data. In addition to the basic data each PO can have multiple items within that purchase order. This creates a relationship where there can be N items to a single Purchase.
When I am doing a form Submit the sending of the Purchase Order specific information, ie using TextBoxFor(m => m.Date), works fine. However I cannot seem to pass the list of all the Items within it. For example when I am doing #Html.TextBoxFor(m => m.Details.ItemName) it is not populating the section in the model during the POST.
I have tried sending all the information using #Html.TextBoxFor(m => m.Details) but it throws errors as the TextBoxFor cannot handle these data types.
I am after a system where I can edit a purchase order model by adding or removing items without committing to my database until the 'save' button is pressed.
My View Model example is
public class PurchasingEditModel
{
public tbl_PurchaseOrder PurchaseOrder;
}
Purchase order in itself has a link to PurchaseOrderDetails (within SQL) via a Foreign key reference of the Purchase Order. This creates the Many Items to One PO.
The controller for the edit page is
public ActionResult Edit(int? pkPurchaseOrder)
{
model.PurchaseOrder = db.PurchaseOrder.Where(x => x.pkPurchaseOrder == pkPurchaseOrder);
return View(model);
}
This together with a standard Edit.cshtml using #Html.TextBoxFor(m => m. all works fine with the display portion, until I want to post the multiple items within the sub-table.
Really the easiest way for me to handle this would be to pass the all contents of model during the display, which has all the elements of the items within the PO, to the POST function.
Any guidance you can give is appreciated.
I have solved my own issue, which makes a change...
To POST the data within a sub-table(IQueryable) Ive had to do the following
Within my main html code add
#foreach(var item in Model.PurchaseOrder.tbl_Details)
{
#Html.Partial("_POItemDetailsPartial", item)
}
Then Ive had to create a MVC Partial Page (Razor) named _POItemsPartial.
Within that page I have put the following..
#using (Html.BeginCollectionItem("Model.PurcahseOrder.tbl_Details")
{
#model ModelSpace.Model.tbl_Details
#Html.TextBoxFor(m => m.Description)
}
When the POST action occurs I now get the description for all the 3 items I have within the PurchaseOrder.
**
UPDATE:
**
Despite getting this data..I am now losing all my original model data such as Total Price it seems that the Partial Call being passed the Model.tbl_Details is only passing that information and clearing the rest.
When it returns it ends up with all higher level data removed. If I comment out the partial call it all comes back.
Turns out I still need help.... :(

Can't save the data using wbragancia widget yii2 for more than one dynamic form in single view

I am new in yii2 and i am using wbraganca/yii2-dynamicform widget in my view. My question is that I have to use more than two dynamic form in a single view. For single dynamic widget it works fine while saving from controller but others are saving just the last data of dynamic widget, while inspecting the post data in network array index for others except first dynamic form are not increasing (there index is only zero). Would you please suggest how should I have to do. How can I use multiple dynamic-form widget in single view. Thank you in advance.
I believe the problem must be in your view. You should ensure that each control has a unique name and then loop through the post variables in the controller.
<?= $form->field($modelx, "[{$i}]MyVariableName", ['labelOptions' => ['label' => false]])->textInput(['name' =>'myClassNameHere'."{$block}[$i][MyVariableName]"]) ?>
See the 'name' option in the code above. It gives a unique name to each field. Here the $block variable is a unique code I append to each widgetItem class in the DynamicFormWidget.
If I now look at my POST data, I see something like the following:
myClassNameHere0[0][MyVariableName]:1
myClassNameHere1[0][MyVariableName]:11
If this does not help - post a simply example that you cannot get working and I will have a look at it.

selecting multiple items in an AS3 list component based on values

I've created a flash AS3 user form for sales people. When I create a user, I select multiple cities from a list component and drop them into an array. When added to the mySQL DB these entries are kept in a separte table which I can then call upon at any time using XML to bring them back into AS3. Now I'm using the same form as a user updaete form and populating it with data from previous MySQL insert.
My question is - How could I have these cities show as 'selected' on the list Component when the update form is loaded? Thus allowing the someone to add to or substract from that selection set. I'm trying to set selectedItems to match the ID's in the XML but failing miserably.
as a test I tried
addUser.citiesList.selectedItems = [3,4];
addUser.citiesList.selectedIndices = [3,4];
The selectedItems yield nothing but the selectedIndices works but I don't want to start matching indexes with Item ID's
looked all over but can't seem to find an answer. Am I missing something or is this not possible?
Well I finally got it working.
Having got the data out of the MySQL db, through PHP and into Flash as XML, I then pushed the user city values into a userCity array.
I got the AS3 list component in the form populated in the same way with all the cities.
I then used the userCity array in a nested for loop to inerate through all the cities in the list component, picking out the ones that had been previously selected and grabbing the index of each to pop into a new array which was the array used for the 'selectedindicies' and hey presto. I now have a cities list (about 36 cities) with the previously selected cities (about 5 cities) already selected and highlighted so that the user knows which cities the sales peson already manages. Now they can add or subtract from that and it will be picked up by my on change event as normal.
The Adobe resources on selectedIndices and selectedItems, for someone like me, who's learning is to say the least - pittyful...
I hope this helps someone else out...

Accessing variables outside class

I will try to explain my issue as good as I can.
I have a class with functions, the purpose of one function is to fetch information from the database and display it.
Everything works as it should, but now I need to access some variables to use them outside my class in another file, I don't know how this should be done so I'm wondering if someone can guide me.
function fetch(){
$this->_select_query = '
SELECT movies_id, movies_title, movies_director, movies_year, movies_category_id, cat.name
FROM movies
LEFT JOIN cat ON id = movies_category_id'
or die(mysqli_error());
$this->_stmt = $this->_mysqli->prepare($this->_select_query);
$this->_stmt->execute();
$this->_stmt->bind_result($this->_select_id, $this->_select_title, $this->_select_director, $this->_select_year, $this->_select_category_id, $this->_select_category_name);
$this->_stmt->store_result();
while($this->_stmt->fetch()){
echo '<tr>
<td>'.$this->_select_title.'</td>
<td>'.$this->_select_director.'</td>
<td>'.$this->_select_year.'</td>
<td>'.$this->_select_category_name.'</td>
<td>Edit</td>
<td>Delete</td>
</tr>
';
}
}//close function fetch
The function fetch is inside a class called movies, now on another page I have a form to edit(update) these movies and I would like to return the title, director etc.. inside that form so it is easy to notice what you are changing.
Now I do know how to do this using php procedural but not with object oriented php.
As you can also notice here I echo out the whole table (another part of the table is on a diffirent page)
So because of this I can't use $movies->fetch()
I do hope someone can give me some more information on my issue since I feel a bit lost at this point, and while staring too much on the same code you can become confused and mix up stuff.
Kind Regards
Edit: should I be using globals, constants ?
You should refactor your code.
As you are saying, you can't do $movies->fetch() since it echoes the table. That's a sign of braking the Single Responsibility Principle. You should divide your function into two: one function that fetches (and returns) the data, and another one that takes data as a parameter and returns a table with the data.
That way, you can reuse the first one when you want to get the values for the edit form.
Since you have a procedural background, I'd recommend that you create a new class that represents a "movie" that has the required fields. Then, for each row in your table you should create an instance of that class and populate the fields, and ultimately return all those instances.
Sorry for not posting any code at the moment, I realized that would have been easier.