I am making a complete admin and invoice app in Django.
For the invoice app, as the user clicks on "Create Sales Invoice" the invoice screen appears.
Now I want the system to dynamically generate new bill as soon as this screen appears, but not saved. As the user starts entering item, I want a new item detail (i.e. each bill has one item detail which has the list of items, its quantity and price).
However, none of them shall be saved unless the user clicks on create bill button.
I need help in how to do this thing, ie create a bill and item detail as the user goes to a create bill, link these two with foreign key, but also have the option to discard them if the user does not end up on clicking "save" button.
Edit 1
My invoicing HTML:
{% extends "base.html" %}
{% block title %}
{% load static from staticfiles %}
<script src="{% static 'bill/script.js' %}"></script>
<link rel="stylesheet" href="{% static 'bill/style.css' %}">
<title>Sales Invoice</title>
{% endblock %}
{% block content%}
<invoice>
<div id="invoice">
<invoiceheader>
<!--
<h1>Invoice</h1>
<address>
<p>Jonathan Neal</p>
<p>101 E. Chapman Ave<br>Orange, CA 92866</p>
<p>(800) 555-1234</p>
</address>
<span><img alt="" src="logo.png"><input type="file" accept="image/*"></span>
-->
</invoiceheader>
<invoicearticle>
<!--<h1>Recipient</h1>-->
<code>
<p>Customer code:
<input id="customer-code" ></input></p>
</code>
<address>
<p></p>
<p id="companyname">Some Company</p>
<p id = "companyaddress">c/o Some Guy</p>
</address>
<table class="meta">
<tr>
<th><span>Invoice #</span></th>
<td><span>101138</span></td>
</tr>
<tr>
<th><span>Date</span></th>
<td><span></span></td>
</tr>
<tr>
<th><span>Amount Due</span></th>
<td><span id="prefix">Rs. </span><span>600.00</span></td>
</tr>
</table>
<table class="inventory" id="inventory_table">
<thead>
<tr>
<th colspan="1"><span>Item Code</span></th>
<th colspan="2"><span>Item Name</span></th>
<th colspan="1"><span>Unit Rate</span></th>
<th colspan="1"><span>Discount 1</span></th>
<th colspan="1"><span>Quantity</span></th>
<th colspan="1"><span>Discount 2</span></th>
<th colspan="1"><span>Free Quantity</span></th>
<th colspan="1"><span>VAT Type</span></th>
<th colspan="1"><span>VAT</span></th>
<th colspan="1"><span>Net Rate</span></th>
</tr>
</thead>
<form>
<tbody>
<tr>
<td colspan="1"><a class="cut">-</a><span class="itemcode" contenteditable></span></td>
<td colspan="2"><span contenteditable></span></td>
<td colspan="1"><span contenteditable>150.00</span></td>
<td colspan="1"><span contenteditable></span></td>
<td colspan="1"><span contenteditable>4</span></td>
<td colspan="1"><span contenteditable></span></td>
<td colspan="1"><span contenteditable></span></td>
<td colspan="1"><span contenteditable></span></td>
<td colspan="1"><span contenteditable></span></td>
<td colspan="1"><span contenteditable></span></td>
</tr>
</tbody>
</form>
</table>
<a class="add">+</a>
<table class="balance">
<tr>
<th><span>Total</span></th>
<td><span data-prefix></span><span>600.00</span></td>
</tr>
<tr>
<th><span>Amount Paid</span></th>
<td><span data-prefix></span><span>0.00</span></td>
</tr>
<tr>
<th><span>Balance Due</span></th>
<td><span data-prefix></span><span>600.00</span></td>
</tr>
</table>
</article>
</div>
</invoice>
<script type="text/javascript">
/* url_sellbill = '{% url "billbrain:sellbill" %}' */
csrf_token='{{csrf_token}}'
</script>
{% endblock %}
My related jquery file (only the necessary part):
Generating Table:
function generateTableRow() {
var emptyColumn = document.createElement('tr');
emptyColumn.innerHTML = '<td><a class="cut">-</a><span class="itemcode" contenteditable></span></td>' +
'<td colspan="2"><span contenteditable></span></td>' +
'<td><span contenteditable>100.00</span></td>' +
'<td><span contenteditable></span></td>' +
'<td><span contenteditable></span></td>'+
'<td><span contenteditable></span></td>' +
'<td><span contenteditable></span></td>'+
'<td><span contenteditable></span></td>' +
'<td><span contenteditable></span></td>' +
'<td><span contenteditable></span></td>' ;
return emptyColumn;
}
Adding customer details on user entering customer code:
$( "#customer-code" ).change(function() {
/*alert( "Handler for .change() called." );*/
var input = $("#customer-code").val();
(function() {
$.ajax({
url : "",
type : "POST",
data : { customer_code: input,
datatype: 'customer',
'csrfmiddlewaretoken': csrf_token}, // data sent with the post request
dataType: 'json',
// handle a successful response
success : function(jsondata) {
$('#companyname').html(jsondata['name'])
$('#companyaddress').html(jsondata['address'])
console.log(jsondata); // log the returned json to the console
console.log("success"); // another sanity check
},
});
}());
});
Similarly, for products, on user entering product id, the other details are auto-generated:
$("#inventory_table").on("focus", ".itemcode", function(){
$(this).data("initialText", $(this).html());
/*alert( "On focus for table inventory called." );*/
});
$("#inventory_table").on("blur", ".itemcode", function(){
/*alert( "On blur for table inventory called." );*/
var input = $(this).html();
if ($(this).data("initialText") !== $(this).html()) {
var el = this;
/*valueis='Hi 5'
alert($(this).closest('tr').find('td:nth-child(4) span').html());*/
(function() {
$.ajax({
url : "",
type : "POST",
data : { item_code: input,
datatype: 'item',
'csrfmiddlewaretoken': csrf_token}, // data sent with the post request
dataType: 'json',
// handle a successful response
success : function(jsondata) {
$(el).closest('tr').find('td:nth-child(2) span').html(jsondata['name'])
$(el).closest('tr').find('td:nth-child(2) span').html(jsondata['name'])
$(el).closest('tr').find('td:nth-child(3) span').html(jsondata['sellingprice'])
console.log(jsondata); // log the returned json to the console
alert(jsondata['name']);
console.log("success"); // another sanity check
},
});
}());
}
});
Finally, this is my views.py file's relevant function:
def bill(request):
if request.method == 'POST':
datatype = request.POST.get('datatype')
if (datatype == 'customer'):
customerkey = request.POST.get('customer_code')
response_data = {}
response_data['name'] = Customer.object.get(customer_key__iexact=customerkey).name
response_data['address'] = Customer.object.get(customer_key__iexact=customerkey).address
jsondata = json.dumps(response_data)
return HttpResponse(jsondata)
if (datatype == 'item'):
productkey = request.POST.get('item_code')
response_data = {}
response_data['name'] = Product.object.get(prodkey__iexact=productkey).name
response_data['sellingprice'] = float(Product.object.get(prodkey__iexact=productkey).selling_price)
#response_data['address'] = Product.object.get(prodkey__iexact=productkey).address
jsondata = json.dumps(response_data)
return HttpResponse(jsondata)
return render(request, 'bill/invoicing.html')
You should use Model Forms to output to the user a form to fill and create an object after submit. You can also use some context data if you need to pre-fill some informations in the form.
Another way is to just create an object and flag it as "CANCELLED" if you want to remember some user's tries (what can be useful sometimes) or just remove it (what can cause performance issues if it is very common situation to not fill started bill).
Related
I need help!
I have an ASP.NET Core 5 MVC Webapplication. I have a list with items from a .mdf-database and want a checkbox at the end of each item-row. When I am in the controller of this view, I want to have the ID of the item, which is checked. There could be more than one checked. But I don't know how to to this.
Below some snippets from my code:
Index.cshtml
<form asp-action="Send">
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Id)
</th>
<th>
#Html.DisplayNameFor(model => model.Bez)
</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Id)
</td>
<td>
#Html.DisplayFor(modelItem => item.Bez)
</td>
<td>
<a asp-action="Edit" asp-route-id="#item.Id">Edit</a> |
<a asp-action="Delete" asp-route-id="#item.Id">Delete</a>
</td>
<td>
#Html.CheckBox("Finalized", false)
</td>
</tr>
}
</tbody>
</table>
<input type="submit" value="Send" class="btn btn-primary" />
<br /><br />
<p>Achtung! Beim Senden an einem Freitag wird der Dienstplan automatisch für den darauffolgenden Montag eingeteilt.</p>
</form>
Can someone help me? I just want the id's in a list in my controller, which are checked.
It seems you want to post the selected Ids to backend. Here is a working demo you could follow:
#Html.CheckBox("Finalized", false,new { #value=item.Id})
Controller:
[HttpPost]
//if the type of item.Id is int, it will receive int array in backend
public IActionResult Send(int[] Finalized)
{
//do your stuff...
}
I can't seem to load the data information on the html table from the api via using vue and axios
I am adding vue as my frontend to my rest api and i have called the api correctly using axios the problem i am having is there is no data shown but the loop displays the number of lines cos i have 3 entries and the table shows 3 empty spaces but no meaningful data and there's no console error please what ami i doing wrong ?
<div class="body">
<table class="table table-bordered table-striped table-hover dataTable ">
<thead>
<tr>
<th>Article Id </th>
<th>Title</th>
<th>Body</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Article Id </th>
<th>Title</th>
<th>Body</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</tfoot>
<tbody>
<tr v-for="article in articles" :key="article.article_id">
<td>{{ article.article_id }}</td>
<td>{{ article.article_title }}</td>
<td>{{ article.article_body }}</td>
<td><button #click="geArticle(article.article_id)" class="btn btn-round btn-primary">Edit</button></td>
<td><button #click="deleteArticle(article.article_id)" class="btn btn-round btn-danger">Delete</button></td>
<td></td>
</tr>
<script>
new Vue({
el: "#startapp",
data: {
articles: [],
// loading: false,
currentArticle: {},
message: null,
currentArticle: {},
newArticle: {'article_title': null, 'article_body': null}
},
mounted(){
this.getArticles();
},
methods: {
getArticles: function() {
axios({
method: 'get',
url: '/api/article'
}).then((response) => this.articles = response.data)
}
}
});
</script>
The data from the api is supposed to show the article_id, article_title and article_body but i get blank spaces and there is no error
One of the things that is likely to go wrong especially as there are no error messages showing is forgetting to run your json-server package. This should run simultaneously as your development tools.
First run:
npm run json
While the above is still running, open another terminal and run this:
npm run serve
I'm pretty new to programming and i'm trying to write a program that will upload a file to a website. I really don't know what I'm doing wrong. The file isn't getting uploaded. I think my issue is to do with the multipart form data but i wouldn't be surprised if i'm wrong.
import requests, os, sys
url = "myURL"
uploadFile = {'ILWinterConditions.kmz': open('C:\\Users\\JOC-001\\Documents\\GIS\\IDOT\\ILWinterConditions.kmz', 'rb')}
payload = {
'fname': 'myfname',
'lname': 'mylname',
'org': 'myorg',
'phone': 'myphone',
'email': 'myemail',
'datadescrip': 'mydatadesc',
'uploadedfile': 'C:\\Users\\JOC-001\\Documents\\GIS\\IDOT\\ILWinterConditions.kmz'
}
r = requests.post(url, verify = False, auth=('myUsername','mypassword'), files=uploadFile, data=payload)
print r.content
Below is the response I'm getting from print and the file is not being uploaded
<head>
<title>*I have censored this*</title>
<link rel="stylesheet" href="styles.css"/>
</head>
<body>
<script type="text/javascript">
// Add other extensions here if we want to allow other files to be
// uploaded. Check is not case-sensitive. Will also be checked on
// the server.
var allowedExtensions = [ "kml", "kmz", "jpg", "png", "csv" ];
var maxSize = 12 * 1024*1024;
var errorMessage = "Only .csv, .kml, .kmz, .jpg, or .png files up to 12MB are accepted!";
// Checks that the file meets our criteria. This is just for user
// convenience-- to catch problems before they attempt to do the
// upload. The file will be checked again on the server too.
function FileIsOkay() {
var fileInput = document.getElementById('uploadedFile');
// First check the file's extension
var fileName = fileInput.value;
var fileExtension = fileName.substr(fileName.lastIndexOf('.') + 1).toLowerCase();
var extensionOK = false;
for (var i=0; i<allowedExtensions.length; ++i) {
if (fileExtension == allowedExtensions[i].toLowerCase()) {
extensionOK = true;
break;
}
}
if (! extensionOK) {
alert(errorMessage);
return false;
}
// Now check the file's size.
// Doesn't work in IE, but that's okay... it'll get checked on
// the server any way.
if (fileInput.files) {
var file = fileInput.files[0];
if (file) {
if (file.size > maxSize) {
alert(errorMessage);
return false;
}
}
}
return true;
}
</script>
<div class="title">
<img src="webdavtitle.png"/>
</div>
<form method="POST" action="uploader.php" enctype="multipart/form-data" onsubmit="return FileIsOkay();" class="fileForm">
<table class="detailsTable">
<tr>
<td class="inputLabel">First Name:</td>
<td class="inputField"><input type="text" name="fname" size="40"></td>
</tr>
<tr>
<td class="inputLabel">Last Name:</td>
<td class="inputField"><input type="text" name="lname" size="40"></td>
</tr>
<tr>
<td class="inputLabel">Organization/Agency:</td>
<td class="inputField"><input type="text" name="org" size="40"></td>
</tr>
<tr>
<td class="inputLabel">Phone (DSN or Com):</td>
<td class="inputField"><input type="text" name="phone" size="40"></td>
</tr>
<tr>
<td class="inputLabel">Email:</td>
<td class="inputField"><input type="text" name="email" size="40"></td>
</tr>
<tr>
<td class="inputLabel">Data Description:</td>
<td class="inputField"><input type="text" name="datadescrip" size="40"></td>
</tr>
<tr>
<td class="inputLabel">
Choose a .kml, .kmz, .jpg,<br/>
or .png file to upload:
</td>
<td class="inputField">
<input id="uploadedFile" name="uploadedfile" size="40" type="file"/>
</td>
</tr>
<tr>
<td></td>
<td class="inputField"><input type="submit" value="Upload File"></input></td>
</tr>
</table>
</form>
<div class="footer">
<img border="0" src="horiz_grey_line.gif">
</div>
<div class="footer">
<img border="0" src="contacthelp.png">
</div>
<div class="footer">
<img border="0" src="nc_address.gif">
<img border="0" src="nc_webpolicy.gif">
</div>
</body>
I figured out the issue with this code. It should have been
uploadFile = {'uploadedfile': open('C:\\Users\\JOC-001\\Documents\\GIS\\IDOT\\ILWinterConditions.kmz', 'rb')}
to fit the form data. and 'payload' did not need the
'uploadedfile': 'C:\\Users\\JOC-001\\Documents\\GIS\\IDOT\\ILWinterConditions.kmz'
I have read this post: How can I create a text link in a Knockout javascript table? along with a couple others.
But, I am missing something somewhere, or not taking the right approach. I've included the relevant chunks of code for my problem. I am trying to use the table generated by knockout to to either update a task or remove a task. The remove part is working fine. I am trying to get the update to link to another page that is used to update the task. I cannot figure out what I need to do to get the link working properly in the update column.
I've tried several different approaches for how to put the url in the list of dictionaries that is passed to the KO model. Any advice to steer me in the right direction? If I am missing any information, please let me know. Thank you.
Views.py
def TaskList(request, job_id):
job_tasks = Tasks.objects.filter(parent=job_id)
tasks_list = []
for task in job_tasks:
task_row = {}
task_row['task_id'] = task.task_id
task_row['t_name'] = task.name
task_row['date'] = task.date_created
task_row['state'] = task.state
task_row['url'] = '{% url tracking:update_task task_id=task.task_id %}'
tasks_list.append(task_row)
json_tasks = json.dumps(tasks_list)
if request.POST:
json_data = request.POST.get('json_blob')
obj = loads(json_data)
task.task_id = obj.get("task_id")
remove_task = Tasks.objects.get(task_id=task.task_id)
remove_task.delete()
messages.success(request, 'Task removed')
HTML
<table>
<thead>
<th>Name</th>
<th>Date</th>
<th>State</th>
<th>Update</th>
<th>Remove</th>
</thead>
<tbody data-bind "foreach: tasks">
<tr>
<td data-bind="text: t_name"></td>
<td data-bind="text: date"></td>
<td data-bind="text: state"></td>
<td a class="btn" data-bind="attr: {href: url}">Update</a></td>
<td button class="btn" data-bind="click: $root.remove_task">Remove</button></td>
</tr>
</tbody>
</table>
{% block javascript_variables_nocompress %}
window.TASKS = {{ json_tasks|safe }};
{% endblock %}
{% block javascript_compress %}
<script type='text/javascript' src="{% static 'js/knockout/knockout.js' %}"></script>
<script type="text/javascript">
$(function() {
var RemoveTaskModel = function () {
var self = this;
self.tasks = ko.observableArray(window.TASKS);
self.remove_task = function(task) {
self.tasks.remove(task);
$("#json_blob").val(ko.toJSON(task));
}
}
ko.applyBinding(new RemoveTaskModel());
});
</script>
{% endblock %}
HTML
I would use reverse to do a reverse lookup of the URL for each task:
from django.core.urlresolvers import reverse
def TaskList(request, job_id):
job_tasks = Tasks.objects.filter(parent=job_id)
tasks_list = []
for task in job_tasks:
...
task_row['url'] = reverse('update_task', args=(),
kwargs={'task_id': task_id})
Then your observableArray should be able to bind the property from the JSON to the anchor tag. You might also note that in your code sample, your td is malformed:
<td a class="btn" data-bind="attr: {href: url}">Update</a></td>
it should be:
<td><a class="btn" data-bind="attr: {href: url}">Update</a></td>
I am trying to load page in two parts.
second part is only render when user click on 'show more details'
<script>
$(document).ready(function(){
$('#toggle_details').click(function(e){
e.preventDefault();
if ($(this).hasClass('up')){
$(this).removeClass('up').addClass('down');
$('#toggle_text').html('Show More Details');
}
else {
$(this).removeClass('down').addClass('up');
$.ajax({
url: 'some_url_returning_json',
data: $(this).serialize(),
processData: false,
dataType: "json",
success: function(data) {
$( '.name' ).html(data.name);
$( '.lname' ).html(data.lname);
alert(data.name);
}
})
$('#toggle_text').html('Hide Details');
}
$('#details').slideToggle("slow");
return false;
});
$('#details').hide();
});
</script>
and my html is :
<div class="ad-grp-tbl creative-tbl custom-tbl">
<table width="100%">
<tr>
<th>Status:</th>
<td id='status'>{{ status }}</td>
</tr>
</table>
<table width="100%" id="details">
<tr>
<th>Name:</th>
<td id="name" >{{data.name}}</td>
</tr>
<tr>
<th>Last Name:</th>
<td id ="lname">{{ data.lname}}</td>
</tr>
</table>
<table>
<tr>
<th class="tog">
<span id="toggle_text" style="color:blue;font-weight:bold">Show More Details</span>
<span class="down" id="toggle_details"></span>
</th>
<td></td>
</tr>
</table>
</div>
So Basically I am not able to load the json return value in the template.
hw can i fix it. or my approach for solving the problem is wrong.
Thanks.
I show you an example:
def post_ajax(request):
TOTLE = 5
OFFSET = int(request.GET.get('offset', 0))
END = OFFSET + TOTLE
if OFFSET + 1 >= Post.objects.count():
LOADED = "已经全部加载完毕"
return HttpResponse(LOADED)
posts = Post.objects.filter(pub_time__lte=timezone.now())[OFFSET:END]
json_list = []
for post in posts:
t = get_template('blog/ajax_post.html')
html = t.render(Context({'post': post}))
# print(html)
json_list.append({
'html': html,
})
data = json.dumps(json_list)
return HttpResponse(data, content_type="application/json")
Is this you need?
Ajax + JQuery will get response and should put data appropriately in the page. Template of original page doesn't have much role to play.
However, you have to implement separate url+view+template that will handle the ajax request. You can use existing view but need to handle for ajax request (i.e. just to send part of html, likely using another template).
The template for ajax response should send only the relevant part of html and not the entire html page.
In the HTML you have ids set but you are using the class selector.
It should be:
$( '#name' ).html(data.name);
$( '#lname' ).html(data.lname);
instead of:
$( '.name' ).html(data.name);
$( '.lname' ).html(data.lname);
. is the class selector and # is the id selector.
You can try using Firebug or Chrome Dev Tools to see that the above returns the items.