Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 7119-createVehicle
gitea/salix/pipeline/pr-dev There was a failure building this commit
Details
gitea/salix/pipeline/pr-dev There was a failure building this commit
Details
This commit is contained in:
commit
a463a8f4d8
|
@ -3,7 +3,7 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `cache`.`available_refres
|
||||||
OUT `vCalc` INT,
|
OUT `vCalc` INT,
|
||||||
`vRefresh` INT,
|
`vRefresh` INT,
|
||||||
`vWarehouse` INT,
|
`vWarehouse` INT,
|
||||||
`vDated` DATE
|
`vAvailabled` DATETIME
|
||||||
)
|
)
|
||||||
proc: BEGIN
|
proc: BEGIN
|
||||||
DECLARE vStartDate DATE;
|
DECLARE vStartDate DATE;
|
||||||
|
@ -12,6 +12,7 @@ proc: BEGIN
|
||||||
DECLARE vInventoryDate DATE;
|
DECLARE vInventoryDate DATE;
|
||||||
DECLARE vLifeScope DATE;
|
DECLARE vLifeScope DATE;
|
||||||
DECLARE vWarehouseFkInventory INT;
|
DECLARE vWarehouseFkInventory INT;
|
||||||
|
DECLARE vDated DATE;
|
||||||
|
|
||||||
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
||||||
BEGIN
|
BEGIN
|
||||||
|
@ -19,13 +20,17 @@ proc: BEGIN
|
||||||
RESIGNAL;
|
RESIGNAL;
|
||||||
END;
|
END;
|
||||||
|
|
||||||
IF vDated < util.VN_CURDATE() THEN
|
IF vAvailabled < util.VN_CURDATE() THEN
|
||||||
LEAVE proc;
|
LEAVE proc;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
|
SET vDated = DATE(vAvailabled);
|
||||||
|
|
||||||
|
SET vAvailabled = vDated + INTERVAL HOUR(vAvailabled) HOUR;
|
||||||
|
|
||||||
CALL vn.item_getStock(vWarehouse, vDated, NULL);
|
CALL vn.item_getStock(vWarehouse, vDated, NULL);
|
||||||
|
|
||||||
SET vParams = CONCAT_WS('/', vWarehouse, vDated);
|
SET vParams = CONCAT_WS('/', vWarehouse, vAvailabled);
|
||||||
CALL cache_calc_start (vCalc, vRefresh, 'available', vParams);
|
CALL cache_calc_start (vCalc, vRefresh, 'available', vParams);
|
||||||
|
|
||||||
IF !vRefresh THEN
|
IF !vRefresh THEN
|
||||||
|
@ -87,11 +92,10 @@ proc: BEGIN
|
||||||
SELECT i.itemFk, i.landed, i.quantity
|
SELECT i.itemFk, i.landed, i.quantity
|
||||||
FROM vn.itemEntryIn i
|
FROM vn.itemEntryIn i
|
||||||
JOIN itemRange ir ON ir.itemFk = i.itemFk
|
JOIN itemRange ir ON ir.itemFk = i.itemFk
|
||||||
LEFT JOIN edi.warehouseFloramondo wf ON wf.entryFk = i.entryFk
|
|
||||||
WHERE i.landed >= vStartDate
|
WHERE i.landed >= vStartDate
|
||||||
|
AND IFNULL(i.availabled, i.landed) <= vAvailabled
|
||||||
AND (ir.ended IS NULL OR i.landed <= ir.ended)
|
AND (ir.ended IS NULL OR i.landed <= ir.ended)
|
||||||
AND i.warehouseInFk = vWarehouse
|
AND i.warehouseInFk = vWarehouse
|
||||||
AND ISNULL(wf.entryFk)
|
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT i.itemFk, i.shipped, i.quantity
|
SELECT i.itemFk, i.shipped, i.quantity
|
||||||
FROM vn.itemEntryOut i
|
FROM vn.itemEntryOut i
|
||||||
|
|
|
@ -15,8 +15,6 @@ BEGIN
|
||||||
*
|
*
|
||||||
* @return tmp.itemList(itemFk, stock, visible, available)
|
* @return tmp.itemList(itemFk, stock, visible, available)
|
||||||
*/
|
*/
|
||||||
DECLARE vIsLogifloraDay BOOL DEFAULT vn.isLogifloraDay(vDated, vWarehouseFk);
|
|
||||||
|
|
||||||
SET vDated = TIMESTAMP(vDated, '00:00:00');
|
SET vDated = TIMESTAMP(vDated, '00:00:00');
|
||||||
|
|
||||||
CREATE OR REPLACE TEMPORARY TABLE tmp.itemList
|
CREATE OR REPLACE TEMPORARY TABLE tmp.itemList
|
||||||
|
@ -36,14 +34,11 @@ BEGIN
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT iei.itemFk, iei.quantity
|
SELECT iei.itemFk, iei.quantity
|
||||||
FROM itemEntryIn iei
|
FROM itemEntryIn iei
|
||||||
LEFT JOIN edi.warehouseFloramondo wf ON wf.entryFk = iei.entryFk
|
|
||||||
JOIN item i ON i.id = iei.itemFk
|
JOIN item i ON i.id = iei.itemFk
|
||||||
WHERE iei.landed >= util.VN_CURDATE()
|
WHERE iei.landed >= util.VN_CURDATE()
|
||||||
AND iei.landed < vDated
|
AND iei.landed < vDated
|
||||||
AND iei.warehouseInFk = vWarehouseFk
|
AND iei.warehouseInFk = vWarehouseFk
|
||||||
AND (vItemFk IS NULL OR iei.itemFk = vItemFk)
|
AND (vItemFk IS NULL OR iei.itemFk = vItemFk)
|
||||||
AND (wf.entryFk IS NULL OR vIsLogifloraDay)
|
|
||||||
AND NOT (iei.landed > util.VN_CURDATE() AND i.isFloramondo)
|
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT ieo.itemFk, ieo.quantity
|
SELECT ieo.itemFk, ieo.quantity
|
||||||
FROM itemEntryOut ieo
|
FROM itemEntryOut ieo
|
||||||
|
@ -52,7 +47,6 @@ BEGIN
|
||||||
AND ieo.shipped < vDated
|
AND ieo.shipped < vDated
|
||||||
AND ieo.warehouseOutFk = vWarehouseFk
|
AND ieo.warehouseOutFk = vWarehouseFk
|
||||||
AND (vItemFk IS NULL OR ieo.itemFk = vItemFk)
|
AND (vItemFk IS NULL OR ieo.itemFk = vItemFk)
|
||||||
AND NOT (ieo.shipped > util.VN_CURDATE() AND i.isFloramondo)
|
|
||||||
) sub
|
) sub
|
||||||
GROUP BY itemFk
|
GROUP BY itemFk
|
||||||
HAVING stock;
|
HAVING stock;
|
||||||
|
|
|
@ -16,5 +16,9 @@ BEGIN
|
||||||
IF NEW.awbFk IS NOT NULL THEN
|
IF NEW.awbFk IS NOT NULL THEN
|
||||||
CALL travel_throwAwb(NEW.id);
|
CALL travel_throwAwb(NEW.id);
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
|
IF NEW.availabled < NEW.landed THEN
|
||||||
|
CALL util.throw('The travel availabled cannot be earlier than landed');
|
||||||
|
END IF;
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
||||||
|
|
|
@ -40,5 +40,9 @@ BEGIN
|
||||||
IF (NOT(NEW.awbFk <=> OLD.awbFk)) AND NEW.awbFk IS NOT NULL THEN
|
IF (NOT(NEW.awbFk <=> OLD.awbFk)) AND NEW.awbFk IS NOT NULL THEN
|
||||||
CALL travel_throwAwb(NEW.id);
|
CALL travel_throwAwb(NEW.id);
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
|
IF NEW.availabled < NEW.landed THEN
|
||||||
|
CALL util.throw('The travel availabled cannot be earlier than landed');
|
||||||
|
END IF;
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
||||||
|
|
|
@ -7,7 +7,8 @@ AS SELECT `t`.`warehouseInFk` AS `warehouseInFk`,
|
||||||
`b`.`quantity` AS `quantity`,
|
`b`.`quantity` AS `quantity`,
|
||||||
`t`.`isReceived` AS `isReceived`,
|
`t`.`isReceived` AS `isReceived`,
|
||||||
`t`.`isRaid` AS `isVirtualStock`,
|
`t`.`isRaid` AS `isVirtualStock`,
|
||||||
`e`.`id` AS `entryFk`
|
`e`.`id` AS `entryFk`,
|
||||||
|
`t`.`availabled`
|
||||||
FROM (
|
FROM (
|
||||||
(
|
(
|
||||||
`vn`.`buy` `b`
|
`vn`.`buy` `b`
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
-- Place your SQL code here
|
||||||
|
ALTER TABLE vn.travel ADD IF NOT EXISTS availabled DATETIME NULL
|
||||||
|
COMMENT 'Indicates the moment in time when the goods become available for picking';
|
|
@ -1,65 +0,0 @@
|
||||||
import selectors from '../../helpers/selectors.js';
|
|
||||||
import getBrowser from '../../helpers/puppeteer';
|
|
||||||
|
|
||||||
describe('Client defaulter path', () => {
|
|
||||||
let browser;
|
|
||||||
let page;
|
|
||||||
|
|
||||||
beforeAll(async() => {
|
|
||||||
browser = await getBrowser();
|
|
||||||
page = browser.page;
|
|
||||||
await page.loginAndModule('insurance', 'client');
|
|
||||||
await page.accessToSection('client.defaulter');
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async() => {
|
|
||||||
await browser.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should count the amount of clients in the turns section', async() => {
|
|
||||||
const result = await page.countElement(selectors.clientDefaulter.anyClient);
|
|
||||||
|
|
||||||
expect(result).toEqual(6);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should check contain expected client', async() => {
|
|
||||||
const clientName =
|
|
||||||
await page.waitToGetProperty(selectors.clientDefaulter.firstClientName, 'innerText');
|
|
||||||
const salesPersonName =
|
|
||||||
await page.waitToGetProperty(selectors.clientDefaulter.firstSalesPersonName, 'innerText');
|
|
||||||
|
|
||||||
expect(clientName).toEqual('Ororo Munroe');
|
|
||||||
expect(salesPersonName).toEqual('salesperson');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should first observation not changed', async() => {
|
|
||||||
const expectedObservation = 'Madness, as you know, is like gravity, all it takes is a little push';
|
|
||||||
const result = await page.waitToGetProperty(selectors.clientDefaulter.firstObservation, 'value');
|
|
||||||
|
|
||||||
expect(result).toContain(expectedObservation);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not add empty observation', async() => {
|
|
||||||
await page.waitToClick(selectors.clientDefaulter.allDefaulterCheckbox);
|
|
||||||
|
|
||||||
await page.waitToClick(selectors.clientDefaulter.addObservationButton);
|
|
||||||
await page.write(selectors.clientDefaulter.observation, '');
|
|
||||||
await page.waitToClick(selectors.clientDefaulter.saveButton);
|
|
||||||
const message = await page.waitForSnackbar();
|
|
||||||
|
|
||||||
expect(message.text).toContain(`The message can't be empty`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should checked all defaulters', async() => {
|
|
||||||
await page.loginAndModule('insurance', 'client');
|
|
||||||
await page.accessToSection('client.defaulter');
|
|
||||||
|
|
||||||
await page.waitToClick(selectors.clientDefaulter.allDefaulterCheckbox);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add observation for all clients', async() => {
|
|
||||||
await page.waitToClick(selectors.clientDefaulter.addObservationButton);
|
|
||||||
await page.write(selectors.clientDefaulter.observation, 'My new observation');
|
|
||||||
await page.waitToClick(selectors.clientDefaulter.saveButton);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,200 +1,2 @@
|
||||||
<vn-crud-model
|
|
||||||
vn-id="model"
|
|
||||||
url="Defaulters/filter"
|
|
||||||
filter="::$ctrl.filter"
|
|
||||||
limit="20"
|
|
||||||
order="amount DESC"
|
|
||||||
data="$ctrl.defaulters"
|
|
||||||
on-data-change="$ctrl.reCheck()"
|
|
||||||
auto-load="true">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-portal slot="topbar">
|
|
||||||
<vn-searchbar
|
|
||||||
vn-focus
|
|
||||||
placeholder="Search client"
|
|
||||||
info="Search client by id or name"
|
|
||||||
auto-state="false"
|
|
||||||
model="model">
|
|
||||||
</vn-searchbar>
|
|
||||||
</vn-portal>
|
|
||||||
<vn-card>
|
<vn-card>
|
||||||
<smart-table
|
|
||||||
model="model"
|
|
||||||
options="$ctrl.smartTableOptions"
|
|
||||||
expr-builder="$ctrl.exprBuilder(param, value)">
|
|
||||||
<slot-actions>
|
|
||||||
<div>
|
|
||||||
<div class="totalBox" style="text-align: center;">
|
|
||||||
<h6 translate>Total</h6>
|
|
||||||
<vn-label-value
|
|
||||||
label="Balance due"
|
|
||||||
value="{{$ctrl.balanceDueTotal | currency: 'EUR': 2}}">
|
|
||||||
</vn-label-value>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="vn-pa-md">
|
|
||||||
<vn-button
|
|
||||||
disabled="$ctrl.checked.length == 0"
|
|
||||||
ng-click="notesDialog.show()"
|
|
||||||
name="notesDialog"
|
|
||||||
vn-tooltip="Add observation"
|
|
||||||
icon="icon-notes">
|
|
||||||
</vn-button>
|
|
||||||
</div>
|
|
||||||
</slot-actions>
|
|
||||||
<slot-table>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th shrink>
|
|
||||||
<vn-multi-check
|
|
||||||
model="model">
|
|
||||||
</vn-multi-check>
|
|
||||||
</th>
|
|
||||||
<th field="clientFk">
|
|
||||||
<span translate>Client</span>
|
|
||||||
</th>
|
|
||||||
<th field="isWorker">
|
|
||||||
<span translate>Es trabajador</span>
|
|
||||||
</th>
|
|
||||||
<th field="salesPersonFk">
|
|
||||||
<span translate>Comercial</span>
|
|
||||||
</th>
|
|
||||||
<th field="countryFk">
|
|
||||||
<span translate>Country</span>
|
|
||||||
</th>
|
|
||||||
<th field="payMethod"
|
|
||||||
vn-tooltip="Pay Method">
|
|
||||||
<span translate>P.Method</span>
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
field="amount"
|
|
||||||
vn-tooltip="Balance due">
|
|
||||||
<span translate>Balance D.</span>
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
field="workerFk"
|
|
||||||
vn-tooltip="Worker who made the last observation">
|
|
||||||
<span translate>Author</span>
|
|
||||||
</th>
|
|
||||||
<th field="observation" expand>
|
|
||||||
<span translate>Last observation</span>
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
vn-tooltip="Last observation date"
|
|
||||||
field="created">
|
|
||||||
<span translate>L. O. Date</span>
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
vn-tooltip="Credit insurance"
|
|
||||||
field="creditInsurance"
|
|
||||||
shrink>
|
|
||||||
<span translate>Credit I.</span>
|
|
||||||
</th>
|
|
||||||
<th field="defaulterSinced">
|
|
||||||
<span translate>From</span>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr ng-repeat="defaulter in $ctrl.defaulters">
|
|
||||||
<td shrink>
|
|
||||||
<vn-check
|
|
||||||
ng-model="defaulter.checked"
|
|
||||||
on-change="$ctrl.saveChecked(defaulter.clientFk)"
|
|
||||||
vn-click-stop>
|
|
||||||
</vn-check>
|
|
||||||
</td>
|
|
||||||
<td title="{{::defaulter.clientName}}">
|
|
||||||
<span
|
|
||||||
vn-click-stop="clientDescriptor.show($event, defaulter.clientFk)"
|
|
||||||
title ="{{::defaulter.clientName}}"
|
|
||||||
class="link">
|
|
||||||
{{::defaulter.clientName}}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<vn-check
|
|
||||||
ng-model="defaulter.isWorker"
|
|
||||||
disabled="true">
|
|
||||||
</vn-check>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span
|
|
||||||
title="{{::defaulter.salesPersonName}}"
|
|
||||||
vn-click-stop="workerDescriptor.show($event, defaulter.salesPersonFk)"
|
|
||||||
class="link">
|
|
||||||
{{::defaulter.salesPersonName | dashIfEmpty}}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{::defaulter.country}}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{::defaulter.payMethod}}
|
|
||||||
</td>
|
|
||||||
<td>{{::defaulter.amount | currency: 'EUR': 2}}</td>
|
|
||||||
<td>
|
|
||||||
<span
|
|
||||||
title="{{::defaulter.workerName}}"
|
|
||||||
vn-click-stop="workerDescriptor.show($event, defaulter.workerFk)"
|
|
||||||
class="link">
|
|
||||||
{{::defaulter.workerName | dashIfEmpty}}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td expand>
|
|
||||||
<vn-textarea
|
|
||||||
vn-three
|
|
||||||
disabled="true"
|
|
||||||
ng-model="defaulter.observation">
|
|
||||||
</vn-textarea>
|
|
||||||
</td>
|
|
||||||
<td shrink-date>
|
|
||||||
<span class="chip {{::$ctrl.chipColor(defaulter.created)}}">
|
|
||||||
{{::defaulter.created | date: 'dd/MM/yyyy'}}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td shrink>{{::defaulter.creditInsurance | currency: 'EUR': 2}}</td>
|
|
||||||
<td shrink-date>{{::defaulter.defaulterSinced | date: 'dd/MM/yyyy'}}</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</slot-table>
|
|
||||||
</smart-table>
|
|
||||||
</vn-card>
|
</vn-card>
|
||||||
<vn-client-descriptor-popover
|
|
||||||
vn-id="client-descriptor">
|
|
||||||
</vn-client-descriptor-popover>
|
|
||||||
<vn-worker-descriptor-popover
|
|
||||||
vn-id="worker-descriptor">
|
|
||||||
</vn-worker-descriptor-popover>
|
|
||||||
<vn-popup vn-id="dialog-summary-client">
|
|
||||||
<vn-client-summary
|
|
||||||
client="$ctrl.clientSelected">
|
|
||||||
</vn-client-summary>
|
|
||||||
</vn-popup>
|
|
||||||
|
|
||||||
<!-- Dialog of add notes button -->
|
|
||||||
<vn-dialog
|
|
||||||
vn-id="notesDialog"
|
|
||||||
on-accept="$ctrl.onResponse()">
|
|
||||||
<tpl-body>
|
|
||||||
<section class="SMSDialog">
|
|
||||||
<h5 class="vn-py-sm">{{$ctrl.$t('Add observation to all selected clients', {total: $ctrl.checked.length})}}</h5>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textarea vn-one
|
|
||||||
vn-id="message"
|
|
||||||
label="Message"
|
|
||||||
ng-model="$ctrl.defaulter.observation"
|
|
||||||
rows="3"
|
|
||||||
required="true"
|
|
||||||
rule>
|
|
||||||
</vn-textarea>
|
|
||||||
</vn-horizontal>
|
|
||||||
</section>
|
|
||||||
</tpl-body>
|
|
||||||
<tpl-buttons>
|
|
||||||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
|
||||||
<button response="accept" translate>Save</button>
|
|
||||||
</tpl-buttons>
|
|
||||||
</vn-dialog>
|
|
||||||
|
|
|
@ -1,199 +1,13 @@
|
||||||
import ngModule from '../module';
|
import ngModule from '../module';
|
||||||
import Section from 'salix/components/section';
|
import Section from 'salix/components/section';
|
||||||
import UserError from 'core/lib/user-error';
|
|
||||||
|
|
||||||
export default class Controller extends Section {
|
export default class Controller extends Section {
|
||||||
constructor($element, $) {
|
constructor($element, $) {
|
||||||
super($element, $);
|
super($element, $);
|
||||||
this.defaulter = {};
|
|
||||||
this.defaulters = [];
|
|
||||||
this.checkedDefaulers = [];
|
|
||||||
|
|
||||||
this.smartTableOptions = {
|
|
||||||
activeButtons: {
|
|
||||||
search: true
|
|
||||||
},
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
field: 'clientFk',
|
|
||||||
autocomplete: {
|
|
||||||
url: 'Clients',
|
|
||||||
showField: 'name',
|
|
||||||
valueField: 'id'
|
|
||||||
}
|
}
|
||||||
}, {
|
async $onInit() {
|
||||||
field: 'salesPersonFk',
|
this.$state.go('customer.defaulter', {id: this.$params.id});
|
||||||
autocomplete: {
|
window.location.href = await this.vnApp.getUrl(`customer/defaulter`);
|
||||||
url: 'Workers/activeWithInheritedRole',
|
|
||||||
where: `{role: 'salesPerson'}`,
|
|
||||||
searchFunction: '{firstName: $search}',
|
|
||||||
showField: 'name',
|
|
||||||
valueField: 'id',
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
field: 'countryFk',
|
|
||||||
autocomplete: {
|
|
||||||
url: 'Countries',
|
|
||||||
showField: 'country',
|
|
||||||
valueField: 'id'
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
field: 'payMethodFk',
|
|
||||||
autocomplete: {
|
|
||||||
showField: 'name',
|
|
||||||
valueField: 'id'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'workerFk',
|
|
||||||
autocomplete: {
|
|
||||||
url: 'Workers/activeWithInheritedRole',
|
|
||||||
searchFunction: '{firstName: $search}',
|
|
||||||
showField: 'name',
|
|
||||||
valueField: 'id',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'observation',
|
|
||||||
searchable: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'isWorker',
|
|
||||||
checkbox: true,
|
|
||||||
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'created',
|
|
||||||
datepicker: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'defaulterSinced',
|
|
||||||
datepicker: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getBalanceDueTotal();
|
|
||||||
}
|
|
||||||
|
|
||||||
set defaulters(value) {
|
|
||||||
if (!value || !value.length) return;
|
|
||||||
this._defaulters = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
get defaulters() {
|
|
||||||
return this._defaulters;
|
|
||||||
}
|
|
||||||
|
|
||||||
get checked() {
|
|
||||||
const clients = this.$.model.data || [];
|
|
||||||
const checkedLines = [];
|
|
||||||
for (let defaulter of clients) {
|
|
||||||
if (defaulter.checked)
|
|
||||||
checkedLines.push(defaulter);
|
|
||||||
}
|
|
||||||
|
|
||||||
return checkedLines;
|
|
||||||
}
|
|
||||||
|
|
||||||
saveChecked(clientId) {
|
|
||||||
this.checkedDefaulers = this.checkedDefaulers.includes(clientId) ?
|
|
||||||
this.checkedDefaulers.filter(id => id !== clientId) : [...this.checkedDefaulers, clientId];
|
|
||||||
}
|
|
||||||
|
|
||||||
reCheck() {
|
|
||||||
if (!this.$.model.data || !this.checkedDefaulers.length) return;
|
|
||||||
|
|
||||||
this.$.model.data.forEach(defaulter => {
|
|
||||||
defaulter.checked = this.checkedDefaulers.includes(defaulter.clientFk);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getBalanceDueTotal() {
|
|
||||||
this.$http.get('Defaulters/filter')
|
|
||||||
.then(res => {
|
|
||||||
if (!res.data) return 0;
|
|
||||||
|
|
||||||
this.balanceDueTotal = res.data.reduce(
|
|
||||||
(accumulator, currentValue) => {
|
|
||||||
return accumulator + (currentValue['amount'] || 0);
|
|
||||||
}, 0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
chipColor(date) {
|
|
||||||
const day = 24 * 60 * 60 * 1000;
|
|
||||||
const today = Date.vnNew();
|
|
||||||
today.setHours(0, 0, 0, 0);
|
|
||||||
|
|
||||||
const observationShipped = new Date(date);
|
|
||||||
observationShipped.setHours(0, 0, 0, 0);
|
|
||||||
|
|
||||||
const difference = today - observationShipped;
|
|
||||||
|
|
||||||
if (difference > (day * 20))
|
|
||||||
return 'alert';
|
|
||||||
if (difference > (day * 10))
|
|
||||||
return 'warning';
|
|
||||||
}
|
|
||||||
|
|
||||||
onResponse() {
|
|
||||||
if (!this.defaulter.observation)
|
|
||||||
throw new UserError(`The message can't be empty`);
|
|
||||||
|
|
||||||
const params = [];
|
|
||||||
for (let defaulter of this.checked) {
|
|
||||||
params.push({
|
|
||||||
text: this.defaulter.observation,
|
|
||||||
clientFk: defaulter.clientFk
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$http.post(`ClientObservations`, params) .then(() => {
|
|
||||||
this.vnApp.showSuccess(this.$t('Observation saved!'));
|
|
||||||
this.sendMail();
|
|
||||||
this.$state.reload();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
sendMail() {
|
|
||||||
const params = {
|
|
||||||
defaulters: this.checked,
|
|
||||||
observation: this.defaulter.observation,
|
|
||||||
};
|
|
||||||
this.$http.post(`Defaulters/observationEmail`, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
exprBuilder(param, value) {
|
|
||||||
switch (param) {
|
|
||||||
case 'isWorker':
|
|
||||||
return {isWorker: value};
|
|
||||||
case 'creditInsurance':
|
|
||||||
case 'amount':
|
|
||||||
case 'clientFk':
|
|
||||||
case 'workerFk':
|
|
||||||
case 'countryFk':
|
|
||||||
case 'payMethod':
|
|
||||||
case 'salesPersonFk':
|
|
||||||
return {[`d.${param}`]: value};
|
|
||||||
case 'created':
|
|
||||||
return {'d.created': {
|
|
||||||
between: this.dateRange(value)}
|
|
||||||
};
|
|
||||||
case 'defaulterSinced':
|
|
||||||
return {'d.defaulterSinced': {
|
|
||||||
between: this.dateRange(value)}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dateRange(value) {
|
|
||||||
const minHour = new Date(value);
|
|
||||||
minHour.setHours(0, 0, 0, 0);
|
|
||||||
const maxHour = new Date(value);
|
|
||||||
maxHour.setHours(23, 59, 59, 59);
|
|
||||||
|
|
||||||
return [minHour, maxHour];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,179 +0,0 @@
|
||||||
import './index';
|
|
||||||
import crudModel from 'core/mocks/crud-model';
|
|
||||||
|
|
||||||
describe('client defaulter', () => {
|
|
||||||
describe('Component vnClientDefaulter', () => {
|
|
||||||
let controller;
|
|
||||||
let $httpBackend;
|
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
const $element = angular.element('<vn-client-defaulter></vn-client-defaulter>');
|
|
||||||
controller = $componentController('vnClientDefaulter', {$element});
|
|
||||||
controller.$.model = crudModel;
|
|
||||||
controller.$.model.data = [
|
|
||||||
{clientFk: 1101, amount: 125},
|
|
||||||
{clientFk: 1102, amount: 500},
|
|
||||||
{clientFk: 1103, amount: 250}
|
|
||||||
];
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('checked() getter', () => {
|
|
||||||
it('should return the checked lines', () => {
|
|
||||||
const data = controller.$.model.data;
|
|
||||||
data[1].checked = true;
|
|
||||||
data[2].checked = true;
|
|
||||||
|
|
||||||
const checkedRows = controller.checked;
|
|
||||||
|
|
||||||
const firstCheckedRow = checkedRows[0];
|
|
||||||
const secondCheckedRow = checkedRows[1];
|
|
||||||
|
|
||||||
expect(firstCheckedRow.clientFk).toEqual(1102);
|
|
||||||
expect(secondCheckedRow.clientFk).toEqual(1103);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('chipColor()', () => {
|
|
||||||
it('should return undefined when the date is the present', () => {
|
|
||||||
let today = Date.vnNew();
|
|
||||||
let result = controller.chipColor(today);
|
|
||||||
|
|
||||||
expect(result).toEqual(undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return warning when the date is 10 days in the past', () => {
|
|
||||||
let pastDate = Date.vnNew();
|
|
||||||
pastDate = pastDate.setDate(pastDate.getDate() - 11);
|
|
||||||
let result = controller.chipColor(pastDate);
|
|
||||||
|
|
||||||
expect(result).toEqual('warning');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return alert when the date is 20 days in the past', () => {
|
|
||||||
let pastDate = Date.vnNew();
|
|
||||||
pastDate = pastDate.setDate(pastDate.getDate() - 21);
|
|
||||||
let result = controller.chipColor(pastDate);
|
|
||||||
|
|
||||||
expect(result).toEqual('alert');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onResponse()', () => {
|
|
||||||
it('should return error for empty message', () => {
|
|
||||||
let error;
|
|
||||||
try {
|
|
||||||
controller.onResponse();
|
|
||||||
} catch (e) {
|
|
||||||
error = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(error).toBeDefined();
|
|
||||||
expect(error.message).toBe(`The message can't be empty`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return saved message', () => {
|
|
||||||
const data = controller.$.model.data;
|
|
||||||
data[1].checked = true;
|
|
||||||
controller.defaulter = {observation: 'My new observation'};
|
|
||||||
|
|
||||||
const params = [{text: controller.defaulter.observation, clientFk: data[1].clientFk}];
|
|
||||||
|
|
||||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
|
||||||
$httpBackend.expect('GET', `Defaulters/filter`).respond(200);
|
|
||||||
$httpBackend.expect('POST', `ClientObservations`, params).respond(200, params);
|
|
||||||
$httpBackend.expect('POST', `Defaulters/observationEmail`).respond(200);
|
|
||||||
|
|
||||||
controller.onResponse();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Observation saved!');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('exprBuilder()', () => {
|
|
||||||
it('should search by sales person', () => {
|
|
||||||
const expr = controller.exprBuilder('salesPersonFk', '5');
|
|
||||||
|
|
||||||
expect(expr).toEqual({'d.salesPersonFk': '5'});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should search by client', () => {
|
|
||||||
const expr = controller.exprBuilder('clientFk', '5');
|
|
||||||
|
|
||||||
expect(expr).toEqual({'d.clientFk': '5'});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getBalanceDueTotal()', () => {
|
|
||||||
it('should return balance due total', () => {
|
|
||||||
const defaulters = controller.$.model.data;
|
|
||||||
$httpBackend.when('GET', `Defaulters/filter`).respond(defaulters);
|
|
||||||
|
|
||||||
controller.getBalanceDueTotal();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.balanceDueTotal).toEqual(875);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('dateRange()', () => {
|
|
||||||
it('should return two dates with the hours at the start and end of the given date', () => {
|
|
||||||
const now = Date.vnNew();
|
|
||||||
|
|
||||||
const today = now.getDate();
|
|
||||||
|
|
||||||
const dateRange = controller.dateRange(now);
|
|
||||||
const start = dateRange[0].toString();
|
|
||||||
const end = dateRange[1].toString();
|
|
||||||
|
|
||||||
expect(start).toContain(today);
|
|
||||||
expect(start).toContain('00:00:00');
|
|
||||||
|
|
||||||
expect(end).toContain(today);
|
|
||||||
expect(end).toContain('23:59:59');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('reCheck()', () => {
|
|
||||||
it(`should recheck buys`, () => {
|
|
||||||
controller.$.model.data = [
|
|
||||||
{checked: false, clientFk: 1},
|
|
||||||
{checked: false, clientFk: 2},
|
|
||||||
{checked: false, clientFk: 3},
|
|
||||||
{checked: false, clientFk: 4},
|
|
||||||
];
|
|
||||||
controller.checkedDefaulers = [1, 2];
|
|
||||||
|
|
||||||
controller.reCheck();
|
|
||||||
|
|
||||||
expect(controller.$.model.data[0].checked).toEqual(true);
|
|
||||||
expect(controller.$.model.data[1].checked).toEqual(true);
|
|
||||||
expect(controller.$.model.data[2].checked).toEqual(false);
|
|
||||||
expect(controller.$.model.data[3].checked).toEqual(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('saveChecked()', () => {
|
|
||||||
it(`should check buy`, () => {
|
|
||||||
const buyCheck = 3;
|
|
||||||
controller.checkedDefaulers = [1, 2];
|
|
||||||
|
|
||||||
controller.saveChecked(buyCheck);
|
|
||||||
|
|
||||||
expect(controller.checkedDefaulers[2]).toEqual(buyCheck);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should uncheck buy`, () => {
|
|
||||||
const buyUncheck = 3;
|
|
||||||
controller.checkedDefaulers = [1, 2, 3];
|
|
||||||
|
|
||||||
controller.saveChecked(buyUncheck);
|
|
||||||
|
|
||||||
expect(controller.checkedDefaulers[2]).toEqual(undefined);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,14 +0,0 @@
|
||||||
Add observation: Añadir observación
|
|
||||||
Add observation to all selected clients: Añadir observación a {{total}} cliente(s) seleccionado(s)
|
|
||||||
Balance D.: Saldo V.
|
|
||||||
Credit I.: Crédito A.
|
|
||||||
Last observation: Última observación
|
|
||||||
L. O. Date: Fecha Ú. O.
|
|
||||||
Last observation date: Fecha última observación
|
|
||||||
Search client: Buscar clientes
|
|
||||||
Worker who made the last observation: Trabajador que ha realizado la última observación
|
|
||||||
Email sended!: Email enviado!
|
|
||||||
Observation saved!: Observación añadida!
|
|
||||||
P.Method: F.Pago
|
|
||||||
Pay Method: Forma de Pago
|
|
||||||
Country: Pais
|
|
|
@ -166,12 +166,11 @@ module.exports = Self => {
|
||||||
LEFT JOIN account.emailUser eu ON eu.userFk = u.id`
|
LEFT JOIN account.emailUser eu ON eu.userFk = u.id`
|
||||||
);
|
);
|
||||||
|
|
||||||
stmt.merge(conn.makeWhere(filter.where));
|
stmt.merge(conn.makeSuffix(filter));
|
||||||
stmts.push(stmt);
|
let itemsIndex = stmts.push(stmt) - 1;
|
||||||
|
|
||||||
const itemsIndex = stmts.push(stmt) - 1;
|
let sql = ParameterizedSQL.join(stmts, ';');
|
||||||
const sql = ParameterizedSQL.join(stmts, ';');
|
let result = await conn.executeStmt(sql);
|
||||||
const result = await conn.executeStmt(sql, myOptions);
|
return itemsIndex === 0 ? result : result[itemsIndex];
|
||||||
return result[itemsIndex];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue