rattail.batch.custorder

Customer Order Batch Handler

Please note this is different from the Customer Order Handler.

class rattail.batch.custorder.CustomerOrderBatchHandler(config, **kwargs)[source]

Handler for all “customer order” batches, regardless of “mode”. The handler must inspect the mode attribute of each batch it deals with, in order to determine which logic to apply.

has_custom_product_autocomplete

If true, this flag indicates that the handler provides custom autocomplete logic for use when selecting a product while creating a new order.

add_email_address(batch, user, **kwargs)[source]

Add email address from the batch to the customer record.

Note that the default behavior does not do that, but instead will send an email alert to configured recipient(s) with the update request.

add_pending_product(batch, pending_info, order_quantity, order_uom, **kwargs)[source]

Add a new row to the batch, for the given “pending” product and order quantity.

Parameters:
  • batch – Reference to the current order batch.

  • pending_info – Dict of information about a new pending product.

  • order_quantity – Quantity of the item to be added to the order.

  • order_uom – Unit of measure for the order quantity.

add_phone_number(batch, user, **kwargs)[source]

Add phone number from the batch to the customer record.

Note that the default behavior does not do that, but instead will send an email alert to configured recipient(s) with the update request.

add_product(batch, product, order_quantity, order_uom, **kwargs)[source]

Add a new row to the batch, for the given product and order quantity.

allow_case_orders()[source]

Returns a boolean indicating whether “case” orders are allowed.

allow_contact_info_choice()[source]

Returns a boolean indicating whether the user is allowed at all, to choose from existing contact info options for the customer, vs. they just have to go with whatever the handler auto-provides.

allow_contact_info_creation()[source]

Returns a boolean indicating whether the user is allowed to enter new contact info for the customer. This setting should only be honored if allow_contact_info_choice() also returns true.

allow_item_discounts()[source]

Returns boolean indicating whether per-item discounts are allowed.

allow_item_discounts_if_on_sale()[source]

Returns boolean indicating whether per-item discounts are allowed when item is already on sale.

allow_past_item_reorder()[source]

Returns boolean indicating whether to expose past items for re-order.

allow_unit_orders()[source]

Returns a boolean indicating whether “unit” orders are allowed.

allow_unknown_product()[source]

Returns a boolean indicating whether “unknown” products are allowed on new orders.

assign_contact(batch, customer=None, person=None, **kwargs)[source]

Assign the customer and/or person “contact” for the order.

batch_model_class

alias of CustomerOrderBatch

custom_product_autocomplete(session, term, **kwargs)[source]

For the given term, this should return a (possibly empty) list of products which “match” the term. Each element in the list should be a dict with “label” and “value” keys.

customer_autocomplete(session, term, **kwargs)[source]

Override the Customer autocomplete, to search by phone number as well as name.

delete_extra_data(batch, progress=None, **kwargs)[source]

Delete all “extra” data for the batch. This method should not bother trying to delete the batch itself, or rows thereof. It typically is only concerned with deleting extra files on disk, related to the batch.

execute(batch, user=None, progress=None, **kwargs)[source]

Default behavior here will create and return a new rattail Customer Order. It also may “add contact info” e.g. to the customer record. Override as needed.

get_case_price_for_row(row)[source]

Calculate and return the per-case price for the given row.

NB. we do not store case price, only unit price. maybe that should change some day..

get_contact(batch)[source]

Should return the contact record (i.e. Customer or Person) for the batch.

get_contact_display(batch)[source]

Should return contact display text for the batch, i.e. customer name.

get_contact_emails(batch)[source]

Retrieve all email records on file for the batch contact, to be presented as options for user to choose from when making a new order.

Note that the default logic will exclude invalid email addresses.

get_contact_id(batch)[source]

Should return contact ID for the batch, i.e. customer ID.

get_contact_notes(batch)[source]

Get extra “contact notes” which should be made visible to the user who is entering the new order.

get_contact_phones(batch)[source]

Retrieve all phone records on file for the batch contact, to be presented as options for user to choose from when making a new order.

get_customer_info(batch, **kwargs)[source]

