@appcorp/stellar-solutions-invoice-module 0.1.73 → 0.1.75

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.
Files changed (89) hide show
  1. package/base-modules/invoice/add-service-product-section.d.ts +1 -5
  2. package/base-modules/invoice/add-service-product-section.js +3 -3
  3. package/base-modules/invoice/cache.d.ts +15 -0
  4. package/base-modules/invoice/cache.js +50 -0
  5. package/base-modules/invoice/calculate-subtotal.d.ts +6 -1
  6. package/base-modules/invoice/calculate-subtotal.js +2 -2
  7. package/base-modules/invoice/calculate-total.d.ts +1 -1
  8. package/base-modules/invoice/calculate-total.js +8 -8
  9. package/base-modules/invoice/company-form-section.d.ts +1 -5
  10. package/base-modules/invoice/company-form-section.js +25 -22
  11. package/base-modules/invoice/constants.d.ts +2 -3
  12. package/base-modules/invoice/constants.js +2 -3
  13. package/base-modules/invoice/context.d.ts +556 -20
  14. package/base-modules/invoice/context.js +542 -340
  15. package/base-modules/invoice/customer-form-section.d.ts +1 -5
  16. package/base-modules/invoice/customer-form-section.js +25 -9
  17. package/base-modules/invoice/form.d.ts +1 -5
  18. package/base-modules/invoice/form.js +9 -9
  19. package/base-modules/invoice/page.d.ts +8 -0
  20. package/base-modules/invoice/page.js +171 -0
  21. package/base-modules/invoice/pricing-form-section.d.ts +1 -5
  22. package/base-modules/invoice/pricing-form-section.js +16 -11
  23. package/base-modules/invoice/products-form-section.d.ts +1 -5
  24. package/base-modules/invoice/products-form-section.js +49 -41
  25. package/base-modules/invoice/services-form-section.d.ts +1 -5
  26. package/base-modules/invoice/services-form-section.js +10 -9
  27. package/base-modules/invoice/validate.d.ts +83 -25
  28. package/base-modules/invoice/validate.js +4 -4
  29. package/base-modules/payment/cache.d.ts +15 -0
  30. package/base-modules/payment/cache.js +52 -0
  31. package/base-modules/payment/constants.d.ts +1 -14
  32. package/base-modules/payment/constants.js +2 -15
  33. package/base-modules/payment/context.d.ts +214 -48
  34. package/base-modules/payment/context.js +312 -240
  35. package/base-modules/payment/drawer.d.ts +0 -6
  36. package/base-modules/payment/drawer.js +89 -44
  37. package/base-modules/payment/form.js +3 -2
  38. package/base-modules/payment/{payment.js → page.js} +2 -5
  39. package/base-modules/payment/types.d.ts +0 -85
  40. package/base-modules/payment/types.js +74 -21
  41. package/base-modules/payment/validate.d.ts +12 -0
  42. package/base-modules/payment/validate.js +19 -8
  43. package/base-modules/payment/view.d.ts +1 -5
  44. package/base-modules/payment/view.js +4 -3
  45. package/base-modules/quote/add-service-product-section.js +1 -1
  46. package/base-modules/quote/cache.d.ts +15 -0
  47. package/base-modules/quote/cache.js +50 -0
  48. package/base-modules/quote/company-form-section.d.ts +1 -1
  49. package/base-modules/quote/company-form-section.js +14 -12
  50. package/base-modules/quote/constants.js +1 -0
  51. package/base-modules/quote/context.d.ts +656 -46
  52. package/base-modules/quote/context.js +431 -293
  53. package/base-modules/quote/customer-form-section.d.ts +1 -1
  54. package/base-modules/quote/customer-form-section.js +24 -9
  55. package/base-modules/quote/form.d.ts +1 -5
  56. package/base-modules/quote/form.js +8 -9
  57. package/base-modules/quote/page.d.ts +8 -0
  58. package/base-modules/quote/page.js +163 -0
  59. package/base-modules/quote/pricing-form-section.js +9 -8
  60. package/base-modules/quote/products-form-section.js +2 -3
  61. package/base-modules/quote/services-form-section.js +1 -1
  62. package/base-modules/quote/types.d.ts +0 -127
  63. package/base-modules/quote/types.js +92 -35
  64. package/base-modules/quote/validate.d.ts +82 -25
  65. package/base-modules/quote/validate.js +3 -4
  66. package/package.json +12 -11
  67. package/base-modules/invoice/actions.d.ts +0 -215
  68. package/base-modules/invoice/actions.js +0 -38
  69. package/base-modules/invoice/drawer.d.ts +0 -13
  70. package/base-modules/invoice/drawer.js +0 -46
  71. package/base-modules/invoice/invoice.d.ts +0 -8
  72. package/base-modules/invoice/invoice.js +0 -69
  73. package/base-modules/invoice/reducer.d.ts +0 -4
  74. package/base-modules/invoice/reducer.js +0 -180
  75. package/base-modules/invoice/types.d.ts +0 -211
  76. package/base-modules/invoice/types.js +0 -43
  77. package/base-modules/payment/actions.d.ts +0 -203
  78. package/base-modules/payment/actions.js +0 -50
  79. package/base-modules/payment/reducer.d.ts +0 -29
  80. package/base-modules/payment/reducer.js +0 -215
  81. package/base-modules/quote/actions.d.ts +0 -215
  82. package/base-modules/quote/actions.js +0 -38
  83. package/base-modules/quote/drawer.d.ts +0 -13
  84. package/base-modules/quote/drawer.js +0 -46
  85. package/base-modules/quote/quote.d.ts +0 -8
  86. package/base-modules/quote/quote.js +0 -69
  87. package/base-modules/quote/reducer.d.ts +0 -4
  88. package/base-modules/quote/reducer.js +0 -181
  89. /package/base-modules/payment/{payment.d.ts → page.d.ts} +0 -0
@@ -1,42 +1,8 @@
1
1
  /**
2
- * Invoice State Context
2
+ * Quote State Context - Using Generic Module Factory
3
3
  *
4
- * This module provides comprehensive state management for the Invoice feature including:
5
- * - CRUD operations (create, read, update, delete)
6
- * - Form validation and error handling
7
- * - Multi-section forms (company, customer, pricing, products, services)
8
- * - Complex calculations (subtotal, tax, discount, total)
9
- * - Dynamic product and service row management
10
- * - Search and filtering functionality
11
- * - Pagination controls
12
- * - Company and customer integration
13
- * - Currency and tax management
14
- * - Internationalization support
15
- * - Theme-aware toast notifications
16
- *
17
- * Organization:
18
- * - Types & Interfaces
19
- * - Main Hook (useInvoiceState)
20
- * - State & Core Hooks
21
- * - Theme Support
22
- * - Toast Helpers
23
- * - Debounced Values
24
- * - Tax & Currency Defaults
25
- * - API Parameters (memoized)
26
- * - API Callbacks (with error handling)
27
- * - Module Entity Hook
28
- * - Effects (list refresh, defaults, calculations)
29
- * - Drawer & Modal Handlers
30
- * - CRUD Operation Handlers
31
- * - Form Handlers (products, services, pricing)
32
- * - Calculation Handlers
33
- * - Pagination Handlers
34
- * - Search Handlers
35
- * - Table Actions (memoized)
36
- * - Return State
37
- * - Context Setup
38
- * - Provider Component
39
- * - Custom Hook
4
+ * This module provides comprehensive state management for the Quote feature using
5
+ * the createGenericModule factory pattern.
40
6
  */
41
7
  "use client";
42
8
  "use strict";
@@ -51,39 +17,6 @@ var __assign = (this && this.__assign) || function () {
51
17
  };
52
18
  return __assign.apply(this, arguments);
53
19
  };
