started shipping module
This commit is contained in:
@@ -45,10 +45,20 @@ services:
|
|||||||
- "8080"
|
- "8080"
|
||||||
networks:
|
networks:
|
||||||
- robot-shop
|
- robot-shop
|
||||||
|
mysql:
|
||||||
|
build:
|
||||||
|
context: shipping/database
|
||||||
|
image: steveww/rs-shipping-db
|
||||||
|
ports:
|
||||||
|
- "3306"
|
||||||
|
networks:
|
||||||
|
- robot-shop
|
||||||
shipping:
|
shipping:
|
||||||
build:
|
build:
|
||||||
context: shipping
|
context: shipping/service
|
||||||
image: steveww/rs-shipping
|
image: steveww/rs-shipping
|
||||||
|
depends_on:
|
||||||
|
- mysql
|
||||||
ports:
|
ports:
|
||||||
- "8080"
|
- "8080"
|
||||||
networks:
|
networks:
|
||||||
|
@@ -1,22 +0,0 @@
|
|||||||
apiVersion: apps/v1beta2
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: mongodb
|
|
||||||
namespace: robot-shop
|
|
||||||
labels:
|
|
||||||
app: mongodb
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: mongodb
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: mongodb
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: mongodb
|
|
||||||
image: steveww/rs-mongodb
|
|
||||||
ports:
|
|
||||||
- containerPort: 27017
|
|
@@ -1,14 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: mongodb
|
|
||||||
namespace: robot-shop
|
|
||||||
labels:
|
|
||||||
app: mongodb
|
|
||||||
spec:
|
|
||||||
ports:
|
|
||||||
- name: mongodb
|
|
||||||
port: 27017
|
|
||||||
targetPort: 27017
|
|
||||||
selector:
|
|
||||||
app: mongodb
|
|
16
shipping/database/Dockerfile
Normal file
16
shipping/database/Dockerfile
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
FROM mysql:5.7.20
|
||||||
|
|
||||||
|
ENV MYSQL_ALLOW_EMPTY_PASSWORD=yes \
|
||||||
|
MYSQL_DATABASE=cities \
|
||||||
|
MYSQL_USER=shipping \
|
||||||
|
MYSQL_PASSWORD=secret
|
||||||
|
|
||||||
|
# change datadir entry in /etc/mysql/my.cnf
|
||||||
|
COPY config.sh /root/
|
||||||
|
RUN /root/config.sh
|
||||||
|
|
||||||
|
COPY scripts/* /docker-entrypoint-initdb.d/
|
||||||
|
|
||||||
|
RUN /entrypoint.sh mysqld & while [ ! -f /tmp/finished ]; do sleep 10; done && mysqladmin shutdown
|
||||||
|
RUN rm /docker-entrypoint-initdb.d/*
|
||||||
|
|
19
shipping/database/config.sh
Executable file
19
shipping/database/config.sh
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
DIR="/etc/mysql"
|
||||||
|
|
||||||
|
FILE=$(fgrep -Rl datadir "$DIR")
|
||||||
|
if [ -n "$FILE" ]
|
||||||
|
then
|
||||||
|
# mkdir /data/mysql
|
||||||
|
echo " "
|
||||||
|
echo "Updating $FILE"
|
||||||
|
echo " "
|
||||||
|
sed -i -e '/^datadir/s/\/var\/lib\//\/data\//' $FILE
|
||||||
|
fgrep -R datadir "$DIR"
|
||||||
|
else
|
||||||
|
echo " "
|
||||||
|
echo "file not found"
|
||||||
|
echo " "
|
||||||
|
fi
|
||||||
|
|
27
shipping/database/convert.sh
Executable file
27
shipping/database/convert.sh
Executable file
@@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Convert cities CSV file to SQL
|
||||||
|
|
||||||
|
if [ -z "$1" ]
|
||||||
|
then
|
||||||
|
echo "File required as first arg"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# \x27 is a single quote
|
||||||
|
# \x60 is back tick
|
||||||
|
awk '
|
||||||
|
BEGIN {
|
||||||
|
FS=","
|
||||||
|
format = "INSERT INTO cities(country_code, city, name, region, latitude, longitude) VALUES(\x27%s\x27, \x27%s\x27, \x27%s\x27, \x27%s\x27, %s, %s);\n"
|
||||||
|
getline
|
||||||
|
}
|
||||||
|
{
|
||||||
|
gsub(/\x27/, "\x60", $2)
|
||||||
|
gsub(/\x27/, "\x60", $3)
|
||||||
|
gsub(/\x27/, "\x60", $4)
|
||||||
|
if(NF == 6) printf format, $1, $2, $3, $4, $5, $6
|
||||||
|
else printf format, $1, $2, $3, $4, $6, $7
|
||||||
|
}
|
||||||
|
' $1
|
||||||
|
|
16
shipping/database/scripts/00-init-schema.sql
Normal file
16
shipping/database/scripts/00-init-schema.sql
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
CREATE TABLE cities (
|
||||||
|
uuid int auto_increment primary key,
|
||||||
|
country_code varchar(2),
|
||||||
|
city varchar(100),
|
||||||
|
name varchar(100),
|
||||||
|
region varchar(100),
|
||||||
|
latitude decimal(10, 7),
|
||||||
|
longitude decimal(10, 7)
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
|
||||||
|
CREATE FULLTEXT INDEX city_idx ON cities(city);
|
||||||
|
|
||||||
|
CREATE INDEX region_idx ON cities(region);
|
||||||
|
|
||||||
|
CREATE INDEX c_code_idx ON cities(country_code);
|
||||||
|
|
BIN
shipping/database/scripts/10-data.sql.gz
Normal file
BIN
shipping/database/scripts/10-data.sql.gz
Normal file
Binary file not shown.
6
shipping/database/scripts/99-finished.sh
Executable file
6
shipping/database/scripts/99-finished.sh
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# signal that the import has finsihed
|
||||||
|
sleep 5
|
||||||
|
touch /tmp/finished
|
||||||
|
|
@@ -23,9 +23,14 @@
|
|||||||
<version>1.7.25</version>
|
<version>1.7.25</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>c3p0</groupId>
|
||||||
<artifactId>jetty-jmx</artifactId>
|
<artifactId>c3p0</artifactId>
|
||||||
<version>9.4.6.v20170531</version>
|
<version>0.9.1.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<version>5.1.45</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
170
shipping/service/src/main/java/org/steveww/spark/Main.java
Normal file
170
shipping/service/src/main/java/org/steveww/spark/Main.java
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
package org.steveww.spark;
|
||||||
|
|
||||||
|
import com.mchange.v2.c3p0.ComboPooledDataSource;
|
||||||
|
import spark.Spark;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.ResultSetMetaData;
|
||||||
|
import java.sql.Types;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(Main.class);
|
||||||
|
private static ComboPooledDataSource cpds = null;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
//
|
||||||
|
// Create database connector
|
||||||
|
// TODO - might need a retry loop here
|
||||||
|
//
|
||||||
|
try {
|
||||||
|
cpds = new ComboPooledDataSource();
|
||||||
|
cpds.setDriverClass( "com.mysql.jdbc.Driver" ); //loads the jdbc driver
|
||||||
|
cpds.setJdbcUrl( "jdbc:mysql://mysql/cities?useSSL=false&autoReconnect=true" );
|
||||||
|
cpds.setUser("shipping");
|
||||||
|
cpds.setPassword("secret");
|
||||||
|
// some config
|
||||||
|
cpds.setMinPoolSize(5);
|
||||||
|
cpds.setAcquireIncrement(5);
|
||||||
|
cpds.setMaxPoolSize(20);
|
||||||
|
cpds.setMaxStatements(180);
|
||||||
|
}
|
||||||
|
catch(Exception e) {
|
||||||
|
logger.error("Database Exception", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spark
|
||||||
|
Spark.port(8080);
|
||||||
|
|
||||||
|
Spark.get("/health", (req, res) -> "OK");
|
||||||
|
|
||||||
|
Spark.get("/count", (req, res) -> {
|
||||||
|
String data = query("select count(*) as count from cities");
|
||||||
|
res.header("Content-Type", "application/json");
|
||||||
|
|
||||||
|
return data;
|
||||||
|
});
|
||||||
|
|
||||||
|
Spark.get("/codes", (req, res) -> {
|
||||||
|
String data = query("select distinct country_code as code from cities order by code asc");
|
||||||
|
res.header("Content-Type", "application/json");
|
||||||
|
|
||||||
|
return data;
|
||||||
|
});
|
||||||
|
|
||||||
|
Spark.get("/match/:code/:text", (req, res) -> {
|
||||||
|
String query = "select name from cities where country_code ='" + req.params(":code") + "' and city like '" + req.params(":text") + "%' order by name asc limit 10";
|
||||||
|
logger.info("Query " + query);
|
||||||
|
String data = query(query);
|
||||||
|
res.header("Content-Type", "application/json");
|
||||||
|
|
||||||
|
return data;
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.info("Ready");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static String query(String query) {
|
||||||
|
StringBuilder buffer = new StringBuilder();
|
||||||
|
Connection conn = null;
|
||||||
|
Statement stmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
conn = cpds.getConnection();
|
||||||
|
stmt = conn.createStatement();
|
||||||
|
rs = stmt.executeQuery(query);
|
||||||
|
ResultSetMetaData metadata = rs.getMetaData();
|
||||||
|
int colCount = metadata.getColumnCount();
|
||||||
|
buffer.append('[');
|
||||||
|
while(rs.next()) {
|
||||||
|
// result set to JSON
|
||||||
|
buffer.append('{');
|
||||||
|
for(int idx = 1; idx <= colCount; idx++) {
|
||||||
|
String name = metadata.getColumnLabel(idx);
|
||||||
|
switch(metadata.getColumnType(idx)) {
|
||||||
|
case Types.INTEGER:
|
||||||
|
int i = rs.getInt(idx);
|
||||||
|
buffer.append(write(name, rs.getInt(idx)));
|
||||||
|
break;
|
||||||
|
case Types.BIGINT:
|
||||||
|
buffer.append(write(name, rs.getLong(idx)));
|
||||||
|
break;
|
||||||
|
case Types.DECIMAL:
|
||||||
|
case Types.NUMERIC:
|
||||||
|
buffer.append(write(name, rs.getBigDecimal(idx)));
|
||||||
|
break;
|
||||||
|
case Types.FLOAT:
|
||||||
|
case Types.REAL:
|
||||||
|
case Types.DOUBLE:
|
||||||
|
buffer.append(write(name, rs.getDouble(idx)));
|
||||||
|
break;
|
||||||
|
case Types.NVARCHAR:
|
||||||
|
case Types.VARCHAR:
|
||||||
|
case Types.LONGNVARCHAR:
|
||||||
|
case Types.LONGVARCHAR:
|
||||||
|
buffer.append(write(name, '"' + rs.getString(idx) + '"'));
|
||||||
|
break;
|
||||||
|
case Types.TINYINT:
|
||||||
|
case Types.SMALLINT:
|
||||||
|
buffer.append(write(name, rs.getShort(idx)));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logger.info("Unknown type " + metadata.getColumnType(idx));
|
||||||
|
}
|
||||||
|
if(idx != colCount) {
|
||||||
|
buffer.append(',');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer.append("}, ");
|
||||||
|
}
|
||||||
|
// trim off trailing ,
|
||||||
|
int idx = buffer.lastIndexOf(",");
|
||||||
|
if(idx != -1) {
|
||||||
|
buffer.setCharAt(idx, ' ');
|
||||||
|
}
|
||||||
|
buffer.append(']');
|
||||||
|
}
|
||||||
|
catch(Exception e) {
|
||||||
|
logger.error("Query Exception", e);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if(rs != null) {
|
||||||
|
try {
|
||||||
|
rs.close();
|
||||||
|
} catch(Exception e) {
|
||||||
|
logger.error("Close Exception", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(stmt != null) {
|
||||||
|
try {
|
||||||
|
stmt.close();
|
||||||
|
} catch(Exception e) {
|
||||||
|
logger.error("Close Exception", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(conn != null) {
|
||||||
|
try {
|
||||||
|
conn.close();
|
||||||
|
} catch(Exception e) {
|
||||||
|
logger.error("Close Exception", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static String write(String key, Object val) {
|
||||||
|
StringBuilder buffer = new StringBuilder();
|
||||||
|
|
||||||
|
buffer.append('"').append(key).append('"').append(": ").append(val);
|
||||||
|
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
}
|
@@ -1,22 +0,0 @@
|
|||||||
apiVersion: apps/v1beta2
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: shipping
|
|
||||||
namespace: robot-shop
|
|
||||||
labels:
|
|
||||||
app: shipping
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: shipping
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: shipping
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: shipping
|
|
||||||
image: steveww/rs-shipping
|
|
||||||
ports:
|
|
||||||
- containerPort: 8080
|
|
@@ -1,14 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: shipping
|
|
||||||
namespace: robot-shop
|
|
||||||
labels:
|
|
||||||
app: shipping
|
|
||||||
spec:
|
|
||||||
ports:
|
|
||||||
- name: shipping
|
|
||||||
port: 8080
|
|
||||||
targetPort: 8080
|
|
||||||
selector:
|
|
||||||
app: shipping
|
|
Binary file not shown.
@@ -1,17 +0,0 @@
|
|||||||
package org.steveww.spark;
|
|
||||||
|
|
||||||
import spark.Spark;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
public class Main {
|
|
||||||
private static Logger logger = LoggerFactory.getLogger(Main.class);
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
Spark.port(8080);
|
|
||||||
Spark.get("/hello", (req, res) -> "Hello World");
|
|
||||||
Spark.awaitInitialization();
|
|
||||||
logger.info("Ready");
|
|
||||||
}
|
|
||||||
}
|
|
@@ -54,6 +54,10 @@ server {
|
|||||||
proxy_pass http://cart:8080/;
|
proxy_pass http://cart:8080/;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
location /api/shipping/ {
|
||||||
|
proxy_pass http://shipping:8080/;
|
||||||
|
}
|
||||||
|
|
||||||
location /nginx_status {
|
location /nginx_status {
|
||||||
stub_status on;
|
stub_status on;
|
||||||
access_log off;
|
access_log off;
|
||||||
|
@@ -1,4 +1,39 @@
|
|||||||
<!-- shopping cart -->
|
<!-- shopping cart -->
|
||||||
<div>
|
<div>
|
||||||
Shopping cart for {{ data.uniqueid }} will be here
|
Shopping cart for {{ data.uniqueid }}
|
||||||
|
<div ng-if="data.cart.total == 0">
|
||||||
|
Your cart is empty, get shopping
|
||||||
|
</div>
|
||||||
|
<div ng-if="data.cart.total != 0">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>QTY</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Sub Total</th>
|
||||||
|
</tr>
|
||||||
|
<tr ng-repeat="item in data.cart.items">
|
||||||
|
<td><input type="number" size="2" min="0" max="10" ng-model="item.qty" ng-change="change(item.sku, item.qty);"/></td>
|
||||||
|
<td>{{ item.name }}</td>
|
||||||
|
<td class="currency">€{{ item.subtotal }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="3"> </td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td> </td>
|
||||||
|
<td>Tax</td>
|
||||||
|
<td class="currency">€{{ data.cart.tax }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td> </td>
|
||||||
|
<td>Total</td>
|
||||||
|
<td class="currency">€{{ data.cart.total }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="3">
|
||||||
|
<button ng-click="buy();">Buy</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -43,6 +43,10 @@ h3 a:visited {
|
|||||||
text-transform: capitalize;
|
text-transform: capitalize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.carttotal {
|
||||||
|
margin-left: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
ul.products {
|
ul.products {
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
}
|
}
|
||||||
@@ -145,3 +149,8 @@ table.credentials {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* cart */
|
||||||
|
.currency {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -28,6 +28,12 @@
|
|||||||
<div class="nav column">
|
<div class="nav column">
|
||||||
<h3><a href="login">Login / Register</a></h3>
|
<h3><a href="login">Login / Register</a></h3>
|
||||||
<h3><a href="cart">Cart</a></h3>
|
<h3><a href="cart">Cart</a></h3>
|
||||||
|
<div ng-if="data.cart.total == 0" class="carttotal">
|
||||||
|
Empty
|
||||||
|
</div>
|
||||||
|
<div ng-if="data.cart.total != 0" class="carttotal">
|
||||||
|
€{{ data.cart.total }}
|
||||||
|
</div>
|
||||||
<h3>Categories</h3>
|
<h3>Categories</h3>
|
||||||
<ul class="products">
|
<ul class="products">
|
||||||
<li ng-repeat="cat in data.categories">
|
<li ng-repeat="cat in data.categories">
|
||||||
@@ -54,8 +60,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- JavaScript -->
|
<!-- JavaScript -->
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular.min.js"></script>
|
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular.js"></script>
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular-route.min.js"></script>
|
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular-route.js"></script>
|
||||||
<script src="js/controller.js"></script>
|
<script src="js/controller.js"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
angular.element(document.getElementsByTagName('head')).append(angular.element('<base href="' + window.location.pathname + '" />'));
|
angular.element(document.getElementsByTagName('head')).append(angular.element('<base href="' + window.location.pathname + '" />'));
|
||||||
|
@@ -8,6 +8,9 @@
|
|||||||
var data = {
|
var data = {
|
||||||
uniqueid: '',
|
uniqueid: '',
|
||||||
user: {},
|
user: {},
|
||||||
|
cart: {
|
||||||
|
total: 0
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
@@ -26,6 +29,9 @@
|
|||||||
}).when('/cart', {
|
}).when('/cart', {
|
||||||
templateUrl: 'cart.html',
|
templateUrl: 'cart.html',
|
||||||
controller: 'cartform'
|
controller: 'cartform'
|
||||||
|
}).when('/shipping', {
|
||||||
|
templateUrl: 'shipping.html',
|
||||||
|
controller: 'shipform'
|
||||||
});
|
});
|
||||||
|
|
||||||
// needed for URL rewrite hash
|
// needed for URL rewrite hash
|
||||||
@@ -46,6 +52,10 @@
|
|||||||
$scope.data.uniqueid = 'foo';
|
$scope.data.uniqueid = 'foo';
|
||||||
$scope.data.categories = [];
|
$scope.data.categories = [];
|
||||||
$scope.data.products = {};
|
$scope.data.products = {};
|
||||||
|
// empty cart
|
||||||
|
$scope.data.cart = {
|
||||||
|
total: 0
|
||||||
|
};
|
||||||
|
|
||||||
$scope.getProducts = function(category) {
|
$scope.getProducts = function(category) {
|
||||||
if($scope.data.products[category]) {
|
if($scope.data.products[category]) {
|
||||||
@@ -108,6 +118,13 @@
|
|||||||
$scope.data.uniqueid = currentUser.uniqueid;
|
$scope.data.uniqueid = currentUser.uniqueid;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// watch for cart changes
|
||||||
|
$scope.$watch(() => { return currentUser.cart.total; }, (newVal, oldVal) => {
|
||||||
|
if(newVal !== oldVal) {
|
||||||
|
$scope.data.cart = currentUser.cart;
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
robotshop.controller('productform', function($scope, $http, $routeParams, $timeout, currentUser) {
|
robotshop.controller('productform', function($scope, $http, $routeParams, $timeout, currentUser) {
|
||||||
@@ -123,7 +140,8 @@
|
|||||||
url: url,
|
url: url,
|
||||||
method: 'GET'
|
method: 'GET'
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
console.log('cart', res);
|
console.log('cart', res.data);
|
||||||
|
currentUser.cart = res.data;
|
||||||
$scope.data.message = 'Added to cart';
|
$scope.data.message = 'Added to cart';
|
||||||
$timeout(clearMessage, 3000);
|
$timeout(clearMessage, 3000);
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
@@ -152,9 +170,62 @@
|
|||||||
loadProduct($routeParams.sku);
|
loadProduct($routeParams.sku);
|
||||||
});
|
});
|
||||||
|
|
||||||
robotshop.controller('cartform', function($scope, $http, currentUser) {
|
robotshop.controller('cartform', function($scope, $http, $location, currentUser) {
|
||||||
$scope.data = {};
|
$scope.data = {};
|
||||||
|
$scope.data.cart = {};
|
||||||
|
$scope.data.cart.total = 0;
|
||||||
$scope.data.uniqueid = currentUser.uniqueid;
|
$scope.data.uniqueid = currentUser.uniqueid;
|
||||||
|
|
||||||
|
$scope.buy = function() {
|
||||||
|
$location.url('/shipping');
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.change = function(sku, qty) {
|
||||||
|
// update the cart
|
||||||
|
var url = '/api/cart/update/' + $scope.data.uniqueid + '/' + sku + '/' + qty;
|
||||||
|
console.log('change', url);
|
||||||
|
$http({
|
||||||
|
url: url,
|
||||||
|
method: 'GET'
|
||||||
|
}).then((res) => {
|
||||||
|
$scope.data.cart = res.data;
|
||||||
|
currentUser.cart = res.data;
|
||||||
|
}).catch((e) => {
|
||||||
|
console.log('ERROR', e);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function loadCart(id) {
|
||||||
|
$http({
|
||||||
|
url: '/api/cart/cart/' + id,
|
||||||
|
method: 'GET'
|
||||||
|
}).then((res) => {
|
||||||
|
$scope.data.cart = res.data;
|
||||||
|
}).catch((e) => {
|
||||||
|
console.log('ERROR', e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
loadCart($scope.data.uniqueid);
|
||||||
|
});
|
||||||
|
|
||||||
|
robotshop.controller('shipform', function($scope, $http, currentUser) {
|
||||||
|
$scope.data = {};
|
||||||
|
$scope.data.codes = [ ];
|
||||||
|
|
||||||
|
function loadCodes() {
|
||||||
|
$http({
|
||||||
|
url: '/api/shipping/codes',
|
||||||
|
method: 'GET'
|
||||||
|
}).then((res) => {
|
||||||
|
$scope.data.codes = res.data;
|
||||||
|
}).catch((e) => {
|
||||||
|
console.log('ERROR', e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
loadCodes();
|
||||||
|
console.log('shipform init');
|
||||||
});
|
});
|
||||||
|
|
||||||
robotshop.controller('loginform', function($scope, $http, currentUser) {
|
robotshop.controller('loginform', function($scope, $http, currentUser) {
|
||||||
|
13
web/static/shipping.html
Normal file
13
web/static/shipping.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!-- shipping template -->
|
||||||
|
<div>
|
||||||
|
<h3>Shipping information</h3>
|
||||||
|
<div>
|
||||||
|
Enter country code <select ng-model="data.selectedCode" ng-options="opt.code for opt in data.codes"></select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Enter your location <input type="text" size="20" ng-model="data.location" ng-disabled="!data.selectedCode"/>
|
||||||
|
<button ng-click="addLocation();">Calculate</button>
|
||||||
|
</div>
|
||||||
|
<!-- TODO - add in shipping distance and cost -->
|
||||||
|
</div>
|
||||||
|
|
Reference in New Issue
Block a user