Finished the orders section of the store.

git-svn-id: http://svn.cleancode.org/svn/pickles@120 4d10bc64-7434-11dc-a737-d2d0f8310089
This commit is contained in:
Josh Sherman 2009-05-18 02:07:31 +00:00
parent 3e58d2c659
commit 4e1006d3cd
11 changed files with 4708 additions and 145 deletions

View file

@ -97,9 +97,10 @@ class Error extends Object {
* Determines if there are any stored errors or warnings
*
* @return boolean Whether or not there are any errors or warnings.
* @todo Rename this to something like hasError()... not sure why I called it isError()
*/
public function isError() {
if (isset($this->errors, $this->warnings)) {
if (isset($this->errors) || isset($this->warnings)) {
return true;
}

View file

@ -32,7 +32,10 @@ class Logger extends Object {
public static function write($type, $message, $class = null) {
if (!file_exists(LOG_PATH)) { mkdir(LOG_PATH, 0777, true); }
$message = '[' . date('r') . '] [client ' . $_SERVER['REMOTE_ADDR'] . '] [uri ' . $_SERVER['REQUEST_URI'] . '] [script ' . $_SERVER['SCRIPT_NAME'] . '] ' . $message;
$message = '[' . date('r') . '] '
. (trim($_SERVER['REMOTE_ADDR']) != '' ? '[client ' . $_SERVER['REMOTE_ADDR'] . '] ' : null)
. (trim($_SERVER['REQUEST_URI']) != '' ? '[uri ' . $_SERVER['REQUEST_URI'] . '] ' : null)
. '[script ' . $_SERVER['SCRIPT_NAME'] . '] ' . $message;
file_put_contents(LOG_PATH . $type . '.log', $message . "\n", FILE_APPEND);
}

View file

@ -1,5 +1,9 @@
<?php
/**
* @todo Add discounts to the order view
* @todo Collapse the updates to the latest 3-5 and then have a "more" option
*/
class store_admin_orders_edit extends store_admin {
protected $display = array(DISPLAY_SMARTY, DISPLAY_JSON);
@ -13,10 +17,11 @@ class store_admin_orders_edit extends store_admin {
c.id AS customer_id,
DATE_FORMAT(o.time_placed, "%m/%d/%Y") AS order_time,
o.total_amount,
os.id AS status_id,
CONCAT(os.id, "|", os.name) AS status_id,
osu.note AS shipping_note,
osu.update_time AS last_update,
o.transaction_id,
s.name AS shipping_method,
CONCAT(s.id, "|", s.name) AS shipping_method,
o.weight,
"This would be the shipping notes" AS memo,
os.name AS status,
@ -94,24 +99,28 @@ class store_admin_orders_edit extends store_admin {
$order['products'] = $this->db->getArray($sql);
$sql = '
SELECT * FROM order_status_updates WHERE order_id = "' . $_REQUEST['id'] . '" ORDER BY update_time DESC;';
$sql = 'SELECT * FROM order_status_updates WHERE order_id = "' . $_REQUEST['id'] . '" ORDER BY update_time DESC;';
$order['updates'] = $this->db->getArray($sql);
$this->setPublic('order', $order);
$this->setPublic('order', $order);
$this->setPublic('serialized_order', serialize($order));
foreach ($this->db->getArray('SELECT * FROM order_statuses;') as $status) {
$statuses[$status['id']] = $status['name'];
$statuses[$status['id']] = $status['name'];
$status_options[$status['id'] . '|' . $status['name']] = $status['name'];
}
$this->setPublic('statuses', $statuses);
$this->setPublic('statuses', $statuses);
$this->setPublic('status_options', $status_options);
foreach ($this->db->getArray('SELECT * FROM shipping;') as $status) {
$shipping_methods[$status['id']] = $status['name'];
foreach ($this->db->getArray('SELECT * FROM shipping;') as $shipping_method) {
$shipping_methods[$status['id']] = $status['name'];
$shipping_method_options[$shipping_method['id'] . '|' . $shipping_method['name']] = $shipping_method['name'];
}
$this->setPublic('shipping_methods', $shipping_methods);
$this->setPublic('shipping_methods', $shipping_methods);
$this->setPublic('shipping_method_options', $shipping_method_options);
}
}
}

View file

@ -0,0 +1,18 @@
<?php
class store_admin_orders_print extends store_admin {
protected $display = DISPLAY_JSON;
public function __default() {
$saver = new store_admin_orders_save($this->config, $this->db, $this->mailer, $this->error);
$saver->__default();
$this->setPublic('packing_slip', nl2br($saver->packing_slip));
$this->setPublic('status', 'Success');
$this->setPublic('message', 'The order has been updated successfully.');
}
}
?>

View file

@ -5,11 +5,18 @@ class store_admin_orders_save extends store_admin {
protected $display = DISPLAY_JSON;
public function __default() {
// Breaks apart the status into the ID and text
list($status_id, $status) = split('\|', $_REQUEST['status']);
// Breaks apart the shipping method into the ID and text
list($shipping_id, $shipping_method) = split('\|', $_REQUEST['shipping_method']);
// Update orders.shipping_id, orders.shipping_note, orders.tracking_number
$this->db->execute('
UPDATE orders
SET
shipping_id = "' . $_REQUEST['shipping_method'] . '",
shipping_id = "' . $shipping_id . '",
tracking_number = "' . $_REQUEST['tracking_number'] . '"
WHERE id = "' . $_REQUEST['id'] . '";
');
@ -21,42 +28,19 @@ class store_admin_orders_save extends store_admin {
) VALUES (
"' . $_REQUEST['id'] . '",
"' . $_SESSION['user_id'] . '",
"' . $_REQUEST['status'] . '",
"' . $status_id . '",
"' . $_REQUEST['shipping_note'] . '",
NOW()
);
');
// Sends the message to the customer
if ($_REQUEST['email_customer'] == 'on') {
$sender = new store_admin_orders_send($this->config, $this->db, $this->mailer, $this->error);
$sender->send($status_id, $status, $shipping_id, $shipping_method, $_REQUEST['shipping_note']);
/*
$affiliate_message = "
{$this->config->store->title} Affiliate Program
-------------------------------------------------------------------
Dear {$contact_address['first_name']} {$contact_address['last_name']},
You have been registered
Your custom URL:
---------------------
{$this->config->store->url}/referral/" . md5($affiliate_id) . "
Your commission rate:
---------------------
{$_REQUEST['commission_rate']}%
------------------
Thank you for your interest in the {$this->config->store->title} Affiliate Program.
{$this->config->store->title}
Phone: {$this->config->store->phone}
Fax: {$this->config->store->fax}
URL: {$this->config->store->url}
";
mail($_REQUEST['email'], 'Welcome to the ' . $this->config->store->title . ' Affiliate Program', $affiliate_message, 'From: ' . $this->config->store->return_email);
*/
$this->packing_slip = $sender->packing_slip;
}
$this->setPublic('status', 'Success');
$this->setPublic('message', 'The order has been updated successfully.');

View file

@ -0,0 +1,126 @@
<?php
class store_admin_orders_send extends store_admin {
protected $display = DISPLAY_JSON;
public function __default() {
$this->send();
}
public function send($status_id = null, $status = null, $shipping_id = null, $shipping_method = null, $shipping_note = null) {
// Unserializes the order so we can use it
$order = unserialize(urldecode($_REQUEST['order']));
if (!isset($status_id, $status, $shipping_id, $shipping_method)) {
// Breaks apart the status into the ID and text
list($status_id, $status) = split('\|', $order['status_id']);
// Breaks apart the shipping method into the ID and text
list($shipping_id, $shipping_method) = split('\|', $order['shipping_method']);
$shipping_note = $order['shipping_note'];
}
// Grabs the date
$date = date('m/d/Y');
// Builds the message
$message = "
{$this->config->store->title}
-------------------------------------------------------------------
Dear {$order['billing_first_name']} {$order['billing_last_name']},
This is an automatic email to let you know that your order was marked as {$status} on: {$date}
Order Number: {$_REQUEST['id']}";
if ($status_id == 4) {
$message .= "
Completion Date: {$date}
Ship Via: {$shipping_method}
Tracking #: {$_REQUEST['tracking_number']}
Shipped to:
---------------------------";
if (trim($order['shipping_company']) != '') {
$message .= "
{$order['shipping_company']}";
}
$message .= "
{$order['shipping_first_name']} {$order['shipping_last_name']}
{$order['shipping_address1']}";
if (trim($order['shipping_address2']) != '') {
$message .= "
{$order['shipping_address2']}";
}
$message .= "
{$order['shipping_city']}, {$order['shipping_state']} {$order['shipping_zip_code']}";
}
$message .= "
Order Summary
---------------------------
";
$total_items = 0;
// Loops through products
foreach ($order['products'] as $product) {
$message .= "
{$product['quantity']} - [{$product['sku']}] {$product['name']} {$product['description']} @ \${$product['price']} each";
$total_items += $product['quantity'];
}
$message .= "
--
{$total_items}: Total Items";
if ($status_id == 4) {
$message .= "
According to our records, this order is now complete.";
}
if (trim($_REQUEST['shipping_note']) != '') {
$message .= "
Additional Notes
---------------------------
{$shipping_note}";
}
$message .= "
------------------
Thank you for your interest in {$this->config->store->title}
{$this->config->store->title}
Phone: {$this->config->store->phone}
Fax: {$this->config->store->fax}
URL: {$this->config->store->url}
";
//mail($_REQUEST['email'], $this->config->store-title . ' - Order #' . $_REQUEST['id'] . ' - ' . $status, $affiliate_message, 'From: ' . $this->config->store->return_email);
mail('josh.sherman@gmail.com, dekin@ribbonnutrition.com', $this->config->store->title . ' - Order #' . $_REQUEST['id'] . ' - ' . $status, $message, 'From: ' . $this->config->store->return_email);
$this->packing_slip = $message;
$this->setPublic('status', 'Success');
$this->setPublic('message', 'The latest update has been successfully resent to the customer.');
}
}
?>

4376
common/static/js/jquery-1.3.2.js vendored Normal file

File diff suppressed because it is too large Load diff

1
common/static/js/jquery.js vendored Symbolic link
View file

@ -0,0 +1 @@
jquery-1.3.2.js

View file

@ -6,7 +6,6 @@
<table style="width: 100%">
<tr>
<th class="left">Name</th>
<th class="left">Company</th>
<th class="left">Phone</th>
<th class="left">Email</th>
<th>Orders</th>
@ -14,13 +13,11 @@
</tr>
{foreach from=$module.customers item=customer}
<tr class="center">
<td class="left">{$customer.billing_last_name}, {$customer.billing_first_name}</td>
<td class="left">{$customer.billing_company}</td>
<td class="left"><a href="/store/admin/customers/view/{$customer.id}">{$customer.billing_last_name}, {$customer.billing_first_name}</a></td>
<td class="left">{$customer.billing_phone}</td>
<td class="left">{$customer.email}</td>
<td class="left">{mailto address=$customer.email}</td>
<td>{$customer.order_count}</td>
<td>
<a href="/store/admin/customers/view/{$customer.id}"><img src="/static/contrib/silk/icons/information.png" alt="View Customer" title="View Customer" /></a>
<a href="/store/admin/customers/edit/{$customer.id}"><img src="/static/contrib/silk/icons/pencil.png" alt="Edit Customer" title="Edit Customer" /></a>
<a href="/store/admin/customers/delete/{$customer.id}" onclick="return confirm('Are you sure you want to delete {$customer.first_name} {$customer.last_name}?')"><img src="/static/contrib/silk/icons/cross.png" alt="Delete Customer" title="Delete Customer" /></a>
</td>

View file

@ -5,8 +5,8 @@
{if is_array($module.discounts)}
<table style="width: 100%">
<tr>
<th class="left">Code</th>
<th class="left">Name</th>
<th class="left">Code</th>
<th class="left">Description</th>
<th>Products</th>
<th>Categories</th>
@ -16,13 +16,13 @@
</tr>
{foreach from=$module.discounts item=discount}
<tr class="center">
<td class="left">{if $discount.coupon != ''}{$discount.coupon}{else}<em>- n/a -</em>{/if}</td>
<td class="left">{$discount.name}</td>
<td class="left">{$discount.coupon}</td>
<td class="left">{$discount.description}</td>
<td>{if $discount.all_products == 'Y'}All{else}Select{/if}</td>
<td>{if $discount.all_categories == 'Y'}All{else}Select{/if}</td>
<td>{if $discount.all_customers == 'Y'}All{else}Select{/if}</td>
<td>{if $discount.valid_through == null}<em>- Never -</em>{else}{$discount.valid_through}{/if}</td>
<td>{if $discount.valid_through == null}<em>Never</em>{else}{$discount.valid_through}{/if}</td>
<td>
<a href="/store/admin/discounts/edit/{$discount.id}"><img src="/static/contrib/silk/icons/pencil.png" alt="Edit Discount" title="Edit Discount" /></a>
<a href="/store/admin/discounts/delete/{$discount.id}" onclick="return confirm('Are you sure you want to delete {$discount.first_name} {$discount.last_name}?')"><img src="/static/contrib/silk/icons/cross.png" alt="Delete Discount" title="Delete Discount" /></a>

View file

@ -1,14 +1,13 @@
<script type="text/javascript" src="/static/js/ajax.js" /></script>
<!--script type="text/javascript" src="/js/processOrder.js" /></script-->
{assign var='order' value=$module.order}
<h3>Order #{$order.order_id}</h3>
<h3>Date: {$order.order_time}</h3>
<h3 style="padding-bottom: 15px">Date: {$order.order_time}</h3>
{literal}
<script type="text/javascript">
function returnToList(responseObject, responseElement) {
function returnToOrders(responseObject, responseElement) {
if (responseObject != null) {
switch (responseObject.status) {
case 'Success':
@ -27,6 +26,42 @@
return responseElement;
}
function displayPackingSlip(responseObject, responseElement) {
if (responseObject != null) {
switch (responseObject.status) {
case 'Success':
var body = document.body;
body.style.backgroundColor = '#FFF';
body.style.color = '#000';
body.innerHTML = responseObject.packing_slip;
// Launch the print dialog
window.print();
// Prompt the user for the print status
while (!confirm('Did the packing slip print successfully?')) {
window.print();
}
// Loads the orders list
document.location.href = '/store/admin/orders';
break;
default:
//alert(responseObject.message);
break;
}
}
var responseMessage = document.createTextNode(responseObject.message);
responseElement.className = responseObject.type;
responseElement.appendChild(responseMessage);
return responseElement;
}
</script>
<style>
form div { margin-top: 10px }
@ -36,119 +71,132 @@
</style>
{/literal}
<form method="post" action="/store/admin/orders/save">
{if $order.total_amount > 0}
<div class="float-left">
<b>Bill To:</b><br />
{if $order.billing_company}{$order.billing_company}<br />{/if}
{$order.billing_first_name} {$order.billing_last_name}<br />
{$order.billing_address1}<br />
{if $order.billing_address2}{$order.billing_address2}<br />{/if}
{$order.billing_city}, {$order.billing_state} {$order.billing_zip_code}<br /><br />
{$order.billing_phone}
{if $order.billing_fax != ''}<br />Fax: {$order.billing_fax}{/if}<br /><br />
<b>Email:</b> {mailto address=$order.email}
</div>
{/if}
<div class="float-left" {if $order.total_amount > 0}style="padding-left: 50px"{/if}>
<b>Ship To:</b><br />
{if $order.shipping_company}{$order.shipping_company}<br />{/if}
{$order.shipping_first_name} {$order.shipping_last_name}<br />
{$order.shipping_address1}<br />
{if $order.shipping_address2}{$order.shipping_address2}<br />{/if}
{$order.shipping_city}, {$order.shipping_state} {$order.shipping_zip_code}<br /><br />
{$order.shipping_phone}
{if $order.shipping_fax != ''}<br />Fax: {$order.shipping_fax}{/if}<br /><br />
<b>Shipping Method:</b> {$order.shipping_method}<br />
<b>Weight:</b> {$order.weight|number_format:2} lbs
{if $order.total_amount > 0}
<div class="float-left">
<b>Bill To:</b><br />
{if $order.billing_company}{$order.billing_company}<br />{/if}
{$order.billing_first_name} {$order.billing_last_name}<br />
{$order.billing_address1}<br />
{if $order.billing_address2}{$order.billing_address2}<br />{/if}
{$order.billing_city}, {$order.billing_state} {$order.billing_zip_code}<br /><br />
{$order.billing_phone}
{if $order.billing_fax != ''}<br />Fax: {$order.billing_fax}{/if}<br /><br />
<b>Email:</b> {mailto address=$order.email}
</div>
{if $order.total_amount > 0}
<div class="float-left" style="padding-left: 50px">
<b>Payment Information:</b><br />
<dl>
<dt>Card Type:</dt>
<dd>{$order.cc_type}</dd>
<dt>Card Number:</dt>
<dd>XXXX-XXXX-XXXX-{$order.cc_last4}</dd>
<dt>Expiration:</dt>
<dd>{$order.cc_expiration|date_format:'%m/%Y'}</dd>
<dt>Transaction #:</dt>
<dd>{$order.transaction_id}</dd>
</dl>
</div>
{/if}
<br class="clear-left" />
<div>
<table class="product-list">
{/if}
<div class="float-left" {if $order.total_amount > 0}style="padding-left: 50px"{/if}>
<b>Ship To:</b><br />
{if $order.shipping_company}{$order.shipping_company}<br />{/if}
{$order.shipping_first_name} {$order.shipping_last_name}<br />
{$order.shipping_address1}<br />
{if $order.shipping_address2}{$order.shipping_address2}<br />{/if}
{$order.shipping_city}, {$order.shipping_state} {$order.shipping_zip_code}<br /><br />
{$order.shipping_phone}
{if $order.shipping_fax != ''}<br />Fax: {$order.shipping_fax}{/if}<br /><br />
<b>Shipping Method:</b> {$order.shipping_method}<br />
<b>Weight:</b> {$order.weight|number_format:2} lbs
</div>
{if $order.total_amount > 0}
<div class="float-left" style="padding-left: 50px">
<b>Payment Information:</b><br />
<dl>
<dt>Card Type:</dt>
<dd>{$order.cc_type}</dd>
<dt>Card Number:</dt>
<dd>XXXX-XXXX-XXXX-{$order.cc_last4}</dd>
<dt>Expiration:</dt>
<dd>{$order.cc_expiration|date_format:'%m/%Y'}</dd>
<dt>Transaction #:</dt>
<dd>{$order.transaction_id}</dd>
</dl>
</div>
{/if}
<br class="clear-left" />
<div>
<table class="product-list">
<tr>
<th class="product-quantity">Qty.</th>
<th class="product-sku">SKU</th>
<th class="product-description">Product Description</th>
<th class="product-price">Price</th>
<th class="product-total">Total</th>
</tr>
{foreach from=$order.products key=id item=product}
<tr>
<th class="product-quantity">Qty.</th>
<th class="product-sku">SKU</th>
<th class="product-description">Product Description</th>
<th class="product-price">Price</th>
<th class="product-total">Total</th>
</tr>
{foreach from=$order.products key=id item=product}
<tr>
<td class="product-quantity">{$product.quantity}</td>
<td class="product-sku" style="text-align: center">{$product.sku}</td>
<td class="product-description">{$product.name}</td>
<td class="product-price">
${$product.price|number_format:2}
</td>
<td class="product-total">
${$product.price*$product.quantity|number_format:2}
</td>
</tr>
{/foreach}
<tr>
<td colspan="3">
<td class="product-quantity">{$product.quantity}</td>
<td class="product-sku" style="text-align: center">{$product.sku}</td>
<td class="product-description">{$product.name}</td>
<td class="product-price">
${$product.price|number_format:2}
</td>
<td class="right">
<b>Subtotal:</b><br />
<b>Shipping:</b><br />
<b>Total:</b>
</td>
<td class="right">
${$order.total_amount-$order.shipping_amount|number_format:2}<br />
${$order.shipping_amount}<br />
${$order.total_amount|number_format:2}<br />
<td class="product-total">
${$product.price*$product.quantity|number_format:2}
</td>
</tr>
</table>
</div>
<br class="clear-left" />
<div class="float-left" style="width: 500px">
{/foreach}
<tr>
<td colspan="3">
</td>
<td class="right">
<b>Subtotal:</b><br />
<b>Shipping:</b><br />
<b>Total:</b>
</td>
<td class="right">
${$order.total_amount-$order.shipping_amount|number_format:2}<br />
${$order.shipping_amount}<br />
${$order.total_amount|number_format:2}<br />
</td>
</tr>
</table>
</div>
<br class="clear-left" />
<div class="float-left" style="width: 500px">
<form method="post" action="">
<dl class="status">
<dt>Customer's Email:</dt>
<dd><input type="text" name="email" id="email" value="{$order.email}" /> <input type="button" value="Resend Last Update" onclick="this.parentNode.parentNode.parentNode.action = '/store/admin/orders/send'; ajaxRequest(this.parentNode.parentNode.parentNode, null, 'after'); return false" /></dd>
<dt>Order Status:</dt>
<dd>{html_options name='status' options=$module.statuses selected=$order.status_id}</dd>
<dd>{html_options name='status' options=$module.status_options selected=$order.status_id}</dd>
<dt>Shipping Method:</dt>
<dd>{html_options name='shipping_method' options=$module.shipping_methods selected=$order.shipping_method}</dd>
<dd>{html_options name='shipping_method' options=$module.shipping_method_options selected=$order.shipping_method}</dd>
<dt>Tracking Number:</dt>
<dd><input type="text" name="tracking_number" id="tracking_number" value="{$order.tracking_number}" /></dd>
<dt>Note:</dt>
<dd><textarea id="shipping_note" name="shipping_note" style="width: 350px"></textarea></dd>
<dt>&nbsp;</dt>
<dd>
<input type="checkbox" name="email_customer" id="email_customer" checked="checked" /> Send update email to customer
</dd>
</dl>
<br class="clear-left" />
<br class="clear-right" />
<div class="center" style="width: 500px">
<input type="hidden" name="parameter" id="parameter" value="" />
<input type="hidden" name="id" value="{$order.order_id}" />
<input type="button" value="Save &amp; Return to List" onclick="ajaxRequest(this.parentNode.parentNode.parentNode, 'returnToList'); return false;" />
<input type="button" value="Save &amp; Print Packing Slip" onclick="alert('almost'); return false; ajaxRequest(this.parentNode.parentNode.parentNode); /*, 'print');*/ return false;" />
<input type="hidden" name="order" value="{$module.serialized_order|urlencode}" />
<input type="button" value="Save &amp; Return to List" onclick="this.parentNode.parentNode.action = '/store/admin/orders/save'; ajaxRequest(this.parentNode.parentNode, 'returnToOrders', 'after'); return false;" />
<input type="button" value="Save &amp; Print Packing Slip" onclick="this.parentNode.parentNode.action = '/store/admin/orders/print'; ajaxRequest(this.parentNode.parentNode, 'displayPackingSlip', 'after'); return false;" />
</div>
</div>
<div class="float-right">
<b>Resend Receipt to:</b> <input type="text" name="email" id="email" value="{$order.email}" /> <input type="button" value="Send" onclick="alert('not yet');"/><br /><br />
<b>Updates:</b>
<table>
</form>
</div>
{if is_array($order.updates)}
<div class="float-right" style="width: 300px;">
<table style="margin-top: 0px;">
<tr>
<th class="left">Status Update</th>
<th>Date</th>
<th>Note</th>
</tr>
{foreach from=$order.updates item="update"}
<tr>
<td>{$module.statuses[$update.status_id]}</td>
<td>{$update.note}</td>
<td>{$update.update_time|date_format:'%m/%d/%Y'}</td>
<td class="center">{$update.update_time|date_format:'%m/%d/%Y'}</td>
<td class="center">{if trim($update.note) != ''}<img src="/static/contrib/silk/icons/note.png" title="{$update.note}" />{/if}</td>
</tr>
{/foreach}
</table>
</div>
<br class="clear-left" />
<br class="clear-right" />
</form>
{/if}
<br class="clear-left" />
<br class="clear-right" />