def testGetName(self): product = self.create_product() supplier = self.create_supplier() info = ProductSupplierInfo(store=self.store, product=product, supplier=supplier) self.assertEqual(info.get_name(), supplier.get_description())
def get_order_item(self, sellable, cost, quantity, batch=None, parent=None): assert batch is None # Associate the product with the supplier if they are not yet. This # happens when the user checked the option to show all products on the # first step supplier_info = self._get_supplier_info() if not supplier_info: supplier_info = ProductSupplierInfo(product=sellable.product, supplier=self.model.supplier, store=self.store) if parent: component = self.get_component(parent, sellable) quantity = quantity * component.quantity else: if sellable.product.is_package: cost = Decimal('0') supplier_info.base_cost = cost item = self.model.add_item(sellable, quantity, parent=parent) self._set_expected_receival_date(item) item.cost = cost return item
def test_lead_time(self): product = self.create_product() Storable(product=product, store=self.store) branch = get_current_branch(self.store) supplier1 = self.create_supplier() ProductSupplierInfo(store=self.store, product=product, supplier=supplier1, lead_time=10) self.assertEqual(product.get_max_lead_time(1, branch), 10) supplier2 = self.create_supplier() ProductSupplierInfo(store=self.store, product=product, supplier=supplier2, lead_time=20) self.assertEqual(product.get_max_lead_time(1, branch), 20) # Now for composed products product = self.create_product(create_supplier=False) product.is_composed = True product.production_time = 5 Storable(product=product, store=self.store) component = self.create_product(create_supplier=False) Storable(product=component, store=self.store) ProductSupplierInfo(store=self.store, product=component, supplier=supplier1, lead_time=7) self.assertEqual(component.get_max_lead_time(1, branch), 7) pc = ProductComponent(product=product, component=component, quantity=1, store=self.store) self.assertEqual(product.get_max_lead_time(1, branch), 12) # Increase the component stock component.storable.increase_stock(1, branch, 0, 0) self.assertEqual(product.get_max_lead_time(1, branch), 5) # Increase the quantity required: pc.quantity = 2 self.assertEqual(product.get_max_lead_time(1, branch), 12)
def maybe_create_product_supplier_info(self, nfe_item, supplier): from stoqlib.domain.product import ProductSupplierInfo product = nfe_item.sellable.product info = product.get_product_supplier_info(supplier, self.branch) if not info: info = ProductSupplierInfo(store=self.store, product=nfe_item.sellable.product, supplier_code=nfe_item.supplier_code, supplier=supplier, branch=self.branch) info.base_cost = Decimal(nfe_item.cost) extra_cost = nfe_item.ipi_cost + nfe_item.icmsst_cost nfe_item.sellable.cost = info.base_cost + extra_cost
def get_order_item(self, sellable, cost, quantity): # Associate the product with the supplier if they are not yet. This # happens when the user checked the option to show all products on the # first step supplier_info = self._get_supplier_info() if not supplier_info: supplier_info = ProductSupplierInfo(product=sellable.product, supplier=self.model.supplier, store=self.store) supplier_info.base_cost = cost item = self.model.add_item(sellable, quantity) self._set_expected_receival_date(item) item.cost = cost return item
def create_model(self): product = self._product supplier = self.target_combo.get_selected_data() if product.is_supplied_by(supplier): product_desc = self._product.sellable.get_description() info(_(u'%s is already supplied by %s') % (product_desc, supplier.person.name)) return model = ProductSupplierInfo(product=product, supplier=supplier, store=self.store) model.base_cost = product.sellable.cost return model
def run_editor(self, obj=None): store = api.new_store() product = self.run_dialog(self.editor_class, self, store, store.fetch(obj), visual_mode=self._read_only) # This means we are creating a new product. After that, add the # current supplier as the supplier for this product if (obj is None and product and not product.is_supplied_by(self._supplier)): ProductSupplierInfo(store=store, supplier=store.fetch(self._supplier), product=product, base_cost=product.sellable.cost, is_main_supplier=True) if store.confirm(product): # If the return value is an ORMObject, fetch it from # the right connection if isinstance(product, ORMObject): product = type(product).get(product.id, store=self.store) # If we created a new object, confirm the dialog automatically if obj is None: self.confirm(product) store.close() return store.close() return product
def test_get_unblocked_sellables(self): # Sellable and query without supplier sellable = self.create_sellable() available = Sellable.get_unblocked_sellables(self.store) self.assertTrue(sellable in list(available)) # Sellable without supplier, but querying with one supplier = self.create_supplier() available = Sellable.get_unblocked_sellables(self.store, supplier=supplier) self.assertFalse(sellable in list(available)) # Relate the two from stoqlib.domain.product import ProductSupplierInfo ProductSupplierInfo(store=self.store, supplier=supplier, product=sellable.product, is_main_supplier=True) # Now the sellable should appear in the results available = Sellable.get_unblocked_sellables(self.store, supplier=supplier) self.assertTrue(sellable in list(available)) # Now the sellable should appear in the results storable = Storable(product=sellable.product, store=self.store) available = Sellable.get_unblocked_sellables(self.store, storable=storable) self.assertTrue(sellable in list(available))
def test_with_unblocked_sellables_query(self): p1 = self.create_product() supplier = self.create_supplier() # Product should appear when querying without a supplier query = Sellable.get_unblocked_sellables_query(self.store) results = self.store.find(ProductFullStockView, query) self.assertTrue(p1.id in [p.product_id for p in results]) # But should not appear when querying with a supplier # When querying using the supplier, we should use the # ProductFullStockSupplierView instead. query = Sellable.get_unblocked_sellables_query(self.store, supplier=supplier) results = self.store.find(ProductFullStockItemSupplierView, query) self.assertFalse(p1.id in [p.id for p in results]) # Now relate the two ProductSupplierInfo(store=self.store, supplier=supplier, product=p1, is_main_supplier=True) # And it should appear now query = Sellable.get_unblocked_sellables_query(self.store, supplier=supplier) results = self.store.find(ProductFullStockItemSupplierView, query) self.assertTrue(p1.id in [s.product_id for s in results]) # But should not appear for a different supplier other_supplier = self.create_supplier() query = Sellable.get_unblocked_sellables_query(self.store, supplier=other_supplier) results = self.store.find(ProductFullStockItemSupplierView, query) self.assertFalse(p1.id in [s.product_id for s in results])
def testDefaultLeadTimeValue(self): product = self.create_product() supplier = self.create_supplier() info = ProductSupplierInfo(store=self.store, product=product, supplier=supplier) default_lead_time = 1 self.assertEqual(info.lead_time, default_lead_time)
def test_get_main_supplier_info(self): self.failIf(self.product.get_main_supplier_info()) supplier = self.create_supplier() ProductSupplierInfo(store=self.store, supplier=supplier, product=self.product, is_main_supplier=True) self.failUnless(self.product.get_main_supplier_info())
def _set_expected_receival_date(self, item): supplier = self.model.supplier product = item.sellable.product supplier_info = ProductSupplierInfo.find_by_product_supplier( self.store, product, supplier, api.get_current_branch(self.store)) if supplier_info is not None: delta = datetime.timedelta(days=supplier_info.lead_time) expected_receival = self.model.open_date + delta item.expected_receival_date = expected_receival
def _set_expected_receival_date(self, item): supplier = self.model.supplier product = item.sellable.product supplier_info = ProductSupplierInfo.find_by_product_supplier( self.store, product, supplier) if supplier_info is not None: delta = datetime.timedelta(days=supplier_info.lead_time) expected_receival = self.model.open_date + delta item.expected_receival_date = expected_receival
def create_product_supplier_info(self, supplier=None, product=None): from stoqlib.domain.product import ProductSupplierInfo product = product or self.create_product(create_supplier=False) supplier = supplier or self.create_supplier() return ProductSupplierInfo( store=self.store, supplier=supplier, product=product, is_main_supplier=True, )
def create_model(self, store): self._model_created = True sellable = Sellable(store=store) model = Product(store=store, sellable=sellable) no_storable = [Product.TYPE_WITHOUT_STOCK, Product.TYPE_PACKAGE] if not self._product_type in no_storable: storable = Storable(product=model, store=store) if self._product_type == Product.TYPE_BATCH: storable.is_batch = True elif self._product_type == Product.TYPE_WITHOUT_STOCK: model.manage_stock = False elif self._product_type == Product.TYPE_CONSIGNED: model.consignment = True elif self._product_type == Product.TYPE_GRID: model.is_grid = True # Configurable products should not manage stock model.manage_stock = False elif self._product_type == Product.TYPE_PACKAGE: model.is_package = True # Package products should not manage stock model.manage_stock = False if self._template is not None: sellable.tax_constant = self._template.sellable.tax_constant sellable.unit = self._template.sellable.unit sellable.category = self._template.sellable.category sellable.base_price = self._template.sellable.base_price sellable.cost = self._template.sellable.cost sellable.default_sale_cfop = self._template.sellable.default_sale_cfop model.manufacturer = self._template.manufacturer model.brand = self._template.brand model.model = self._template.model model.family = self._template.family model.ncm = self._template.ncm model.set_icms_template(self._template._icms_template) model.set_ipi_template(self._template._ipi_template) model.set_pis_template(self._template._pis_template) model.set_cofins_template(self._template._cofins_template) for product_attr in self._template.attributes: ProductAttribute(store=self.store, product_id=model.id, attribute_id=product_attr.attribute.id) for supplier_info in self._template.suppliers: ProductSupplierInfo(store=self.store, product=model, supplier=supplier_info.supplier) else: sellable.tax_constant = sysparam.get_object( self.store, 'DEFAULT_PRODUCT_TAX_CONSTANT') sellable.unit_id = sysparam.get_object_id('SUGGESTED_UNIT') return model
def _get_supplier_info(self): sellable = self.proxy.model.sellable if not sellable: # FIXME: We should not be accessing a private method here sellable, batch = self._get_sellable_and_batch() if not sellable: return product = sellable.product supplier = self.model.supplier return ProductSupplierInfo.find_by_product_supplier( self.store, product, supplier)
def _get_supplier_info(self): sellable = self.proxy.model.sellable if not sellable: # FIXME: We should not be accessing a private method here sellable, batch = self._get_sellable_and_batch() if not sellable: return product = sellable.product supplier = self.model.supplier return ProductSupplierInfo.find_by_product_supplier( self.store, product, supplier, api.get_current_branch(self.store))
def get_order_item(self, sellable, cost, quantity, batch=None, parent=None): assert batch is None # Associate the product with the supplier if they are not yet. This # happens when the user checked the option to show all products on the # first step supplier_info = self._get_supplier_info() if not supplier_info: supplier_info = ProductSupplierInfo(product=sellable.product, supplier=self.model.supplier, store=self.store) if parent: component_quantity = self.get_component_quantity(parent, sellable) quantity = quantity * component_quantity cost = Decimal('0') else: supplier_info.base_cost = cost item = self.model.add_item(sellable, quantity, parent=parent) self._set_expected_receival_date(item) item.cost = cost return item
def process_one(self, data, fields, store): base_category = self._get_or_create( SellableCategory, store, suggested_markup=Decimal(data.markup), salesperson_commission=Decimal(data.commission), category=None, description=data.base_category) # create a commission source self._get_or_create(CommissionSource, store, direct_value=Decimal(data.commission), installments_value=Decimal(data.commission2), category=base_category) category = self._get_or_create(SellableCategory, store, description=data.category, suggested_markup=Decimal(data.markup2), category=base_category) sellable = Sellable(store=store, cost=Decimal(data.cost), category=category, description=data.description, price=Decimal(data.price)) sellable.barcode = data.barcode sellable.code = u'%02d' % self._code self._code += 1 if u'unit' in fields: if not data.unit in self.units: raise ValueError(u"invalid unit: %s" % data.unit) sellable.unit = store.fetch(self.units[data.unit]) sellable.tax_constant_id = self.tax_constant_id product = Product(store=store, sellable=sellable, ncm=data.ncm) taxes = self._maybe_create_taxes(store) product.set_icms_template(taxes['icms']) product.set_pis_template(taxes['pis']) product.set_cofins_template(taxes['cofins']) supplier = store.fetch(self.supplier) ProductSupplierInfo(store=store, supplier=supplier, is_main_supplier=True, base_cost=Decimal(data.cost), product=product) Storable(product=product, store=store)
def testSuppliers(self): product = self.create_product() supplier = self.create_supplier() info = ProductSupplierInfo(store=self.store, product=product, supplier=supplier) suppliers = list(product.get_suppliers_info()) # self.create_product already adds a supplier. so here we must have 2 self.assertEqual(len(suppliers), 2) self.assertEqual(info in suppliers, True) # product.suppliers should behave just like get_suppliers_info() self.assertEqual(len(list(product.suppliers)), 2) self.assertEqual(info in product.suppliers, True) self.assertEqual(product.is_supplied_by(supplier), True)
def process_one(self, data, fields, store): base_category = self._get_or_create(SellableCategory, store, suggested_markup=int(data.markup), salesperson_commission=int( data.commission), category=None, description=data.base_category) # create a commission source self._get_or_create(CommissionSource, store, direct_value=int(data.commission), installments_value=int(data.commission2), category=base_category) category = self._get_or_create(SellableCategory, store, description=data.category, suggested_markup=int(data.markup2), category=base_category) sellable = Sellable(store=store, cost=Decimal(data.cost), category=category, description=data.description, price=int(data.price)) sellable.barcode = sellable.code = data.barcode if u'unit' in fields: if not data.unit in self.units: raise ValueError(u"invalid unit: %s" % data.unit) sellable.unit = store.fetch(self.units[data.unit]) sellable.tax_constant = store.fetch(self.tax_constant) product = Product(sellable=sellable, store=store) supplier = store.fetch(self.supplier) ProductSupplierInfo(store=store, supplier=supplier, is_main_supplier=True, base_cost=Decimal(data.cost), product=product) Storable(product=product, store=store)
def create_purchase(self, supplier, work_order_item, is_freebie, branch: Branch, station: BranchStation, user: LoginUser): """Create a purchase :param supplier: the |supplier| of that purchase :param work_order_item: The work order item that a purchase is being created for. :param is_freebie: indicates if the item is a freebie """ sellable = work_order_item.sellable store = self.work_order.store purchase = PurchaseOrder(store=store, branch=branch, station=station, status=PurchaseOrder.ORDER_PENDING, supplier=supplier, responsible=user, work_order=self.work_order) if is_freebie: purchase.notes = _( 'The product %s is a freebie') % sellable.description # FIXME We may want the cost 0, but as it is we wont be able to # receive this purchase without changing the receiving. We must # evaluate the consequences of changing the receiving a little bit # further in order to change that behavior. cost = decimal.Decimal('0.01') else: psi = ProductSupplierInfo.find_by_product_supplier( store, sellable.product, supplier, branch) cost = psi.base_cost if psi else sellable.cost # Add the sellable to the purchase purchase_item = purchase.add_item(sellable, quantity=work_order_item.quantity, cost=cost) work_order_item.purchase_item = purchase_item purchase.confirm(user) return purchase
def create_purchase(self, supplier, work_order_item, is_freebie): """Create a purchase :param supplier: the |supplier| of that purchase :param work_order_item: The work order item that a purchase is being created for. :param is_freebie: indicates if the item is a freebie """ sellable = work_order_item.sellable store = self.work_order.store current_branch = api.get_current_branch(store) purchase = PurchaseOrder(store=store, status=PurchaseOrder.ORDER_PENDING, supplier=supplier, responsible=api.get_current_user(store), branch=current_branch, work_order=self.work_order) if is_freebie: purchase.notes = _('The product %s is a freebie') % sellable.description # FIXME We may want the cost 0, but as it is we wont be able to # receive this purchase without changing the receiving. We must # evaluate the consequences of changing the receiving a little bit # further in order to change that behavior. cost = decimal.Decimal('0.01') else: psi = ProductSupplierInfo.find_by_product_supplier(store, sellable.product, supplier) cost = psi.base_cost if psi else sellable.cost # Add the sellable to the purchase purchase_item = purchase.add_item(sellable, quantity=work_order_item.quantity, cost=cost) work_order_item.purchase_item = purchase_item purchase.confirm() return purchase