Skip to content

Commit ca13d6e

Browse files
committed
[FIX] pos: orm_serialization
1 parent 75b0906 commit ca13d6e

File tree

5 files changed

+107
-78
lines changed

5 files changed

+107
-78
lines changed

addons/point_of_sale/static/src/app/models/related_models/base.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ export class Base extends WithLazyGetterTrap {
2929
* This method is called when the instance is created or updated
3030
* @param {*} _vals
3131
*/
32-
setup(_vals) {}
32+
setup(_vals) {
33+
this._dirty = typeof this.id !== "number";
34+
}
3335

3436
/**
3537
* This method is invoked only during instance creation to preserve the state across updates.
@@ -77,7 +79,28 @@ export class Base extends WithLazyGetterTrap {
7779
return { ...this.uiState };
7880
}
7981

82+
_markDirty() {
83+
if (this.models._loadingData || this._dirty) {
84+
return;
85+
}
86+
87+
this._dirty = true;
88+
this.model.getParentFields().forEach((field) => {
89+
this[field.name]?._markDirty?.();
90+
});
91+
}
92+
8093
backLink(link) {
8194
return this.model.backLink(this, link);
8295
}
96+
97+
getId() {
98+
// Returns integer id if exist or return uuid
99+
const id = this.id;
100+
if (typeof id === "number" || !this.uuid) {
101+
return id;
102+
}
103+
const idUpdates = JSON.parse(localStorage.getItem("idUpdates")) || {};
104+
return idUpdates[this.uuid] || this.uuid;
105+
}
83106
}

addons/point_of_sale/static/src/app/models/related_models/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ export function createRelatedModels(modelDefs, modelClasses = {}, opts = {}) {
450450
}
451451

452452
_delete(record, opts = {}) {
453-
const id = record.id;
453+
const id = record.getId();
454454
const ownFields = getFields(this.name);
455455
const handleCommand = (inverse, field, record, backend = false) => {
456456
if (inverse && !inverse.dummy && typeof id === "number") {
@@ -459,7 +459,7 @@ export function createRelatedModels(modelDefs, modelClasses = {}, opts = {}) {
459459
const oldVal = map.get(inverse.name);
460460
map.set(inverse.name, [
461461
...(oldVal || []),
462-
{ id: record.id, parentId: record[field.name].id },
462+
{ id: record.id, parentId: record[field.name].id, getId: record.getId() },
463463
]);
464464
}
465465
};

addons/point_of_sale/static/src/app/models/related_models/serialization.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,11 @@ const deepSerialization = (
5353
continue;
5454
}
5555

56-
if (typeof childRecord.id !== "number") {
56+
if (typeof childRecord.getId() !== "number") {
5757
toCreate.push(childRecord);
58+
} else if (childRecord._dirty) {
59+
toUpdate.push(childRecord);
60+
childRecord._dirty = false;
5861
}
5962
serialized[relatedModel][childRecord.uuid] = childRecord.uuid;
6063
}
@@ -67,7 +70,7 @@ const deepSerialization = (
6770
...(result[fieldName] || []),
6871
...toUpdate.map((childRecord) => [
6972
1,
70-
childRecord.id,
73+
childRecord.getId(),
7174
recursiveSerialize(childRecord, field.inverse_name),
7275
]),
7376
...toCreate.map((childRecord) => [
@@ -93,15 +96,15 @@ const deepSerialization = (
9396
if (modelCommands.unlink.has(fieldName) || modelCommands.delete.has(fieldName)) {
9497
result[fieldName] = result[fieldName] || [];
9598
const processRecords = (records, cmdCode) => {
96-
for (const { id, parentId } of records) {
99+
for (const { id, parentId, getId } of records) {
97100
const isAlreadyDeleted = serialized[relatedModel]?.["_deleted_" + id];
98101
if (parentId === record.id && !isAlreadyDeleted) {
99102
const isCascadeDelete =
100103
record.models[relatedModel]?.fields[field.inverse_name]?.ondelete;
101104
if (isCascadeDelete) {
102105
serialized[relatedModel]["_deleted_" + id] = true;
103106
}
104-
result[fieldName].push([cmdCode, id]);
107+
result[fieldName].push([cmdCode, getId]);
105108
}
106109
}
107110
};
@@ -164,6 +167,8 @@ const deepSerialization = (
164167
res[key] = getValue();
165168
}
166169

170+
record._dirty = false;
171+
167172
// Cleanup: remove empty entries from uuidMapping.
168173
for (const key in uuidMapping) {
169174
if (

addons/point_of_sale/static/src/app/models/related_models/utils.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ export class AggregatedUpdates {
119119
[...fields].map((fieldName) => [fieldName, record[fieldName]])
120120
),
121121
});
122+
record._markDirty();
122123
}
123124
}
124125

addons/point_of_sale/static/tests/unit/related_models/orm_serialization.test.js

Lines changed: 71 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -161,31 +161,31 @@ describe("ORM serialization", () => {
161161
}
162162

163163
// Server results with ids
164-
models.connectNewData({
165-
"pos.order": [{ ...order.raw, id: 1, lines: [11, 12] }],
166-
"pos.order.line": [
167-
{ ...line1.raw, id: "b", order_id: 1 },
168-
{ ...line2.raw, id: "c", order_id: 1 },
169-
],
170-
});
164+
// debugger
165+
const idUpdates = {
166+
[order.uuid]: 1,
167+
[line1.uuid]: 11,
168+
[line2.uuid]: 12,
169+
};
170+
localStorage.setItem("idUpdates", JSON.stringify(idUpdates));
171171

172172
line1.quantity = 99;
173-
// {
174-
// const result = models.serializeForORM(order);
175-
// expect(result.lines.length).toBe(1);
176-
// expect(result.lines[0][0]).toBe(1);
177-
// expect(result.lines[0][1]).toBe(11);
178-
// expect(result.lines[0][2].quantity).toBe(99);
179-
// }
180-
181-
// // Delete line
182-
// line1.delete();
183-
// {
184-
// const result = models.serializeForORM(order);
185-
// expect(result.lines.length).toBe(1);
186-
// expect(result.lines[0][0]).toBe(3);
187-
// expect(result.lines[0][1]).toBe(11);
188-
// }
173+
{
174+
const result = models.serializeForORM(order);
175+
expect(result.lines.length).toBe(1);
176+
expect(result.lines[0][0]).toBe(1);
177+
expect(result.lines[0][1]).toBe(11);
178+
expect(result.lines[0][2].quantity).toBe(99);
179+
}
180+
181+
// Delete line
182+
line1.delete();
183+
{
184+
const result = models.serializeForORM(order);
185+
expect(result.lines.length).toBe(1);
186+
expect(result.lines[0][0]).toBe(3);
187+
expect(result.lines[0][1]).toBe(11);
188+
}
189189
});
190190

191191
test("serialization of non-dynamic model relationships", () => {
@@ -287,14 +287,14 @@ describe("ORM serialization", () => {
287287
parentLine = models["pos.order.line"].getBy("uuid", parentLine.uuid);
288288

289289
line1.quantity = 99;
290-
// {
291-
// const result = models.serializeForORM(order);
292-
// expect(result.lines.length).toBe(1);
293-
// expect(result.lines[0][0]).toBe(1);
294-
// expect(result.lines[0][1]).toBe(11);
295-
// expect(result.lines[0][2].quantity).toBe(99);
296-
// expect(result.relations_uuid_mapping).toBe(undefined);
297-
// }
290+
{
291+
const result = models.serializeForORM(order);
292+
expect(result.lines.length).toBe(1);
293+
expect(result.lines[0][0]).toBe(1);
294+
expect(result.lines[0][1]).toBe(11);
295+
expect(result.lines[0][2].quantity).toBe(99);
296+
expect(result.relations_uuid_mapping).toBe(undefined);
297+
}
298298
});
299299

300300
test("recursive relationship with group of lines", () => {
@@ -402,46 +402,46 @@ describe("ORM serialization", () => {
402402
expect(order.groups[0].lines.length).toBe(1);
403403
expect(order.groups[1].lines.length).toBe(1);
404404

405-
// {
406-
// const result = models.serializeForORM(order);
407-
// expect(result.groups[0].lines).toBeEmpty();
408-
// expect(result.groups[1].lines).toBeEmpty();
409-
// expect(result.lines.length).toBe(1);
410-
// expect(result.lines[0][0]).toBe(1);
411-
// expect(result.lines[0][1]).toBe(111);
412-
// expect(result.lines[0][2].group_id).toBe(group2.id);
413-
// expect(result.relations_uuid_mapping).toBe(undefined);
414-
// }
415-
416-
// // Delete line
417-
// line1.delete();
418-
// //update the group, to be sure the lines are empty
419-
// group1.index = 3;
420-
// group2.index = 4;
421-
// {
422-
// const result = models.serializeForORM(order);
423-
// expect(result.groups.length).toBe(2);
424-
// expect(result.groups[0][0]).toBe(1);
425-
// expect(result.groups[0][1]).toBe(group1.id);
426-
// expect(result.groups[0][2].index).toBe(3);
427-
// expect(result.groups[0][2].lines).toBeEmpty();
428-
// expect(result.groups[1][0]).toBe(1);
429-
// expect(result.groups[1][1]).toBe(group2.id);
430-
// expect(result.groups[1][2].index).toBe(4);
431-
// expect(result.groups[1][2].lines).toBeEmpty();
432-
433-
// expect(result.lines.length).toBe(1);
434-
// expect(result.lines[0][0]).toBe(3);
435-
// expect(result.lines[0][1]).toBe(110);
436-
// expect(result.relations_uuid_mapping).toBe(undefined);
437-
// }
438-
439-
// {
440-
// //All update/delete have been cleared
441-
// const result = models.serializeForORM(order);
442-
// expect(result.groups).toBeEmpty();
443-
// expect(result.lines).toBeEmpty();
444-
// }
405+
{
406+
const result = models.serializeForORM(order);
407+
expect(result.groups[0].lines).toBeEmpty();
408+
expect(result.groups[1].lines).toBeEmpty();
409+
expect(result.lines.length).toBe(1);
410+
expect(result.lines[0][0]).toBe(1);
411+
expect(result.lines[0][1]).toBe(111);
412+
expect(result.lines[0][2].group_id).toBe(group2.id);
413+
expect(result.relations_uuid_mapping).toBe(undefined);
414+
}
415+
416+
// Delete line
417+
line1.delete();
418+
//update the group, to be sure the lines are empty
419+
group1.index = 3;
420+
group2.index = 4;
421+
{
422+
const result = models.serializeForORM(order);
423+
expect(result.groups.length).toBe(2);
424+
expect(result.groups[0][0]).toBe(1);
425+
expect(result.groups[0][1]).toBe(group1.id);
426+
expect(result.groups[0][2].index).toBe(3);
427+
expect(result.groups[0][2].lines).toBeEmpty();
428+
expect(result.groups[1][0]).toBe(1);
429+
expect(result.groups[1][1]).toBe(group2.id);
430+
expect(result.groups[1][2].index).toBe(4);
431+
expect(result.groups[1][2].lines).toBeEmpty();
432+
433+
expect(result.lines.length).toBe(1);
434+
expect(result.lines[0][0]).toBe(3);
435+
expect(result.lines[0][1]).toBe(110);
436+
expect(result.relations_uuid_mapping).toBe(undefined);
437+
}
438+
439+
{
440+
//All update/delete have been cleared
441+
const result = models.serializeForORM(order);
442+
expect(result.groups).toBeEmpty();
443+
expect(result.lines).toBeEmpty();
444+
}
445445
});
446446

447447
test("grouped lines and nested lines", () => {

0 commit comments

Comments
 (0)