Friday, March 19, 2021

I started the lino_xl.lib.webshop plugin, with Sharif watching me. It (currently) has four database models Cart, CartItem, Address and PaymentMethod. It needs and uses the existing plugins vat, sales, contacts, products, ledger,… I also added a demo project of same name “webshop”.

We discovered and fixed #4036. We had (simplified) the following construct:

class UserPlan(dd.Model):
    class Meta:
        abstract = True

    start_plan = StartPlan()

class StartPlan(dd.Action):
  ...
  def run_from_ui(self, ar, **kw):
      options = self.get_options(ar)
      pm = self.get_plan_model(ar)
      ...

  def get_plan_model(self, ar):
      return self.defining_actor.model

Explanation: When the application has more than one concrete model that inherits from lino.modlib.users.UserPlan, Lino’s behaviour was wrong. Calling webshop.Cart.start_plan created an instance of lino_xl.lib.sheets.Report, the concrete model that happens to be the first to use it.

I fixed this by saying:

class StartPlan(dd.Action):

  def get_plan_model(self, ar):
      return ar.actor.model

I stumbled into a similar pitfall: The quick link ‘webshop.MyCart.start_plan’ was getting bound to the start_plan action on lino_xl.lib.sheets.Report. This was caused by the lino.core.actors.resolve_action(). I optimized the behaviour of this function and added test coverage in How plugins build the application menu.

How to link user and partner? A normal webshop user fills in their postal address or other contact data. Webshop adds the possibility to define multiple invoicing and delivery addresses. The partners of the users are not our partners. The partner of the generated invoices is always a same partner, stored in the User.partner field and leading to a given sales.SalesRule.

The ar.success “x items have been placed to your shopping cart!” didn’t not show up because I must say alert=True.

The lino_xl.lib.webshop.AddToCart action made us stumble into another pitfall: when an action uses ar.confirm, then the implementing code is being called several times, once for each call to ar.confirm. And each time the full text of the confirmation message must remain the same.