hvp-shared 6.47.0 → 6.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants/index.d.ts +1 -0
- package/dist/constants/index.js +1 -0
- package/dist/constants/pricing.constants.d.ts +2 -2
- package/dist/constants/pricing.constants.js +6 -4
- package/dist/constants/pricing.constants.test.js +23 -11
- package/dist/constants/qvet-cash-flow.enums.d.ts +45 -0
- package/dist/constants/qvet-cash-flow.enums.js +56 -0
- package/dist/contracts/qvet/responses.d.ts +46 -0
- package/package.json +1 -1
package/dist/constants/index.js
CHANGED
|
@@ -30,3 +30,4 @@ __exportStar(require("./job-category.constants"), exports);
|
|
|
30
30
|
__exportStar(require("./special-collaborators.constants"), exports);
|
|
31
31
|
__exportStar(require("./commissions.constants"), exports);
|
|
32
32
|
__exportStar(require("./hr.enums"), exports);
|
|
33
|
+
__exportStar(require("./qvet-cash-flow.enums"), exports);
|
|
@@ -128,8 +128,8 @@ export declare function calculateRecommendedPricePVP(params: {
|
|
|
128
128
|
unitPurchasePriceBI: number;
|
|
129
129
|
vatSalePercent: number;
|
|
130
130
|
}): number | null;
|
|
131
|
-
/** Cost-based multiplier for floor price (PHARM, PHARM_FRAC, COST_ML, COST) */
|
|
132
|
-
export declare const MIN_PRICE_COST_FACTOR =
|
|
131
|
+
/** Cost-based multiplier for floor price (PHARM, PHARM_FRAC, COST_ML, COST) — cost + 25% margin */
|
|
132
|
+
export declare const MIN_PRICE_COST_FACTOR = 1.25;
|
|
133
133
|
/** Cost-based multiplier for floor price (EXT_COST) */
|
|
134
134
|
export declare const MIN_PRICE_EXT_COST_FACTOR = 1;
|
|
135
135
|
/** Fraction of salePricePVP for recommended minimum price (COMP_SVC) */
|
|
@@ -218,9 +218,11 @@ function getDefaultPricePolicy(section, saleUnit, conversionFactor) {
|
|
|
218
218
|
// =============================================================================
|
|
219
219
|
// ROUNDING HELPER
|
|
220
220
|
// =============================================================================
|
|
221
|
-
/** Round to nearest multiple of 5 */
|
|
221
|
+
/** Round to nearest multiple of 5 (minimum 5 for positive values) */
|
|
222
222
|
function roundToNearest5(value) {
|
|
223
|
-
|
|
223
|
+
if (value <= 0)
|
|
224
|
+
return 0;
|
|
225
|
+
return Math.max(5, Math.round(value / 5) * 5);
|
|
224
226
|
}
|
|
225
227
|
/**
|
|
226
228
|
* Calculate the recommended price PVP (con IVA) for a catalog item.
|
|
@@ -243,8 +245,8 @@ function calculateRecommendedPricePVP(params) {
|
|
|
243
245
|
// =============================================================================
|
|
244
246
|
// FLOOR PRICE CALCULATION
|
|
245
247
|
// =============================================================================
|
|
246
|
-
/** Cost-based multiplier for floor price (PHARM, PHARM_FRAC, COST_ML, COST) */
|
|
247
|
-
exports.MIN_PRICE_COST_FACTOR =
|
|
248
|
+
/** Cost-based multiplier for floor price (PHARM, PHARM_FRAC, COST_ML, COST) — cost + 25% margin */
|
|
249
|
+
exports.MIN_PRICE_COST_FACTOR = 1.25;
|
|
248
250
|
/** Cost-based multiplier for floor price (EXT_COST) */
|
|
249
251
|
exports.MIN_PRICE_EXT_COST_FACTOR = 1.0;
|
|
250
252
|
/** Fraction of salePricePVP for recommended minimum price (COMP_SVC) */
|
|
@@ -319,17 +319,17 @@ describe('calculateFloorPrices', () => {
|
|
|
319
319
|
const defaults = { unitPurchasePriceBI: 100, vatSalePercent: 16, salePricePVP: 500 };
|
|
320
320
|
describe('cost-based policies (PHARM, PHARM_FRAC, COST_ML, COST)', () => {
|
|
321
321
|
const costPolicies = [pricing_constants_1.PricePolicy.PHARM, pricing_constants_1.PricePolicy.PHARM_FRAC, pricing_constants_1.PricePolicy.COST_ML, pricing_constants_1.PricePolicy.COST];
|
|
322
|
-
it.each(costPolicies)('%s: both = cost ×
|
|
323
|
-
// $100 *
|
|
322
|
+
it.each(costPolicies)('%s: both = cost × 1.25 × (1+VAT/100), round5', (policy) => {
|
|
323
|
+
// $100 * 1.25 * 1.16 = $145 → round5 = $145
|
|
324
324
|
const result = (0, pricing_constants_1.calculateFloorPrices)({ ...defaults, pricePolicy: policy });
|
|
325
|
-
expect(result.recommendedMinimumPrice).toBe(
|
|
326
|
-
expect(result.floorPrice).toBe(
|
|
325
|
+
expect(result.recommendedMinimumPrice).toBe(145);
|
|
326
|
+
expect(result.floorPrice).toBe(145);
|
|
327
327
|
});
|
|
328
328
|
it('should round to nearest 5', () => {
|
|
329
|
-
// $80 *
|
|
329
|
+
// $80 * 1.25 * 1.16 = $116 → round5 = $115
|
|
330
330
|
const result = (0, pricing_constants_1.calculateFloorPrices)({ ...defaults, pricePolicy: pricing_constants_1.PricePolicy.PHARM, unitPurchasePriceBI: 80 });
|
|
331
|
-
expect(result.recommendedMinimumPrice).toBe(
|
|
332
|
-
expect(result.floorPrice).toBe(
|
|
331
|
+
expect(result.recommendedMinimumPrice).toBe(115);
|
|
332
|
+
expect(result.floorPrice).toBe(115);
|
|
333
333
|
});
|
|
334
334
|
it('should return null when cost is 0', () => {
|
|
335
335
|
const result = (0, pricing_constants_1.calculateFloorPrices)({ ...defaults, pricePolicy: pricing_constants_1.PricePolicy.PHARM, unitPurchasePriceBI: 0 });
|
|
@@ -342,14 +342,20 @@ describe('calculateFloorPrices', () => {
|
|
|
342
342
|
expect(result.floorPrice).toBeNull();
|
|
343
343
|
});
|
|
344
344
|
it('should handle 0% VAT', () => {
|
|
345
|
-
// $100 *
|
|
345
|
+
// $100 * 1.25 * 1.0 = $125 → $125
|
|
346
346
|
const result = (0, pricing_constants_1.calculateFloorPrices)({ ...defaults, pricePolicy: pricing_constants_1.PricePolicy.COST, vatSalePercent: 0 });
|
|
347
|
-
expect(result.recommendedMinimumPrice).toBe(
|
|
348
|
-
expect(result.floorPrice).toBe(
|
|
347
|
+
expect(result.recommendedMinimumPrice).toBe(125);
|
|
348
|
+
expect(result.floorPrice).toBe(125);
|
|
349
|
+
});
|
|
350
|
+
it('should never return less than 5 for positive cost', () => {
|
|
351
|
+
// $1 * 1.25 * 1.0 = $1.25 → round5 = 0, but min is 5
|
|
352
|
+
const result = (0, pricing_constants_1.calculateFloorPrices)({ ...defaults, pricePolicy: pricing_constants_1.PricePolicy.PHARM, unitPurchasePriceBI: 1, vatSalePercent: 0 });
|
|
353
|
+
expect(result.recommendedMinimumPrice).toBe(5);
|
|
354
|
+
expect(result.floorPrice).toBe(5);
|
|
349
355
|
});
|
|
350
356
|
});
|
|
351
357
|
describe('EXT_COST', () => {
|
|
352
|
-
it('both = cost × 1.0 × (1+VAT/100), round5', () => {
|
|
358
|
+
it('both = cost × 1.0 × (1+VAT/100), round5 (at-cost recovery)', () => {
|
|
353
359
|
// $100 * 1.0 * 1.16 = $116 → round5 = $115
|
|
354
360
|
const result = (0, pricing_constants_1.calculateFloorPrices)({ ...defaults, pricePolicy: pricing_constants_1.PricePolicy.EXT_COST });
|
|
355
361
|
expect(result.recommendedMinimumPrice).toBe(115);
|
|
@@ -366,6 +372,12 @@ describe('calculateFloorPrices', () => {
|
|
|
366
372
|
expect(result.recommendedMinimumPrice).toBe(230);
|
|
367
373
|
expect(result.floorPrice).toBe(230);
|
|
368
374
|
});
|
|
375
|
+
it('should never return less than 5 for positive cost', () => {
|
|
376
|
+
// $2 * 1.0 * 1.0 = $2 → round5 = 0, but min is 5
|
|
377
|
+
const result = (0, pricing_constants_1.calculateFloorPrices)({ ...defaults, pricePolicy: pricing_constants_1.PricePolicy.EXT_COST, unitPurchasePriceBI: 2, vatSalePercent: 0 });
|
|
378
|
+
expect(result.recommendedMinimumPrice).toBe(5);
|
|
379
|
+
expect(result.floorPrice).toBe(5);
|
|
380
|
+
});
|
|
369
381
|
});
|
|
370
382
|
describe('COMP_SVC', () => {
|
|
371
383
|
it('recommendedMinimumPrice = salePricePVP × 0.50, floorPrice = 0', () => {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QVET Cash Flow Review Enums
|
|
3
|
+
*
|
|
4
|
+
* Used in the cash flow review workflow where collaborators and admins
|
|
5
|
+
* annotate QVET cash transactions (entradas/salidas de caja) with
|
|
6
|
+
* supplier, account type, evidence, and invoice status.
|
|
7
|
+
*
|
|
8
|
+
* DB values use QVET abbreviations (CE, SE, FA, etc.) for historical
|
|
9
|
+
* compatibility. Enum keys use descriptive English names.
|
|
10
|
+
*/
|
|
11
|
+
/** Whether the transaction goes through formal or informal accounting */
|
|
12
|
+
export declare enum CashFlowAccountType {
|
|
13
|
+
FORMAL = "FORMAL",
|
|
14
|
+
INFORMAL = "INFORMAL"
|
|
15
|
+
}
|
|
16
|
+
/** Evidence status for the transaction receipt/voucher */
|
|
17
|
+
export declare enum CashFlowEvidence {
|
|
18
|
+
/** Comprobante guardado (receipt saved in Dropbox) */
|
|
19
|
+
SAVED = "CE",
|
|
20
|
+
/** Se extravió (receipt existed but was lost/not captured) */
|
|
21
|
+
MISSING = "SE",
|
|
22
|
+
/** Sin comprobantes (no receipt for this type of payment) */
|
|
23
|
+
NO_RECEIPT = "SC"
|
|
24
|
+
}
|
|
25
|
+
/** Invoice status for formal transactions */
|
|
26
|
+
export declare enum CashFlowInvoiceStatus {
|
|
27
|
+
/** Factura recibida */
|
|
28
|
+
INVOICED = "FA",
|
|
29
|
+
/** Proveedor factura automáticamente */
|
|
30
|
+
AUTO_INVOICED = "FA_AUTO",
|
|
31
|
+
/** Pendiente de factura */
|
|
32
|
+
PENDING = "PE",
|
|
33
|
+
/** No facturable (informales, etc.) */
|
|
34
|
+
NOT_APPLICABLE = "SF"
|
|
35
|
+
}
|
|
36
|
+
/** Validation result for a cash flow entry */
|
|
37
|
+
export declare enum CashFlowValidationStatus {
|
|
38
|
+
VALID = "valid",
|
|
39
|
+
INVALID = "invalid"
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Invoice statuses allowed when accountType is FORMAL.
|
|
43
|
+
* NOT_APPLICABLE is only valid for INFORMAL accounts.
|
|
44
|
+
*/
|
|
45
|
+
export declare const FORMAL_ALLOWED_INVOICE_STATUSES: readonly [CashFlowInvoiceStatus.INVOICED, CashFlowInvoiceStatus.AUTO_INVOICED, CashFlowInvoiceStatus.PENDING];
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* QVET Cash Flow Review Enums
|
|
4
|
+
*
|
|
5
|
+
* Used in the cash flow review workflow where collaborators and admins
|
|
6
|
+
* annotate QVET cash transactions (entradas/salidas de caja) with
|
|
7
|
+
* supplier, account type, evidence, and invoice status.
|
|
8
|
+
*
|
|
9
|
+
* DB values use QVET abbreviations (CE, SE, FA, etc.) for historical
|
|
10
|
+
* compatibility. Enum keys use descriptive English names.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.FORMAL_ALLOWED_INVOICE_STATUSES = exports.CashFlowValidationStatus = exports.CashFlowInvoiceStatus = exports.CashFlowEvidence = exports.CashFlowAccountType = void 0;
|
|
14
|
+
/** Whether the transaction goes through formal or informal accounting */
|
|
15
|
+
var CashFlowAccountType;
|
|
16
|
+
(function (CashFlowAccountType) {
|
|
17
|
+
CashFlowAccountType["FORMAL"] = "FORMAL";
|
|
18
|
+
CashFlowAccountType["INFORMAL"] = "INFORMAL";
|
|
19
|
+
})(CashFlowAccountType || (exports.CashFlowAccountType = CashFlowAccountType = {}));
|
|
20
|
+
/** Evidence status for the transaction receipt/voucher */
|
|
21
|
+
var CashFlowEvidence;
|
|
22
|
+
(function (CashFlowEvidence) {
|
|
23
|
+
/** Comprobante guardado (receipt saved in Dropbox) */
|
|
24
|
+
CashFlowEvidence["SAVED"] = "CE";
|
|
25
|
+
/** Se extravió (receipt existed but was lost/not captured) */
|
|
26
|
+
CashFlowEvidence["MISSING"] = "SE";
|
|
27
|
+
/** Sin comprobantes (no receipt for this type of payment) */
|
|
28
|
+
CashFlowEvidence["NO_RECEIPT"] = "SC";
|
|
29
|
+
})(CashFlowEvidence || (exports.CashFlowEvidence = CashFlowEvidence = {}));
|
|
30
|
+
/** Invoice status for formal transactions */
|
|
31
|
+
var CashFlowInvoiceStatus;
|
|
32
|
+
(function (CashFlowInvoiceStatus) {
|
|
33
|
+
/** Factura recibida */
|
|
34
|
+
CashFlowInvoiceStatus["INVOICED"] = "FA";
|
|
35
|
+
/** Proveedor factura automáticamente */
|
|
36
|
+
CashFlowInvoiceStatus["AUTO_INVOICED"] = "FA_AUTO";
|
|
37
|
+
/** Pendiente de factura */
|
|
38
|
+
CashFlowInvoiceStatus["PENDING"] = "PE";
|
|
39
|
+
/** No facturable (informales, etc.) */
|
|
40
|
+
CashFlowInvoiceStatus["NOT_APPLICABLE"] = "SF";
|
|
41
|
+
})(CashFlowInvoiceStatus || (exports.CashFlowInvoiceStatus = CashFlowInvoiceStatus = {}));
|
|
42
|
+
/** Validation result for a cash flow entry */
|
|
43
|
+
var CashFlowValidationStatus;
|
|
44
|
+
(function (CashFlowValidationStatus) {
|
|
45
|
+
CashFlowValidationStatus["VALID"] = "valid";
|
|
46
|
+
CashFlowValidationStatus["INVALID"] = "invalid";
|
|
47
|
+
})(CashFlowValidationStatus || (exports.CashFlowValidationStatus = CashFlowValidationStatus = {}));
|
|
48
|
+
/**
|
|
49
|
+
* Invoice statuses allowed when accountType is FORMAL.
|
|
50
|
+
* NOT_APPLICABLE is only valid for INFORMAL accounts.
|
|
51
|
+
*/
|
|
52
|
+
exports.FORMAL_ALLOWED_INVOICE_STATUSES = [
|
|
53
|
+
CashFlowInvoiceStatus.INVOICED,
|
|
54
|
+
CashFlowInvoiceStatus.AUTO_INVOICED,
|
|
55
|
+
CashFlowInvoiceStatus.PENDING,
|
|
56
|
+
];
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
* }
|
|
24
24
|
* ```
|
|
25
25
|
*/
|
|
26
|
+
import { CashFlowAccountType, CashFlowEvidence, CashFlowInvoiceStatus, CashFlowValidationStatus } from '../../constants/qvet-cash-flow.enums';
|
|
26
27
|
/**
|
|
27
28
|
* @deprecated No longer used. Backend uses standard ApiListSuccessResponse with meta.
|
|
28
29
|
* Kept for backward compatibility during migration.
|
|
@@ -613,6 +614,50 @@ export interface QvetCashClosingsQueryParams {
|
|
|
613
614
|
skip?: number;
|
|
614
615
|
sort?: string;
|
|
615
616
|
}
|
|
617
|
+
/**
|
|
618
|
+
* Review data added by collaborators/admins to a QVET cash flow entry.
|
|
619
|
+
*
|
|
620
|
+
* QVET-sourced fields (branch, amount, etc.) remain immutable.
|
|
621
|
+
* All editable data lives in this subdocument.
|
|
622
|
+
*
|
|
623
|
+
* @example PATCH /api/qvet/cash-flows/:id/review
|
|
624
|
+
*/
|
|
625
|
+
export interface CashFlowReview {
|
|
626
|
+
/** Proveedor (may differ from QVET's supplier field) */
|
|
627
|
+
supplier?: string;
|
|
628
|
+
/** Tipo de cuenta assigned by collaborator */
|
|
629
|
+
accountType?: CashFlowAccountType;
|
|
630
|
+
/** Receipt/voucher evidence status */
|
|
631
|
+
evidence?: CashFlowEvidence;
|
|
632
|
+
/** Invoice status (FORMAL accounts cannot be NOT_APPLICABLE) */
|
|
633
|
+
invoiceStatus?: CashFlowInvoiceStatus;
|
|
634
|
+
/** Auto-calculated or admin-overridden validation result */
|
|
635
|
+
validationStatus?: CashFlowValidationStatus;
|
|
636
|
+
/** Tipo de cuenta overridden by admin (used for accounting export) */
|
|
637
|
+
adminAccountType?: CashFlowAccountType;
|
|
638
|
+
/** Free-text observations */
|
|
639
|
+
observations?: string;
|
|
640
|
+
/** Collaborator ID who last updated */
|
|
641
|
+
lastUpdatedBy?: string;
|
|
642
|
+
/** ISO 8601 timestamp of last update */
|
|
643
|
+
lastUpdatedAt?: string;
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Request body for updating a cash flow review.
|
|
647
|
+
*
|
|
648
|
+
* @example PATCH /api/qvet/cash-flows/:id/review
|
|
649
|
+
*/
|
|
650
|
+
export interface UpdateCashFlowReviewRequest {
|
|
651
|
+
supplier?: string;
|
|
652
|
+
accountType?: CashFlowAccountType;
|
|
653
|
+
evidence?: CashFlowEvidence;
|
|
654
|
+
invoiceStatus?: CashFlowInvoiceStatus;
|
|
655
|
+
/** Only admin can override */
|
|
656
|
+
validationStatus?: CashFlowValidationStatus;
|
|
657
|
+
/** Only admin can set */
|
|
658
|
+
adminAccountType?: CashFlowAccountType;
|
|
659
|
+
observations?: string;
|
|
660
|
+
}
|
|
616
661
|
/**
|
|
617
662
|
* Single cash flow record from QVET (Entradas/Salidas de Caja)
|
|
618
663
|
* Represents cash in/out transactions outside of regular sales
|
|
@@ -634,6 +679,7 @@ export interface QvetCashFlowResponse {
|
|
|
634
679
|
supplier: string;
|
|
635
680
|
staffName: string;
|
|
636
681
|
closingDate: string;
|
|
682
|
+
review?: CashFlowReview;
|
|
637
683
|
syncedAt: string;
|
|
638
684
|
}
|
|
639
685
|
/**
|