def _remember_customer(request): if 'customer_id' in request.session: request.ctx.customer = Customer.load(request.session['customer_id']) elif 'customer_id' in request.params: request.ctx.customer = Customer.load(request.params.get('customer_id')) if request.ctx.customer: if request.ctx.customer.campaign.company.enterprise_id != request.ctx.enterprise.enterprise_id: raise HTTPForbidden() #pragma: no cover
def show_appointments(self): customer_id = self.request.matchdict.get('customer_id') customer = Customer.load(customer_id) return { 'customer' : customer, 'appointments' : Appointment.find_by_customer(customer) }
def _save(self, customer_id=None, do_redir=True): user_id = None if self.request.ctx.user: user_id = self.request.ctx.user.user_id cust = Customer.load(customer_id) if not cust: cust = Customer() cust.user_created = cust.user_assigned = user_id else: self.forbid_if(cust.campaign.company.enterprise_id != self.enterprise_id) cust.bind(self.request.POST) cust.save() cust.flush() cust.clear_attributes() for i in range(10): attr_name = self.request.POST.get('attr_name[%d]' % i) attr_value = self.request.POST.get('attr_value[%d]' % i) if attr_name and attr_value: cust.set_attr(attr_name, attr_value) self.flash('Successfully saved %s %s.' % (cust.fname, cust.lname)) if do_redir: redir = self.request.POST.get('redir') return HTTPFound(redir if redir else '/crm/customer/edit/%s' % cust.customer_id) else: return cust
def status_dialog(self): customer_id = self.request.matchdict.get('customer_id') customer = Customer.load(customer_id) self.forbid_if(not customer or customer.campaign.company.enterprise_id != self.enterprise_id) order = order_item = events = redir = None if self.request.GET.get('order_id'): order = CustomerOrder.load(self.request.GET.get('order_id')) self.forbid_if(not order or order.campaign.company.enterprise_id != self.enterprise_id) events = util.select_list(StatusEvent.find_all_applicable(self.enterprise_id, order), 'event_id', 'display_name', True) redir = '/crm/customer/show_orders/%s' % customer_id elif self.request.GET.get('order_item_id'): order_item = OrderItem.load(self.request.GET.get('order_item_id')) self.forbid_if(not order_item or order_item.order.campaign.company.enterprise_id != self.enterprise_id) events = util.select_list(StatusEvent.find_all_applicable(self.enterprise_id, order_item), 'event_id', 'display_name', True) redir = '/crm/customer/edit_order_dialog/%s/%s' % (customer_id, order_item.order_id) else: events = util.select_list(StatusEvent.find_all_applicable(self.enterprise_id, customer), 'event_id', 'display_name', True) redir = '/crm/customer/edit/%s' % customer_id return { 'customer' : customer, 'order' : order, 'order_item' : order_item, 'events' : events, 'redir' : redir }
def show_attributes(self): customer_id = self.request.matchdict.get('customer_id') customer = Customer.load(customer_id) self.forbid_if(not customer or customer.campaign.company.enterprise_id != self.enterprise_id) return { 'customer' : customer, 'attrs' : customer.get_attrs() }
def _prep_add_order_dialog(self, customer_id): customer = Customer.load(customer_id) self.forbid_if(not customer or customer.campaign.company.enterprise_id != self.enterprise_id) products = Product.find_by_campaign(customer.campaign) return { 'customer' : customer, 'products' : products }
def show_orders(self): customer_id = self.request.matchdict.get('customer_id') customer = Customer.load(customer_id) self.forbid_if(not customer or customer.campaign.company.enterprise_id != self.enterprise_id) return { 'customer' : customer, 'orders' : [order for order in customer.orders if order.delete_dt is None and order.cancel_dt is None] }
def delete(self): customer_id = self.request.matchdict.get('customer_id') customer = Customer.load(customer_id) self.forbid_if(not customer or customer.campaign.company.enterprise_id != self.enterprise_id) customer.mod_dt = util.now() customer.delete_dt = util.now() Status.add(customer, customer, StatusEvent.find(self.enterprise_id, 'Customer', 'DELETED'), 'Customer Deleted') return 'True'
def show_billings(self): customer_id = self.request.matchdict.get('customer_id') customer = Customer.load(customer_id) self.forbid_if(not customer or customer.campaign.company.enterprise_id != self.enterprise_id) return { 'customer' : customer, 'billings' : Journal.find_all_by_customer(customer, self.offset), 'offset' : self.offset }
def show_history(self): customer_id = self.request.matchdict.get('customer_id') customer = Customer.load(customer_id) self.forbid_if(not customer or customer.campaign.company.enterprise_id != self.enterprise_id) return { 'customer' : customer, 'history' : Status.find_by_customer(customer, self.offset), 'offset' : self.offset }
def show_status_dialog(self): customer_id = self.request.matchdict.get('customer_id') status_id = self.request.matchdict.get('status_id') customer = Customer.load(customer_id) self.forbid_if(not customer or customer.campaign.company.enterprise_id != self.enterprise_id) status = Status.load(status_id) self.forbid_if(not status or str(customer.customer_id) != str(customer_id)) return { 'customer' : customer, 'status' : status }
def show_billing_dialog(self): customer_id = self.request.matchdict.get('customer_id') journal_id = self.request.matchdict.get('journal_id') customer = Customer.load(customer_id) self.forbid_if(not customer or customer.campaign.company.enterprise_id != self.enterprise_id) journal = Journal.load(journal_id) self.forbid_if(not journal or str(journal.customer_id) != str(customer_id)) return { 'customer' : customer, 'journal' : journal }
def apply_payment(self): customer_id = self.request.matchdict.get('customer_id') order_id = self.request.matchdict.get('order_id') if 'bill_cc_token' in self.request.POST and self.request.POST['bill_cc_token']: cust = Customer.load(customer_id) order = CustomerOrder.load(order_id) bill = self._create_billing(cust) self._bill_credit_card(cust, order, bill) else: self._apply_payment(customer_id, order_id) return HTTPFound('/crm/customer/edit_order_dialog/%s/%s' % (customer_id, order_id))
def cancel_order_dialog(self): customer_id = self.request.matchdict.get('customer_id') order_id = self.request.matchdict.get('order_id') customer = Customer.load(customer_id) self.forbid_if(not customer or customer.campaign.company.enterprise_id != self.enterprise_id) order = CustomerOrder.load(order_id) self.forbid_if(not order or order.customer_id != customer.customer_id) return { 'customer' : customer, 'order' : order }
def return_item_dialog(self): customer_id = self.request.matchdict.get('customer_id') order_id = self.request.matchdict.get('order_id') order_item_id = self.request.matchdict.get('order_item_id') customer = Customer.load(customer_id) self.forbid_if(not customer or customer.campaign.company.enterprise_id != self.enterprise_id) order = customer.get_order(order_id) self.forbid_if(not order) order_item = OrderItem.load(order_item_id) self.forbid_if(not order_item or str(order_item.order.order_id) != str(order.order_id)) return { 'customer' : customer, 'order' : order, 'order_item' : order_item }
def _edit_impl(self): customer_id = self.request.matchdict.get('customer_id') customer = None if customer_id: customer = Customer.load(customer_id) self.forbid_if(not customer or customer.campaign.company.enterprise_id != self.enterprise_id) self._add_to_recent(customer) else: customer = Customer() customer.campaign = self.request.ctx.site.company.default_campaign return { 'customer' : customer, 'users' : util.select_list(Users.find_all(self.enterprise_id), 'user_id', ['fname', 'lname'], True), 'phases' : util.select_list(CustomerPhase.find_all(self.enterprise_id), 'phase_id', 'display_name', True), 'campaigns' : util.select_list(Campaign.find_all(self.enterprise_id), 'campaign_id', 'name') }
def return_item(self): customer_id = self.request.matchdict.get('customer_id') order_id = self.request.matchdict.get('order_id') order_item_id = self.request.matchdict.get('order_item_id') customer = Customer.load(customer_id) self.forbid_if(not customer or customer.campaign.company.enterprise_id != self.enterprise_id) order = customer.get_order(order_id) self.forbid_if(not order) order_item = OrderItem.load(order_item_id) self.forbid_if(not order_item or str(order_item.order.order_id) != str(order.order_id)) user = self.request.ctx.user return_type = self.request.POST.get('rt_refund_type') quantity_returned = float(self.request.POST.get('quantity_returned')) credit_amount = float(self.request.POST.get('credit_amount')) jrnl = Journal.create_new(credit_amount, customer, order, user, return_type) ret = ProductReturn.create_new(order_item.product, order_item.order, quantity_returned, credit_amount, jrnl, user) status_note = "'%s' returned. $%.2f refunded by %s" % (order_item.product.name, credit_amount, return_type) Status.add(customer, order_item, Status.find_event(self.enterprise_id, order_item, 'RETURN'), status_note) order_item.quantity -= quantity_returned if order_item.quantity == 0: order_item.delete_dt = util.today() order_item.save() if order_item.product.track_inventory: InventoryJournal.create_new(order_item.product, 'Return', quantity_returned, order_item, None, None, ret) for attr_kid in order_item.children: Status.add(customer, attr_kid, Status.find_event(self.enterprise_id, attr_kid, 'RETURN'), status_note) attr_kid_prod = attr_kid.product if attr_kid_prod.track_inventory: InventoryJournal.create_new(attr_kid_prod, 'Return', quantity_returned, attr_kid) self.flash(status_note) if len(order.active_items) == 0: # KB: [2012-09-06]: Deleted the one thing out of this # order. Kill the order status_note = 'Only item in order returned. Order cancelled.' self._cancel_order_impl(order_id, status_note, False) self.flash(status_note) ret = HTTPFound('/crm/customer/show_orders/%s' % customer_id) else: ret = HTTPFound('/crm/customer/edit_order_dialog/%s/%s' % (customer_id, order_id)) customer.invalidate_caches() return ret
def edit_order_dialog(self): customer_id = self.request.matchdict.get('customer_id') order_id = self.request.matchdict.get('order_id') customer = Customer.load(customer_id) self.forbid_if(not customer or customer.campaign.company.enterprise_id != self.enterprise_id) order = customer.get_order(order_id) return { 'customer' : customer, 'order' : order, 'comm_packing_slip_id' : order.campaign.comm_packing_slip_id, 'total_price' : order.total_price(), 'total_item_price' : order.total_item_price(), 'total_handling_price' : order.total_handling_price(), 'total_shipping_price' : order.total_shipping_price(), 'total_payments_applied' : order.total_payments_applied(), 'total_discounts_applied' : order.total_discounts_applied(), 'total_due' : order.total_payments_due() }
def exclog_tween(request, get_logger=logging.getLogger): # getLogger injected for testing purposes try: return handler(request) except ignored: raise except: logger = get_logger('exc_logger') ent = Enterprise.load(request.session['enterprise_id']) if 'enterprise_id' in request.session else None cust = Customer.load(request.session['customer_id']) if 'customer_id' in request.session else None user = Users.load(request.session['user_id']) if 'user_id' in request.session else None if extra_info: message = dedent("""\n %(url)s ENTERPRISE: %(ent)s CUSTOMER: %(cust)s USER: %(user)s SESSION %(sess)s ENVIRONMENT %(env)s PARAMETERS %(params)s """ % dict(url=request.url, sess=pformat(request.session.items()), ent ="%s : %s" % (ent.enterprise_id, ent.name) if ent else None, cust="%s : %s" % (cust.customer_id, cust.email) if cust else None, user="******" % (user.user_id, user.email) if user else None, env=pformat(request.environ), params=pformat(request.params))) else: message = request.url logger.exception(message) raise
def _edit_impl(self): appointment_id = self.request.matchdict.get('appointment_id') customer_id = self.request.matchdict.get('customer_id') if appointment_id: appointment = Appointment.load(appointment_id) self.forbid_if(not appointment) else: appointment = Appointment() hours = util.hours_list() customer = None customer = Customer.load(customer_id) self.forbid_if(customer and customer.campaign.company.enterprise_id != self.enterprise_id) appointment.customer_id = customer_id return { 'today' : util.today_date(), 'tomorrow' : util.today_date() + datetime.timedelta(days=1), 'customer' : customer, 'appointment' : appointment, 'timezones' : country_timezones('US'), 'hours' : hours }
def apply_payment_dialog(self): customer_id = self.request.matchdict.get('customer_id') order_id = self.request.matchdict.get('order_id') customer = Customer.load(customer_id) self.forbid_if(not customer or customer.campaign.company.enterprise_id != self.enterprise_id) order = customer.get_order(order_id) self.forbid_if(not order) total_due = order.total_payments_due() pre_order_balance = customer.get_current_balance() return { 'customer' : customer, 'order' : order, 'total_price' : order.total_price(), 'payment_methods' : Journal.get_payment_methods(self.request.ctx.enterprise), 'total_payments_applied' : order.total_payments_applied(), 'total_discounts_applied' : order.total_discounts_applied(), 'total_due' : total_due, 'pre_order_balance' : pre_order_balance, 'enterprise' : self.request.ctx.enterprise, 'total_due_after_balance' : total_due+pre_order_balance if (total_due+pre_order_balance) > 0 else 0 }
def _apply_payment(self, customer_id, order_id, pmt_amount=None, pmt_method=None, pmt_note=None): #pylint: disable-msg=R0913 """ KB: [2011-03-09]: Check that everything is kosher Create a journal entry for the order for the amount and type specified in the UI Create a status noting the type and amount of the payment applied. """ customer = Customer.load(customer_id) self.forbid_if(not customer or customer.campaign.company.enterprise_id != self.enterprise_id) order = customer.get_order(order_id) self.forbid_if(not order) user = self.request.ctx.user current_customer_balance = customer.get_current_balance() #prior_payments_applied = order.total_payments_applied() prior_total_due = order.total_payments_due() balance_amount_to_apply = float(self.request.POST.get('pmt_balance_amount_to_apply', 0.0)) amt = float(util.nvl(pmt_amount, self.request.POST.get('pmt_amount'))) method = util.nvl(pmt_method, self.request.POST.get('pmt_method')) note = util.nvl(pmt_note, self.request.POST.get('pmt_note')) self.forbid_if(round(amt + balance_amount_to_apply, 2) > round(prior_total_due, 2), "amt + balance_amount_to_apply > prior_total_due") self.forbid_if(current_customer_balance > 0 and round(balance_amount_to_apply, 2) > round(current_customer_balance, 2), "balance_amount_to_apply > current_customer_balance") pmt_type = 'PartialPayment' if amt == prior_total_due: pmt_type = 'FullPayment' Journal.create_new(amt, customer, order, user, pmt_type, method, note) status_note = '%s applied: $%s' % (pmt_type, util.money(amt)) Status.add(customer, order, Status.find_event(self.enterprise_id, order, 'PAYMENT_APPLIED'), status_note) self.flash(status_note) if balance_amount_to_apply > 0: Journal.create_new(balance_amount_to_apply, customer, order, user, 'CreditDecrease') status_note = '%s applied: $%s' % ('CreditDecrease', util.money(balance_amount_to_apply)) Status.add(customer, order, Status.find_event(self.enterprise_id, order, 'PAYMENT_APPLIED'), status_note) self.flash(status_note) customer.invalidate_caches() customer.flush() return 'True'
def save_status(self): customer_id = self.request.matchdict.get('customer_id') customer = Customer.load(customer_id) self.forbid_if(not customer or customer.campaign.company.enterprise_id != self.enterprise_id) event = StatusEvent.load(self.request.POST.get('event_id')) self.forbid_if(not event or not self.request.POST.get('event_id') or (not event.is_system and event.enterprise_id is not None and event.enterprise_id != self.enterprise_id)) order = None note = self.request.POST.get('note') if self.request.POST.get('order_id'): order = CustomerOrder.load(self.request.POST.get('order_id')) self.forbid_if(not order or order.campaign.company.enterprise_id != self.enterprise_id) Status.add(customer, order, event, note, self.request.ctx.user) self.flash('Statused Order to %s' % event.display_name) elif self.request.POST.get('order_item_id'): order_item = OrderItem.load(self.request.POST.get('order_item_id')) self.forbid_if(not order_item or order_item.order.campaign.company.enterprise_id != self.enterprise_id) Status.add(customer, order_item, event, note, self.request.ctx.user) self.flash('Statused Item to %s' % event.display_name) else: Status.add(customer, customer, event, note, self.request.ctx.user) self.flash('Statused Customer to %s' % event.display_name) customer.invalidate_caches() return self.find_redirect()
def add_order(self): """ KB: [2013-02-20]: MOD ATTR CustomerController.add_order : Modify to allow for attributes to be passed in the post. """ customer_id = self.request.matchdict.get('customer_id') cust = Customer.load(customer_id) self.forbid_if(not cust) # KB: [2013-02-24]: products are passed as products[$product_id] = quantity product_ids = {} for key in self.request.POST.keys(): if key.startswith('products'): match = re.search(r'^.*\[(.*)\]', key) if match: pid = match.group(1) quant = float(util.nvl(self.request.POST.get(key), '1.0')) if pid not in product_ids: product_ids[pid] = 0 product_ids[pid] += quant # KB: [2013-02-24]: attributes are passed as attributes[$attribute_id] = $parent_product_id attributes = {} for key in self.request.POST.keys(): if key.startswith('attributes'): match = re.search(r'^.*\[(.*)\]', key) if match: attribute_product_id = match.group(1) parent_product_id = self.request.POST.get(key) attributes[attribute_product_id] = { 'parent_product' : Product.load(parent_product_id), 'attribute_product' : Product.load(attribute_product_id) } order_id = self._add_order_impl(customer_id, product_ids, attributes, None, self.request.ctx.user, self.request.POST.get('discount_id'), self.request.POST.get('campaign_id', self.request.GET.get('campaign_id')), self.incl_tax) cust.invalidate_caches() return str(order_id)
def _add_order_impl(self, customer_id, product_ids, attributes, prices, user, discount_id, campaign_id, incl_tax=True): #pylint: disable-msg=R0913 """ KB: [2013-02-20]: attributes = [{quantity : 0, product : <Product...>}, {...}] """ cust = Customer.load(customer_id) self.forbid_if(not cust or cust.campaign.company.enterprise_id != self.enterprise_id) cart = Cart() campaign_id = campaign_id if campaign_id else cust.campaign_id cart.discount_id = discount_id for pid in product_ids.keys(): quantity = product_ids[pid] price = prices[pid] if prices and pid in prices else None attrs = {} for attr in [attr['attribute_product'] for attr in attributes.values() if str(attr['parent_product'].product_id) == pid]: attrs[attr.product_id] = { 'quantity' : 0, 'product' : attr} cart.add_item(product=Product.load(pid), campaign=cust.campaign, quantity=quantity, attributes=attrs, base_price=price) order = cust.add_order(cart, user, self.enterprise_id, cust.campaign, incl_tax=incl_tax) order.flush() return order.order_id
def edit_order(self): #pylint: disable-msg=R0915,R0912 customer_id = self.request.matchdict.get('customer_id') order_id = self.request.matchdict.get('order_id') oids_to_delete = self.request.POST.getall('order_items_to_delete[]') customer = Customer.load(customer_id) self.forbid_if(not customer or customer.campaign.company.enterprise_id != self.enterprise_id) order = customer.get_order(order_id) self.forbid_if(not order) order.shipping_total = self.request.POST.get('shipping_total') if self.request.POST.get('shipping_total') else 0.0 order.create_dt = self.request.POST.get('create_dt') if self.request.POST.get('create_dt') else order.create_dt order.save() total_payments_applied = order.total_payments_applied() for oid in oids_to_delete: oitem = OrderItem.load(oid) Status.add(customer, oitem, Status.find_event(self.enterprise_id, oitem, 'DELETED'), 'OrderItem deleted ') prod = oitem.product if prod.track_inventory: InventoryJournal.create_new(prod, 'Cancelled Item', oitem.quantity, oitem) for attr_kid in oitem.children: Status.add(customer, attr_kid, Status.find_event(self.enterprise_id, attr_kid, 'DELETED'), 'OrderItem deleted ') attr_kid_prod = attr_kid.product if attr_kid_prod.track_inventory: InventoryJournal.create_new(attr_kid_prod, 'Cancelled Item', oitem.quantity, attr_kid) attr_kid.soft_delete() oitem.soft_delete() # extract order_items[27][quantity] to set those properties. order_items = {} for key in self.request.POST.keys(): if key.startswith('order_items'): match = re.search(r'^.*\[(.*)\]\[(.*)\]', key) if match: order_item_id = match.group(1) attr = match.group(2) new_val = float(self.request.POST.get(key)) if attr != 'product_id' else self.request.POST.get(key) # KB: [2011-03-07]: If the ID ends in '_', its not really an ID but a new item. # product_id will only show up as non-null in the hash of a new product if order_item_id[-1] == '_': order_item_product = Product.load(self.request.POST.get('order_items[%s][product_id]' % order_item_id)) if not order_items.has_key(order_item_id): order_items[order_item_id] = order.augment_order(customer, order_item_product, customer.campaign, self.request.ctx.user) oitem = order_items[order_item_id] assert oitem.product is not None if 'quantity' == attr: new_val = float(new_val) if order_item_product.track_inventory: InventoryJournal.create_new(order_item_product, 'Sale', new_val, oitem) setattr(oitem, attr, new_val) oitem.save() else: if not order_items.has_key(order_item_id): order_items[order_item_id] = OrderItem.load(order_item_id) oitem = order_items[order_item_id] order_item_product = oitem.product if util.money(getattr(oitem, attr)) != util.money(new_val): Status.add(customer, oitem, Status.find_event(self.enterprise_id, oitem, 'MODIFIED'), 'Order Item modified: (id=%s). %s : %s -> %s' % (oitem.order_item_id, attr, util.money(getattr(oitem, attr)), util.money(new_val))) if 'quantity' == attr: new_val = float(new_val) if not total_payments_applied: if order_item_product.track_inventory: InventoryJournal.cleanup(oitem, 'Sale') InventoryJournal.create_new(order_item_product, 'Sale', new_val, oitem) setattr(oitem, attr, new_val) oitem.save() Status.add(customer, order, Status.find_event(self.enterprise_id, order, 'MODIFIED'), 'Order modified') customer.invalidate_caches() self.flash("Saved Order") return 'True'
def customer(self): from pvscore.model.crm.customer import Customer return Customer.load(self.customer_id)
def self_get_balance(self): customer_id = self.request.matchdict.get('customer_id') customer = Customer.load(customer_id) self.forbid_if(not customer or str(self.request.ctx.customer.customer_id) != str(customer_id) or customer.campaign.company.enterprise_id != self.enterprise_id) return str(customer.get_current_balance())