Merge pull request '5561-ticket.sale-tracking_cambiandoCrudModel' (!1614) from 5561-ticket.sale-tracking_cambiandoCrudModel into dev
gitea/salix/pipeline/head This commit looks good Details

Reviewed-on: #1614
Reviewed-by: Juan Ferrer <juan@verdnatura.es>
Reviewed-by: Javi Gallego <jgallego@verdnatura.es>
This commit is contained in:
Vicent Llopis 2023-08-22 10:42:41 +00:00
commit 9479b1931f
19 changed files with 616 additions and 182 deletions

View File

@ -0,0 +1,4 @@
INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
VALUES
('SaleTracking', 'deleteSaleGroupDetail', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
('SaleTracking', 'replaceOrCreate', 'WRITE', 'ALLOW', 'ROLE', 'employee');

View File

@ -0,0 +1,7 @@
DELETE FROM `vn`.`saleGroupDetail` WHERE id IN (468106,468104,468107,468105,495210,495208,495207,495209,462879,462880,447186,450623,450622,455606,455605,455827,455829,455828,459067,460689,460691,460690,460692,462408,463403,463405,463404,463129,463127,463126,463128,468098,468096,468099,468097,468310,468314,468313,475654,468325,473248,474803,474739,475042,475052,475047,475041,475051,475046,475040,475050,475045,475039,475049,475044,475038,475048,475043,474888,474892,474890,474887,474891,474889,481109,481107,481105,481108,481106,481110,479008,490787,490792,490791,485295,485294,485293,485528,490796,487853,487959,491303,490789,490914,490913,492305,492310,492307,492304,492309,492306,492303,492308,494111,494110,494480,494482,494481,494483,495202,495200,495199,495201,497209,499765,499763,499767,499764,499768,499766,502014,502013,508820,508819,508818,463133,463131,463130,463132,468102,468100,468103,468101,468311,468316,468315,468327,474894,474898,474896,474893,474897,474895,495206,495204,495203,495205,499771,499769,499773,499770,499774,499772);
ALTER TABLE `vn`.`saleGroupDetail` ADD CONSTRAINT saleGroupDetail_UN UNIQUE KEY (saleFk);
INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalId`)
VALUES
('SaleGroupDetail','deleteById','WRITE','ALLOW','employee');

View File

@ -28,11 +28,15 @@ module.exports = Self => {
Object.assign(myOptions, options); Object.assign(myOptions, options);
const stmt = new ParameterizedSQL(` const stmt = new ParameterizedSQL(`
SELECT iss.created, SELECT
iss.id,
iss.created,
iss.saleFk, iss.saleFk,
iss.quantity, iss.quantity,
iss.userFk, iss.userFk,
ish.id itemShelvingFk,
ish.shelvingFk, ish.shelvingFk,
s.parkingFk,
p.code, p.code,
u.name u.name
FROM itemShelvingSale iss FROM itemShelvingSale iss

View File

@ -41,11 +41,6 @@
"type": "belongsTo", "type": "belongsTo",
"model": "VnUser", "model": "VnUser",
"foreignKey": "userFk" "foreignKey": "userFk"
},
"shelving": {
"type": "belongsTo",
"model": "Shelving",
"foreignKey": "shelvingFk"
} }
} }
} }

View File

@ -0,0 +1,69 @@
module.exports = Self => {
Self.remoteMethod('delete', {
description: 'Delete sale trackings and item shelving sales',
accessType: 'READ',
accepts: [
{
arg: 'saleFk',
type: 'number',
description: 'The sale id'
},
{
arg: 'stateCode',
type: 'string'
}
],
returns: {
type: ['object'],
root: true
},
http: {
path: `/delete`,
verb: 'POST'
}
});
Self.delete = async(saleFk, stateCode, options) => {
const models = Self.app.models;
const myOptions = {};
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try {
if (stateCode === 'PREPARED') {
const itemShelvingSales = await models.ItemShelvingSale.find({where: {saleFk: saleFk}}, myOptions);
for (let itemShelvingSale of itemShelvingSales)
await itemShelvingSale.destroy(myOptions);
}
const state = await models.State.findOne({
where: {code: stateCode}
}, myOptions);
const filter = {
where: {
saleFk: saleFk,
stateFk: state.id
}
};
const saleTrackings = await models.SaleTracking.find(filter, myOptions);
for (let saleTracking of saleTrackings)
await saleTracking.destroy(myOptions);
if (tx) await tx.commit();
return true;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
};
};

View File

@ -0,0 +1,94 @@
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
module.exports = Self => {
Self.remoteMethod('filter', {
description: 'Returns a list with the lines of a ticket and its different states of preparation',
accessType: 'READ',
accepts: [
{
arg: 'id',
type: 'number',
required: true,
description: 'The ticket id',
http: {source: 'path'}
},
{
arg: 'filter',
type: 'object',
description: 'Filter defining where and paginated data'
}
],
returns: {
type: ['object'],
root: true
},
http: {
path: `/:id/filter`,
verb: 'GET'
}
});
Self.filter = async(id, filter, options) => {
const conn = Self.dataSource.connector;
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const stmts = [];
let stmt;
stmts.push('CALL cache.last_buy_refresh(FALSE)');
stmt = new ParameterizedSQL(
`SELECT t.clientFk,
t.shipped,
s.ticketFk,
s.itemFk,
s.quantity,
s.concept,
s.id saleFk,
i.image,
i.subName,
IF(stPrevious.saleFk,TRUE,FALSE) as isPreviousSelected,
stPrevious.isChecked as isPrevious,
stPrepared.isChecked as isPrepared,
stControled.isChecked as isControled,
sgd.id saleGroupDetailFk,
(MAX(sgd.id) IS NOT NULL) AS hasSaleGroupDetail,
p.code AS parkingCode,
i.value5,
i.value6,
i.value7,
i.value8,
i.value9,
i.value10
FROM vn.ticket t
JOIN vn.sale s ON s.ticketFk = t.id
JOIN vn.item i ON i.id = s.itemFk
LEFT JOIN cache.last_buy lb ON lb.item_id = i.id AND lb.warehouse_id = t.warehouseFk
LEFT JOIN vn.state st ON TRUE
LEFT JOIN vn.saleTracking stPrevious ON stPrevious.saleFk = s.id
AND stPrevious.stateFk = (SELECT id FROM vn.state WHERE code = 'PREVIOUS_PREPARATION')
LEFT JOIN vn.saleTracking stPrepared ON stPrepared.saleFk = s.id
AND stPrepared.stateFk = (SELECT id FROM vn.state WHERE code = 'PREPARED')
LEFT JOIN vn.saleTracking stControled ON stControled.saleFk = s.id
AND stControled.stateFk = (SELECT id FROM vn.state s2 WHERE code = 'CHECKED')
LEFT JOIN vn.saleGroupDetail sgd ON sgd.saleFk = s.id
LEFT JOIN vn.saleGroup sg ON sg.id = sgd.saleGroupFk
LEFT JOIN vn.parking p ON p.id = sg.parkingFk
WHERE t.id = ?
GROUP BY s.id`, [id]);
stmts.push(stmt);
stmt.merge(Self.makeSuffix(filter));
const index = stmts.push(stmt) - 1;
const sql = ParameterizedSQL.join(stmts, ';');
const result = await conn.executeStmt(sql, myOptions);
return result[index];
};
};

View File

@ -0,0 +1,90 @@
module.exports = Self => {
Self.remoteMethodCtx('new', {
description: `Replaces the record or creates it if it doesn't exist`,
accessType: 'READ',
accepts: [
{
arg: 'saleFk',
type: 'number',
description: 'The sale id'
},
{
arg: 'isChecked',
type: 'boolean'
},
{
arg: 'quantity',
type: 'number'
},
{
arg: 'stateCode',
type: 'string'
}
],
returns: {
type: ['object'],
root: true
},
http: {
path: `/new`,
verb: 'POST'
}
});
Self.new = async(ctx, saleFk, isChecked, quantity, stateCode, options) => {
const models = Self.app.models;
const userId = ctx.req.accessToken.userId;
const myOptions = {};
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try {
const state = await models.State.findOne({
where: {code: stateCode}
}, myOptions);
const saleTracking = await models.SaleTracking.findOne({
where: {
saleFk: saleFk,
stateFk: state.id,
workerFk: userId
}
}, myOptions);
let newSaleTracking;
if (saleTracking) {
newSaleTracking = await saleTracking.updateAttributes({
saleFk: saleFk,
stateFk: state.id,
workerFk: userId,
isChecked: isChecked,
originalQuantity: quantity,
isScanned: null
}, myOptions);
} else {
newSaleTracking = await models.SaleTracking.create({
saleFk: saleFk,
stateFk: state.id,
workerFk: userId,
isChecked: isChecked,
originalQuantity: quantity,
isScanned: null
}, myOptions);
}
if (tx) await tx.commit();
return newSaleTracking;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
};
};

