Adding archive button to products, updating README
This commit is contained in:
parent
a251da2d95
commit
a6798def0f
24
README.md
24
README.md
|
|
@ -21,7 +21,7 @@ The PHP application currently handles most functionality, while the Go applicati
|
|||
### Quick Start
|
||||
|
||||
``` shell
|
||||
git clone git@code.springupsoftware.com:cmc/cmc-sales.git
|
||||
git clone git@code.springupsoftware.com:springup/cmc-sales.git
|
||||
cd cmc-sales
|
||||
|
||||
# Easy way - use the setup script
|
||||
|
|
@ -54,6 +54,28 @@ gunzip < backups/backup_*.sql.gz | mariadb -h 127.0.0.1 -u cmc -p cmc
|
|||
|
||||
Both applications share the same database, allowing for gradual migration.
|
||||
|
||||
### Database Migrations
|
||||
|
||||
Database schema changes are managed using [Goose](https://github.com/pressly/goose) migrations in the `go/sql/migrations/` directory.
|
||||
|
||||
**Creating a new migration:**
|
||||
```bash
|
||||
cd go
|
||||
make migrate-create name=add_new_column_to_table
|
||||
```
|
||||
|
||||
**Running migrations:**
|
||||
```bash
|
||||
cd go
|
||||
make migrate # Apply all pending migrations
|
||||
make migrate-status # Check migration status
|
||||
make migrate-down # Rollback last migration
|
||||
```
|
||||
|
||||
**Migration files** use the Goose format with `-- +goose Up` and `-- +goose Down` sections. See `go/sql/migrations/` for examples.
|
||||
|
||||
**Configuration:** Database connection settings are in `go/goose.env` (create from `goose.env.example`).
|
||||
|
||||
### Requirements
|
||||
|
||||
- **Go Application**: Requires Go 1.23+ (for latest sqlc)
|
||||
|
|
|
|||
7
go/sql/migrations/004_add_archived_to_products.sql
Normal file
7
go/sql/migrations/004_add_archived_to_products.sql
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
-- +goose Up
|
||||
-- Add archived field to products table
|
||||
ALTER TABLE products ADD COLUMN archived TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'Product is archived and hidden from main listing';
|
||||
|
||||
-- +goose Down
|
||||
-- Remove archived column from products
|
||||
ALTER TABLE products DROP COLUMN archived;
|
||||
|
|
@ -19,10 +19,21 @@ class ProductsController extends AppController {
|
|||
$this->Session->setFlash(__('Invalid Principle ID', true));
|
||||
$this->redirect(array('action'=>'index'));
|
||||
}
|
||||
$this->set('products', $this->Product->find('all', array('conditions'=>array('Product.principle_id'=>$id),'order'=>'Product.title ASC')));
|
||||
$this->set('products', $this->Product->find('all', array('conditions'=>array('Product.principle_id'=>$id, 'Product.archived'=>0),'order'=>'Product.title ASC')));
|
||||
$this->set('principle', $this->Product->Principle->findById($id));
|
||||
}
|
||||
|
||||
function view_archived_principle($id = null) {
|
||||
if(!$id) {
|
||||
$this->Session->setFlash(__('Invalid Principle ID', true));
|
||||
$this->redirect(array('action'=>'index'));
|
||||
}
|
||||
$this->set('products', $this->Product->find('all', array('conditions'=>array('Product.principle_id'=>$id, 'Product.archived'=>1),'order'=>'Product.title ASC')));
|
||||
$this->set('principle', $this->Product->Principle->findById($id));
|
||||
$currentuser = $this->getCurrentUser();
|
||||
$this->set('is_admin', $currentuser['User']['access_level'] == 'admin');
|
||||
}
|
||||
|
||||
function view($id = null) {
|
||||
if (!$id) {
|
||||
$this->Session->setFlash(__('Invalid Product.', true));
|
||||
|
|
@ -122,9 +133,73 @@ class ProductsController extends AppController {
|
|||
$this->Session->setFlash(__('Invalid id for Product', true));
|
||||
$this->redirect(array('action'=>'index'));
|
||||
}
|
||||
|
||||
// Check if user is admin
|
||||
$currentuser = $this->getCurrentUser();
|
||||
if($currentuser['User']['access_level'] != 'admin') {
|
||||
$this->Session->setFlash(__('Only administrators can delete products', true));
|
||||
$this->redirect(array('action'=>'index'));
|
||||
return;
|
||||
}
|
||||
|
||||
$product = $this->Product->findById($id);
|
||||
if (!$product) {
|
||||
$this->Session->setFlash(__('Invalid Product', true));
|
||||
$this->redirect(array('action'=>'index'));
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->Product->del($id)) {
|
||||
$this->Session->setFlash(__('Product deleted', true));
|
||||
$this->redirect(array('action'=>'view_archived_principle', $product['Product']['principle_id']));
|
||||
}
|
||||
}
|
||||
|
||||
function archive($id = null) {
|
||||
if (!$id) {
|
||||
$this->Session->setFlash(__('Invalid id for Product', true));
|
||||
$this->redirect(array('action'=>'index'));
|
||||
return;
|
||||
}
|
||||
|
||||
$product = $this->Product->findById($id);
|
||||
if (!$product) {
|
||||
$this->Session->setFlash(__('Invalid Product', true));
|
||||
$this->redirect(array('action'=>'index'));
|
||||
return;
|
||||
}
|
||||
|
||||
$this->Product->id = $id;
|
||||
if ($this->Product->saveField('archived', 1)) {
|
||||
$this->Session->setFlash(__('Product archived', true));
|
||||
$this->redirect(array('action'=>'view_principle', $product['Product']['principle_id']));
|
||||
} else {
|
||||
$this->Session->setFlash(__('Failed to archive product', true));
|
||||
$this->redirect(array('action'=>'view_principle', $product['Product']['principle_id']));
|
||||
}
|
||||
}
|
||||
|
||||
function unarchive($id = null) {
|
||||
if (!$id) {
|
||||
$this->Session->setFlash(__('Invalid id for Product', true));
|
||||
$this->redirect(array('action'=>'index'));
|
||||
return;
|
||||
}
|
||||
|
||||
$product = $this->Product->findById($id);
|
||||
if (!$product) {
|
||||
$this->Session->setFlash(__('Invalid Product', true));
|
||||
$this->redirect(array('action'=>'index'));
|
||||
return;
|
||||
}
|
||||
|
||||
$this->Product->id = $id;
|
||||
if ($this->Product->saveField('archived', 0)) {
|
||||
$this->Session->setFlash(__('Product unarchived', true));
|
||||
$this->redirect(array('action'=>'view_archived_principle', $product['Product']['principle_id']));
|
||||
} else {
|
||||
$this->Session->setFlash(__('Failed to unarchive product', true));
|
||||
$this->redirect(array('action'=>'view_archived_principle', $product['Product']['principle_id']));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
42
php/app/views/products/view_archived_principle.ctp
Normal file
42
php/app/views/products/view_archived_principle.ctp
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<div class="products view">
|
||||
|
||||
<h2><?php echo $principle['Principle']['name']; ?>: Archived Products
|
||||
<span style="float: right; font-size: 14px;">
|
||||
<?php echo $html->link(__('Back to Active Products', true), array('action'=>'view_principle', $principle['Principle']['id'])); ?>
|
||||
</span>
|
||||
</h2>
|
||||
<table cellpadding="0" cellspacing="0" class="productTable">
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
|
||||
<th class="actions"><?php __('Actions');?></th>
|
||||
</tr>
|
||||
<?php
|
||||
$i = 0;
|
||||
foreach ($products as $product):
|
||||
$class = null;
|
||||
if ($i++ % 2 == 0) {
|
||||
$class = ' class="altrow"';
|
||||
}
|
||||
?>
|
||||
<tr<?php echo $class;?>>
|
||||
<td>
|
||||
<?php echo $product['Product']['title']; ?>
|
||||
</td>
|
||||
|
||||
<td class="actions">
|
||||
<?php echo $html->link(__('View', true), array('action'=>'view', $product['Product']['id'])); ?>
|
||||
<?php echo $html->link(__('Un-Archive', true), array('action'=>'unarchive', $product['Product']['id']), null, sprintf(__('Are you sure you want to un-archive %s?', true), $product['Product']['title'])); ?>
|
||||
<?php if($is_admin): ?>
|
||||
<?php echo $html->link(__('Delete', true), array('action'=>'delete', $product['Product']['id']), null, sprintf(__('Are you sure you want to permanently delete %s?', true), $product['Product']['title'])); ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<?php endforeach; ?>
|
||||
</table>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<?php debug($products); ?>
|
||||
|
||||
|
||||
|
|
@ -1,6 +1,10 @@
|
|||
<div class="products view">
|
||||
|
||||
<h2><?php echo $principle['Principle']['name']; ?>: Products</h2>
|
||||
<h2><?php echo $principle['Principle']['name']; ?>: Products
|
||||
<span style="float: right; font-size: 14px;">
|
||||
<?php echo $html->link(__('View Archived Products', true), array('action'=>'view_archived_principle', $principle['Principle']['id'])); ?>
|
||||
</span>
|
||||
</h2>
|
||||
<table cellpadding="0" cellspacing="0" class="productTable">
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
|
|
@ -24,6 +28,7 @@ foreach ($products as $product):
|
|||
<?php echo $html->link(__('View', true), array('action'=>'view', $product['Product']['id'])); ?>
|
||||
<?php echo $html->link(__('Edit', true), array('action'=>'edit', $product['Product']['id'])); ?>
|
||||
<?php echo $html->link(__('Create New Product based on this', true), array('action'=>'cloneProduct', $product['Product']['id'])); ?>
|
||||
<?php echo $html->link(__('Archive', true), array('action'=>'archive', $product['Product']['id']), null, sprintf(__('Are you sure you want to archive %s?', true), $product['Product']['title'])); ?>
|
||||
</td>
|
||||
<?php endforeach; ?>
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -618,8 +618,19 @@ td.rightAlign {
|
|||
/* View Products Table */
|
||||
|
||||
table.productTable {
|
||||
width: auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table.productTable th {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table.productTable td {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
table.productTable td.actions {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue