Skip to content

Comments

[IMP] awesomeclicker: add editor metadata in Python file#1173

Open
jupao-odoo wants to merge 43 commits intoodoo:19.0from
odoo-dev:19.0-add-editor-awesomeclicker-jupao
Open

[IMP] awesomeclicker: add editor metadata in Python file#1173
jupao-odoo wants to merge 43 commits intoodoo:19.0from
odoo-dev:19.0-add-editor-awesomeclicker-jupao

Conversation

@jupao-odoo
Copy link

Added a new line 'editor': "jupao" in the module code to indicate the editor used for this script. This helps with code clarity and consistency within the module.

Added a new line 'editor': "jupao" in the module code to
indicate the editor used for this script. This helps with
code clarity and consistency within the module.
@robodoo
Copy link

robodoo commented Feb 16, 2026

Pull request status dashboard

@ltinel ltinel self-requested a review February 16, 2026 16:14
Copy link

@ltinel ltinel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work :)

FYI, if you scroll to the bottom of your PR, you'll find some Runbot links, among which the ci/style check. In there, you'll find a few styling suggestions (typically incorrect use of whitespace or newlines). Could you implement those to make the check pass?

""",

'author': "Odoo",
'editor': "jupao",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for this change :) I guess it was just a test?


available_from = fields.Date(
copy=False,
default=lambda self: fields.Date.today() + timedelta(days=90)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We usually work with relativedelta (from dateutil.relativedelta import relativedelta):

Suggested change
default=lambda self: fields.Date.today() + timedelta(days=90)
default=lambda self: fields.Date.today() + relativedelta(months=3)

<field name="arch" type="xml">
<search string="Property">

<field name="name" string="Title"/>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of overriding the string here (which is fine, by the way), you could also set it directly in the model (in the py file).

Comment on lines 5 to 11
'summary': """
Starting module for "Master the Odoo web framework, chapter 1: Build a new application"
""",

'description': """
Starting module for "Master the Odoo web framework, chapter 1: Build a new application"
""",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These don't seem quite right :)

Copy link

@ltinel ltinel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job :)

<field name="expected_price"/>
<field name="selling_price"/>
<field name="available_from"/>
<field name="name" width="100px"/>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's fine to set a width, but hardcoding pixels can be risky, since users can have different screen sizes (monitor, laptop, smartphone, ...)

Copy link

@ltinel ltinel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job :)

Copy link

@ltinel ltinel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely done :)

def _check_selling_price_min(self):
for record in self:
if (
record.selling_price and record.expected_price and record.selling_price < record.expected_price * 0.9
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you use the float_compare and float_is_zero utilities here? It's preferable to use "approximate" comparisons when working with floats.

- Initialize module structure
- Create estate.property model
- Add basic fields and attributes
- Add security access rules
- Add action and menus for UI
Add custom views for the `estate.property` model to improve user interface
and data interaction. The commit introduces:

- A list view showing key fields: name, postcode, bedrooms, living area,
  expected price, selling price, and available date.
- A form view with structured groups and a notebook for detailed information
  including description, property features, and reserved fields like active
  and state.
- A search view with filters and group-by options to easily find and categorize
  properties, including an "Available" filter for new and offer_received
  properties, and a group-by on postcode.

This improves the usability of the real estate module, replacing default
auto-generated views with tailored ones that match business requirements.

Closes task-6
Introduce estate.property.type and estate.property.tag models.
Extend estate.property with:

- Many2one relation to property type
- Many2many relation to property tags
- One2many relation to property offers

Add corresponding views and menus where required.

Fix flake8 issues to satisfy ci/style checks.
- estate.property:
  * added total_area computed field (living_area + garden_area)
  * added best_price computed field (maximum of offer prices)
  * added @onchange on 'garden' to set default garden_area=10 and garden_orientation='north'

- estate.property.offer:
  * added validity_date computed field (with inverse)
Chapter 9: link business logic to UI actions

- estate.property:
  * Add "Cancel" and "Sold" buttons in form view header.
  * Enforce state constraints: a cancelled property cannot be sold and a sold property cannot be cancelled.
  * Raise UserError when state transitions are invalid.

- estate.property.offer:
  * Add "Accept" and "Refuse" buttons.
  * Accepting an offer sets the buyer and selling price on the related property.
  * Only one offer can be accepted per property.

- Updated views to include buttons in header sections.
- Added Python methods implementing the business logic for these actions.
- Ensure expected_price and selling_price are positive
- Prevent selling_price from being lower than 90% of expected_price
- Add uniqueness constraints on property type names
- Add uniqueness constraints on property tag names
-Move many2many tags
-Add inline property type class
-Add widget bar
- Color decorations for property and offer list views based on state/status
- Editable list views for offers and tags
- Hide availability date by default in property list
- Set default 'Available' filter in property search
- Make living area search return properties with area >= entered value
- Add stat button on property type form to show related offers
- Refine offer count display and button layout
…perties

- Prevent deletion of properties unless state is 'New' or 'Cancelled'
  (implemented using @api.ondelete)
- Override create() on estate.offer:
  - Set property state to 'Offer Received' when an offer is created
  - Prevent creation of an offer with a lower price than existing offers
- Extend res.users model:
  - Add property_ids One2many field linked to estate.property
  - Add domain to display only available properties
- Inherit base.view_users_form to display property_ids
  in a new notebook page on the user form
- Filter the offer button to show only offers related to the current property type
- Add SQL constraints for expected_price and selling_price to enforce positivity
- Ensure property type name is unique at the database level
- Clean up form view: removed unnecessary buttons and improved layout
- Updated .gitignore to exclude local config files (.settings.json, .flake8, .vscode)
…perty sold

- Added estate_account module as a link between estate and account
- Inherited estate.property and overridden action_sold to create customer invoices
- Automatically generates invoice lines: 6% commission + 100 administrative fees
- Ensures invoices are created only if buyer and selling_price are defined
- Updated __manifest__ and module structure for proper installation and visibility in Apps
- Introduce minimal kanban template using QWeb
- Display name, tags and pricing information
- Add conditional rendering for best offer and selling price
- Enable default grouping by property type
- Disable drag & drop on kanban records
This commit applies changes following the review comments:
- Mark all other offers as refused (as suggested, though may not be ideal for tracking)
- Removed empty or unnecessary sections
- Corrected author information where needed (typically Odoo S.A.)
- Fixed minor issues flagged in previous review comments
- Reverted test changes or irrelevant edits
This commit fixes the invoice calculation to use the correct estate price and ensures the license field is properly included.
- Use Python constraint instead of SQL constraint
- Switch to @api.model_create_multi (Odoo 17)
- Remove unnecessary isinstance check
- Fix invoice creation (journal_id required)
- Minor cleanup and best practice alignment
- Format code to follow Odoo guidelines
- Remove unused imports
- Improve indentation and spacing
- Minor refactoring without functional changes
- Fix test errors
- Adjust code to satisfy CI checks
- No functional changes
- Cleaned up obsolete fields
- No functional changes
- Restore "Administrative fees" invoice line with fixed amount (100.0)
- Use float_compare for selling price constraint to handle rounding safely
- Prevents false ValidationErrors and ensures invoice lines follow business logic
@jupao-odoo jupao-odoo force-pushed the 19.0-add-editor-awesomeclicker-jupao branch from 3a87b1b to e205ffa Compare February 20, 2026 12:06
- Keep `status` field invisible (`column_invisible="True"`)
- Use it for row decorations (`decoration-success` / `decoration-danger`)
- Drive button visibility logic in list and form views
- Prevent breaking UI features if the field is removed or shown
-removed invisible columns
-removed comments
- Updated Playground component to use Owl useState hook
- Implemented increment method to update counter state
- Modified playground.xml to display counter using t-esc
- Added button with t-on-click to trigger increment action

This introduces a simple reactive counter to demonstrate Owl's
reactivity system and component re-rendering.
- Created Card component accepting title and content props
- Implemented Bootstrap card layout in template
- Imported and used Card component inside Playground
- Added multiple Card instances to demonstrate props usage

This showcases parent-to-child communication in Owl
through props and reusable component composition.
- Updated Card component to use t-out for rendering content
- Imported and used Owl's markup function in Playground
- Demonstrated safe rendering of HTML strings with markup
- Regular strings continue to be escaped with t-esc

This allows Card to display rich HTML content safely while preserving
default escaping behavior for normal strings.
- Defined props schema for Card component (title and content as strings)
- Enabled Owl to perform runtime validation in dev mode
- Updated Playground to intentionally use incorrect prop name to demonstrate validation error

This makes the Card component API explicit and helps catch
prop-related mistakes during development.
Copy link

@ltinel ltinel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job :)

Comment on lines +142 to +161
<list editable="bottom"
decoration-success="status == 'accepted'"
decoration-danger="status == 'refused'">
<field name="price"/>
<field name="partner_id"/>
<field name="validity"/>
<field name="date_deadline"/>

<button name="action_accept"
type="object"
string="Accept"
class="btn-success"
invisible="status in ('accepted','refused')"/>

<button name="action_refuse"
type="object"
string="Refuse"
class="btn-danger"
invisible="status in ('accepted','refused')"/>
</list>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to redefine the list view here, since it's already defined in estate_property_offer_views.xml

…ck props

- Added optional onChange prop to Counter with prop validation
- Updated Counter to call onChange whenever incremented
- Modified Playground to track sum in local state
- Implemented incrementSum method in Playground
- Passed incrementSum as a callback prop to multiple Counter instances
- Displayed the current sum below the counters in the template

This demonstrates child-to-parent communication using callback props
and reactive state updates in Owl.
…namic styling

- Created TodoList component maintaining state of todos
- Created TodoItem component receiving a todo as prop with prop validation
- Displayed TodoList in Playground using t-foreach and unique t-key
- Added dynamic classes to TodoItem: text-muted and text-decoration-line-through if completed
- Demonstrated visual distinction for completed vs. pending todos

This showcases stateful components, list rendering, prop validation,
and dynamic attribute usage in Owl.
- Removed hardcoded todos; initialized todos state as empty array
- Added input field with placeholder "Enter a new task"
- Implemented addTodo method triggered on keyup event
- Created new todo with unique id when Enter key is pressed
- Cleared input after adding a todo
- Input is ignored if empty to prevent empty tasks

This makes the TodoList interactive, demonstrating Owl's reactivity
and handling of user input events.
- Fixed prop handling and rendering in Card component
- Resolved state and callback behavior in Counter component
- Ensured proper reactivity and display of values

This addresses bugs related to component updates and prop usage.
- Corrected prop validation and rendering in Card component
- Fixed state or display issues in EstateProperty component
…List

- Implemented input autofocus in TodoList using t-ref and useRef
- Extracted autofocus logic into reusable useAutofocus hook in utils.js
- Added toggleState callback prop in TodoItem to mark todos as completed
- Added checkbox input in TodoItem linked to isCompleted state
- Implemented removeTodo callback prop in TodoItem
- Added clickable remove icon to delete todos from the list
- Ensured proper child-to-parent communication and reactive updates

This enhances TodoList interactivity with DOM access, state toggling,
and deletion functionality.
- Refactored Card component to use default slot instead of content prop
- Removed content prop and updated usages in Playground
- Allowed arbitrary content inside Card (e.g., Counter component)
- Added prop validation for Card
- Introduced internal state to manage open/closed status
- Added toggle button in Card header to show/hide body
- Used t-if for conditional rendering of card content

This improves Card flexibility with slots and enhances UX
with collapsible content behavior.
Fix style and linting issues reported by flake8 to comply with
coding guidelines.
Copy link

@ltinel ltinel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, great work 🙂

});

this.inputRef.el.value = "";
this.inputRef.el.focus();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really needed? I would expect the focus to stay on the input anyway.

…estate_property

- Corrected issues in TodoList and TodoItem components
- Fixed utility functions in utils.js
- Resolved rendering and prop handling in Card component
- Fixed flake8 and other minor issues in estate_property files
- Ensured proper reactivity, callbacks, and component behavior
Copy link

@ltinel ltinel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding new commits every time, could you amend your old ones and then force push? To amend the last one, you can do git commit --amend, to amend older ones, you can do an interactive rebase: git rebase -i HEAD~{number of commits in the past}. To force push, do git push --force, to force push with lease, do git push --force-with-lease. This last command ("with lease") prevents you from overriding changes that were pushed on your remote branch, but that your local branch is unaware of (typically if someone else pushed something on your branch and you didn't pull their changes before pushing yours).


<!-- Delete button -->
<button
type="button"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for this

@ltinel
Copy link

ltinel commented Feb 23, 2026

Feel free to mark my comments as "resolved" once you've addressed them :)

- Fixed bugs in Owl components (Card, Counter, TodoList, TodoItem, utils)
- Corrected issues in estate property files
- Ensured proper reactivity, prop handling, and lint compliance
- Ensured proper reactivity, prop handling, and lint compliance
- Updated AwesomeDashboard component to use Layout from @web/search/layout
- Added className 'o_dashboard h-100' to Layout
- Created dashboard.scss and set .o_dashboard background color to gray
- Ensured proper structure with control panel and main content area
…vice

- Injected action service using useService hook
- Added "Customers" button opening existing action by xml id
- Added "Leads" button triggering dynamic action on crm.lead
  with list and form views
- Integrated buttons into dashboard control panel

This enables quick navigation to key business views
directly from the Awesome Dashboard.
- Created generic DashboardItem component using default slot
- Implemented card layout with dynamic width (18 * size)rem
- Added optional size prop (default = 1) with prop validation
- Inserted two DashboardItem instances in dashboard (size 1 and 2)

This improves dashboard structure with reusable and flexible
card-based layout components.
- Updated Dashboard component to call /awesome_dashboard/statistics via rpc
- Fetched key business metrics:
  - Number of new orders this month
  - Total amount of new orders
  - Average t-shirt amount per order
  - Number of cancelled orders
  - Average time from 'new' to 'sent' or 'cancelled'
- Displayed metrics using DashboardItem cards
- Ensured data loads asynchronously on dashboard startup
Copy link

@ltinel ltinel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great :)

- Created awesome_dashboard.statistics service
- Implemented loadStatistics method using rpc
- Used memoize utility to cache network call results
- Updated Dashboard component to consume the new service
- Prevented repeated calls to /awesome_dashboard/statistics on remount

This improves performance by caching dashboard data
and centralizing statistics logic in a reusable service.
- Moved dashboard buttons into Layout's dedicated slot (t-set-slot="layout-buttons")
- Removed unsupported className prop usage; nested buttons in display instead
- Created a dedicated file for the buttons component
- Set default prop values where applicable

This refactors the dashboard layout for proper slot usage
and improves component organization.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants