create and edit products

This commit is contained in:
Tiago vasconcelos 2022-07-15 10:22:13 +01:00
parent c19618eddc
commit 88c45a9c45
5 changed files with 131 additions and 117 deletions

View file

@ -51,7 +51,6 @@ async def create_diagonalley_product(data: createProduct) -> Products:
async def update_diagonalley_product(product_id: str, **kwargs) -> Optional[Stalls]: async def update_diagonalley_product(product_id: str, **kwargs) -> Optional[Stalls]:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
# with open_ext_db("diagonalley") as db:
await db.execute( await db.execute(
f"UPDATE diagonalley.products SET {q} WHERE id = ?", f"UPDATE diagonalley.products SET {q} WHERE id = ?",
(*kwargs.values(), product_id), (*kwargs.values(), product_id),
@ -60,7 +59,7 @@ async def update_diagonalley_product(product_id: str, **kwargs) -> Optional[Stal
"SELECT * FROM diagonalley.products WHERE id = ?", (product_id,) "SELECT * FROM diagonalley.products WHERE id = ?", (product_id,)
) )
return get_diagonalley_stall(product_id) return Products(**row) if row else None
async def get_diagonalley_product(product_id: str) -> Optional[Products]: async def get_diagonalley_product(product_id: str) -> Optional[Products]:
@ -190,6 +189,7 @@ async def get_diagonalley_stall(stall_id: str) -> Optional[Stalls]:
row = await db.fetchone( row = await db.fetchone(
"SELECT * FROM diagonalley.stalls WHERE id = ?", (stall_id,) "SELECT * FROM diagonalley.stalls WHERE id = ?", (stall_id,)
) )
print("ROW", row)
return Stalls(**row) if row else None return Stalls(**row) if row else None

View file

@ -8,9 +8,9 @@ async def m001_initial(db):
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
stall TEXT NOT NULL, stall TEXT NOT NULL,
product TEXT NOT NULL, product TEXT NOT NULL,
categories TEXT NOT NULL, categories TEXT,
description TEXT NOT NULL, description TEXT,
image TEXT NOT NULL, image TEXT,
price INTEGER NOT NULL, price INTEGER NOT NULL,
quantity INTEGER NOT NULL quantity INTEGER NOT NULL
); );

View file

@ -25,7 +25,7 @@ class createStalls(BaseModel):
class createProduct(BaseModel): class createProduct(BaseModel):
stall: str = Query(...) stall: str = Query(...)
product: str = Query(None) product: str = Query(...)
categories: str = Query(None) categories: str = Query(None)
description: str = Query(None) description: str = Query(None)
image: str = Query(None) image: str = Query(None)
@ -37,9 +37,9 @@ class Products(BaseModel):
id: str id: str
stall: str stall: str
product: str product: str
categories: str categories: Optional[str]
description: str description: Optional[str]
image: str image: Optional[str]
price: int price: int
quantity: int quantity: int

View file

