def test_create(self): # Allow creating purchases in the past. sysparam.set_bool(self.store, 'ALLOW_OUTDATED_OPERATIONS', True) self.wizard = PurchaseWizard(self.store) purchase_branch = self.create_branch() purchase_order = PurchaseOrder(branch=purchase_branch) sellable = self.create_sellable() purchase_order.add_item(sellable=sellable) self.wizard.model.identifier = 12345 self.wizard.model.open_date = localdate(2010, 1, 3).date() self._check_start_step('wizard-purchase-start-step') self._check_item_step('wizard-purchase-item-step') self._check_payment_step('wizard-purchase-payment-step') purchase = self.wizard.model models = [purchase] models.extend(purchase.get_items()) models.extend(purchase.payments) models.append(purchase.group) self.check_wizard(self.wizard, 'wizard-purchase-finish-step', models=models) self.click(self.wizard.next_button)
def test_create(self): # Allow creating purchases in the past. sysparam(self.store).update_parameter(u"ALLOW_OUTDATED_OPERATIONS", u"1") self.wizard = PurchaseWizard(self.store) purchase_branch = self.create_branch() purchase_order = PurchaseOrder(branch=purchase_branch) sellable = self.create_sellable() purchase_order.add_item(sellable=sellable) self.wizard.model.identifier = 12345 self.wizard.model.open_date = localdate(2010, 1, 3).date() self._check_start_step('wizard-purchase-start-step') self._check_item_step('wizard-purchase-item-step') self._check_payment_step('wizard-purchase-payment-step') purchase = self.wizard.model models = [purchase] models.extend(purchase.get_items()) models.extend(purchase.payments) models.append(purchase.group) self.check_wizard(self.wizard, 'wizard-purchase-finish-step', models=models) self.click(self.wizard.next_button)
def test_create(self): # Allow creating purchases in the past. sysparam.set_bool(self.store, 'ALLOW_OUTDATED_OPERATIONS', True) with self.sysparam(MANDATORY_CHECK_NUMBER=True): self.wizard = PurchaseWizard(self.store) purchase_branch = self.create_branch() purchase_order = PurchaseOrder(branch=purchase_branch, station=self.current_station, store=self.store) sellable = self.create_sellable() purchase_order.add_item(sellable=sellable) self.wizard.model.identifier = 12345 self.wizard.model.open_date = localdate(2010, 1, 3).date() self._check_start_step('wizard-purchase-start-step') self._check_item_step('wizard-purchase-item-step') payment_step = self.wizard.get_current_step() payment_step.slave.bank_first_check_number.set_text('12') self._check_payment_step('wizard-purchase-payment-step') purchase = self.wizard.model models = [purchase] models.extend(purchase.get_items()) models.extend(purchase.payments) models.append(purchase.group) self.check_wizard(self.wizard, 'wizard-purchase-finish-step', models=models) self.click(self.wizard.next_button)
def _create_purchase_order(self, store, supplier, items): order = PurchaseOrder(supplier=store.fetch(supplier), branch=api.get_current_branch(store), status=PurchaseOrder.ORDER_QUOTING, expected_receival_date=None, responsible=api.get_current_user(store), group=PaymentGroup(store=store), store=store) for sellable, quantity in items: order.add_item(store.fetch(sellable), quantity) return order
def next_step(self): self.wizard.all_products = self.all_products.get_active() if self.wizard.is_for_another_branch(): info(_('The identifier for this purchase will be defined when it ' 'is synchronized to the detination branch')) self.model.identifier = PurchaseOrder.get_temporary_identifier(self.store) return PurchaseItemStep(self.wizard, self, self.store, self.model)
def _on_WorkOrderStatusChangedEvent(self, order, old_status): if old_status == WorkOrder.STATUS_OPENED: #Do nothing at this point. return optical_wo = OpticalWorkOrder.find_by_work_order(order.store, order) # If there is no optical WO, nothing to do here if optical_wo is None: return if optical_wo.can_create_purchase(): with api.new_store() as store: rv = run_dialog(OpticalSupplierEditor, None, store, order) if not rv: # Return None to let the status be changed without creating a purchase order return order.supplier_order = rv.supplier_order optical_wo.create_purchase(order.store.fetch(rv.supplier), order.store.fetch(rv.item), rv.is_freebie) return for purchase in PurchaseOrder.find_by_work_order(order.store, order): if optical_wo.can_receive_purchase(purchase): optical_wo.receive_purchase(purchase, reserve=True)
def _create_and_confirm_purchase_order(self, identifier, payment_group, notes, station, responsible): self.purchase_order = PurchaseOrder( store=self.store, identifier=identifier, branch=self.branch, status=PurchaseOrder.ORDER_PENDING, open_date=localnow(), notes=notes, freight_type=self.freight_type, expected_freight=self.freight_cost, supplier=self.nfe_supplier.supplier, group=payment_group, station=station) self._add_purchase_order_item() self.purchase_order.confirm(responsible=responsible)
def __init__(self, store, model=None, edit_mode=False): title = self._get_title(model) self.sync_mode = api.sysparam.get_bool('SYNCHRONIZED_MODE') self.current_branch = api.get_current_branch(store) if self.sync_mode and not model: self.temporary_identifier = PurchaseOrder.get_temporary_identifier( store) model = model or self._create_model(store) # Should we show all products or only the ones associated with the # selected supplier? self.all_products = False # If we receive the order right after the purchase. self.receiving_model = None purchase_edit = [ PurchaseOrder.ORDER_CONFIRMED, PurchaseOrder.ORDER_PENDING ] if not model.status in purchase_edit: raise ValueError('Invalid order status. It should ' 'be ORDER_PENDING or ORDER_CONFIRMED') first_step = StartPurchaseStep(self, store, model) BaseWizard.__init__(self, store, first_step, model, title=title, edit_mode=edit_mode)
def test_find_by_work_order(self): work_order = self.create_workorder() purchase = self.create_purchase_order() purchase.work_order = work_order results = PurchaseOrder.find_by_work_order(work_order.store, work_order) for expected_purchase in results: self.assertEquals(purchase, expected_purchase)
def create_purchase_order(self, supplier=None, branch=None): from stoqlib.domain.purchase import PurchaseOrder group = self.create_payment_group() return PurchaseOrder(supplier=supplier or self.create_supplier(), branch=branch or self.create_branch(), group=group, responsible=get_current_user(self.store), store=self.store)
def receive_purchase(self, purchase_order: PurchaseOrder, station: BranchStation, user: LoginUser, reserve=False): receiving = purchase_order.create_receiving_order(station) receiving.confirm(user) if reserve: self.reserve_products(purchase_order, user)
def _create_model(self, store): supplier = sysparam(store).SUGGESTED_SUPPLIER branch = api.get_current_branch(store) status = PurchaseOrder.ORDER_QUOTING group = PaymentGroup(store=store) return PurchaseOrder(supplier=supplier, branch=branch, status=status, expected_receival_date=None, responsible=api.get_current_user(store), group=group, store=store)
def _dialog_purchase(self, id): from stoqlib.domain.purchase import PurchaseOrder from stoqlib.gui.dialogs.purchasedetails import PurchaseDetailsDialog store = api.new_store() purchase = PurchaseOrder.get(int(id), store) retval = run_dialog(PurchaseDetailsDialog, self.app, store, purchase) if store.confirm(retval): self.refresh() store.close()
def test_new_purchase_confirm(self, run_dialog, new_store): new_store.return_value = self.store supplier = self.create_supplier() sale = self.create_sale() product = self.create_product() work_order = self.create_workorder() work_order.status = WorkOrder.STATUS_WORK_IN_PROGRESS work_order.sale = sale work_item = work_order.add_sellable(product.sellable) self.create_optical_work_order(work_order) app = self.create_app(ServicesApp, u'services') app.search.refresh() for wo_view in app.search.results: if wo_view.work_order == work_order: break self.assertIsNotNone(wo_view) app.search.results.select(wo_view) # Before the action, there are no purchase orders for this work order results = PurchaseOrder.find_by_work_order(self.store, work_order) self.assertEquals(results.count(), 0) action = OpticalWorkOrderActions.get_instance().get_action('OpticalNewPurchase') run_dialog.return_value = Settable(supplier=supplier, supplier_order='1111', item=work_item, is_freebie=True) with contextlib.nested( mock.patch.object(self.store, 'commit'), mock.patch.object(self.store, 'close')): self.activate(action) run_dialog.assert_called_once_with(OpticalSupplierEditor, None, self.store, work_order) # Now there should be one purchase order results = PurchaseOrder.find_by_work_order(self.store, work_order) self.assertEquals(results.count(), 1) app.deactivate()
def _create_model(self, store): supplier_id = sysparam.get_object_id('SUGGESTED_SUPPLIER') branch = api.get_current_branch(store) group = PaymentGroup(store=store) status = PurchaseOrder.ORDER_PENDING return PurchaseOrder(supplier_id=supplier_id, responsible=api.get_current_user(store), branch=branch, status=status, group=group, store=store)
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 purchase = PurchaseOrder(store=store, status=PurchaseOrder.ORDER_PENDING, supplier=supplier, responsible=api.get_current_user(store), branch=api.get_current_branch(store), 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: cost = 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
def _get_purchase_from_quote(self, quote, store): quote_purchase = quote.purchase real_order = quote_purchase.clone() has_selected_items = False # add selected items for quoted_item in self.quoted_items: order = store.fetch(quoted_item.order) if order is quote_purchase and quoted_item.selected: purchase_item = store.fetch(quoted_item.item).clone() purchase_item.order = real_order has_selected_items = True # override some cloned data real_order.group = PaymentGroup(store=store) real_order.open_date = localtoday().date() real_order.quote_deadline = None real_order.status = PurchaseOrder.ORDER_PENDING if has_selected_items: return real_order else: PurchaseOrder.delete(real_order.id, store=store)
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
def create_purchase_order(self, responsible, create_payments=False, station_name=u'StoqLinkServer'): payment_group = self._create_payment_group() identifier = PurchaseOrder.get_temporary_identifier(self.store) notes = _(u"Invoice number: %s") % self.invoice_number station = set_current_branch_station(self.store, station_name, confirm=False) self._create_and_confirm_purchase_order(identifier, payment_group, notes, station, responsible) if create_payments: self._create_payments(station) self.create_receiving_order(station) self.store.commit() return self.purchase_order
def test_work_order_cancel_change_status(self): product = self.create_product() opt_type = OpticalProduct.TYPE_GLASS_LENSES optical_product = self.create_optical_product(optical_type=opt_type) optical_product.product = product sale = self.create_sale() sale_item = sale.add_sellable(sellable=product.sellable) wo = self.create_workorder() work_item = wo.add_sellable(product.sellable) work_item.sale_item = sale_item wo.sale = sale wo.approve(self.current_user) app = self.create_app(ServicesApp, u'services') app.search.refresh() for wo_view in app.search.results: if wo_view.work_order == wo: break self.assertIsNotNone(wo_view) app.search.results.select(wo_view) with mock.patch('plugins.optical.opticalui.run_dialog') as run_dialog: # No optical work order related to this WO, the dialog doesn't even run wo.work(self.current_branch, self.current_user) self.assertNotCalled(run_dialog) wo.pause(self.current_user, 'Reason') optical_wo = self.create_optical_work_order() optical_wo.work_order = wo with mock.patch('plugins.optical.opticalui.run_dialog') as run_dialog: run_dialog.return_value = None wo.work(self.current_branch, self.current_user) # At this point we didnt create a purchase results = PurchaseOrder.find_by_work_order(wo.store, wo) self.assertEquals(len(list(results)), 0) app.deactivate()
def test_work_order_cancel_change_status(self): product = self.create_product() opt_type = OpticalProduct.TYPE_GLASS_LENSES optical_product = self.create_optical_product(optical_type=opt_type) optical_product.product = product sale = self.create_sale() sale_item = sale.add_sellable(sellable=product.sellable) wo = self.create_workorder() work_item = wo.add_sellable(product.sellable) work_item.sale_item = sale_item wo.sale = sale wo.approve() app = self.create_app(ServicesApp, u'services') app.search.refresh() for wo_view in app.search.results: if wo_view.work_order == wo: break self.assertIsNotNone(wo_view) app.search.results.select(wo_view) with mock.patch('plugins.optical.opticalui.run_dialog') as run_dialog: # No optical work order related to this WO, the dialog doesn't even run wo.work() self.assertNotCalled(run_dialog) wo.pause('Reason') optical_wo = self.create_optical_work_order() optical_wo.work_order = wo with mock.patch('plugins.optical.opticalui.run_dialog') as run_dialog: run_dialog.return_value = None wo.work() # At this point we didnt create a purchase results = PurchaseOrder.find_by_work_order(wo.store, wo) self.assertEquals(len(list(results)), 0) app.deactivate()
def __init__(self, store, model=None, edit_mode=False): title = self._get_title(model) self.sync_mode = api.sysparam.get_bool('SYNCHRONIZED_MODE') self.current_branch = api.get_current_branch(store) if self.sync_mode and not model: self.temporary_identifier = PurchaseOrder.get_temporary_identifier(store) model = model or self._create_model(store) # Should we show all products or only the ones associated with the # selected supplier? self.all_products = False # If we receive the order right after the purchase. self.receiving_model = None purchase_edit = [PurchaseOrder.ORDER_CONFIRMED, PurchaseOrder.ORDER_PENDING] if not model.status in purchase_edit: raise ValueError('Invalid order status. It should ' 'be ORDER_PENDING or ORDER_CONFIRMED') first_step = StartPurchaseStep(self, store, model) BaseWizard.__init__(self, store, first_step, model, title=title, edit_mode=edit_mode)
def test_work_order_change_status(self): supplier = self.create_supplier() product = self.create_product() opt_type = OpticalProduct.TYPE_GLASS_LENSES optical_product = self.create_optical_product(optical_type=opt_type) optical_product.product = product sale = self.create_sale() sale_item = sale.add_sellable(sellable=product.sellable) wo = self.create_workorder() work_item = wo.add_sellable(product.sellable) work_item.sale_item = sale_item wo.sale = sale optical_wo = self.create_optical_work_order() optical_wo.work_order = wo app = self.create_app(ServicesApp, u'services') app.search.refresh() for wo_view in app.search.results: if wo_view.work_order == wo: break self.assertIsNotNone(wo_view) app.search.results.select(wo_view) with mock.patch('plugins.optical.opticalui.run_dialog') as run_dialog: wo.approve(self.current_user) run_dialog.return_value = Settable(supplier=supplier, supplier_order='1111', item=work_item, is_freebie=False) wo.work(self.current_branch, self.current_user) results = PurchaseOrder.find_by_work_order(wo.store, wo) self.assertEquals(len(list(results)), 1) wo.finish(self.current_branch, self.current_user) app.deactivate()
def test_work_order_change_status(self): supplier = self.create_supplier() product = self.create_product() opt_type = OpticalProduct.TYPE_GLASS_LENSES optical_product = self.create_optical_product(optical_type=opt_type) optical_product.product = product sale = self.create_sale() sale_item = sale.add_sellable(sellable=product.sellable) wo = self.create_workorder() work_item = wo.add_sellable(product.sellable) work_item.sale_item = sale_item wo.sale = sale optical_wo = self.create_optical_work_order() optical_wo.work_order = wo app = self.create_app(ServicesApp, u'services') app.search.refresh() for wo_view in app.search.results: if wo_view.work_order == wo: break self.assertIsNotNone(wo_view) app.search.results.select(wo_view) with mock.patch('plugins.optical.opticalui.run_dialog') as run_dialog: wo.approve() run_dialog.return_value = Settable(supplier=supplier, supplier_order='1111', item=work_item, is_freebie=False) wo.work() results = PurchaseOrder.find_by_work_order(wo.store, wo) self.assertEquals(len(list(results)), 1) wo.finish() app.deactivate()
def process_one(self, data, fields, store): person = store.find(Person, name=data.supplier_name).one() if person is None or person.supplier is None: raise ValueError(u"%s is not a valid supplier" % ( data.supplier_name, )) supplier = person.supplier person = store.find(Person, name=data.transporter_name).one() if person is None or person.transporter is None: raise ValueError(u"%s is not a valid transporter" % ( data.transporter_name, )) transporter = person.transporter person = store.find(Person, name=data.branch_name).one() if person is None or person.branch is None: raise ValueError(u"%s is not a valid branch" % ( data.branch_name, )) branch = person.branch person = store.find(Person, name=data.user_name).one() if person is None or person.login_user is None: raise ValueError(u"%s is not a valid user" % ( data.user_name, )) login_user = person.login_user group = PaymentGroup(store=store) purchase = PurchaseOrder(store=store, status=PurchaseOrder.ORDER_PENDING, supplier=supplier, transporter=transporter, group=group, responsible=get_current_user(store), branch=branch) for sellable in self.parse_multi(Sellable, data.sellable_list, store): if not sellable.product: continue PurchaseItem(store=store, quantity=int(data.quantity), base_cost=sellable.cost, sellable=sellable, order=purchase) method = PaymentMethod.get_by_name(store, data.payment_method) method.create_payment(Payment.TYPE_OUT, purchase.group, branch, purchase.purchase_total, self.parse_date(data.due_date)) purchase.confirm() receiving_order = ReceivingOrder(responsible=login_user, supplier=supplier, invoice_number=int(data.invoice), transporter=transporter, branch=branch, store=store) receiving_order.add_purchase(purchase) for purchase_item in purchase.get_items(): ReceivingOrderItem( store=store, cost=purchase_item.sellable.cost, sellable=purchase_item.sellable, quantity=int(data.quantity), purchase_item=purchase_item, receiving_order=receiving_order ) receiving_order.confirm()
def process_one(self, data, fields, store): person = store.find(Person, name=data.supplier_name).one() if person is None or person.supplier is None: raise ValueError(u"%s is not a valid supplier" % (data.supplier_name, )) supplier = person.supplier person = store.find(Person, name=data.transporter_name).one() if person is None or person.transporter is None: raise ValueError(u"%s is not a valid transporter" % (data.transporter_name, )) transporter = person.transporter person = store.find(Person, name=data.branch_name).one() if person is None or person.branch is None: raise ValueError(u"%s is not a valid branch" % (data.branch_name, )) branch = person.branch login_user = store.find(LoginUser, username=u'admin').one() group = PaymentGroup(store=store) purchase = PurchaseOrder(store=store, status=PurchaseOrder.ORDER_PENDING, open_date=self.parse_date(data.due_date), supplier=supplier, transporter=transporter, group=group, responsible=get_current_user(store), branch=branch) for sellable in self.parse_multi(Sellable, data.sellable_list, store): if not sellable.product: continue PurchaseItem(store=store, quantity=int(data.quantity), base_cost=sellable.cost, sellable=sellable, order=purchase) method = PaymentMethod.get_by_name(store, data.payment_method) method.create_payment(Payment.TYPE_OUT, purchase.group, branch, purchase.purchase_total, self.parse_date(data.due_date)) purchase.confirm() for payment in purchase.payments: payment.open_date = purchase.open_date receiving_order = ReceivingOrder(responsible=login_user, supplier=supplier, invoice_number=int(data.invoice), transporter=transporter, branch=branch, store=store) receiving_order.add_purchase(purchase) for purchase_item in purchase.get_items(): ReceivingOrderItem(store=store, cost=purchase_item.sellable.cost, sellable=purchase_item.sellable, quantity=int(data.quantity), purchase_item=purchase_item, receiving_order=receiving_order) receiving_order.confirm()
class NFePurchase(Domain): __storm_table__ = 'nfe_purchase' user_id = IdCol() #: The user responsible for the import user = Reference(user_id, "LoginUser.id") branch_id = IdCol() #: The branch that is buying/receiving the products branch = Reference(branch_id, "Branch.id") nfe_supplier_id = IdCol() #: The supplier of the products nfe_supplier = Reference(nfe_supplier_id, "NFeSupplier.id") purchase_order_id = IdCol() #: Reference the purchase order when the importing is done purchase_order = Reference(purchase_order_id, "PurchaseOrder.id") #: The CNPJ of the branch that is importing the nfe cnpj = UnicodeCol(default=u"") #: Invoice number invoice_number = IntCol() #: Invoice series invoice_series = IntCol() #: Stores the date that this nfe was imported process_date = DateTimeCol(default_factory=localnow) #: If this purchase is already confirmed confirm_purchase = BoolCol(default=False) #: Freight type can be FOB and CIF freight_type = UnicodeCol(default=u"fob") #: The price of the freight freight_cost = PriceCol() #: The total cost of products + services total_cost = PriceCol() #: The Raw NFe's XML xml = XmlCol() payments = ReferenceSet('id', 'NFePayment.nfe_purchase_id') @property def supplier_name(self): return self.nfe_supplier.name or self.nfe_supplier.fancy_name @property def branch_description(self): return self.branch.get_description() @property def freight_type_str(self): if self.freight_type == PurchaseOrder.FREIGHT_FOB: return u"FOB" return u"CIF" @property def items(self): items = self.store.find(NFeItem, NFeItem.nfe_purchase == self) return items @classmethod def find_purchase_order(cls, store, nfe_supplier, invoice_number, invoice_series): return store.find( NFePurchase, And(NFePurchase.nfe_supplier == nfe_supplier, NFePurchase.invoice_number == invoice_number, NFePurchase.invoice_series == invoice_series)).one() # Private Methods def _create_payment_group(self): return PaymentGroup(store=self.store, recipient=self.nfe_supplier.supplier.person, payer=self.branch.person) def _create_and_confirm_purchase_order(self, identifier, payment_group, notes, station, responsible): self.purchase_order = PurchaseOrder( store=self.store, identifier=identifier, branch=self.branch, status=PurchaseOrder.ORDER_PENDING, open_date=localnow(), notes=notes, freight_type=self.freight_type, expected_freight=self.freight_cost, supplier=self.nfe_supplier.supplier, group=payment_group, station=station) self._add_purchase_order_item() self.purchase_order.confirm(responsible=responsible) def _add_purchase_order_item(self): for item in self.items: sellable = item.sellable purchase_item = self.purchase_order.add_item( sellable=sellable, quantity=item.quantity, cost=item.cost, ipi_value=item.ipi_cost, icms_st_value=item.icmsst_cost) item.purchase_item_id = purchase_item.id sellable.product.ncm = item.ncm or sellable.product.ncm self.maybe_create_product_supplier_info(item, self.nfe_supplier.supplier) product = sellable.product if product and product.is_package: for component in product.get_components(): self.purchase_order.add_item( sellable=component.component.sellable, # The real cost and quantity will be # calculated from the parent item cost=item.cost, quantity=item.quantity, parent=purchase_item) def _create_payments(self, station): nfe_payments = list(self.payments) # FIXME: receive from frontend method = PaymentMethod.get_by_name(store=self.store, name=u"bill") # FIXME: Select method in frontend and add option to split the payment # in more than one duplicate identifier = Payment.get_temporary_identifier(self.store) if not nfe_payments: payment = method.create_payment( branch=self.purchase_order.branch, station=station, payment_type=Payment.TYPE_OUT, payment_group=self.purchase_order.group, value=self.purchase_order.purchase_total, identifier=identifier) payment.status = u'paid' return payment payments = [] for i, item in enumerate(nfe_payments, start=1): identifier = Payment.get_temporary_identifier(self.store) payment = Payment(store=self.store, branch=self.purchase_order.branch, identifier=identifier, value=item.value, base_value=item.value, due_date=item.due_date, status=Payment.STATUS_PAID, group=self.purchase_order.group, method=method, bill_received=True, payment_type=Payment.TYPE_OUT, station=station) payment.description = method.describe_payment( payment.group, i, len(list(nfe_payments))) item.description = payment.description self.purchase_order.group.add_item(payment) payments.append(payment) return payments # # Public # def get_key(self): if self.xml is None: return inf_nfe = self.xml.find('.//{*}infNFe') # Removing prefix NFe from the actual Id key = inf_nfe.get('Id')[3:] return key def find_or_create_supplier(self, nfe_supplier): # FIXME: Need to do the same thing to Individual suppliers person = Person.get_or_create_by_document( self.store, nfe_supplier.cnpj, name=nfe_supplier.name, phone_number=nfe_supplier.phone_number, notes=u"Automatically created by Stoq-Link") person.company.state_registry = nfe_supplier.state_registry person.company.fancy_name = nfe_supplier.fancy_name or nfe_supplier.name if person.supplier is None: supplier = Supplier(store=self.store, person=person) nfe_supplier.supplier = supplier return person.supplier def create_purchase_order(self, responsible, create_payments=False, station_name=u'StoqLinkServer'): payment_group = self._create_payment_group() identifier = PurchaseOrder.get_temporary_identifier(self.store) notes = _(u"Invoice number: %s") % self.invoice_number station = set_current_branch_station(self.store, station_name, confirm=False) self._create_and_confirm_purchase_order(identifier, payment_group, notes, station, responsible) if create_payments: self._create_payments(station) self.create_receiving_order(station) self.store.commit() return self.purchase_order def create_receiving_order(self, station): notes = u"Created automatically with Stoq-Link" # TODO Eventually get this from the invoice data. cfop = sysparam.get_object(self.store, 'DEFAULT_RECEIVING_CFOP') receiving_invoice = ReceivingInvoice( store=self.store, freight_total=self.freight_cost, invoice_number=self.invoice_number, invoice_total=self.total_cost, supplier=self.purchase_order.supplier, branch=self.branch, responsible=self.user, station=station) receiving_order = ReceivingOrder(store=self.store, branch=self.branch, station=station, notes=notes, cfop=cfop, confirm_date=datetime.datetime.now(), status=u'closed', receiving_invoice=receiving_invoice) receiving_order.add_purchase(self.purchase_order) for item in self.purchase_order.get_items(): receiving_order.add_purchase_item(item=item) if self.freight_type == PurchaseOrder.FREIGHT_CIF: receiving_order.update_payments(create_freight_payment=True) receiving_invoice.freight_type = receiving_invoice.guess_freight_type() receiving_order.confirm(self.user) return receiving_order 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 create_sellable(self, product_info, responsible): if product_info.get('is_package') != 'true': raise SellableError( """A criação de produtos somente é permitida para produtos do tipo pacote. Verifique o cache do seu navegador.""") sellable = None if product_info["code"]: sellable = self.store.find(Sellable, Sellable.code == product_info["code"]) if sellable: return sellable = Sellable(store=self.store, description=product_info["description"], cost=Decimal(product_info["cost"]), price=Decimal(product_info["price"])) sellable.code = product_info["code"] sellable.barcode = product_info["barcode"] sellable.notes = "Created via API" + product_info["notes"] sellable.unit_id = product_info["unit_id"] or None sellable.tax_constant_id = product_info["tax_constant"] or None sellable.default_sale_cfop_id = product_info[ "default_sale_cfop_id"] or None sellable.category_id = product_info["category_id"] or None # FIXME Need to get more info from NFe to fill both Product and Storable product = Product(store=self.store, sellable=sellable) product.manage_stock = product_info.get('manage_stock') == 'true' product.is_package = product_info.get('is_package') == 'true' package_quantity = product_info.get('package_quantity') item_ean = product_info.get('item_ean') item = self.store.find(Sellable, barcode=item_ean).one() ProductComponent(product=product, component=item.product, price=sellable.get_price(), quantity=Decimal(package_quantity)) return sellable