View File

@ -0,0 +1,30 @@
const models = require('vn-loopback/server/server').models;
describe('sale-tracking delete()', () => {
it('should delete a row of saleTracking and itemShelvingSale', async() => {
const tx = await models.SaleTracking.beginTransaction({});
try {
const options = {transaction: tx};
const itemShelvingsBefore = await models.ItemShelvingSale.find(null, options);
const saleTrackingsBefore = await models.SaleTracking.find(null, options);
const saleFk = 1;
const stateCode = 'PREPARED';
const result = await models.SaleTracking.delete(saleFk, stateCode, options);
const itemShelvingsAfter = await models.ItemShelvingSale.find(null, options);
const saleTrackingsAfter = await models.SaleTracking.find(null, options);
expect(result).toEqual(true);
expect(saleTrackingsAfter.length).toBeLessThan(saleTrackingsBefore.length);
expect(itemShelvingsAfter.length).toBeLessThan(itemShelvingsBefore.length);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
});

View File

@ -0,0 +1,23 @@
const app = require('vn-loopback/server/server');
describe('sale-tracking filter()', () => {
it('should return 1 result filtering by ticket id', async() => {
const tx = await app.models.Claim.beginTransaction({});
try {
const options = {transaction: tx};
const id = 1;
const filter = {order: ['concept ASC', 'quantity DESC']};
const result = await app.models.SaleTracking.filter(id, filter, options);
expect(result.length).toEqual(4);
expect(result[0].ticketFk).toEqual(1);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
});

View File

@ -1,6 +1,6 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
describe('ticket listSaleTracking()', () => { describe('sale-tracking listSaleTracking()', () => {
it('should call the listSaleTracking method and return the response', async() => { it('should call the listSaleTracking method and return the response', async() => {
const tx = await models.SaleTracking.beginTransaction({}); const tx = await models.SaleTracking.beginTransaction({});

View File

@ -0,0 +1,49 @@
const models = require('vn-loopback/server/server').models;
describe('sale-tracking new()', () => {
it('should update a saleTracking', async() => {
const tx = await models.SaleTracking.beginTransaction({});
try {
const options = {transaction: tx};
const ctx = {req: {accessToken: {userId: 55}}};
const saleFk = 1;
const isChecked = true;
const quantity = 20;
const stateCode = 'PREPARED';
const result = await models.SaleTracking.new(ctx, saleFk, isChecked, quantity, stateCode, options);
expect(result.isChecked).toBe(true);
expect(result.originalQuantity).toBe(20);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should create a saleTracking', async() => {
const tx = await models.SaleTracking.beginTransaction({});
try {
const options = {transaction: tx};
const ctx = {req: {accessToken: {userId: 1}}};
const saleFk = 1;
const isChecked = true;
const quantity = 20;
const stateCode = 'PREPARED';
const result = await models.SaleTracking.new(ctx, saleFk, isChecked, quantity, stateCode, options);
expect(result.isChecked).toBe(true);
expect(result.originalQuantity).toBe(20);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
});

View File

@ -1,33 +0,0 @@
module.exports = Self => {
Self.remoteMethodCtx('salePreparingList', {
description: 'Returns a list with the lines of a ticket and its different states of preparation',
accessType: 'READ',
accepts: [{
arg: 'id',
type: 'number',
required: true,
description: 'The ticket id',
http: {source: 'path'}
}],
returns: {
type: ['object'],
root: true
},
http: {
path: `/:id/salePreparingList`,
verb: 'GET'
}
});
Self.salePreparingList = async(ctx, id, options) => {
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
query = `CALL vn.salePreparingList(?)`;
const [sales] = await Self.rawSql(query, [id], myOptions);
return sales;
};
};

View File

@ -1,3 +1,6 @@
module.exports = Self => { module.exports = Self => {
require('../methods/sale-tracking/filter')(Self);
require('../methods/sale-tracking/listSaleTracking')(Self); require('../methods/sale-tracking/listSaleTracking')(Self);
require('../methods/sale-tracking/new')(Self);
require('../methods/sale-tracking/delete')(Self);
}; };

View File

@ -1,6 +1,5 @@
module.exports = Self => { module.exports = Self => {
require('../methods/sale/getClaimableFromTicket')(Self); require('../methods/sale/getClaimableFromTicket')(Self);
require('../methods/sale/salePreparingList')(Self);
require('../methods/sale/reserve')(Self); require('../methods/sale/reserve')(Self);
require('../methods/sale/deleteSales')(Self); require('../methods/sale/deleteSales')(Self);
require('../methods/sale/updatePrice')(Self); require('../methods/sale/updatePrice')(Self);

View File

@ -1,11 +1,19 @@
<vn-crud-model <vn-crud-model
vn-id="model" vn-id="model"
url="sales" url="SaleTrackings/{{$ctrl.$params.id}}/filter"
filter="::$ctrl.filter"
link="{ticketFk: $ctrl.$params.id}"
limit="20" limit="20"
data="$ctrl.sales" data="$ctrl.sales"
order="concept ASC" order="concept ASC, quantity DESC"
auto-load="true">
</vn-crud-model>
<vn-crud-model
url="Shelvings"
data="shelvings"
auto-load="true">
</vn-crud-model>
<vn-crud-model
url="Parkings"
data="parkings"
auto-load="true"> auto-load="true">
</vn-crud-model> </vn-crud-model>
<vn-data-viewer model="model"> <vn-data-viewer model="model">
@ -13,7 +21,7 @@
<vn-table model="model"> <vn-table model="model">
<vn-thead> <vn-thead>
<vn-tr> <vn-tr>
<vn-th field="isChecked" center>Is checked</vn-th> <vn-th field="isChecked" center expand>Is checked</vn-th>
<vn-th field="itemFk" number>Item</vn-th> <vn-th field="itemFk" number>Item</vn-th>
<vn-th field="concept">Description</vn-th> <vn-th field="concept">Description</vn-th>
<vn-th field="quantity" number>Quantity</vn-th> <vn-th field="quantity" number>Quantity</vn-th>
@ -23,76 +31,84 @@
</vn-thead> </vn-thead>
<vn-tbody> <vn-tbody>
<vn-tr ng-repeat="sale in $ctrl.sales"> <vn-tr ng-repeat="sale in $ctrl.sales">
<vn-td center> <vn-td center expand>
<vn-chip <vn-chip
ng-class="::{ ng-class="{
'pink': sale.preparingList.hasSaleGroupDetail, 'pink': sale.hasSaleGroupDetail,
'none': !sale.preparingList.hasSaleGroupDetail, 'none': !sale.hasSaleGroupDetail,
}" }"
class="circleState" class="circleState"
vn-tooltip="has saleGroupDetail" vn-tooltip="sale group detail"
> vn-click-stop="$ctrl.clickSaleGroupDetail($index)">
</vn-chip> </vn-chip>
<vn-chip ng-class="::{ <vn-chip
'notice': sale.preparingList.isPreviousSelected, ng-class="{
'none': !sale.preparingList.isPreviousSelected, 'notice': sale.isPreviousSelected,
}" 'none': !sale.isPreviousSelected,
class="circleState" }"
vn-tooltip="is previousSelected"> class="circleState"
vn-tooltip="previous selected"
vn-click-stop="$ctrl.clickPreviousSelected($index)">
</vn-chip> </vn-chip>
<vn-chip ng-class="::{ <vn-chip
'dark-notice': sale.preparingList.isPrevious, ng-class="{
'none': !sale.preparingList.isPrevious, 'dark-notice': sale.isPrevious,
}" 'none': !sale.isPrevious,
class="circleState" }"
vn-tooltip="is previous"> class="circleState"
vn-tooltip="previous"
vn-click-stop="$ctrl.clickPrevious($index)">
</vn-chip> </vn-chip>
<vn-chip ng-class="::{ <vn-chip
'warning': sale.preparingList.isPrepared, ng-class="{
'none': !sale.preparingList.isPrepared, 'warning': sale.isPrepared,
}" 'none': !sale.isPrepared,
class="circleState" }"
vn-tooltip="is prepared"> class="circleState"
vn-tooltip="prepared"
vn-click-stop="$ctrl.clickPrepared($index)">
</vn-chip> </vn-chip>
<vn-chip ng-class="::{ <vn-chip
'yellow': sale.preparingList.isControled, ng-class="{
'none': !sale.preparingList.isControled, 'yellow': sale.isControled,
}" 'none': !sale.isControled,
class="circleState" }"
vn-tooltip="is controled"> class="circleState"
vn-tooltip="checked"
vn-click-stop="$ctrl.clickControled($index)">
</vn-chip> </vn-chip>
</vn-td> </vn-td>
<vn-td number> <vn-td number>
<span <span
ng-click="itemDescriptor.show($event, sale.item.id)" ng-click="itemDescriptor.show($event, sale.itemFk)"
class="link"> class="link">
{{::sale.item.id}} {{::sale.itemFk}}
</span> </span>
</vn-td> </vn-td>
<vn-td vn-fetched-tags> <vn-td vn-fetched-tags>
<div> <div>
<vn-one title="{{::sale.item.name}}">{{::sale.item.name}}</vn-one> <vn-one title="{{::sale.concept}}">{{::sale.concept}}</vn-one>
<vn-one ng-if="::sale.item.subName"> <vn-one ng-if="::sale.subName">
<h3 title="{{::sale.item.subName}}">{{::sale.item.subName}}</h3> <h3 title="{{::sale.subName}}">{{::sale.subName}}</h3>
</vn-one> </vn-one>
</div> </div>
<vn-fetched-tags <vn-fetched-tags
max-length="6" max-length="6"
item="::sale.item" item="::sale"
tabindex="-1"> tabindex="-1">
</vn-fetched-tags> </vn-fetched-tags>
</vn-td> </vn-td>
<vn-td number>{{::sale.quantity}}</vn-td> <vn-td number>{{::sale.quantity}}</vn-td>
<vn-td center>{{::sale.saleGroupDetail.saleGroup.parking.code | dashIfEmpty}}</vn-td> <vn-td center>{{::sale.parkingCode | dashIfEmpty}}</vn-td>
<vn-td actions> <vn-td actions>
<vn-icon-button <vn-icon-button
vn-click-stop="$ctrl.showSaleTracking(sale)" vn-click-stop="$ctrl.showSaleTracking(sale)"
vn-tooltip="Sale tracking" vn-tooltip="Log states"
icon="history"> icon="history">
</vn-icon-button> </vn-icon-button>
<vn-icon-button <vn-icon-button
vn-click-stop="$ctrl.showItemShelvingSale(sale)" vn-click-stop="$ctrl.showItemShelvingSale(sale)"
vn-tooltip="ItemShelvings sale" vn-tooltip="Shelvings sale"
icon="icon-inventory"> icon="icon-inventory">
</vn-icon-button> </vn-icon-button>
</vn-td> </vn-td>
@ -154,28 +170,35 @@
<vn-popup vn-id="itemShelvingSale"> <vn-popup vn-id="itemShelvingSale">
<vn-crud-model <vn-crud-model
vn-id="modelSaleTracking" vn-id="modelItemShelvingSale"
url="ItemShelvingSales/filter" url="ItemShelvingSales/filter"
link="{saleFk: $ctrl.saleId}" link="{saleFk: $ctrl.saleId}"
limit="20" limit="20"
data="$ctrl.itemShelvingSales" data="$ctrl.itemShelvingSales"
auto-load="true"> auto-load="true">
</vn-crud-model> </vn-crud-model>
<vn-data-viewer model="modelSaleTracking"> <vn-data-viewer model="modelItemShelvingSale" class="vn-w-lg">
<vn-card class="vn-w-lg"> <vn-table>
<vn-table model="modelSaleTracking">
<vn-thead> <vn-thead>
<vn-tr> <vn-tr>
<vn-th field="quantity" number>Quantity</vn-th> <vn-th field="quantity" number>Quantity</vn-th>
<vn-th field="workerFk">Worker</vn-th> <vn-th field="workerFk">Worker</vn-th>
<vn-th field="shelving" shrink>Shelving</vn-th> <vn-th field="shelving" expand>Shelving</vn-th>
<vn-th field="parking" shrink>Parking</vn-th> <vn-th field="parking" expand>Parking</vn-th>
<vn-th field="created" expand>Created</vn-th> <vn-th field="created" expand>Created</vn-th>
</vn-tr> </vn-tr>
</vn-thead> </vn-thead>
<vn-tbody> <vn-tbody>
<vn-tr ng-repeat="itemShelvingSale in $ctrl.itemShelvingSales"> <vn-tr ng-repeat="itemShelvingSale in $ctrl.itemShelvingSales">
<vn-td number>{{::itemShelvingSale.quantity}}</vn-td> <vn-td-editable number shrink>
<text>{{itemShelvingSale.quantity}}</text>
<field>
<vn-input-number class="dense" vn-focus
ng-model="itemShelvingSale.quantity"
on-change="$ctrl.updateQuantity(itemShelvingSale)">
</vn-input-number>
</field>
</vn-td-editable>
<vn-td expand> <vn-td expand>
<span <span
class="link" class="link"
@ -183,8 +206,24 @@
{{::itemShelvingSale.name | dashIfEmpty}} {{::itemShelvingSale.name | dashIfEmpty}}
</span> </span>
</vn-td> </vn-td>
<vn-td shrink>{{::itemShelvingSale.shelvingFk}}</vn-td> <vn-td expand>
<vn-td shrink>{{::itemShelvingSale.code}}</vn-td> <vn-autocomplete
data="shelvings"
show-field="code"
value-field="code"
ng-model="itemShelvingSale.shelvingFk"
on-change="$ctrl.updateShelving(itemShelvingSale)">
</vn-autocomplete>
</vn-td>
<vn-td expand>
<vn-autocomplete
data="parkings"
show-field="code"
value-field="id"
ng-model="itemShelvingSale.parkingFk"
on-change="$ctrl.updateParking(itemShelvingSale)">
</vn-autocomplete>
</vn-td>
<vn-td expand>{{::itemShelvingSale.created | date: 'dd/MM/yyyy HH:mm'}}</vn-td> <vn-td expand>{{::itemShelvingSale.created | date: 'dd/MM/yyyy HH:mm'}}</vn-td>
</vn-tr> </vn-tr>
</vn-tbody> </vn-tbody>

View File

@ -3,62 +3,6 @@ import Section from 'salix/components/section';
import './style.scss'; import './style.scss';
class Controller extends Section { class Controller extends Section {
constructor($element, $) {
super($element, $);
this.filter = {
include: [
{
relation: 'item'
},
{
relation: 'saleTracking',
scope: {
fields: ['isChecked']
}
},
{
relation: 'saleGroupDetail',
scope: {
fields: ['saleGroupFk'],
include: {
relation: 'saleGroup',
scope: {
fields: ['parkingFk'],
include: {
relation: 'parking',
scope: {
fields: ['code']
}
}
}
}
}
}
]
};
}
get sales() {
return this._sales;
}
set sales(value) {
this._sales = value;
if (value) {
const query = `Sales/${this.$params.id}/salePreparingList`;
this.$http.get(query)
.then(res => {
this.salePreparingList = res.data;
for (const salePreparing of this.salePreparingList) {
for (const sale of this.sales) {
if (salePreparing.saleFk == sale.id)
sale.preparingList = salePreparing;
}
}
});
}
}
showItemDescriptor(event, sale) { showItemDescriptor(event, sale) {
this.quicklinks = { this.quicklinks = {
btnThree: { btnThree: {
@ -75,20 +19,145 @@ class Controller extends Section {
} }
showSaleTracking(sale) { showSaleTracking(sale) {
this.saleId = sale.id; this.saleId = sale.saleFk;
this.$.saleTracking.show(); this.$.saleTracking.show();
} }
showItemShelvingSale(sale) { showItemShelvingSale(sale) {
this.saleId = sale.id; this.saleId = sale.saleFk;
this.$.itemShelvingSale.show(); this.$.itemShelvingSale.show();
} }
clickSaleGroupDetail(index) {
const sale = this.sales[index];
if (!sale.saleGroupDetailFk) return;
return this.$http.delete(`SaleGroupDetails/${sale.saleGroupDetailFk}`)
.then(() => {
sale.hasSaleGroupDetail = false;
this.vnApp.showSuccess(this.$t('Data saved!'));
});
}
clickPreviousSelected(index) {
const sale = this.sales[index];
if (!sale.isPreviousSelected) {
this.saleTrackingNew(sale, 'PREVIOUS_PREPARATION', false);
sale.isPreviousSelected = true;
} else {
this.saleTrackingDel(sale, 'PREVIOUS_PREPARATION');
sale.isPreviousSelected = false;
sale.isPrevious = false;
}
}
clickPrevious(index) {
const sale = this.sales[index];
if (!sale.isPrevious) {
this.saleTrackingNew(sale, 'PREVIOUS_PREPARATION', true);
sale.isPrevious = true;
sale.isPreviousSelected = true;
} else {
this.saleTrackingNew(sale, 'PREVIOUS_PREPARATION', false);
sale.isPrevious = false;
}
}
clickPrepared(index) {
const sale = this.sales[index];
if (!sale.isPrepared) {
this.saleTrackingNew(sale, 'PREPARED', true);
sale.isPrepared = true;
} else {
this.saleTrackingDel(sale, 'PREPARED');
sale.isPrepared = false;
}
}
clickControled(index) {
const sale = this.sales[index];
if (!sale.isControled) {
this.saleTrackingNew(sale, 'CHECKED', true);
sale.isControled = true;
} else {
this.saleTrackingDel(sale, 'CHECKED');
sale.isControled = false;
}
}
saleTrackingNew(sale, stateCode, isChecked) {
const params = {
saleFk: sale.saleFk,
isChecked: isChecked,
quantity: sale.quantity,
stateCode: stateCode
};
this.$http.post(`SaleTrackings/new`, params).then(() => {
this.vnApp.showSuccess(this.$t('Data saved!'));
});
}
saleTrackingDel(sale, stateCode) {
const params = {
saleFk: sale.saleFk,
stateCode: stateCode
};
this.$http.post(`SaleTrackings/delete`, params).then(() => {
this.vnApp.showSuccess(this.$t('Data saved!'));
});
}
updateQuantity(itemShelvingSale) {
const params = {
quantity: itemShelvingSale.quantity
};
this.$http.patch(`ItemShelvingSales/${itemShelvingSale.id}`, params)
.then(() => {
this.vnApp.showSuccess(this.$t('Data saved!'));
});
}
async updateShelving(itemShelvingSale) {
const params = {
shelvingFk: itemShelvingSale.shelvingFk
};
const res = await this.$http.patch(`ItemShelvings/${itemShelvingSale.itemShelvingFk}`, params);
const filter = {
fields: ['parkingFk'],
where: {
code: res.data.shelvingFk
}
};
this.$http.get(`Shelvings/findOne`, {filter})
.then(res => {
itemShelvingSale.parkingFk = res.data.parkingFk;
this.vnApp.showSuccess(this.$t('Data saved!'));
});
}
async updateParking(itemShelvingSale) {
const filter = {
fields: ['id'],
where: {
code: itemShelvingSale.shelvingFk
}
};
const res = await this.$http.get(`Shelvings/findOne`, {filter});
const params = {
parkingFk: itemShelvingSale.parkingFk
};
this.$http.patch(`Shelvings/${res.data.id}`, params)
.then(() => this.vnApp.showSuccess(this.$t('Data saved!')));
}
} }
ngModule.vnComponent('vnTicketSaleTracking', { ngModule.vnComponent('vnTicketSaleTracking', {
template: require('./index.html'), template: require('./index.html'),
controller: Controller, controller: Controller,
bindings: { bindings: {
ticket: '<' ticket: '<',
model: '<?'
} }
}); });

View File

@ -1,6 +1,7 @@
ItemShelvings sale: Carros línea Shelvings sale: Carros línea
has saleGroupDetail: tiene detalle grupo lineas Log states: Historial estados
is previousSelected: es previa seleccionada sale group detail: detalle grupo lineas
is previous: es previa previous selected: previa seleccionado
is prepared: esta preparado previous: previa
is controled: esta controlado prepared: preparado
checked: revisado

View File

@ -1,14 +1,5 @@
@import "variables"; @import "variables";
vn-sale-tracking {
.chip {
display: inline-block;
min-width: 15px;
min-height: 25px;
}
}
.circleState { .circleState {
display: inline-block; display: inline-block;
justify-content: center; justify-content: center;