54
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
55
- if (k2 === undefined) k2 = k;
56
- var desc = Object.getOwnPropertyDescriptor(m, k);
57
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
58
- desc = { enumerable: true, get: function() { return m[k]; } };
59
- }
60
- Object.defineProperty(o, k2, desc);
61
- }) : (function(o, m, k, k2) {
62
- if (k2 === undefined) k2 = k;
63
- o[k2] = m[k];
64
- }));
65
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
66
- Object.defineProperty(o, "default", { enumerable: true, value: v });
67
- }) : function(o, v) {
68
- o["default"] = v;
69
- });
70
- var __importStar = (this && this.__importStar) || (function () {
71
- var ownKeys = function(o) {
72
- ownKeys = Object.getOwnPropertyNames || function (o) {
73
- var ar = [];
74
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
75
- return ar;
76
- };
77
- return ownKeys(o);
78
- };
79
- return function (mod) {
80
- if (mod && mod.__esModule) return mod;
81
- var result = {};
82
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
83
- __setModuleDefault(result, mod);
84
- return result;
85
- };
86
- })();
87
20
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
88
21
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
89
22
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -129,34 +62,161 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
129
62
  }
130
63
  return to.concat(ar || Array.prototype.slice.call(from));
131
64
  };
65
+ var _a;
132
66
  Object.defineProperty(exports, "__esModule", { value: true });
133
- exports.useQuoteStateContext = exports.QuoteStateContextProvider = exports.QuoteStateContext = void 0;
134
- var react_1 = __importStar(require("react"));
67
+ exports.useQuoteModule = exports.initialQuoteState = exports.QUOTE_ACTION_TYPES = exports.quoteModuleConfig = exports.useQuoteContext = exports.QuoteProvider = exports.quoteReducer = void 0;
68
+ var react_1 = require("react");
69
+ var date_fns_1 = require("date-fns");
135
70
  var next_themes_1 = require("next-themes");
136
71
  var next_intl_1 = require("next-intl");
137
72
  var util_functions_1 = require("@react-pakistan/util-functions");
73
+ var generic_module_factory_1 = require("@react-pakistan/util-functions/factory/generic-module-factory");
74
+ var generic_component_factory_1 = require("@react-pakistan/util-functions/factory/generic-component-factory");
138
75
  var toast_utils_1 = require("@appcorp/shadcn/lib/toast-utils");
139
- var actions_1 = require("./actions");
76
+ // import { CompanyTypeBE } from "@appcorp/stellar-solutions-company-module/base-modules/company/types";
77
+ // import { CustomerTypeBE } from "@appcorp/stellar-solutions-company-module/base-modules/customer/types";
78
+ // import { ContactTypeBE } from "@appcorp/stellar-solutions-company-module/base-modules/contact/types";
79
+ // import { ProductTypeBE } from "@appcorp/stellar-solutions-product-module/base-modules/product/types";
80
+ // import { TaxTypeBE } from "@appcorp/stellar-solutions-modules/global-modules/preferences/types";
140
81
  var constants_1 = require("./constants");
141
- var reducer_1 = require("./reducer");
142
- var types_1 = require("./types");
82
+ // import {
83
+ // DISCOUNT_UNIT,
84
+ // INVOICE_MODE,
85
+ // INVOICE_STATUS,
86
+ // Product,
87
+ // QUOTE_INVOICE_CATEGORY,
88
+ // QUOTE_STATUS,
89
+ // QuoteInvoiceTypeBE,
90
+ // QuoteInvoiceTypeFE,
91
+ // Service,
92
+ // } from "../invoice/types";
93
+ var cache_1 = require("./cache");
143
94
  var validate_1 = require("./validate");
144
95
  var calculate_subtotal_1 = require("./calculate-subtotal");
145
96
  var calculate_total_1 = require("./calculate-total");
146
97
  var context_1 = require("@appcorp/stellar-solutions-modules/global-modules/tax/context");
147
98
  var context_2 = require("@appcorp/stellar-solutions-modules/global-modules/preferences/context");
148
99
  // ============================================================================
149
- // MAIN HOOK
100
+ // MODULE CONFIGURATION
101
+ // ============================================================================
102
+ var quoteConfig = {
103
+ name: "Quote",
104
+ displayName: "Quote",
105
+ initialState: {
106
+ // List Data
107
+ items: [],
108
+ count: 0,
109
+ // Search & Pagination
110
+ currentPage: 1,
111
+ pageLimit: constants_1.pageLimit,
112
+ searchQuery: "",
113
+ // UI State
114
+ disableSaveButton: false,
115
+ drawer: null,
116
+ quoteMode: null,
117
+ modal: null,
118
+ loading: true,
119
+ // Form Fields
120
+ afterDiscount: "0",
121
+ category: util_functions_1.QUOTE_INVOICE_CATEGORY.QUOTE,
122
+ companiesList: [],
123
+ companyId: "",
124
+ companyQuery: "",
125
+ contactsList: [],
126
+ countryQuery: "",
127
+ currency: "",
128
+ customerId: "",
129
+ date: new Date().toISOString(),
130
+ discount: "0",
131
+ discountUnit: util_functions_1.DISCOUNT_UNIT.FIXED_VALUE,
132
+ errors: {},
133
+ expiryDate: (0, date_fns_1.addDays)(new Date(), 7).toISOString(),
134
+ getProducts: [],
135
+ id: "",
136
+ invoiceStatus: util_functions_1.INVOICE_STATUS.UNPAID,
137
+ mode: "Create",
138
+ netTotal: "",
139
+ note: "",
140
+ payments: [],
141
+ products: [],
142
+ productQuery: "",
143
+ productsList: [
144
+ {
145
+ id: "",
146
+ mode: "Create",
147
+ price: "",
148
+ quantity: "1",
149
+ rowTotal: "",
150
+ },
151
+ ],
152
+ quoteStatus: util_functions_1.QUOTE_STATUS.DRAFT,
153
+ ref: "",
154
+ servicesList: [
155
+ {
156
+ description: "",
157
+ mode: "Create",
158
+ name: "",
159
+ price: "",
160
+ quantity: "1",
161
+ rowTotal: "",
162
+ },
163
+ ],
164
+ services: [],
165
+ subTotal: "",
166
+ tax: "",
167
+ taxQuery: "",
168
+ taxRate: "",
169
+ taxes: [],
170
+ total: "",
171
+ customer: {
172
+ address: "",
173
+ city: "",
174
+ country: "",
175
+ createdAt: "",
176
+ email: "",
177
+ firstName: "",
178
+ id: "",
179
+ lastName: "",
180
+ phone: "",
181
+ quotesInvoices: [],
182
+ updatedAt: "",
183
+ },
184
+ company: {
185
+ contacts: [],
186
+ country: "",
187
+ createdAt: "",
188
+ email: "",
189
+ id: "",
190
+ name: "",
191
+ phone: "",
192
+ quotesInvoices: [],
193
+ updatedAt: "",
194
+ website: "",
195
+ },
196
+ },
197
+ drawerTypes: __assign({}, generic_component_factory_1.DRAWER_TYPES),
198
+ };
199
+ // ============================================================================
200
+ // CREATE QUOTE MODULE
201
+ // ============================================================================
202
+ exports.quoteReducer = (_a = (0, generic_module_factory_1.createGenericModule)(quoteConfig), _a.reducer), exports.QuoteProvider = _a.Provider, exports.useQuoteContext = _a.useContext, exports.quoteModuleConfig = _a.config, exports.QUOTE_ACTION_TYPES = _a.actionTypes, exports.initialQuoteState = _a.initialState;
203
+ // ============================================================================
204
+ // ENHANCED QUOTE HOOK WITH API INTEGRATION
150
205
  // ============================================================================
