feat: hide authorizer for rental orders, auto-set sale type

Rental orders no longer show the "Authorizer Required?" question or
the Authorizer field. The sale type is automatically set to 'Rentals'
when creating or confirming a rental order. Validation logic also
skips authorizer checks for rental sale type.

Made-with: Cursor
This commit is contained in:
gsinghpal
2026-02-25 23:33:23 -05:00
parent 3c8f83b8e6
commit 14fe9ab716
51 changed files with 4192 additions and 822 deletions

View File

@@ -0,0 +1,22 @@
.o_inspection_photos .o_attachment.o_attachment_many2many {
min-width: 140px;
min-height: 140px;
}
.o_inspection_photos .o_attachment.o_attachment_many2many .o_image_box {
width: 120px;
height: 120px;
}
.o_inspection_photos .o_attachment.o_attachment_many2many .o_preview_image {
width: 120px !important;
height: 120px !important;
object-fit: cover;
cursor: pointer;
}
.o_inspection_photos .o_attachments {
display: flex;
flex-wrap: wrap;
gap: 12px;
}

View File

@@ -0,0 +1,43 @@
/** @odoo-module **/
import { registry } from "@web/core/registry";
import { Many2ManyBinaryField, many2ManyBinaryField } from "@web/views/fields/many2many_binary/many2many_binary_field";
import { useFileViewer } from "@web/core/file_viewer/file_viewer_hook";
export class InspectionPhotoField extends Many2ManyBinaryField {
setup() {
super.setup();
this.fileViewer = useFileViewer();
}
get viewableFiles() {
return this.files
.filter((f) => this.isImage(f))
.map((f) => ({
name: f.name,
isImage: true,
isViewable: true,
downloadUrl: `/web/content/${f.id}?download=true`,
defaultSource: `/web/image/${f.id}`,
}));
}
onClickImage(fileId) {
const viewable = this.viewableFiles;
const clicked = viewable.find(
(vf) => vf.defaultSource === `/web/image/${fileId}`
);
if (clicked) {
this.fileViewer.open(clicked, viewable);
}
}
}
InspectionPhotoField.template = "fusion_rental.InspectionPhotoField";
export const inspectionPhotoField = {
...many2ManyBinaryField,
component: InspectionPhotoField,
};
registry.category("fields").add("inspection_photos", inspectionPhotoField);

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="fusion_rental.InspectionPhotoField" t-inherit="web.Many2ManyBinaryField" t-inherit-mode="primary">
<xpath expr="//t[@t-call='web.Many2ManyBinaryField.attachment_preview']" position="replace">
<t t-call="fusion_rental.InspectionPhotoField.attachment_preview"/>
</xpath>
</t>
<t t-name="fusion_rental.InspectionPhotoField.attachment_preview">
<t t-set="editable" t-value="!props.readonly"/>
<div t-attf-class="o_attachment o_attachment_many2many #{ editable ? 'o_attachment_editable' : '' } #{upload ? 'o_attachment_uploading' : ''}" t-att-title="file.name">
<div class="o_attachment_wrap">
<t t-set="ext" t-value="getExtension(file)"/>
<t t-set="url" t-value="getUrl(file.id)"/>
<div class="o_image_box float-start" t-att-data-tooltip="file.name">
<a t-if="isImage(file)" href="#" t-on-click.prevent="() => this.onClickImage(file.id)">
<img class="o_preview_image o_hover object-fit-cover rounded align-baseline"
t-attf-src="/web/image/{{ file.id }}"
onerror="this.src = '/web/static/img/mimetypes/image.svg'"
style="cursor: zoom-in;"/>
</a>
<a t-else="" t-att-href="url" aria-label="Download" download="">
<span class="o_image o_preview_image o_hover" t-att-data-mimetype="file.mimetype" t-att-data-ext="ext" role="img"/>
</a>
</div>
<div class="caption">
<a class="ml4" t-att-data-tooltip="file.name" t-att-href="url" download=""><t t-esc='file.name'/></a>
</div>
<div class="caption small">
<a class="ml4 small text-uppercase" t-att-href="url" download=""><b><t t-esc='ext'/></b></a>
<div t-if="editable" class="progress o_attachment_progress_bar">
<div class="progress-bar progress-bar-striped active" style="width: 100%">Uploading</div>
</div>
</div>
<div class="o_attachment_uploaded"><i class="text-success fa fa-check" role="img" aria-label="Uploaded" title="Uploaded"/></div>
<div t-if="editable" class="o_attachment_delete" t-on-click.stop="() => this.onFileRemove(file.id)"><span role="img" aria-label="Delete" title="Delete">x</span></div>
</div>
</div>
</t>
</templates>