Return a data dict containing misc. info pertaining to the customer/person for the order batch.

get_default_item_discount(product=None, **kwargs)[source]

Returns default item discount available. If product is given, the default may be specific to its department etc.

get_past_orders(batch, **kwargs)[source]

Retrieve a list of past orders for the batch contact.

get_past_products(batch, **kwargs)[source]

Should return a (possibly empty) list of products which have been ordered in the past by the customer who is associated with the given batch.

get_product_info(batch, product, **kwargs)[source]

Return a data dict containing misc. info pertaining to the given product, for the order batch.

init_batch(batch, progress=None, **kwargs)[source]

Assign the “local” store to the batch, if applicable.

make_new_order(batch, rows, user=None, progress=None, **kwargs)[source]

Create and return a new rattail Customer Order based on the batch contents.

new_order_requires_customer()[source]

Returns a boolean indicating whether a new “customer order” in fact requires a proper customer account, or not. Note that in all cases a new order requires a person to associate with, but technically the customer is optional, unless this returns true.

normalize_email(email)[source]

Normalize the given email record to simple data dict, for passing around via JSON etc.

normalize_phone(phone)[source]

Normalize the given phone record to simple data dict, for passing around via JSON etc.

person_autocomplete(session, term, **kwargs)[source]

Override the Person autocomplete, to search by phone number as well as name.

product_price_may_be_questionable()[source]

Returns a boolean indicating whether “any” product’s price may be questionable. So this isn’t saying that a price is questionable but rather that it may be, if the user indicates it. (That checkbox is only shown for the user if this flag is true.)

refresh_row(row)[source]

This method will be passed a row object which has already been properly added to a batch, and which has basic required fields already populated. This method is then responsible for further populating all applicable fields for the row, based on current data within the appropriate system(s).

Note that in some cases this method may be called multiple times for the same row, e.g. once when first creating the batch and then later when a user explicitly refreshes the batch. The method logic must account for this possibility.

refresh_row_from_pending_product(row)[source]

Refresh basic row attributes from its pending product.

remove_row(row)[source]

Remove the given row from its batch, and update the batch accordingly. How exactly the row is “removed” is up to this method. Default is to set the row’s removed flag, then invoke the refresh_batch_status() method.

Note that callers should not use this method, but custom batch handlers should override this method. Conversely, custom handlers should not override the do_remove_row() method, but callers should use that one directly.

set_initial_item_status(item, user, **kwargs)[source]

Set the initial status for the given order item, and attach any events.

The first logical status is CUSTORDER_ITEM_STATUS_INITIATED and an item may stay there if there is some other step(s) which must occur before the item is ready to proceed. For instance the default logic will leave it there if the price needs to be confirmed, but you can override as needed, for instance if you require payment up-front.

The second status is CUSTORDER_ITEM_STATUS_READY which indicates the item is ready to proceed. The default logic will auto-advance the item to this status if the price does not need to be confirmed. Again you may need to override e.g. to prevent this until up-front payment is received.

unassign_contact(batch, **kwargs)[source]

Unassign the customer and/or person “contact” for the order.

uom_choices_for_product(product)[source]

Return a list of UOM choices for the given product.

uom_choices_for_row(row)[source]

Return a list of UOM choices for the given batch row.

update_contact_info(batch, user, **kwargs)[source]

Update contact info from the batch, onto the customer record.

update_pending_product(row, data)[source]

Update the pending product data for the given batch row.

why_not_add_product(product, batch)[source]

This method can inspect the given product, and batch, to determine if the product may be added to the batch as a new row. Useful to e.g. prevent one customer from ordering too many things, etc.

Returns:

If there is a reason not to add the product, should return that reason as a string; otherwise None.

why_not_execute(batch, **kwargs)[source]

This method should inspect the given batch and, if there is a reason that execution should not be allowed for it, the method should return a text string indicating that reason. It should return None if no such reason could be identified, and execution should be allowed.

Note that it is assumed the batch has not already been executed, since execution is globally prevented for such batches. In other words you needn’t check for that as a possible reason not to execute.