salix/modules/ticket/front/sale/index.js

573 lines
15 KiB
JavaScript
Raw Normal View History

2018-03-22 17:02:48 +00:00
import ngModule from '../module';
2020-03-18 07:35:59 +00:00
import Section from 'salix/components/section';
import './style.scss';
2018-03-22 17:02:48 +00:00
2020-03-18 07:35:59 +00:00
class Controller extends Section {
constructor($element, $) {
super($element, $);
this._sales = [];
2022-04-11 07:04:05 +00:00
this.manaCode = 'mana';
this.getConfig();
2022-03-29 11:42:37 +00:00
}
sortBy(propertyName) {
this.reverse = (this.propertyName === propertyName) ? !this.reverse : false;
this.propertyName = propertyName;
2022-03-29 11:42:37 +00:00
}
2022-04-11 07:04:05 +00:00
get manaCode() {
return this._manaCode;
2022-03-29 11:42:37 +00:00
}
2022-04-11 07:04:05 +00:00
set manaCode(value) {
this._manaCode = value;
}
2019-07-22 11:14:00 +00:00
get ticket() {
return this._ticket;
}
set ticket(value) {
this._ticket = value;
2019-08-13 12:03:02 +00:00
this.isTicketEditable();
2020-02-27 11:31:38 +00:00
this.isTicketLocked();
2019-07-22 11:14:00 +00:00
}
get sales() {
if (this._sales) {
for (let sale of this._sales)
sale.amount = this.getSaleTotal(sale);
}
return this._sales;
}
2018-10-22 06:23:10 +00:00
set sales(value) {
this._sales = value;
}
2020-06-23 11:40:49 +00:00
get ticketState() {
2021-04-07 11:39:36 +00:00
const ticket = this.ticket;
if (!ticket) return null;
2020-06-23 11:40:49 +00:00
2021-04-07 11:39:36 +00:00
const ticketState = ticket.ticketState;
return ticketState && ticketState.state.code;
}
getConfig() {
let filter = {
fields: ['daysForWarningClaim'],
};
this.$http.get(`TicketConfigs`, {filter})
.then(res => {
this.ticketConfig = res.data;
});
}
get isClaimable() {
if (this.ticket) {
const landedPlusWeek = new Date(this.ticket.landed);
landedPlusWeek.setDate(landedPlusWeek.getDate() + 7);
const hasClaimManagerRole = this.aclService.hasAny(['claimManager']);
2023-01-16 14:18:24 +00:00
return landedPlusWeek >= Date.vnNew() || hasClaimManagerRole;
}
return false;
}
2018-10-22 06:23:10 +00:00
getSaleTotal(sale) {
2020-06-23 14:39:20 +00:00
if (sale.quantity == null || sale.price == null)
return null;
2020-06-23 14:39:20 +00:00
const price = sale.quantity * sale.price;
const discount = (sale.discount * price) / 100;
return price - discount;
2018-10-22 06:23:10 +00:00
}
2018-06-19 10:10:38 +00:00
2020-06-30 08:01:30 +00:00
getMana() {
this.$http.get(`Tickets/${this.$params.id}/getSalesPersonMana`)
.then(res => {
this.edit.mana = res.data;
this.$.$applyAsync(() => {
this.$.editDiscount.relocate();
this.$.editPricePopover.relocate();
});
});
2022-10-21 06:55:05 +00:00
this.getUsesMana();
2020-06-30 08:01:30 +00:00
}
2022-10-21 06:55:05 +00:00
getUsesMana() {
this.$http.get(`Sales/usesMana`)
.then(res => {
2022-11-14 10:00:13 +00:00
this.usesMana = res.data;
2022-10-21 06:55:05 +00:00
});
}
/**
* Returns checked instances
*
* @return {Array} Checked instances
*/
2020-06-29 09:43:53 +00:00
selectedSales() {
if (!this.sales) return;
return this.sales.filter(sale => {
return sale.checked;
});
}
2020-06-29 09:43:53 +00:00
selectedValidSales() {
if (!this.sales) return;
const selectedSales = this.selectedSales();
return selectedSales.filter(sale => {
return sale.id != undefined;
});
}
2020-06-23 11:40:49 +00:00
/**
* Returns the total of checked instances
*
* @return {Number} Total checked instances
*/
2020-06-29 09:43:53 +00:00
selectedSalesCount() {
const selectedSales = this.selectedSales();
if (selectedSales)
return selectedSales.length;
2020-06-23 11:40:49 +00:00
return 0;
}
2020-06-29 09:43:53 +00:00
hasSelectedSales() {
return this.selectedSalesCount() > 0;
2020-06-23 11:40:49 +00:00
}
hasOneSaleSelected() {
2020-06-29 09:43:53 +00:00
if (this.selectedSalesCount() === 1)
2020-06-23 11:40:49 +00:00
return true;
return false;
}
/**
* Returns new instances
*
* @return {Array} New instances
*/
newInstances() {
if (!this.sales) return;
return this.sales.filter(sale => {
return !sale.id;
});
}
2019-08-09 06:04:44 +00:00
resetChanges() {
if (this.newInstances().length === 0)
this.$.watcher.updateOriginalData();
this.card.reload();
}
2023-09-13 17:48:58 +00:00
state(value) {
const params = {ticketFk: this.$params.id, code: value};
return this.$http.post('Tickets/state', params).then(() => {
2020-06-23 11:40:49 +00:00
this.vnApp.showSuccess(this.$t('Data saved!'));
this.card.reload();
}).finally(() => this.resetChanges());
}
2018-07-17 06:44:31 +00:00
2020-06-29 09:43:53 +00:00
removeSales() {
const sales = this.selectedValidSales();
const params = {sales: sales, ticketId: this.ticket.id};
this.$http.post(`Sales/deleteSales`, params).then(() => {
2020-06-29 09:43:53 +00:00
this.removeSelectedSales();
this.vnApp.showSuccess(this.$t('Data saved!'));
}).finally(() => this.resetChanges());
2020-06-29 09:43:53 +00:00
}
2020-06-29 09:43:53 +00:00
removeSelectedSales() {
const sales = this.selectedSales();
sales.forEach(sale => {
const index = this.sales.indexOf(sale);
this.sales.splice(index, 1);
});
}
2018-07-17 06:44:31 +00:00
2020-06-30 08:01:30 +00:00
createClaim() {
2023-05-17 12:04:13 +00:00
const today = new Date();
today.setHours(0, 0, 0, 0);
const timeDifference = today.getTime() - new Date(this.ticket.landed).getTime();
const pastDays = Math.floor(timeDifference / 86400000);
if (pastDays >= this.ticketConfig[0].daysForWarningClaim)
this.$.claimConfirm.show();
else
2023-05-26 12:52:47 +00:00
this.$.claimSure.show();
}
onCreateClaimAccepted() {
2020-06-30 08:01:30 +00:00
const sales = this.selectedValidSales();
const params = {ticketId: this.ticket.id, sales: sales};
2020-06-30 08:01:30 +00:00
this.resetChanges();
this.$http.post(`Claims/createFromSales`, params)
.then(res => this.$state.go('claim.card.basicData', {id: res.data.id}));
}
2023-04-13 12:04:10 +00:00
2020-05-25 12:45:26 +00:00
showTransferPopover(event) {
this.setTransferParams();
2020-07-01 09:57:01 +00:00
this.$.transfer.show(event);
2020-05-25 12:45:26 +00:00
}
2019-08-09 06:04:44 +00:00
setTransferParams() {
2020-06-29 09:43:53 +00:00
const checkedSales = JSON.stringify(this.selectedValidSales());
2019-08-09 06:04:44 +00:00
const sales = JSON.parse(checkedSales);
this.transfer = {
lastActiveTickets: [],
sales: sales
};
2019-08-09 06:04:44 +00:00
const params = {ticketId: this.ticket.id};
const query = `clients/${this.ticket.clientFk}/lastActiveTickets`;
2019-08-09 06:04:44 +00:00
this.$http.get(query, {params}).then(res => {
this.transfer.lastActiveTickets = res.data;
});
}
2018-07-17 06:44:31 +00:00
2019-08-09 06:04:44 +00:00
transferSales(ticketId) {
const params = {
ticketId: ticketId,
sales: this.transfer.sales
};
2020-03-18 07:35:59 +00:00
this.$.watcher.updateOriginalData();
2019-09-24 09:55:36 +00:00
const query = `tickets/${this.ticket.id}/transferSales`;
2020-06-23 11:40:49 +00:00
this.$http.post(query, params)
2023-05-23 06:43:31 +00:00
.then(res => {
if (res.data && res.data.id === this.ticket.id) {
this.$.transfer.hide();
this.$.model.refresh();
} else this.$state.go('ticket.card.sale', {id: res.data.id});
});
}
2018-07-17 06:44:31 +00:00
showEditPricePopover(event, sale) {
if (!this.isEditable) return;
2020-06-23 11:40:49 +00:00
this.edit = {
2020-06-23 11:40:49 +00:00
price: sale.price,
sale: sale
};
2020-06-23 11:40:49 +00:00
this.$.editPricePopover.show(event);
}
2018-07-17 06:44:31 +00:00
updatePrice() {
2020-06-23 11:40:49 +00:00
const sale = this.edit.sale;
2020-06-23 14:39:20 +00:00
const newPrice = this.edit.price;
if (newPrice != null && newPrice != sale.price) {
2020-06-23 11:40:49 +00:00
const query = `Sales/${sale.id}/updatePrice`;
2020-06-23 14:39:20 +00:00
this.$http.post(query, {newPrice}).then(res => {
2020-06-23 11:40:49 +00:00
sale.price = res.data.price;
2020-06-29 07:38:42 +00:00
this.edit = null;
2020-06-23 11:40:49 +00:00
this.vnApp.showSuccess(this.$t('Data saved!'));
}).finally(() => this.resetChanges());
}
2018-11-06 12:59:16 +00:00
2020-03-18 07:35:59 +00:00
this.$.editPricePopover.hide();
}
2018-07-17 06:44:31 +00:00
showEditDiscountPopover(event, sale) {
2020-02-27 11:31:38 +00:00
if (this.isLocked) return;
if (sale) {
this.edit = {
discount: sale.discount,
sale: sale
};
} else {
this.edit = {
discount: null,
sales: this.selectedValidSales()
};
}
2020-06-23 11:40:49 +00:00
this.$.editDiscount.show(event);
}
changeDiscount() {
const sale = this.edit.sale;
2020-06-23 14:39:20 +00:00
const newDiscount = this.edit.discount;
if (newDiscount != null && newDiscount != sale.discount)
2020-06-23 11:40:49 +00:00
this.updateDiscount([sale]);
this.$.editDiscount.hide();
}
changeMultipleDiscount() {
const sales = this.edit.sales;
2020-06-23 14:39:20 +00:00
const newDiscount = this.edit.discount;
2020-06-23 11:40:49 +00:00
const hasChanges = sales.some(sale => {
2020-06-23 14:39:20 +00:00
return sale.discount != newDiscount;
2020-06-23 11:40:49 +00:00
});
2020-06-23 14:39:20 +00:00
if (newDiscount != null && hasChanges)
2020-06-23 11:40:49 +00:00
this.updateDiscount(sales);
this.$.editDiscount.hide();
2020-06-23 11:40:49 +00:00
}
updateDiscount(sales) {
const saleIds = sales.map(sale => {
return sale.id;
});
2022-04-11 07:04:05 +00:00
const params = {salesIds: saleIds, newDiscount: this.edit.discount, manaCode: this.manaCode};
2020-06-23 11:40:49 +00:00
const query = `Tickets/${this.$params.id}/updateDiscount`;
this.$http.post(query, params).then(() => {
this.vnApp.showSuccess(this.$t('Data saved!'));
2020-06-23 11:40:49 +00:00
for (let sale of sales)
sale.discount = this.edit.discount;
2020-06-29 07:38:42 +00:00
this.edit = null;
}).finally(() => this.resetChanges());
2020-06-23 11:40:49 +00:00
}
getNewPrice() {
if (this.edit.sale) {
2020-06-23 11:40:49 +00:00
const sale = this.edit.sale;
let newDiscount = sale.discount;
let newPrice = this.edit.price || sale.price;
if (this.edit.discount != null)
newDiscount = this.edit.discount;
if (this.edit.price != null)
newPrice = this.edit.price;
const price = sale.quantity * newPrice;
const discount = (newDiscount * price) / 100;
return price - discount;
}
return 0;
}
2018-07-17 06:44:31 +00:00
2020-06-23 11:40:49 +00:00
hasReserves() {
return this.sales.some(sale => {
return sale.reserved == true;
});
}
2018-07-17 06:44:31 +00:00
/*
2018-10-23 12:33:07 +00:00
* Unmark sale as reserved
*/
2018-06-19 07:09:49 +00:00
unmarkAsReserved() {
this.setReserved(false);
}
/*
2018-10-23 12:33:07 +00:00
* Mark sale as reserved
*/
markAsReserved() {
this.setReserved(true);
}
2018-06-19 07:09:49 +00:00
setReserved(reserved) {
const selectedSales = this.selectedValidSales();
const params = {ticketId: this.ticket.id, sales: selectedSales, reserved: reserved};
this.$http.post(`Sales/reserve`, params).then(() => {
selectedSales.forEach(sale => {
sale.reserved = reserved;
});
}).finally(() => this.resetChanges());
2018-06-19 07:09:49 +00:00
}
newOrderFromTicket() {
this.$http.post(`Orders/newFromTicket`, {ticketFk: this.ticket.id}).then(res => {
const path = this.$state.href('order.card.catalog', {id: res.data});
2019-09-19 13:51:39 +00:00
window.open(path, '_blank');
2020-06-23 11:40:49 +00:00
this.vnApp.showSuccess(this.$t('Order created'));
});
}
showSMSDialog() {
const address = this.ticket.address;
2020-02-21 07:37:37 +00:00
const client = this.ticket.client;
const phone = address.mobile || address.phone ||
client.mobile || client.phone;
2020-06-29 09:43:53 +00:00
const sales = this.selectedValidSales();
const items = sales.map(sale => {
return `${sale.quantity} ${sale.concept}`;
});
const notAvailables = items.join(', ');
const params = {
ticketFk: this.ticket.id,
2020-10-08 11:42:20 +00:00
created: this.ticket.updated,
2022-11-03 13:16:11 +00:00
landed: this.ticket.landed,
notAvailables
};
this.newSMS = {
2021-02-03 11:43:30 +00:00
ticketId: this.ticket.id,
2019-04-16 05:59:12 +00:00
destinationFk: this.ticket.clientFk,
2020-02-21 07:37:37 +00:00
destination: phone,
2020-06-23 11:40:49 +00:00
message: this.$t('Product not available', params)
};
2020-03-18 07:35:59 +00:00
this.$.sms.open();
}
2019-05-06 05:40:59 +00:00
2023-01-12 11:56:51 +00:00
onSmsSend(sms) {
return this.$http.post(`Tickets/${this.ticket.id}/sendSms`, sms)
.then(() => this.vnApp.showSuccess(this.$t('SMS sent')));
}
/**
* Inserts a new instance
*/
add() {
2020-03-18 07:35:59 +00:00
this.$.model.insert({});
}
/*
* Creates a new sale if it's a new instance
* Updates the sale quantity for existing instance
*/
2020-06-23 11:40:49 +00:00
changeQuantity(sale) {
2020-10-13 06:42:13 +00:00
if (!sale.itemFk || sale.quantity == null) return;
2020-03-13 07:20:30 +00:00
if (!sale.id)
2020-03-13 07:20:30 +00:00
return this.addSale(sale);
this.updateQuantity(sale);
}
/*
2020-06-23 11:40:49 +00:00
* Changes a sale quantity
*/
updateQuantity(sale) {
2020-06-23 11:40:49 +00:00
const data = {quantity: sale.quantity};
this.$http.post(`Sales/${sale.id}/updateQuantity`, data).then(() => {
2020-06-23 11:40:49 +00:00
this.vnApp.showSuccess(this.$t('Data saved!'));
}).catch(e => {
2020-03-18 07:35:59 +00:00
this.$.model.refresh();
throw e;
}).finally(() => this.resetChanges());
}
/*
2020-06-23 11:40:49 +00:00
* Changes a sale concept
*/
2020-07-01 10:53:56 +00:00
updateConcept(sale) {
2019-09-06 09:43:15 +00:00
const data = {newConcept: sale.concept};
this.$http.post(`Sales/${sale.id}/updateConcept`, data).then(() => {
2020-06-23 11:40:49 +00:00
this.vnApp.showSuccess(this.$t('Data saved!'));
}).catch(e => {
2020-03-18 07:35:59 +00:00
this.$.model.refresh();
throw e;
}).finally(() => this.resetChanges());
}
/*
* Adds a new sale
*/
addSale(sale) {
const data = {
2024-05-17 12:20:33 +00:00
barcode: sale.itemFk,
quantity: sale.quantity
};
const query = `tickets/${this.ticket.id}/addSale`;
this.$http.post(query, data).then(res => {
if (!res.data) return;
const newSale = res.data;
sale.id = newSale.id;
sale.image = newSale.item.image;
sale.subName = newSale.item.subName;
sale.concept = newSale.concept;
sale.quantity = newSale.quantity;
sale.discount = newSale.discount;
sale.price = newSale.price;
sale.item = newSale.item;
2020-06-23 11:40:49 +00:00
this.vnApp.showSuccess(this.$t('Data saved!'));
}).finally(() => this.resetChanges());
}
isTicketEditable() {
2020-07-01 10:53:56 +00:00
this.$http.get(`Tickets/${this.$params.id}/isEditable`)
2020-06-29 09:43:53 +00:00
.then(res => this.isEditable = res.data);
}
2020-02-27 11:31:38 +00:00
isTicketLocked() {
2020-07-01 10:53:56 +00:00
this.$http.get(`Tickets/${this.$params.id}/isLocked`)
2020-06-29 09:43:53 +00:00
.then(res => this.isLocked = res.data);
2020-02-27 11:31:38 +00:00
}
calculateSalePrice() {
const sales = this.selectedValidSales();
2021-11-30 12:47:16 +00:00
if (!sales) return;
const query = `Sales/recalculatePrice`;
2021-12-01 10:39:48 +00:00
this.$http.post(query, sales).then(() => {
2021-11-30 12:47:16 +00:00
this.vnApp.showSuccess(this.$t('Data saved!'));
this.$.model.refresh();
});
}
2020-03-11 14:56:02 +00:00
createRefund(withWarehouse) {
const sales = this.selectedValidSales();
if (!sales) return;
const salesIds = sales.map(sale => sale.id);
2024-01-31 08:59:32 +00:00
const params = {salesIds: salesIds, withWarehouse: withWarehouse, negative: true};
2024-01-26 14:32:50 +00:00
const query = 'Sales/clone';
this.$http.post(query, params).then(res => {
const [refundTicket] = res.data;
this.vnApp.showSuccess(this.$t('The following refund ticket have been created', {
ticketId: refundTicket.id
}));
this.$state.go('ticket.card.sale', {id: refundTicket.id});
this.resetChanges();
});
}
2020-03-11 14:56:02 +00:00
itemSearchFunc($search) {
return /^\d+$/.test($search)
? {id: $search}
: {name: {like: '%' + $search + '%'}};
}
2022-03-29 11:42:37 +00:00
save() {
if (this.edit.sale) this.changeDiscount();
if (this.edit.sales) this.changeMultipleDiscount();
2022-03-29 11:42:37 +00:00
}
cancel() {
this.$.editDiscount.hide();
}
goToLog(saleId) {
this.$state.go('ticket.card.log', {
originId: this.$params.id,
changedModel: 'Sale',
changedModelId: saleId
});
}
2018-03-26 12:55:10 +00:00
}
ngModule.vnComponent('vnTicketSale', {
template: require('./index.html'),
controller: Controller,
bindings: {
ticket: '<'
},
require: {
2018-10-22 06:23:10 +00:00
card: '?^vnTicketCard'
}
2018-03-22 17:02:48 +00:00
});