151
- var useQuoteState = function () {
206
+ // interface StateProviderProps {
207
+ // children: ReactNode;
208
+ // }
209
+ var useQuoteModule = function () {
152
210
  var _a;
153
211
  // ---------------------------------------------------------------------------
154
- // State & Core Hooks
212
+ // State via factory context
155
213
  // ---------------------------------------------------------------------------
156
- var _b = (0, react_1.useReducer)(reducer_1.quoteReducer, reducer_1.initialQuoteState), state = _b[0], dispatch = _b[1];
214
+ var context = (0, exports.useQuoteContext)();
215
+ var state = context.state;
157
216
  var t = (0, next_intl_1.useTranslations)("quote");
158
217
  var theme = (0, next_themes_1.useTheme)().theme;
159
- var taxes = (0, context_1.useTaxStateContext)().taxes;
218
+ var taxModule = (0, context_1.useTaxModule)();
219
+ var taxes = taxModule.state.items;
160
220
  var currencies = (0, context_2.usePreferenceStateContext)().currencies;
161
221
  // ---------------------------------------------------------------------------
162
222
  // Toast Helpers
@@ -199,10 +259,10 @@ var useQuoteState = function () {
199
259
  })[0];
200
260
  }, [currencies]);
201
261
  // ---------------------------------------------------------------------------
202
- // API PARAMETERS
262
+ // API Parameters
203
263
  // ---------------------------------------------------------------------------