@ -1,6 +1,7 @@
{% extends "base.html" %} {% from "macros.jinja" import window_vars with context {% extends "base.html" %} {% from "macros.jinja" import window_vars with context
%} {% block page %} %} {% block page %}
<div class="row q-col-gutter-md"> <div class="row q-col-gutter-md">
<!-- PRODUCT DIALOG -->
<q-dialog v-model="productDialog.show" position="top"> <q-dialog v-model="productDialog.show" position="top">
<q-card class="q-pa-lg q-pt-xl" style="width: 500px"> <q-card class="q-pa-lg q-pt-xl" style="width: 500px">
<q-form @submit="sendProductFormData" class="q-gutter-md"> <q-form @submit="sendProductFormData" class="q-gutter-md">
@ -26,28 +27,37 @@
v-model.trim="productDialog.data.description" v-model.trim="productDialog.data.description"
label="Description" label="Description"
></q-input> ></q-input>
<div class="row"> <!-- <div class="row"> -->
<div class="col-5"> <!-- <div class="col-5">
<q-select <q-select
filled filled
dense dense
v-model.trim="productDialog.data.categories"
multiple multiple
v-model.trim="productDialog.data.categories"
:options="categories" :options="categories"
label="Categories" label="Categories"
class="q-pr-sm" class="q-pr-sm"
></q-select> ></q-select>
</div> </div> -->
<div class="col-7"> <!-- <div class="col-7"> -->
<q-input <q-select
filled filled
multiple
dense dense
v-model.trim="productDialog.categoriesextra" emit-value
placeholder="crafts,robots,etc (seperate by comma)" v-model.trim="productDialog.data.categories"
label="Other categories *optional" use-input
></q-input> use-chips
</div> multiple
</div> hide-dropdown-icon
input-debounce="0"
new-value-mode="add-unique"
label="Categories"
placeholder="crafts,robots,etc"
hint="Hit Enter to add"
></q-select>
<!-- </div> -->
<!-- </div> -->
<q-file <q-file
class="q-pr-md" class="q-pr-md"
@ -108,14 +118,14 @@
>Create Product</q-btn >Create Product</q-btn
> >
<q-btn v-close-popup flat color="grey" class="q-ml-auto" <q-btn v-close-popup flat @click="resetDialog('productDialog')" color="grey" class="q-ml-auto"
>Cancel</q-btn >Cancel</q-btn
> >
</div> </div>
</q-form> </q-form>
</q-card> </q-card>
</q-dialog> </q-dialog>
<!-- ZONE DIALOG -->
<q-dialog v-model="zoneDialog.show" position="top"> <q-dialog v-model="zoneDialog.show" position="top">
<q-card class="q-pa-lg q-pt-xl" style="width: 500px"> <q-card class="q-pa-lg q-pt-xl" style="width: 500px">
<q-form @submit="sendZoneFormData" class="q-gutter-md"> <q-form @submit="sendZoneFormData" class="q-gutter-md">
@ -152,15 +162,14 @@
>Create Shipping Zone</q-btn >Create Shipping Zone</q-btn
> >
<q-btn v-close-popup flat color="grey" class="q-ml-auto" <q-btn v-close-popup flat @click="resetDialog('zoneDialog')" color="grey" class="q-ml-auto"
>Cancel</q-btn >Cancel</q-btn
> >
</div> </div>
</q-form> </q-form>
</q-card> </q-card>
</q-dialog> </q-dialog>
<!-- SHOP DIALOG -->
<q-dialog v-model="shopDialog.show" position="top"> <q-dialog v-model="shopDialog.show" position="top">
<q-card class="q-pa-lg q-pt-xl" style="width: 500px"> <q-card class="q-pa-lg q-pt-xl" style="width: 500px">
<q-form @submit="sendShopFormData" class="q-gutter-md"> <q-form @submit="sendShopFormData" class="q-gutter-md">
@ -173,7 +182,8 @@
filled filled
dense dense
multiple multiple
:options="stalls" emit-value
:options="stalls.map(s => ({label: s.name, value: s.id}))"
label="Stalls" label="Stalls"
v-model.trim="shopDialog.data.stalls" v-model.trim="shopDialog.data.stalls"
></q-select> ></q-select>
@ -195,14 +205,14 @@
>Launch</q-btn >Launch</q-btn
> >
<q-btn v-close-popup flat color="grey" class="q-ml-auto" <q-btn v-close-popup flat @click="resetDialog('shopDialog')" color="grey" class="q-ml-auto"
>Cancel</q-btn >Cancel</q-btn
> >
</div> </div>
</q-form> </q-form>
</q-card> </q-card>
</q-dialog> </q-dialog>
<!-- STALL/STORE DIALOG -->
<q-dialog v-model="stallDialog.show" position="top"> <q-dialog v-model="stallDialog.show" position="top">
<q-card class="q-pa-lg q-pt-xl" style="width: 500px"> <q-card class="q-pa-lg q-pt-xl" style="width: 500px">
<q-form @submit="sendStallFormData" class="q-gutter-md"> <q-form @submit="sendStallFormData" class="q-gutter-md">
@ -292,7 +302,7 @@
type="submit" type="submit"
>Create Store</q-btn >Create Store</q-btn
> >
<q-btn v-close-popup flat color="grey" class="q-ml-auto" <q-btn v-close-popup flat @click="resetDialog('stallDialog')" color="grey" class="q-ml-auto"
>Cancel</q-btn >Cancel</q-btn
> >
</div> </div>
@ -329,7 +339,7 @@
</q-card-section> </q-card-section>
</q-card> </q-card>
<q-card> <q-card> <!-- ORDERS TABLE -->
<q-card-section> <q-card-section>
<div class="row items-center no-wrap q-mb-md"> <div class="row items-center no-wrap q-mb-md">
<div class="col"> <div class="col">
@ -393,7 +403,7 @@
</q-card-section> </q-card-section>
</q-card> </q-card>
<q-card> <q-card> <!-- PRODUCTS TABLE -->
<q-card-section> <q-card-section>
<div class="row items-center no-wrap q-mb-md"> <div class="row items-center no-wrap q-mb-md">
<div class="col"> <div class="col">
@ -472,8 +482,8 @@
</q-table> </q-table>
</q-card-section> </q-card-section>
</q-card> </q-card>
<!-- STORES -->
<q-card> <q-card> <!-- STORES TABLE -->
<q-card-section> <q-card-section>
<div class="row items-center no-wrap q-mb-md"> <div class="row items-center no-wrap q-mb-md">
<div class="col"> <div class="col">
@ -531,8 +541,8 @@
</q-table> </q-table>
</q-card-section> </q-card-section>
</q-card> </q-card>
<!-- ZONES -->
<q-card> <q-card> <!-- ZONES TABLE -->
<q-card-section> <q-card-section>
<div class="row items-center no-wrap q-mb-md"> <div class="row items-center no-wrap q-mb-md">
<div class="col"> <div class="col">
@ -658,6 +668,7 @@ const mapStalls = obj => {
} }
const mapProducts = obj => { const mapProducts = obj => {
obj._data = _.clone(obj) obj._data = _.clone(obj)
console.log(obj)
return obj return obj
} }
const mapZone = obj => { const mapZone = obj => {
@ -744,7 +755,8 @@ new Vue({
'Technology (Phones and Computers)', 'Technology (Phones and Computers)',
'Home (furniture and accessories)', 'Home (furniture and accessories)',
'Gifts (flowers, cards, etc)', 'Gifts (flowers, cards, etc)',
'Adult' 'Adult',
'Other'
], ],
relayOptions: [ relayOptions: [
'wss://nostr-relay.herokuapp.com/ws', 'wss://nostr-relay.herokuapp.com/ws',
@ -924,6 +936,10 @@ new Vue({
} }
}, },
methods: { methods: {
resetDialog(dialog){
this[dialog].show = false
this[dialog].data = {}
},
generateKeys: function(){ generateKeys: function(){
var self = this var self = this
LNbits.api LNbits.api
@ -967,6 +983,7 @@ new Vue({
////////////////STALLS////////////////// ////////////////STALLS//////////////////
//////////////////////////////////////// ////////////////////////////////////////
getStalls: function () { getStalls: function () {
console.log(this.g.user)
var self = this var self = this
LNbits.api LNbits.api
.request( .request(
@ -1037,9 +1054,7 @@ new Vue({
return obj.id == data.id return obj.id == data.id
}) })
self.stalls.push(mapStalls(response.data)) self.stalls.push(mapStalls(response.data))
self.stallDialog.show = false self.resetDialog('stallDialog')
self.stallDialog.data = {}
data = {}
}) })
.catch(function (error) { .catch(function (error) {
LNbits.utils.notifyApiError(error) LNbits.utils.notifyApiError(error)
@ -1058,9 +1073,10 @@ new Vue({
) )
.then(function (response) { .then(function (response) {
self.stalls.push(mapStalls(response.data)) self.stalls.push(mapStalls(response.data))
self.stallDialog.show = false self.resetDialog('stallDialog')
self.stallDialog.data = {} //self.stallDialog.show = false
data = {} //self.stallDialog.data = {}
//data = {}
}) })
.catch(function (error) { .catch(function (error) {
LNbits.utils.notifyApiError(error) LNbits.utils.notifyApiError(error)
@ -1105,7 +1121,7 @@ new Vue({
self.g.user.wallets[0].inkey self.g.user.wallets[0].inkey
) )
.then(function (response) { .then(function (response) {
console.log(response.data) console.log("RESP DATA", response.data)
if (response.data) { if (response.data) {
self.products = response.data.map(mapProducts) self.products = response.data.map(mapProducts)
} }
@ -1119,22 +1135,24 @@ new Vue({
var link = _.findWhere(self.products, {id: linkId}) var link = _.findWhere(self.products, {id: linkId})
self.productDialog.data = _.clone(link._data) self.productDialog.data = _.clone(link._data)
self.productDialog.data.categories = self.productDialog.data.categories.split(",")
self.productDialog.show = true self.productDialog.show = true
}, },
sendProductFormData: function () { sendProductFormData: function () {
let _data = {...this.productDialog.data}
var data = { var data = {
stall: this.productDialog.data.stall, stall: _data.stall,
product: this.productDialog.data.product, product: _data.product,
categories: categories: _data.categories && _data.categories.toString(),
this.productDialog.data.categories + description: _data.description,
this.productDialog.categoriesextra, image: _data.image,
description: this.productDialog.data.description, price: _data.price,
image: this.productDialog.data.image, quantity: _data.quantity
price: this.productDialog.data.price,
quantity: this.productDialog.data.quantity
} }
if (this.productDialog.data.id) { if (_data.id) {
this.updateProduct({...this.productDialog.data, ...data}) data.id = _data.id
this.updateProduct(data)
} else { } else {
this.createProduct(data) this.createProduct(data)
} }
@ -1163,80 +1181,72 @@ new Vue({
this.productDialog = {...this.productDialog} this.productDialog = {...this.productDialog}
}, },
updateProduct: function (data) { updateProduct: function (data) {
var self = this
LNbits.api
.request(
'PUT',
'/diagonalley/api/v1/products' + data.id,
_.findWhere(self.g.user.wallets, {
id: self.productDialog.data.wallet
}).inkey,
_.pick(
data,
'shopname',
'relayaddress',
'shippingzone1',
'zone1cost',
'shippingzone2',
'zone2cost',
'email'
)
)
.then(function (response) {
self.products = _.reject(self.products, function (obj) {
return obj.id == data.id
})
self.products.push(mapProducts(response.data))
self.productDialog.show = false
self.productDialog.data = {}
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
createProduct: function (data) {
var self = this var self = this
let wallet = _.findWhere(this.stalls, { let wallet = _.findWhere(this.stalls, {
id: self.productDialog.data.stall id: self.productDialog.data.stall
}).wallet }).wallet
console.log(wallet)
LNbits.api LNbits.api
.request( .request(
'POST', 'PUT',
'/diagonalley/api/v1/products', '/diagonalley/api/v1/products/' + data.id,
_.findWhere(self.g.user.wallets, { _.findWhere(self.g.user.wallets, {
id: wallet id: wallet
}).inkey, }).inkey,
data data
) )
.then(function (response) { .then(function (response) {
self.products = _.reject(self.products, function (obj) {
return obj.id == data.id
})
self.products.push(mapProducts(response.data)) self.products.push(mapProducts(response.data))
self.productDialog.show = false self.resetDialog('productDialog')
self.productDialog.data = {} //self.productDialog.show = false
//self.productDialog.data = {}
}) })
.catch(function (error) { .catch(function (error) {
LNbits.utils.notifyApiError(error) LNbits.utils.notifyApiError(error)
}) })
}, },
createProduct: function (data) {
let self = this
const walletId = _.findWhere(this.stalls, {id: data.stall}).wallet
console.log("DATA", walletId, data)
LNbits.api
.request(
'POST',
'/diagonalley/api/v1/products',
_.findWhere(self.g.user.wallets, {id: walletId}).inkey,
data
)
.then((response) => {
console.log(response)
self.products.push(mapProducts(response.data))
self.resetDialog('productDialog')
})
.catch((error) => {
LNbits.utils.notifyApiError(error)
})
},
deleteProduct: function (productId) { deleteProduct: function (productId) {
var self = this const product = _.findWhere(this.products, {id: productId})
var product = _.findWhere(this.products, {id: productId}) const walletId = _.findWhere(this.stalls, {id: product.stall}).wallet
LNbits.utils LNbits.utils
.confirmDialog('Are you sure you want to delete this products link?') .confirmDialog('Are you sure you want to delete this products link?')
.onOk(function () { .onOk(() => {
LNbits.api LNbits.api
.request( .request(
'DELETE', 'DELETE',
'/diagonalley/api/v1/products/' + productId, '/diagonalley/api/v1/products/' + productId,
_.findWhere(self.g.user.wallets, {id: product.wallet}).inkey _.findWhere(this.g.user.wallets, {id: walletId}).adminkey
) )
.then(function (response) { .then(() => {
self.products = _.reject(self.products, function (obj) { this.products = _.reject(this.products, (obj) => {
return obj.id == productId return obj.id == productId
}) })
}) })
.catch(function (error) { .catch((error) => {
LNbits.utils.notifyApiError(error) LNbits.utils.notifyApiError(error)
}) })
}) })
@ -1368,7 +1378,7 @@ new Vue({
LNbits.api LNbits.api
.request( .request(
'GET', 'GET',
'/diagonalley/api/v1/shops?all_wallets', '/diagonalley/api/v1/shops?all_wallets=true',
this.g.user.wallets[0].inkey this.g.user.wallets[0].inkey
) )
.then(function (response) { .then(function (response) {

View file

@ -83,6 +83,9 @@ async def api_diagonalley_products(
stalls = [stall.id for stall in await get_diagonalley_stalls(wallet_ids)] stalls = [stall.id for stall in await get_diagonalley_stalls(wallet_ids)]
if not stalls:
return
return [product.dict() for product in await get_diagonalley_products(stalls)] return [product.dict() for product in await get_diagonalley_products(stalls)]
@ -94,17 +97,17 @@ async def api_diagonalley_product_create(
if product_id: if product_id:
product = await get_diagonalley_product(product_id) product = await get_diagonalley_product(product_id)
if not product: if not product:
return {"message": "Withdraw product does not exist."} return {"message": "Withdraw product does not exist."}
if product.wallet != wallet.wallet.id: stall = await get_diagonalley_stall(stall_id = product.stall)
if stall.wallet != wallet.wallet.id:
return {"message": "Not your withdraw product."} return {"message": "Not your withdraw product."}
product = await update_diagonalley_product(product_id, **data.dict()) product = await update_diagonalley_product(product_id, **data.dict())
else: else:
product = await create_diagonalley_product(data=data) product = await create_diagonalley_product(data=data)
print("PRODUCT", product)
return product.dict() return product.dict()
@ -117,7 +120,8 @@ async def api_diagonalley_products_delete(
if not product: if not product:
return {"message": "Product does not exist."} return {"message": "Product does not exist."}
if product.wallet != wallet.wallet.id: stall = await get_diagonalley_stall(product.stall)
if stall.wallet != wallet.wallet.id:
return {"message": "Not your Diagon Alley."} return {"message": "Not your Diagon Alley."}
await delete_diagonalley_product(product_id) await delete_diagonalley_product(product_id)
@ -144,7 +148,7 @@ async def api_diagonalley_zone_create(
@diagonalley_ext.post("/api/v1/zones/{zone_id}") @diagonalley_ext.post("/api/v1/zones/{zone_id}")
async def api_diagonalley_zone_update( async def api_diagonalley_zone_update(
data: createZones, data: createZones,
zone_id: str = Query(None), zone_id: str,
wallet: WalletTypeInfo = Depends(require_admin_key), wallet: WalletTypeInfo = Depends(require_admin_key),
): ):
zone = await get_diagonalley_zone(zone_id) zone = await get_diagonalley_zone(zone_id)
@ -191,13 +195,13 @@ async def api_diagonalley_stalls(
@diagonalley_ext.put("/api/v1/stalls/{stall_id}") @diagonalley_ext.put("/api/v1/stalls/{stall_id}")
async def api_diagonalley_stall_create( async def api_diagonalley_stall_create(
data: createStalls, data: createStalls,
stall_id: str = Query(None), stall_id: str = None,
wallet: WalletTypeInfo = Depends(require_invoice_key), wallet: WalletTypeInfo = Depends(require_invoice_key),
): ):
if stall_id: if stall_id:
stall = await get_diagonalley_stall(stall_id) stall = await get_diagonalley_stall(stall_id)
print("ID", stall_id)
if not stall: if not stall:
return {"message": "Withdraw stall does not exist."} return {"message": "Withdraw stall does not exist."}
@ -213,7 +217,7 @@ async def api_diagonalley_stall_create(
@diagonalley_ext.delete("/api/v1/stalls/{stall_id}") @diagonalley_ext.delete("/api/v1/stalls/{stall_id}")
async def api_diagonalley_stall_delete( async def api_diagonalley_stall_delete(
stall_id: str = Query(None), wallet: WalletTypeInfo = Depends(require_admin_key) stall_id: str, wallet: WalletTypeInfo = Depends(require_admin_key)
): ):
stall = await get_diagonalley_stall(stall_id) stall = await get_diagonalley_stall(stall_id)
@ -255,7 +259,7 @@ async def api_diagonalley_order_create(
@diagonalley_ext.delete("/api/v1/orders/{order_id}") @diagonalley_ext.delete("/api/v1/orders/{order_id}")
async def api_diagonalley_order_delete( async def api_diagonalley_order_delete(
order_id: str = Query(None), wallet: WalletTypeInfo = Depends(get_key_type) order_id: str, wallet: WalletTypeInfo = Depends(get_key_type)
): ):
order = await get_diagonalley_order(order_id) order = await get_diagonalley_order(order_id)
@ -272,7 +276,7 @@ async def api_diagonalley_order_delete(
@diagonalley_ext.get("/api/v1/orders/paid/{order_id}") @diagonalley_ext.get("/api/v1/orders/paid/{order_id}")
async def api_diagonalley_order_paid( async def api_diagonalley_order_paid(
order_id: str = Query(None), wallet: WalletTypeInfo = Depends(require_admin_key) order_id, wallet: WalletTypeInfo = Depends(require_admin_key)
): ):
await db.execute( await db.execute(
"UPDATE diagonalley.orders SET paid = ? WHERE id = ?", "UPDATE diagonalley.orders SET paid = ? WHERE id = ?",
@ -286,7 +290,7 @@ async def api_diagonalley_order_paid(
@diagonalley_ext.get("/api/v1/orders/shipped/{order_id}") @diagonalley_ext.get("/api/v1/orders/shipped/{order_id}")
async def api_diagonalley_order_shipped( async def api_diagonalley_order_shipped(
order_id: str = Query(None), wallet: WalletTypeInfo = Depends(get_key_type) order_id, wallet: WalletTypeInfo = Depends(get_key_type)
): ):
await db.execute( await db.execute(
"UPDATE diagonalley.orders SET shipped = ? WHERE id = ?", "UPDATE diagonalley.orders SET shipped = ? WHERE id = ?",
@ -307,7 +311,7 @@ async def api_diagonalley_order_shipped(
@diagonalley_ext.get("/api/v1/stall/products/{stall_id}") @diagonalley_ext.get("/api/v1/stall/products/{stall_id}")
async def api_diagonalley_stall_products( async def api_diagonalley_stall_products(
stall_id: str = Query(None), wallet: WalletTypeInfo = Depends(get_key_type) stall_id, wallet: WalletTypeInfo = Depends(get_key_type)
): ):
rows = await db.fetchone( rows = await db.fetchone(