204
264
  var listParams = (0, react_1.useMemo)(function () { return ({
205
- category: types_1.QUOTE_INVOICE_CATEGORY.QUOTE,
265
+ category: util_functions_1.QUOTE_INVOICE_CATEGORY.QUOTE,
206
266
  currentPage: state.currentPage,
207
267
  includeCompany: true,
208
268
  includeCustomer: true,
@@ -216,11 +276,10 @@ var useQuoteState = function () {
216
276
  companyId: state.companyId,
217
277
  currency: state.currency,
218
278
  customerId: state.customerId,
219
- date: state.date,
220
- discount: (_a = state === null || state === void 0 ? void 0 : state.discount) === null || _a === void 0 ? void 0 : _a.trim(),
279
+ date: new Date(state.date),
280
+ discount: Number((_a = state === null || state === void 0 ? void 0 : state.discount) === null || _a === void 0 ? void 0 : _a.trim()),
221
281
  discountUnit: state.discountUnit,
222
- drawer: state.drawer,
223
- expiryDate: state.expiryDate,
282
+ expiryDate: new Date(state.expiryDate),
224
283
  id: state.id,
225
284
  invoiceStatus: state.invoiceStatus,
226
285
  mode: state.mode,
@@ -235,9 +294,9 @@ var useQuoteState = function () {
235
294
  var name = _a.name;
236
295
  return name;
237
296
  }),
238
- subTotal: state.subTotal,
239
- taxRate: state.taxRate,
240
- total: state.total,
297
+ subTotal: Number(state.subTotal),
298
+ taxRate: Number(state.taxRate),
299
+ total: Number(state.total),
241
300
  phone: (_b = state.customer) === null || _b === void 0 ? void 0 : _b.phone,
242
301
  firstName: (_c = state.customer) === null || _c === void 0 ? void 0 : _c.firstName,
243
302
  lastName: (_d = state.customer) === null || _d === void 0 ? void 0 : _d.lastName,
@@ -250,22 +309,19 @@ var useQuoteState = function () {
250
309
  var byIdParams = (0, react_1.useMemo)(function () { return ({ id: state.id }); }, [state.id]);
251
310
  var deleteParams = (0, react_1.useMemo)(function () { return ({ id: state.id }); }, [state.id]);
252
311
  // ---------------------------------------------------------------------------
253
- // API CALLBACKS
312
+ // API Callbacks
254
313
  // ---------------------------------------------------------------------------
255
314
  var listCallback = (0, react_1.useCallback)(function (_a) {
315
+ var _b;
256
316
  var data = _a.data, error = _a.error;
257
317
  if (error) {
258
318
  showErrorToast(t("messagesNetworkError"));
259
319
  return;
260
320
  }
261
321
  if (data === null || data === void 0 ? void 0 : data.items) {
262
- dispatch({
263
- type: actions_1.QUOTE_ACTION_TYPES.SET_QUOTES,
264
- payload: { quotes: data.items },
265
- });
266
- dispatch({
267
- type: actions_1.QUOTE_ACTION_TYPES.SET_COUNT,
268
- payload: { count: data === null || data === void 0 ? void 0 : data.count },
322
+ context.dispatch({
323
+ type: exports.QUOTE_ACTION_TYPES.SET_ITEMS,
324
+ payload: { items: data.items, count: (_b = data === null || data === void 0 ? void 0 : data.count) !== null && _b !== void 0 ? _b : 0 },
269
325
  });
270
326
  }
271
327
  }, [t, showErrorToast]);
@@ -276,14 +332,18 @@ var useQuoteState = function () {
276
332
  return;
277
333
  }
278
334
  if (data) {
335
+ (0, cache_1.invalidateQuotesCache)();
279
336
  showSuccessToast(state.mode === "Edit"
280
337
  ? t("messagesQuoteUpdated")
281
338
  : t("messagesQuoteCreated"));
282
- dispatch({ type: actions_1.QUOTE_ACTION_TYPES.RESET_FORM });
283
- dispatch({ type: actions_1.QUOTE_ACTION_TYPES.RESET_ERRORS });
339
+ context.dispatch({ type: exports.QUOTE_ACTION_TYPES.RESET_FORM });
340
+ context.dispatch({
341
+ type: exports.QUOTE_ACTION_TYPES.SET_ERRORS,
342
+ payload: { errors: {} },
343
+ });
284
344
  listFetchNow();
285
- dispatch({
286
- type: actions_1.QUOTE_ACTION_TYPES.SET_DRAWER,
345
+ context.dispatch({
346
+ type: exports.QUOTE_ACTION_TYPES.SET_DRAWER,
287
347
  payload: { drawer: null },
288
348
  });
289
349
  }
@@ -291,7 +351,7 @@ var useQuoteState = function () {
291
351
  // eslint-disable-next-line react-hooks/exhaustive-deps
292
352
  [t, state.mode, showErrorToast, showSuccessToast]);
293
353
  var byIdCallback = (0, react_1.useCallback)(function (_a) {
294
- var _b, _c, _d, _e, _f;
354
+ var _b, _c, _d;
295
355
  var data = _a.data, error = _a.error;
296
356
  if (error) {
297
357
  showErrorToast(t("messagesQuoteFetchError"));
@@ -306,39 +366,53 @@ var useQuoteState = function () {
306
366
  var _a, _b;
307
367
  return (__assign(__assign({}, item), { price: (_a = item === null || item === void 0 ? void 0 : item.product) === null || _a === void 0 ? void 0 : _a.salePrice, id: item === null || item === void 0 ? void 0 : item.productId, quantity: item === null || item === void 0 ? void 0 : item.quantity, rowTotal: parseFloat((_b = item === null || item === void 0 ? void 0 : item.product) === null || _b === void 0 ? void 0 : _b.salePrice) * parseInt(item.quantity) }));
308
368
  });
309
- var updatedData = __assign(__assign(__assign(__assign({}, data), { mode: "Edit", companyId: (data === null || data === void 0 ? void 0 : data.companyId) || "", customerId: (data === null || data === void 0 ? void 0 : data.customerId) || "" }), (((_b = data === null || data === void 0 ? void 0 : data.customer) === null || _b === void 0 ? void 0 : _b.id) && {
369
+ // Normalize currency: API may return currency id or code. Store id in state.
370
+ var normalizedCurrency_1 = data.currency;
371
+ if (normalizedCurrency_1) {
372
+ var foundById = currencies.find(function (_a) {
373
+ var id = _a.id;
374
+ return id === normalizedCurrency_1;
375
+ });
376
+ if (!foundById) {
377
+ var foundByCode = currencies.find(function (_a) {
378
+ var code = _a.code;
379
+ return code === normalizedCurrency_1;
380
+ });
381
+ if (foundByCode)
382
+ normalizedCurrency_1 = foundByCode.id;
383
+ }
384
+ }
385
+ var updatedData = __assign(__assign(__assign(__assign(__assign({}, data), (normalizedCurrency_1 && { currency: normalizedCurrency_1 })), { mode: "Edit", companyId: (data === null || data === void 0 ? void 0 : data.companyId) || "", customerId: (data === null || data === void 0 ? void 0 : data.customerId) || "" }), (((_b = data === null || data === void 0 ? void 0 : data.customer) === null || _b === void 0 ? void 0 : _b.id) && {
310
386
  customer: __assign({}, data.customer),
311
387
  })), { servicesList: __spreadArray([], updatedServices, true).filter(function (item) { return item.name; }), productsList: __spreadArray([], updatedProducts, true).filter(function (item) { return item.id; }), companiesList: [__assign({}, data.company)] });
388
+ context.dispatch({
389
+ type: exports.QUOTE_ACTION_TYPES.SET_FORM_DATA,
390
+ payload: { form: updatedData },
391
+ });
312
392
  if ((_c = updatedData === null || updatedData === void 0 ? void 0 : updatedData.company) === null || _c === void 0 ? void 0 : _c.name) {
313
- dispatch({
314
- type: actions_1.QUOTE_ACTION_TYPES.SET_DRAWER,
315
- payload: { drawer: types_1.QUOTE_DRAWER.QUOTE_COMPANY_FORM_DRAWER },
393
+ context.dispatch({
394
+ type: exports.QUOTE_ACTION_TYPES.SET_DRAWER,
395
+ payload: { drawer: generic_component_factory_1.DRAWER_TYPES.FORM_DRAWER },
316
396
  });
317
- }
318
- if ((_d = updatedData === null || updatedData === void 0 ? void 0 : updatedData.customer) === null || _d === void 0 ? void 0 : _d.firstName) {
319
- dispatch({
320
- type: actions_1.QUOTE_ACTION_TYPES.SET_DRAWER,
321
- payload: { drawer: types_1.QUOTE_DRAWER.QUOTE_CUSTOMER_FORM_DRAWER },
397
+ context.dispatch({
398
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
399
+ payload: { key: "quoteMode", value: "INVOICE_MODE.COMPANY" },
322
400
  });
323
401
  }
324
- dispatch({
325
- type: actions_1.QUOTE_ACTION_TYPES.SET_FORM,
326
- payload: { form: updatedData },
327
- });
328
- if ((_e = updatedData === null || updatedData === void 0 ? void 0 : updatedData.company) === null || _e === void 0 ? void 0 : _e.name) {
329
- dispatch({
330
- type: actions_1.QUOTE_ACTION_TYPES.SET_DRAWER,
331
- payload: { drawer: types_1.QUOTE_DRAWER.QUOTE_COMPANY_FORM_DRAWER },
402
+ if ((_d = updatedData === null || updatedData === void 0 ? void 0 : updatedData.customer) === null || _d === void 0 ? void 0 : _d.firstName) {
403
+ context.dispatch({
404
+ type: exports.QUOTE_ACTION_TYPES.SET_DRAWER,
405
+ payload: { drawer: generic_component_factory_1.DRAWER_TYPES.FORM_DRAWER },
332
406
  });
333
- }
334
- if ((_f = updatedData === null || updatedData === void 0 ? void 0 : updatedData.customer) === null || _f === void 0 ? void 0 : _f.firstName) {
335
- dispatch({
336
- type: actions_1.QUOTE_ACTION_TYPES.SET_DRAWER,
337
- payload: { drawer: types_1.QUOTE_DRAWER.QUOTE_CUSTOMER_FORM_DRAWER },
407
+ context.dispatch({
408
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
409
+ payload: { key: "quoteMode", value: "INVOICE_MODE.CUSTOMER" },
338
410
  });
339
411
  }
340
412
  }
341
- }, [t, showErrorToast]);
413
+ },
414
+ // eslint-disable-next-line react-hooks/exhaustive-deps
415
+ [t, showErrorToast, currencies]);
342
416
  var deleteCallback = (0, react_1.useCallback)(function (_a) {
343
417
  var data = _a.data, error = _a.error;
344
418
  if (error) {
@@ -346,8 +420,9 @@ var useQuoteState = function () {
346
420
  return;
347
421
  }
348
422
  if (data) {
423
+ (0, cache_1.invalidateQuotesCache)();
349
424
  showSuccessToast(t("messagesQuoteDeleted"));
350
- dispatch({ type: actions_1.QUOTE_ACTION_TYPES.RESET_FORM });
425
+ context.dispatch({ type: exports.QUOTE_ACTION_TYPES.RESET_FORM });
351
426
  listFetchNow();
352
427
  }
353
428
  },
@@ -356,7 +431,7 @@ var useQuoteState = function () {
356
431
  // ---------------------------------------------------------------------------
357
432
  // Module Entity Hook
358
433
  // ---------------------------------------------------------------------------
359
- var _c = (0, util_functions_1.useModuleEntity)({
434
+ var _b = (0, util_functions_1.useModuleEntityV2)({
360
435
  byIdCallback: byIdCallback,
361
436
  byIdParams: byIdParams,
362
437
  deleteCallback: deleteCallback,
@@ -368,13 +443,37 @@ var useQuoteState = function () {
368
443
  unitByIdUrl: constants_1.QUOTE_API_ROUTES.QUOTE_BY_ID,
369
444
  unitUrl: constants_1.QUOTE_API_ROUTES.QUOTE,
370
445
  updateCallback: updateCallback,
371
- updateDeps: [state],
372
- listDeps: [debouncedQuery, state.currentPage, state.pageLimit],
373
446
  updateParams: __assign(__assign({}, updateParams), { mode: "Create" }),
374
- }), byIdError = _c.byIdError, byIdFetchNow = _c.byIdFetchNow, byIdLoading = _c.byIdLoading, deleteError = _c.deleteError, deleteFetchNow = _c.deleteFetchNow, deleteLoading = _c.deleteLoading, listError = _c.listError, listFetchNow = _c.listFetchNow, listLoading = _c.listLoading, updateError = _c.updateError, updateFetchNow = _c.updateFetchNow, updateLoading = _c.updateLoading;
447
+ }), byIdError = _b.byIdError, byIdFetchNow = _b.byIdFetchNow, byIdLoading = _b.byIdLoading, deleteError = _b.deleteError, deleteFetchNow = _b.deleteFetchNow, deleteLoading = _b.deleteLoading, listError = _b.listError, listFetchNow = _b.listFetchNow, listLoading = _b.listLoading, updateError = _b.updateError, updateFetchNow = _b.updateFetchNow, updateLoading = _b.updateLoading;
375
448
  // ---------------------------------------------------------------------------
376
449
  // Effects
377
450
  // ---------------------------------------------------------------------------
451
+ (0, react_1.useEffect)(function () {
452
+ (function () { return __awaiter(void 0, void 0, void 0, function () {
453
+ var _a, count, items, _b;
454
+ return __generator(this, function (_c) {
455
+ switch (_c.label) {
456
+ case 0:
457
+ _c.trys.push([0, 2, , 3]);
458
+ return [4 /*yield*/, (0, cache_1.getCachedQuotes)({
459
+ params: listParams,
460
+ })];
461
+ case 1:
462
+ _a = _c.sent(), count = _a.count, items = _a.items;
463
+ context.dispatch({
464
+ type: exports.QUOTE_ACTION_TYPES.SET_ITEMS,
465
+ payload: { items: items || [], count: count || 0 },
466
+ });
467
+ return [3 /*break*/, 3];
468
+ case 2:
469
+ _b = _c.sent();
470
+ showErrorToast(t("messagesNetworkError"));
471
+ return [3 /*break*/, 3];
472
+ case 3: return [2 /*return*/];
473
+ }
474
+ });
475
+ }); })();
476
+ }, [listParams]); // eslint-disable-line react-hooks/exhaustive-deps
378
477
  (0, react_1.useEffect)(function () {
379
478
  listFetchNow();
380
479
  // eslint-disable-next-line
@@ -396,19 +495,18 @@ var useQuoteState = function () {
396
495
  case 1:
397
496
  data = (_a.sent()).data;
398
497
  if (data === null || data === void 0 ? void 0 : data.items) {
399
- dispatch({
400
- type: actions_1.QUOTE_ACTION_TYPES.SET_PRODUCTS_LIST,
401
- payload: { list: data.items },
498
+ context.dispatch({
499
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
500
+ payload: { key: "getProducts", value: data.items },
402
501
  });
403
502
  }
404
503
  return [2 /*return*/];
405
504
  }
406
505
  });
407
506
  }); })();
408
- }, [debouncedProductList]);
507
+ }, [debouncedProductList]); // eslint-disable-line react-hooks/exhaustive-deps
409
508
  (0, react_1.useEffect)(function () {
410
- if (state.drawer === types_1.QUOTE_DRAWER.QUOTE_CUSTOMER_FORM_DRAWER &&
411
- debouncedCustomer) {
509
+ if (state.quoteMode === "INVOICE_MODE.CUSTOMER" && debouncedCustomer) {
412
510
  (function () { return __awaiter(void 0, void 0, void 0, function () {
413
511
  var data;
414
512
  return __generator(this, function (_a) {
@@ -423,9 +521,16 @@ var useQuoteState = function () {
423
521
  case 1:
424
522
  data = (_a.sent()).data;
425
523
  if (data) {
426
- dispatch({
427
- type: actions_1.QUOTE_ACTION_TYPES.SET_CUSTOMER,
428
- payload: { customer: __assign({}, data), customerId: data.id },
524
+ context.dispatch({
525
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
526
+ payload: {
527
+ key: "customer",
528
+ value: __assign(__assign({}, state.customer), data),
529
+ },
530
+ });
531
+ context.dispatch({
532
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
533
+ payload: { key: "customerId", value: data.id },
429
534
  });
430
535
  }
431
536
  return [2 /*return*/];
@@ -433,10 +538,9 @@ var useQuoteState = function () {
433
538
  });
434
539
  }); })();
435
540
  }
436
- }, [debouncedCustomer, state.drawer]);
541
+ }, [debouncedCustomer, state.drawer]); // eslint-disable-line react-hooks/exhaustive-deps
437
542
  (0, react_1.useEffect)(function () {
438
- if (state.drawer === types_1.QUOTE_DRAWER.QUOTE_COMPANY_FORM_DRAWER &&
439
- debouncedCompanyList) {
543
+ if (state.quoteMode === "INVOICE_MODE.COMPANY" && debouncedCompanyList) {
440
544
  (function () { return __awaiter(void 0, void 0, void 0, function () {
441
545
  var data;
442
546
  return __generator(this, function (_a) {
@@ -453,9 +557,9 @@ var useQuoteState = function () {
453
557
  case 1:
454
558
  data = (_a.sent()).data;
455
559
  if (data === null || data === void 0 ? void 0 : data.items) {
456
- dispatch({
457
- type: actions_1.QUOTE_ACTION_TYPES.SET_COMPANIES_LIST,
458
- payload: { companiesList: data.items },
560
+ context.dispatch({
561
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
562
+ payload: { key: "companiesList", value: data.items },
459
563
  });
460
564
  }
461
565
  return [2 /*return*/];
@@ -463,7 +567,7 @@ var useQuoteState = function () {
463
567
  });
464
568
  }); })();
465
569
  }
466
- }, [debouncedCompanyList, state.drawer]);
570
+ }, [debouncedCompanyList, state.drawer]); // eslint-disable-line react-hooks/exhaustive-deps
467
571
  (0, react_1.useEffect)(function () {
468
572
  (function () { return __awaiter(void 0, void 0, void 0, function () {
469
573
  var data;
@@ -483,9 +587,9 @@ var useQuoteState = function () {
483
587
  case 1:
484
588
  data = (_a.sent()).data;
485
589
  if (data.items) {
486
- dispatch({
487
- type: actions_1.QUOTE_ACTION_TYPES.SET_TAXES,
488
- payload: { taxes: data.items },
590
+ context.dispatch({
591
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
592
+ payload: { key: "taxes", value: data.items },
489
593
  });
490
594
  }
491
595
  _a.label = 2;
@@ -493,25 +597,22 @@ var useQuoteState = function () {
493
597
  }
494
598
  });
495
599
  }); })();
496
- }, [debouncedTaxList]);
600
+ }, [debouncedTaxList]); // eslint-disable-line react-hooks/exhaustive-deps
497
601
  (0, react_1.useEffect)(function () {
498
602
  var _a = (0, calculate_total_1.calculateTotal)(state.subTotal, state.taxRate, state.discountUnit, state.discount || "0"), afterDiscount = _a.afterDiscount, tax = _a.tax, total = _a.total;
499
- dispatch({
500
- type: actions_1.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
501
- payload: {
502
- key: "total",
503
- value: total,
504
- },
603
+ context.dispatch({
604
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
605
+ payload: { key: "total", value: total },
505
606
  });
506
- dispatch({
507
- type: actions_1.QUOTE_ACTION_TYPES.SET_TAX,
508
- payload: { tax: tax },
607
+ context.dispatch({
608
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
609
+ payload: { key: "tax", value: tax },
509
610
  });
510
- dispatch({
511
- type: actions_1.QUOTE_ACTION_TYPES.SET_AFTER_DISCOUNT,
512
- payload: { afterDiscount: String(afterDiscount) },
611
+ context.dispatch({
612
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
613
+ payload: { key: "afterDiscount", value: String(afterDiscount) },
513
614
  });
514
- }, [state.discountUnit, state.discount, state.subTotal, state.taxRate]);
615
+ }, [state.discountUnit, state.discount, state.subTotal, state.taxRate]); // eslint-disable-line react-hooks/exhaustive-deps
515
616
  // ---------------------------------------------------------------------------
516
617
  // Item Management Handlers
517
618
  // ---------------------------------------------------------------------------
@@ -524,11 +625,11 @@ var useQuoteState = function () {
524
625
  price: "",
525
626
  rowTotal: "",
526
627
  };
527
- dispatch({
528
- type: actions_1.QUOTE_ACTION_TYPES.ADD_ITEM_SERVICE,
529
- payload: { servicesList: __spreadArray(__spreadArray([], state.servicesList, true), [newItem], false) },
628
+ context.dispatch({
629
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
630
+ payload: { key: "servicesList", value: __spreadArray(__spreadArray([], state.servicesList, true), [newItem], false) },
530
631
  });
531
- }, [state.servicesList]);
632
+ }, [context, state.servicesList]);
532
633
  var handleAddItemProduct = (0, react_1.useCallback)(function () {
533
634
  var newItem = {
534
635
  id: "",
@@ -537,17 +638,17 @@ var useQuoteState = function () {
537
638
  quantity: "1",
538
639
  rowTotal: "",
539
640
  };
540
- dispatch({
541
- type: actions_1.QUOTE_ACTION_TYPES.ADD_ITEM_PRODUCT,
542
- payload: { productsList: __spreadArray(__spreadArray([], state.productsList, true), [newItem], false) },
641
+ context.dispatch({
642
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
643
+ payload: { key: "productsList", value: __spreadArray(__spreadArray([], state.productsList, true), [newItem], false) },
543
644
  });
544
- }, [state.productsList]);
645
+ }, [context, state.productsList]);
545
646
  // ---------------------------------------------------------------------------
546
647
  // Drawer & Modal Handlers
547
648
  // ---------------------------------------------------------------------------
548
649
  var handleCreate = (0, react_1.useCallback)(function (text) {
549
- dispatch({
550
- type: actions_1.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
650
+ context.dispatch({
651
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
551
652
  payload: {
552
653
  key: "ref",
553
654
  value: (0, util_functions_1.generateRef)({
@@ -555,26 +656,28 @@ var useQuoteState = function () {
555
656
  }),
556
657
  },
557
658
  });
558
- if (text === "company") {
559
- dispatch({
560
- type: actions_1.QUOTE_ACTION_TYPES.SET_DRAWER,
561
- payload: { drawer: types_1.QUOTE_DRAWER.QUOTE_COMPANY_FORM_DRAWER },
562
- });
563
- }
564
- if (text === "customer") {
565
- dispatch({
566
- type: actions_1.QUOTE_ACTION_TYPES.SET_DRAWER,
567
- payload: { drawer: types_1.QUOTE_DRAWER.QUOTE_CUSTOMER_FORM_DRAWER },
568
- });
569
- }
570
- }, []);
659
+ context.dispatch({
660
+ type: exports.QUOTE_ACTION_TYPES.SET_DRAWER,
661
+ payload: { drawer: generic_component_factory_1.DRAWER_TYPES.FORM_DRAWER },
662
+ });
663
+ context.dispatch({
664
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
665
+ payload: {
666
+ key: "quoteMode",
667
+ value: text === "company"
668
+ ? "INVOICE_MODE.COMPANY"
669
+ : "INVOICE_MODE.CUSTOMER",
670
+ },
671
+ });
672
+ }, [context]);
571
673
  // ---------------------------------------------------------------------------
572
674
  // CRUD Operation Handlers
573
675
  // ---------------------------------------------------------------------------
574
- var handleEdit = (0, react_1.useCallback)(function (id) {
575
- byIdFetchNow(undefined, {
676
+ var handleEdit = (0, react_1.useCallback)(function (row) {
677
+ var record = row;
678
+ byIdFetchNow === null || byIdFetchNow === void 0 ? void 0 : byIdFetchNow(undefined, {
679
+ params: { id: record === null || record === void 0 ? void 0 : record.id },
576
680
  body: JSON.stringify({
577
- id: id,
578
681
  includeCompany: true,
579
682
  includeCustomer: true,
580
683
  includePayments: true,
@@ -584,43 +687,58 @@ var useQuoteState = function () {
584
687
  });
585
688
  // eslint-disable-next-line react-hooks/exhaustive-deps
586
689
  }, []);
587
- var handleDelete = (0, react_1.useCallback)(function (id) {
588
- deleteFetchNow === null || deleteFetchNow === void 0 ? void 0 : deleteFetchNow(undefined, {
589
- body: JSON.stringify({ id: id }),
690
+ var handleView = (0, react_1.useCallback)(function (row) {
691
+ var record = row;
692
+ byIdFetchNow === null || byIdFetchNow === void 0 ? void 0 : byIdFetchNow(undefined, {
693
+ params: { id: record === null || record === void 0 ? void 0 : record.id },
694
+ body: JSON.stringify({
695
+ includeCompany: true,
696
+ includeCustomer: true,
697
+ includePayments: true,
698
+ includeProducts: true,
699
+ includeServices: true,
700
+ }),
590
701
  });
591
702
  // eslint-disable-next-line react-hooks/exhaustive-deps
592
703
  }, []);
704
+ var handleDelete = (0, react_1.useCallback)(function (row) {
705
+ var record = row;
706
+ deleteFetchNow === null || deleteFetchNow === void 0 ? void 0 : deleteFetchNow(undefined, { params: { id: record === null || record === void 0 ? void 0 : record.id } });
707
+ // eslint-disable-next-line react-hooks/exhaustive-deps
708
+ }, []);
593
709
  // ---------------------------------------------------------------------------
594
710
  // Form Submission Handler
595
711
  // ---------------------------------------------------------------------------
596
712
  var handleSubmit = (0, react_1.useCallback)(function () {
597
713
  if (!state.servicesList[0].name && !state.productsList[0].id) {
598
- dispatch({
599
- type: actions_1.QUOTE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
714
+ context.dispatch({
715
+ type: exports.QUOTE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
600
716
  payload: { disableSaveButton: true },
601
717
  });
602
718
  return;
603
719
  }
604
- dispatch({
605
- type: actions_1.QUOTE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
720
+ context.dispatch({
721
+ type: exports.QUOTE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
606
722
  payload: { disableSaveButton: true },
607
723
  });
608
724
  (0, util_functions_1.validateForm)({
609
- params: __assign(__assign({}, updateParams), { currency: updateParams.currency || defaultCurrency.code, taxRate: updateParams.taxRate || defaultTax.taxRate }),
725
+ params: __assign(__assign({}, updateParams), { quoteMode: state.quoteMode, currency: updateParams.currency || defaultCurrency.id, taxRate: updateParams.taxRate || defaultTax.taxRate }),
610
726
  schema: validate_1.formValid,
611
727
  successCallback: function () {
612
728
  updateFetchNow(undefined, {
613
- body: JSON.stringify(__assign(__assign({}, updateParams), { products: state.productsList.filter(function (item) { return item.id; }), services: state.servicesList.filter(function (item) { return item.name; }), currency: updateParams.currency || defaultCurrency.code, taxRate: updateParams.taxRate || defaultTax.taxRate })),
729
+ body: JSON.stringify(__assign(__assign({}, updateParams), { products: state.productsList.filter(function (item) { return item.id; }), services: state.servicesList.filter(function (item) { return item.name; }), currency: updateParams.currency || defaultCurrency.id, taxRate: updateParams.taxRate || defaultTax.taxRate })),
614
730
  });
615
731
  },
616
732
  errorCallback: function (e) {
617
- dispatch({
618
- type: actions_1.QUOTE_ACTION_TYPES.SET_ERRORS,
733
+ context.dispatch({
734
+ type: exports.QUOTE_ACTION_TYPES.SET_ERRORS,
619
735
  payload: { errors: e },
620
736
  });
621
737
  },
622
738
  });
739
+ // eslint-disable-next-line react-hooks/exhaustive-deps
623
740
  }, [
741
+ context,
624
742
  updateFetchNow,
625
743
  updateParams,
626
744
  defaultCurrency,
@@ -633,44 +751,44 @@ var useQuoteState = function () {
633
751
  // ---------------------------------------------------------------------------
634
752
  var handleChange = (0, react_1.useCallback)(function (key, value) {
635
753
  if (key === "companyQuery") {
636
- dispatch({
637
- type: actions_1.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
754
+ context.dispatch({
755
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
638
756
  payload: { key: key, value: value },
639
757
  });
640
758
  return;
641
759
  }
642
760
  if (key === "taxRate") {
643
- dispatch({
644
- type: actions_1.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
761
+ context.dispatch({
762
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
645
763
  payload: { key: key, value: Number(value) },
646
764
  });
647
765
  return;
648
766
  }
649
767
  if (key === "discountUnit") {
650
- dispatch({
651
- type: actions_1.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
768
+ context.dispatch({
769
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
652
770
  payload: { key: key, value: value },
653
771
  });
654
772
  return;
655
773
  }
656
- // Dispatch the input field change
657
- dispatch({
658
- type: actions_1.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
774
+ context.dispatch({
775
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
659
776
  payload: { key: key, value: value },
660
777
  });
661
- dispatch({
662
- type: actions_1.QUOTE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
778
+ context.dispatch({
779
+ type: exports.QUOTE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
663
780
  payload: { disableSaveButton: false },
664
781
  });
665
- dispatch({
666
- type: actions_1.QUOTE_ACTION_TYPES.RESET_ERRORS,
782
+ context.dispatch({
783
+ type: exports.QUOTE_ACTION_TYPES.SET_ERRORS,
784
+ payload: { errors: {} },
667
785
  });
668
- }, []);
786
+ }, [context]);
669
787
  var handleItemChangeServices = (0, react_1.useCallback)(function (_a) {
670
788
  var _b;
671
789
  var index = _a.index, key = _a.key, value = _a.value;
672
- dispatch({
673
- type: actions_1.QUOTE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
790
+ context.dispatch({
791
+ type: exports.QUOTE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
674
792
  payload: { disableSaveButton: false },
675
793
  });
676
794
  var updatedItems = __spreadArray([], state.servicesList, true);
@@ -681,21 +799,21 @@ var useQuoteState = function () {
681
799
  updatedItems[index].rowTotal = rowTotal;
682
800
  var allProducts = state.productsList;
683
801
  var subtotal = (0, calculate_subtotal_1.calculateSubtotal)(updatedItems, allProducts);
684
- dispatch({
685
- type: actions_1.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
802
+ context.dispatch({
803
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
686
804
  payload: { key: "subTotal", value: subtotal },
687
805
  });
688
- dispatch({
689
- type: actions_1.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
806
+ context.dispatch({
807
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
690
808
  payload: { key: "servicesList", value: updatedItems },
691
809
  });
692
- }, [state.productsList, state.servicesList]);
810
+ }, [context, state.productsList, state.servicesList]);
693
811
  var handleItemChangeProducts = (0, react_1.useCallback)(function (_a) {
694
812
  var _b, _c, _d;
695
813
  var _e;
696
814
  var index = _a.index, key = _a.key, value = _a.value;
697
- dispatch({
698
- type: actions_1.QUOTE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
815
+ context.dispatch({
816
+ type: exports.QUOTE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
699
817
  payload: { disableSaveButton: false },
700
818
  });
701
819
  var updatedItems = __spreadArray([], state.productsList, true);
@@ -703,12 +821,13 @@ var useQuoteState = function () {
703
821
  var matchingProduct = (_e = state.getProducts) === null || _e === void 0 ? void 0 : _e.find(function (product) { return product.id === value; });
704
822
  if (matchingProduct) {
705
823
  var quantity = parseFloat(String(updatedItems[index].quantity)) || 0;
706
- var rowTotal = (quantity * parseFloat(matchingProduct.salePrice)).toFixed(2);
707
- updatedItems[index] = __assign(__assign({}, updatedItems[index]), (_b = {}, _b[key] = value, _b.price = matchingProduct.salePrice, _b.mode = updatedItems[index].mode === "Create" ? "Create" : "Edit", _b.rowTotal = rowTotal, _b));
824
+ var rowTotal = (quantity *
825
+ parseFloat(String(matchingProduct.price))).toFixed(2);
826
+ updatedItems[index] = __assign(__assign({}, updatedItems[index]), (_b = {}, _b[key] = value, _b.price = String(matchingProduct.price), _b.mode = updatedItems[index].mode === "Create" ? "Create" : "Edit", _b.rowTotal = rowTotal, _b));
708
827
  var allServices = state.servicesList;
709
828
  var subtotal = (0, calculate_subtotal_1.calculateSubtotal)(allServices, updatedItems);
710
- dispatch({
711
- type: actions_1.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
829
+ context.dispatch({
830
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
712
831
  payload: { key: "subTotal", value: subtotal },
713
832
  });
714
833
  }
@@ -724,98 +843,106 @@ var useQuoteState = function () {
724
843
  updatedItems[index] = __assign(__assign({}, updatedItems[index]), { rowTotal: rowTotal });
725
844
  var allServices = state.servicesList;
726
845
  var subtotal = (0, calculate_subtotal_1.calculateSubtotal)(allServices, updatedItems);
727
- dispatch({
728
- type: actions_1.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
846
+ context.dispatch({
847
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
729
848
  payload: { key: "subTotal", value: subtotal },
730
849
  });
731
850
  }
732
- dispatch({
733
- type: actions_1.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
851
+ context.dispatch({
852
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
734
853
  payload: { key: "productsList", value: updatedItems },
735
854
  });
736
- }, [state.servicesList, state.productsList, state.getProducts]);
855
+ }, [context, state.servicesList, state.productsList, state.getProducts]);
737
856
  // ---------------------------------------------------------------------------
738
- // PAGINATION HANDLERS
857
+ // Pagination Handlers
739
858
  // ---------------------------------------------------------------------------
740
859
  var handleNextClick = (0, react_1.useCallback)(function () {
741
- dispatch({
742
- type: actions_1.QUOTE_ACTION_TYPES.SET_CURRENT_PAGE,
860
+ context.dispatch({
861
+ type: exports.QUOTE_ACTION_TYPES.SET_CURRENT_PAGE,
743
862
  payload: { currentPage: state.currentPage + 1 },
744
863
  });
745
- }, [state.currentPage]);
864
+ }, [context, state.currentPage]);
746
865
  var handlePreviousClick = (0, react_1.useCallback)(function () {
747
- dispatch({
748
- type: actions_1.QUOTE_ACTION_TYPES.SET_CURRENT_PAGE,
866
+ context.dispatch({
867
+ type: exports.QUOTE_ACTION_TYPES.SET_CURRENT_PAGE,
749
868
  payload: { currentPage: state.currentPage - 1 },
750
869
  });
751
- }, [state.currentPage]);
870
+ }, [context, state.currentPage]);
752
871
  var handlePageLimit = (0, react_1.useCallback)(function (k, value) {
753
872
  var val = __assign({}, value);
754
- dispatch({
755
- type: actions_1.QUOTE_ACTION_TYPES.SET_PAGE_LIMIT,
873
+ context.dispatch({
874
+ type: exports.QUOTE_ACTION_TYPES.SET_PAGE_LIMIT,
756
875
  payload: { pageLimit: Number(val.option) },
757
876
  });
758
- // Reset to page 1 when page limit changes
759
- dispatch({
760
- type: actions_1.QUOTE_ACTION_TYPES.SET_CURRENT_PAGE,
877
+ context.dispatch({
878
+ type: exports.QUOTE_ACTION_TYPES.SET_CURRENT_PAGE,
761
879
  payload: { currentPage: 1 },
762
880
  });
763
- }, []);
881
+ }, [context]);
764
882
  var searchOnChange = (0, react_1.useCallback)(function (k, v) {
765
- dispatch({
766
- type: actions_1.QUOTE_ACTION_TYPES.SET_SEARCH_QUERY,
883
+ context.dispatch({
884
+ type: exports.QUOTE_ACTION_TYPES.SET_SEARCH_QUERY,
767
885
  payload: { searchQuery: v },
768
886
  });
769
- }, []);
887
+ }, [context]);
770
888
  var clearSearch = (0, react_1.useCallback)(function () {
771
- dispatch({
772
- type: actions_1.QUOTE_ACTION_TYPES.SET_SEARCH_QUERY,
889
+ context.dispatch({
890
+ type: exports.QUOTE_ACTION_TYPES.SET_SEARCH_QUERY,
773
891
  payload: { searchQuery: "" },
774
892
  });
775
- }, []);
893
+ }, [context]);
776
894
  // ---------------------------------------------------------------------------
777
- // SEARCH HANDLERS
895
+ // Search Handlers
778
896
  // ---------------------------------------------------------------------------
779
897
  var handleTaxSearch = (0, react_1.useCallback)(function (searchQuery) {
780
- dispatch({
781
- type: actions_1.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
898
+ context.dispatch({
899
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
782
900
  payload: { key: "taxQuery", value: searchQuery },
783
901
  });
784
- }, []);
902
+ }, [context]);
785
903
  // ---------------------------------------------------------------------------
786
- // DRAWER & MODAL HANDLERS
904
+ // Drawer & Modal Handlers
787
905
  // ---------------------------------------------------------------------------
788
906
  var closeDrawer = (0, react_1.useCallback)(function () {
789
- dispatch({
790
- type: actions_1.QUOTE_ACTION_TYPES.SET_DRAWER,
907
+ context.dispatch({
908
+ type: exports.QUOTE_ACTION_TYPES.SET_DRAWER,
791
909
  payload: { drawer: null },
792
910
  });
793
- dispatch({ type: actions_1.QUOTE_ACTION_TYPES.RESET_FORM });
794
- dispatch({ type: actions_1.QUOTE_ACTION_TYPES.RESET_ERRORS });
795
- }, []);
911
+ context.dispatch({
912
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
913
+ payload: { key: "quoteMode", value: null },
914
+ });
915
+ context.dispatch({ type: exports.QUOTE_ACTION_TYPES.RESET_FORM });
916
+ context.dispatch({
917
+ type: exports.QUOTE_ACTION_TYPES.SET_ERRORS,
918
+ payload: { errors: {} },
919
+ });
920
+ }, [context]);
796
921
  // ---------------------------------------------------------------------------
797
- // FORM HANDLERS
922
+ // Form Row Handlers
798
923
  // ---------------------------------------------------------------------------
799
924
  var handleDeleteServiceRow = (0, react_1.useCallback)(function (i) {
800
925
  if (state.servicesList.length > 1) {
801
- var res = state.servicesList.splice(i, 1);
802
- dispatch({
803
- type: actions_1.QUOTE_ACTION_TYPES.DELETE_ITEM_SERVICE,
804
- payload: { servicesList: __spreadArray([], res, true) },
926
+ var updatedList = __spreadArray([], state.servicesList, true);
927
+ updatedList.splice(i, 1);
928
+ context.dispatch({
929
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
930
+ payload: { key: "servicesList", value: updatedList },
805
931
  });
806
932
  }
807
- }, [state.servicesList]);
933
+ }, [context, state.servicesList]);
808
934
  var handleDeleteProductRow = (0, react_1.useCallback)(function (i) {
809
935
  if (state.productsList.length > 1) {
810
- var res = state.productsList.splice(i, 1);
811
- dispatch({
812
- type: actions_1.QUOTE_ACTION_TYPES.DELETE_ITEM_PRODUCT,
813
- payload: { productsList: __spreadArray([], res, true) },
936
+ var updatedList = __spreadArray([], state.productsList, true);
937
+ updatedList.splice(i, 1);
938
+ context.dispatch({
939
+ type: exports.QUOTE_ACTION_TYPES.SET_INPUT_FIELD,
940
+ payload: { key: "productsList", value: updatedList },
814
941
  });
815
942
  }
816
- }, [state.productsList]);
943
+ }, [context, state.productsList]);
817
944
  // ---------------------------------------------------------------------------
818
- // TABLE ACTIONS
945
+ // Table Actions
819
946
  // ---------------------------------------------------------------------------
820
947
  var headerActions = (0, react_1.useMemo)(function () { return [
821
948
  {
@@ -832,36 +959,47 @@ var useQuoteState = function () {
832
959
  },
833
960
  ]; }, [t, handleCreate]);
834
961
  var rowActions = (0, react_1.useMemo)(function () { return [
962
+ {
963
+ enabled: true,
964
+ handleAction: function (id) { return handleView(id); },
965
+ label: t("actionsButtonView"),
966
+ order: 1,
967
+ },
835
968
  {
836
969
  enabled: true,
837
970
  handleAction: function (id) { return handleEdit(id); },
838
971
  label: t("actionsButtonEdit"),
839
- order: 1,
972
+ order: 2,
840
973
  },
841
974
  {
842
975
  enabled: true,
843
976
  handleAction: function (id) { return handleDelete(id); },
844
977
  label: t("actionsButtonDelete"),
845
- order: 2,
978
+ order: 3,
846
979
  },
847
- ]; }, [t, handleEdit, handleDelete]);
980
+ ]; }, [t, handleEdit, handleDelete, handleView]);
848
981
  // ---------------------------------------------------------------------------
849
- // RETURN STATE
982
+ // Return State (flat, backward-compatible + factory-compatible)
850
983
  // ---------------------------------------------------------------------------
851
- return __assign(__assign({}, state), { byIdError: byIdError, byIdLoading: byIdLoading, clearSearch: clearSearch, closeDrawer: closeDrawer, deleteError: deleteError, deleteLoading: deleteLoading, dispatch: dispatch, handleAddItemProduct: handleAddItemProduct, handleAddItemService: handleAddItemService, handleChange: handleChange, handleDeleteProductRow: handleDeleteProductRow, handleDeleteServiceRow: handleDeleteServiceRow, handleItemChangeProducts: handleItemChangeProducts, handleItemChangeServices: handleItemChangeServices, handleNextClick: handleNextClick, handlePageLimit: handlePageLimit, handlePreviousClick: handlePreviousClick, handleSubmit: handleSubmit, handleTaxSearch: handleTaxSearch, headerActions: headerActions, listError: listError, listFetchNow: listFetchNow, listLoading: listLoading, rowActions: rowActions, searchOnChange: searchOnChange, updateError: updateError, updateLoading: updateLoading });
852
- };
853
- exports.QuoteStateContext = (0, react_1.createContext)(__assign(__assign({}, reducer_1.initialQuoteState), { byIdError: undefined, byIdLoading: false, clearSearch: function () { return void 0; }, closeDrawer: function () { return void 0; }, deleteError: undefined, deleteLoading: false, dispatch: function () { return void 0; }, handleAddItemProduct: function () { return void 0; }, handleAddItemService: function () { return void 0; }, handleChange: function () { return void 0; }, handleDeleteProductRow: function () { return void 0; }, handleDeleteServiceRow: function () { return void 0; }, handleItemChangeProducts: function () { return void 0; }, handleItemChangeServices: function () { return void 0; }, handleNextClick: function () { return void 0; }, handlePageLimit: function () { return void 0; }, handlePreviousClick: function () { return void 0; }, handleSubmit: function () { return void 0; }, handleTaxSearch: function () { return void 0; }, headerActions: [], listError: undefined, listFetchNow: function () { return void 0; }, listLoading: false, rowActions: [], searchOnChange: function () { return void 0; }, updateError: undefined, updateLoading: false }));
854
- var QuoteStateContextProvider = function (_a) {
855
- var children = _a.children;
856
- var state = useQuoteState();
857
- return (react_1.default.createElement(exports.QuoteStateContext.Provider, { value: state }, children));
858
- };
859
- exports.QuoteStateContextProvider = QuoteStateContextProvider;
860
- var useQuoteStateContext = function () {
861
- var state = (0, react_1.useContext)(exports.QuoteStateContext);
862
- if (state === undefined) {
863
- throw new Error("useQuoteStateContext must be used within a QuoteContextProvider");
864
- }
865
- return state;
984
+ return __assign(__assign(__assign({}, context), state), { quotes: state.items, byIdError: byIdError, byIdLoading: byIdLoading, clearSearch: clearSearch, closeDrawer: closeDrawer, deleteError: deleteError, deleteLoading: deleteLoading, dispatch: context.dispatch, handleAddItemProduct: handleAddItemProduct, handleAddItemService: handleAddItemService, handleChange: handleChange, handleCloseDrawer: closeDrawer, handleCreate: handleCreate, handleDelete: handleDelete, handleDeleteProductRow: handleDeleteProductRow, handleDeleteServiceRow: handleDeleteServiceRow, handleEdit: handleEdit, handleItemChangeProducts: handleItemChangeProducts, handleItemChangeServices: handleItemChangeServices, handleNextClick: handleNextClick, handlePageChange: function (page) {
985
+ context.dispatch({
986
+ type: exports.QUOTE_ACTION_TYPES.SET_CURRENT_PAGE,
987
+ payload: { currentPage: page },
988
+ });
989
+ }, handlePageLimit: handlePageLimit, handlePageLimitChange: function (limit) {
990
+ context.dispatch({
991
+ type: exports.QUOTE_ACTION_TYPES.SET_PAGE_LIMIT,
992
+ payload: { pageLimit: limit },
993
+ });
994
+ context.dispatch({
995
+ type: exports.QUOTE_ACTION_TYPES.SET_CURRENT_PAGE,
996
+ payload: { currentPage: 1 },
997
+ });
998
+ }, handlePreviousClick: handlePreviousClick, handleSearch: function (query) {
999
+ context.dispatch({
1000
+ type: exports.QUOTE_ACTION_TYPES.SET_SEARCH_QUERY,
1001
+ payload: { searchQuery: query },
1002
+ });
1003
+ }, handleSubmit: handleSubmit, handleTaxSearch: handleTaxSearch, handleView: handleView, headerActions: headerActions, listError: listError, listFetchNow: listFetchNow, listLoading: listLoading, rowActions: rowActions, searchOnChange: searchOnChange, updateError: updateError, updateLoading: updateLoading });
866
1004
  };
867
- exports.useQuoteStateContext = useQuoteStateContext;
1005
+ exports.useQuoteModule = useQuoteModule;